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 }