00001 
00002 
00003 
00004 
00005 #include "cddefines.h"
00006 #include "cddrive.h"
00007 #include "physconst.h"
00008 #include "geometry.h"
00009 #include "radius.h"
00010 #include "rfield.h"
00011 #include "opacity.h"
00012 #include "grid.h"
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 static long int iplo , iphi;
00024 
00025 
00026 static double Elo , Ehi;
00027 
00028 
00029 STATIC double Spec_cont( realnum cont[] );
00030 
00031 void cdSPEC( 
00032         
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049         int nOption ,
00050 
00051         
00052 
00053         double EnergyLow[] , 
00054 
00055         
00056         long int nEnergy ,
00057 
00058         
00059         double ReturnedSpectrum[] )
00060 
00061 {
00062         
00063         realnum *cont , 
00064                 refac;
00065         long int ncell , j;
00066 
00067         
00068         bool lgFREE;
00069 
00070         DEBUG_ENTRY( "cdSPEC()" );
00071 
00072         if( nOption == 1 )
00073         {
00074                 
00075                 cont = rfield.flux_total_incident;
00076                 lgFREE = false;
00077         }
00078         else if( nOption == 2 )
00079         {
00080                 
00081 
00082                 cont = rfield.flux;
00083                 lgFREE = false;
00084         }
00085         else if( nOption == 3 )
00086         {
00087                 
00088                 lgFREE = false;
00089                 cont = rfield.ConRefIncid;
00090         }
00091         else if( nOption == 4 )
00092         {
00093                 
00094                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00095 
00096                 
00097                 lgFREE = true;
00098                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00099                 for( j=0; j<rfield.nflux; ++j)
00100                 {
00101                         cont[j] = rfield.ConEmitOut[j]*refac;
00102                 }
00103         }
00104         else if( nOption == 5 )
00105         {
00106                 
00107                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00108                 
00109                 lgFREE = true;
00110                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00111                 for( j=0; j<rfield.nflux; ++j)
00112                 {
00113                         cont[j] = rfield.ConEmitReflec[j]*refac;
00114                 }
00115         }
00116         else if( nOption == 6 )
00117         {
00118                 
00119                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00120                 
00121                 lgFREE = true;
00122                 
00123                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00124                 for( j=0; j<rfield.nflux; ++j)
00125                 {
00126                         
00127 
00128                         cont[j] = rfield.outlin[j] *rfield.widflx[j]/rfield.anu[j]*refac;
00129                 }
00130         }
00131         else if( nOption == 7 )
00132         {
00133                 
00134                 if( geometry.lgSphere )
00135                 {
00136                         refac = 0.;
00137                 }
00138                 else
00139                 {
00140                         refac = 1.;
00141                 }
00142 
00143                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00144                 
00145                 lgFREE = true;
00146                 for( j=0; j<rfield.nflux; ++j)
00147                 {
00148                         
00149 
00150                         cont[j] = rfield.reflin[j] *rfield.widflx[j]/rfield.anu[j]*refac;
00151                 }
00152         }
00153         else
00154         {
00155                 fprintf(ioQQQ," cdSPEC called with impossible nOption (%i)\n", nOption);
00156                 cdEXIT(EXIT_FAILURE);
00157         }
00158 
00159         
00160         iplo = 0;
00161         iphi = 0;
00162         
00163         for( ncell = 0; ncell < nEnergy-1; ++ncell )
00164         {
00165                 
00166                 Elo = EnergyLow[ncell];
00167                 Ehi = EnergyLow[ncell+1];
00168                 ReturnedSpectrum[ncell] = Spec_cont( cont );
00169         }
00170 
00171         
00172         if( lgFREE )
00173         {
00174                 free(cont);
00175         }
00176         return;
00177 }
00178 
00179 
00180 STATIC double Spec_cont( realnum cont[] )
00181 {
00182         double sum;
00183         long int i;
00184 
00185         DEBUG_ENTRY( "Spec_cont()" );
00186 
00187         
00188 
00189 
00190         
00191         if( iplo >= rfield.nflux )
00192                 return 0.;
00193 
00194         
00195 
00196         
00197         while( (iplo < rfield.nflux)  &&  
00198                 !(Elo <= (rfield.AnuOrg[iplo+1]-rfield.widflx[iplo+1]/2.) &&
00199                  (Elo >= (rfield.AnuOrg[iplo]-rfield.widflx[iplo]/2.)  )) )
00200                 ++iplo;
00201 
00202         iphi = iplo;
00203         
00204         while( (iphi < rfield.nflux)  &&  
00205                 !(Ehi <= (rfield.AnuOrg[iphi+1]-rfield.widflx[iphi+1]/2.) &&
00206                  (Ehi >= (rfield.AnuOrg[iphi]-rfield.widflx[iphi]/2.)  )) )
00207                 ++iphi;
00208 
00209         sum = 0.;
00210         if( iphi-iplo>1 )
00211         {
00212                 
00213 
00214                 for( i=iplo+1; i<iphi; ++i )
00215                 {
00216                         sum += cont[i] * rfield.anu2[i];
00217                 }
00218         }
00219         ASSERT( sum>=0.);
00220 
00221         
00222 
00223 
00224         if( iplo == iphi )
00225         {
00226                 
00227                 sum = cont[iplo]/rfield.widflx[iplo]*(Ehi-Elo) * rfield.anu2[iplo];
00228                 ASSERT( sum>=0.);
00229         }
00230         else
00231         {
00232                 
00233                 double piece;
00234 
00235                 
00236                 piece = cont[iplo]/rfield.widflx[iplo]*( (rfield.AnuOrg[iplo+1]-rfield.widflx[iplo+1]/2.) - Elo ) * 
00237                         rfield.anu2[iplo];
00238                 ASSERT( piece >= 0.);
00239                 sum += piece;
00240 
00241                 
00242                 piece = cont[iphi]/rfield.widflx[iphi]*(Ehi - (rfield.AnuOrg[iphi]-rfield.widflx[iphi]/2.) ) * 
00243                         rfield.anu2[iphi];
00244                 ASSERT( piece >= 0.);
00245                 sum += piece;
00246                 ASSERT( sum>=0.);
00247         }
00248 
00249         
00250         sum *= EN1RYD / (Ehi - Elo );
00251 
00252         ASSERT( sum >=0. );
00253         return sum;
00254 
00255 #       if 0
00256         
00257         
00258 
00259         
00260         if( (Ehi-Elo) < rfield.widflx[ip] )
00261         {
00262                 
00263                 double Emiddle = (Elo + Ehi)/2.;
00264                 double f1 , f2 ,finterp;
00265                 ASSERT( (Elo >= (rfield.anu[ip]+rfield.widflx[ip]/2.
00266                 
00267 
00268                 
00269                 
00270                 f1 = cont[ip-1] /rfield.widflx[ip-1] *rfield.anu2[ip-1]*EN1RYD;
00271                 f2 = cont[ip] /rfield.widflx[ip] *rfield.anu2[ip]*EN1RYD;
00272 
00273                 finterp = f1 + (f2-f1) /rfield.widflx[ip] *
00274                         fabs(Emiddle-(rfield.anu[ip]-rfield.widflx[ip]/2.));
00275                 return( finterp );
00276         }
00277         else
00278         {
00279                 
00280                 sum = cont[ip] * rfield.anu2[ip]* EN1RYD;
00281                 
00282                 EcHi = ( rfield.anu[ip] + rfield.widflx[ip]/2. + rfield.anu[ip+1] - rfield.widflx[ip+1]/2.)/2.;
00283                 
00284                 sum *= (EcHi - Elo )/rfield.widflx[ip];
00285         }
00286 
00287         
00288         ++ip;
00289 
00290         
00291 
00292         while( Ehi > rfield.anu[ip]+rfield.widflx[ip]/2. )
00293         {
00294                 sum += cont[ip] * rfield.anu2[ip]*EN1RYD;
00295                 ++ip;
00296         }
00297 
00298         
00299         EcLo = ( rfield.anu[ip] - rfield.widflx[ip]/2. + rfield.anu[ip-1] + rfield.widflx[ip-1]/2.)/2.;
00300 
00301         
00302         sum += cont[ip] * rfield.anu2[ip] * EN1RYD *
00303                 (Ehi - EcLo )/rfield.widflx[ip];
00304 
00305         
00306         sum /= (Ehi - Elo );
00307 
00308         return(sum);
00309 #       endif
00310 }
00311 
00312 
00313 void cdSPEC2( 
00314         
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333         int nOption ,
00334 
00335         
00336         long int nEnergy ,
00337 
00338         
00339         realnum ReturnedSpectrum[] )
00340 
00341 {
00342         
00343         realnum *cont , 
00344                 refac;
00345         long int ncell , j;
00346 
00347         
00348         bool lgFREE;
00349 
00350         DEBUG_ENTRY( "cdSPEC2()" );
00351 
00352         ASSERT( nOption <= NUM_OUTPUT_TYPES );
00353 
00354         if( nOption == 1 )
00355         {
00356                 
00357                 cont = rfield.flux_total_incident;
00358                 lgFREE = false;
00359         }
00360         else if( nOption == 2 )
00361         {
00362                 
00363 
00364                 cont = rfield.flux;
00365                 lgFREE = false;
00366         }
00367         else if( nOption == 3 )
00368         {
00369                 
00370                 lgFREE = false;
00371                 cont = rfield.ConRefIncid;
00372         }
00373         else if( nOption == 4 )
00374         {
00375                 
00376                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00377                 
00378                 lgFREE = true;
00379                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00380                 for( j=0; j<rfield.nflux; ++j)
00381                 {
00382                         cont[j] = rfield.ConEmitOut[j]*refac;
00383                 }
00384         }
00385         else if( nOption == 5 )
00386         {
00387                 
00388                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00389                 
00390                 lgFREE = true;
00391                 for( j=0; j<rfield.nflux; ++j)
00392                 {
00393                         cont[j] = rfield.ConEmitReflec[j];
00394                 }
00395         }
00396         else if( nOption == 6 )
00397         {
00398                 
00399                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00400                 
00401                 lgFREE = true;
00402                 
00403                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00404                 for( j=0; j<rfield.nflux; ++j)
00405                 {
00406                         cont[j] = rfield.outlin[j]*refac;
00407                 }
00408         }
00409         else if( nOption == 7 )
00410         {
00411                 
00412                 if( geometry.lgSphere )
00413                 {
00414                         refac = 0.;
00415                 }
00416                 else
00417                 {
00418                         refac = 1.;
00419                 }
00420 
00421                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00422                 
00423                 lgFREE = true;
00424                 for( j=0; j<rfield.nflux; ++j)
00425                 {
00426                         
00427 
00428                         cont[j] = rfield.reflin[j]*refac;
00429                 }
00430         }
00431         else if( nOption == 8 )
00432         {
00433                 
00434                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00435                 
00436                 lgFREE = true;
00437                 
00438                 refac = (realnum)radius.r1r0sq*geometry.covgeo;
00439                 for( j=0; j<rfield.nflux; ++j)
00440                 {
00441                         
00442 
00443                         cont[j] = (rfield.ConEmitOut[j]+ rfield.outlin[j])*refac
00444                                           + rfield.flux[j]*(realnum)radius.r1r0sq;
00445                 }
00446         }
00447         else if( nOption == 9 )
00448         {
00449                 
00450                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00451                 
00452                 lgFREE = true;
00453                 for( j=0; j<rfield.nflux; ++j)
00454                 {
00455                         
00456 
00457                         cont[j] = ((rfield.ConRefIncid[j]+rfield.ConEmitReflec[j]) +
00458                                 rfield.reflin[j]);
00459                 }
00460         }
00461         else if( nOption == 10 )
00462         {
00463                 
00464                 cont = (realnum*)MALLOC( sizeof(realnum)*(size_t)rfield.nupper );
00465                 
00466                 lgFREE = true;
00467                 for( j=0; j<nEnergy; ++j)
00468                 {
00469                         
00470 
00471                         cont[j] = opac.ExpmTau[j]*rfield.trans_coef_total[j];
00472                 }
00473         }
00474         else
00475         {
00476                 fprintf(ioQQQ," cdSPEC called with impossible nOption (%i)\n", nOption);
00477                 cdEXIT(EXIT_FAILURE);
00478         }
00479 
00480         
00481         for( ncell = 0; ncell < nEnergy; ++ncell )
00482         {
00483         if( ncell >= rfield.nflux )
00484                 {
00485                         ReturnedSpectrum[ncell] = SMALLFLOAT;
00486                 }
00487                 else
00488                 {
00489                         ReturnedSpectrum[ncell] = cont[ncell];
00490                 }
00491                 ASSERT( ReturnedSpectrum[ncell] >=0.f );
00492         }
00493 
00494         
00495         if( lgFREE )
00496         {
00497                 free(cont);
00498         }
00499         return;
00500 }