00001
00002
00003
00004 #include "cddefines.h"
00005 #include "called.h"
00006 #include "rfield.h"
00007 #include "trace.h"
00008 #include "input.h"
00009 #include "parse.h"
00010
00011 void ParseInterp(char *chCard,
00012 bool *lgEOF)
00013 {
00014 char chLab4[5];
00015 bool lgDONE,
00016 lgEOL,
00017 lgHit;
00018 long int i,
00019 k,
00020 npairs;
00021 double cmax,
00022 cmin,
00023 fac;
00024
00025 DEBUG_ENTRY( "ParseInterp()" );
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 if( rfield.nspec >= LIMSPC-1 )
00037 {
00038 fprintf( ioQQQ, " Too many spectra entered. Increase LIMSPC\n" );
00039 cdEXIT(EXIT_FAILURE);
00040 }
00041
00042 if( !rfield.lgContMalloc[rfield.nspec] )
00043 {
00044 rfield.tNuRyd[rfield.nspec] = (realnum*)MALLOC((size_t)(NCELL*sizeof(realnum)) );
00045 rfield.tslop[rfield.nspec] = (realnum*)MALLOC((size_t)(NCELL*sizeof(realnum)) );
00046 rfield.tFluxLog[rfield.nspec] = (realnum*)MALLOC((size_t)(NCELL*sizeof(realnum)) );
00047 rfield.lgContMalloc[rfield.nspec] = true;
00048 }
00049
00050 strcpy( rfield.chSpType[rfield.nspec], "INTER" );
00051
00052
00053 npairs = 0;
00054
00055
00056 lgDONE = false;
00057
00058
00059 *lgEOF = false;
00060 while( !lgDONE && !*lgEOF )
00061 {
00062 i = 5;
00063 lgEOL = false;
00064
00065
00066
00067
00068
00069 while( !lgEOL && npairs<NCELL )
00070 {
00071 rfield.tNuRyd[rfield.nspec][npairs] =
00072 (realnum)FFmtRead(chCard ,&i,INPUT_LINE_LENGTH,&lgEOL);
00073 rfield.tFluxLog[rfield.nspec][npairs] =
00074 (realnum)FFmtRead(chCard ,&i,INPUT_LINE_LENGTH,&lgEOL);
00075 ++npairs;
00076 }
00077
00078 if( !lgEOL )
00079 {
00080 fprintf( ioQQQ, "Too many continuum points were entered.\n" );
00081 fprintf( ioQQQ,
00082 "The current logic limits the number of possible points to the value of NCELL, which is %i.\n",NCELL );
00083 fprintf( ioQQQ,
00084 "Increase the value of NCELL in rfield.h.\nSorry.\n" );
00085 cdEXIT(EXIT_FAILURE);
00086 }
00087
00088
00089 --npairs;
00090
00091
00092 input_readarray(chCard,lgEOF);
00093
00094
00095
00096 while( !*lgEOF && lgInputComment(chCard) )
00097 {
00098 input_readarray(chCard,lgEOF);
00099 }
00100
00101
00102 cap4( chLab4 , chCard );
00103
00104
00105 if( called.lgTalk && (strncmp(chLab4,"CONT",4)==0) )
00106 {
00107 fprintf( ioQQQ, " * ");
00108
00109 k=0;
00110 while( chCard[k]!='\0' )
00111 {
00112 fprintf(ioQQQ,"%c",chCard[k]);
00113 ++k;
00114 }
00115 while( k<80 )
00116 {
00117 fprintf(ioQQQ,"%c",' ');
00118 ++k;
00119 }
00120 fprintf( ioQQQ,"*\n");
00121 }
00122
00123
00124 caps(chCard);
00125
00126
00127 if( strncmp(chCard,"CONT",4) != 0 )
00128 {
00129
00130 lgDONE = true;
00131 }
00132
00133
00134 if( chCard[0] == ' ' )
00135 *lgEOF = true;
00136 }
00137
00138
00139 if( lgDONE )
00140 {
00141 input.nRead -= input.iReadWay;
00142 }
00143
00144
00145 --npairs;
00146 if( npairs < 1 )
00147 {
00148 fprintf( ioQQQ, "There must be at least 2 pairs to interpolate,\nSorry\n" );
00149 cdEXIT(EXIT_FAILURE);
00150 }
00151
00152
00153
00154 else if( npairs >= NCELL - 2 )
00155 {
00156 fprintf( ioQQQ, " Too many continuum points entered.\n" );
00157 fprintf( ioQQQ,
00158 "The current logic limits the number of possible points to the value of NCELL, which is %i.\nSorry.\n",NCELL );
00159 fprintf( ioQQQ, " Increase NCELL (in cddefines.h) to more than the number of continuum points.\n" );
00160 cdEXIT(EXIT_FAILURE);
00161 }
00162
00163 if( rfield.tNuRyd[rfield.nspec][0] == 0. )
00164 {
00165
00166 if( rfield.tNuRyd[rfield.nspec][1] > 0. )
00167 {
00168
00169 rfield.tNuRyd[rfield.nspec][0] = (realnum)rfield.emm;
00170 }
00171 else if( rfield.tNuRyd[rfield.nspec][1] < 0. )
00172 {
00173
00174 rfield.tNuRyd[rfield.nspec][0] = (realnum)log10(rfield.emm);
00175 }
00176 else
00177 {
00178
00179 fprintf( ioQQQ,
00180 "An energy of zero was entered for element%3ld in INTERPOLATE and is not allowed.\nSorry\n",
00181 rfield.nspec );
00182 cdEXIT(EXIT_FAILURE);
00183 }
00184 }
00185
00186
00187 if( rfield.tNuRyd[rfield.nspec][0] >= 5. )
00188 {
00189 for( i=0; i < (npairs + 1); i++ )
00190 {
00191 rfield.tNuRyd[rfield.nspec][i] =
00192 (realnum)pow(10.,rfield.tNuRyd[rfield.nspec][i] - 15.517);
00193 }
00194 }
00195
00196 else if( rfield.tNuRyd[rfield.nspec][0] < 0. )
00197 {
00198
00199 for( i=0; i < (npairs + 1); i++ )
00200 {
00201 rfield.tNuRyd[rfield.nspec][i] = (realnum)pow(10.,(double)rfield.tNuRyd[rfield.nspec][i]);
00202 }
00203 }
00204
00205 else
00206 {
00207
00208 for( i=0; i < (npairs + 1); i++ )
00209 {
00210 if( rfield.tNuRyd[rfield.nspec][i] == 0. )
00211 {
00212 fprintf( ioQQQ, "An energy of zero was entered for element%3ld in INTERPOLATE and is not allowed.\nSorry\n",
00213 i );
00214 cdEXIT(EXIT_FAILURE);
00215 }
00216 }
00217 }
00218
00219
00220 {
00221
00222 enum {DEBUG_LOC=false};
00223 if( DEBUG_LOC )
00224 {
00225 for( i=0; i < npairs; i++ )
00226 {
00227 fprintf(ioQQQ,"%.4e\t%.3e\n",
00228 rfield.tNuRyd[rfield.nspec][i],
00229 pow(10.,(double)rfield.tFluxLog[rfield.nspec][i]) * rfield.tNuRyd[rfield.nspec][i]);
00230 }
00231 cdEXIT(EXIT_SUCCESS);
00232 }
00233 }
00234
00235 for( i=0; i < npairs; i++ )
00236 {
00237
00238 if( rfield.tNuRyd[rfield.nspec][i+1] <= rfield.tNuRyd[rfield.nspec][i] )
00239 {
00240 fprintf( ioQQQ, "The energies MUST be in increasing order. Energy #%3ld=%10.2e Ryd was greater than or equal to the next one.\nSorry.\n",
00241 i, rfield.tNuRyd[rfield.nspec][i] );
00242 cdEXIT(EXIT_FAILURE);
00243 }
00244
00245
00246 rfield.tslop[rfield.nspec][i] = (realnum)((rfield.tFluxLog[rfield.nspec][i+1] -
00247 rfield.tFluxLog[rfield.nspec][i])/log10(rfield.tNuRyd[rfield.nspec][i+1]/
00248 rfield.tNuRyd[rfield.nspec][i]));
00249 }
00250
00251
00252
00253
00254
00255 if( npairs + 2 < NCELL )
00256 {
00257
00258
00259
00260 for( i=npairs + 1; i < NCELL; i++ )
00261 {
00262 rfield.tNuRyd[rfield.nspec][i] = 0.;
00263 }
00264 }
00265
00266
00267 if( rfield.tNuRyd[rfield.nspec][0] > rfield.emm )
00268 {
00269
00270 fprintf( ioQQQ,
00271 "\n NOTE The incident continuum was not defined over the entire energy range. Some energies are set to zero.\n" );
00272 fprintf( ioQQQ,
00273 " NOTE You may be making a BIG mistake.\n\n" );
00274 }
00275
00276
00277 if( rfield.tNuRyd[rfield.nspec][0] > rfield.emm )
00278 rfield.lgMMok = false;
00279
00280 if( rfield.tNuRyd[rfield.nspec][0] > 1/36. )
00281 rfield.lgHPhtOK = false;
00282
00283
00284 if( rfield.tNuRyd[rfield.nspec][npairs] < rfield.egamry )
00285 rfield.lgGamrOK = false;
00286
00287
00288 if( rfield.tNuRyd[rfield.nspec][npairs] < rfield.EnerGammaRay )
00289 rfield.lgXRayOK = false;
00290
00291
00292 cmax = -38.;
00293 cmin = 28;
00294
00295
00296
00297 for( i=0; i <= npairs; i++ )
00298 {
00299 cmax = MAX2(cmax,rfield.tFluxLog[rfield.nspec][i]);
00300 cmin = MIN2(cmin,rfield.tFluxLog[rfield.nspec][i]);
00301 }
00302
00303
00304 if( cmax - cmin > 74. )
00305 {
00306 fprintf( ioQQQ, "The dynamic range of the specified continuum is too large.\nSorry.\n" );
00307 cdEXIT(EXIT_FAILURE);
00308 }
00309
00310 if( cmin < -37. )
00311 {
00312 fac = -cmin - 37.;
00313
00314 for( i=0; i <= npairs; i++ )
00315 {
00316 rfield.tFluxLog[rfield.nspec][i] += (realnum)fac;
00317 }
00318 }
00319
00320 else if( cmax > 37. )
00321 {
00322 fac = cmax - 37.;
00323
00324 for( i=0; i <= npairs; i++ )
00325 {
00326 rfield.tFluxLog[rfield.nspec][i] -= (realnum)fac;
00327 }
00328 }
00329
00330
00331 if( trace.lgConBug && trace.lgTrace )
00332 {
00333 fprintf( ioQQQ, " Table for this continuum;\ni\tTNU\tTFAC\tTSLOP, npairs=%li\n",
00334 npairs );
00335 for( i=0; i < npairs; i++ )
00336 {
00337 fprintf( ioQQQ, "%li\t%.4e\t%.4e\t%.4e\n",
00338 i , rfield.tNuRyd[rfield.nspec][i],
00339 rfield.tFluxLog[rfield.nspec][i], rfield.tslop[rfield.nspec][i] );
00340 }
00341 i = npairs;
00342 fprintf( ioQQQ, "%li\t%.4e\t%.4e\n",
00343 i , rfield.tNuRyd[rfield.nspec][i],
00344 rfield.tFluxLog[rfield.nspec][i]);
00345 }
00346
00347
00348
00349
00350 i = 0;
00351 while( rfield.tNuRyd[rfield.nspec][i] <= 1. && i < npairs-1 )
00352 {
00353 i += 1;
00354 }
00355
00356
00357
00358
00359 if( i < 1 )
00360 {
00361 fprintf( ioQQQ, "ParseInput finds insane i after rfield.tNuRyd loop\n");
00362 ShowMe();
00363 cdEXIT(EXIT_FAILURE);
00364 }
00365
00366
00367 fac = rfield.tFluxLog[rfield.nspec][i-1];
00368 for( i=0; i <= npairs; i++ )
00369 {
00370 rfield.tFluxLog[rfield.nspec][i] -= (realnum)fac;
00371
00372 }
00373
00374
00375 cmin = log10( FLT_MIN );
00376 cmax = log10( FLT_MAX );
00377 lgHit = false;
00378 for( i=0; i <= npairs; i++ )
00379 {
00380 if( rfield.tFluxLog[rfield.nspec][i] <= cmin ||
00381 rfield.tFluxLog[rfield.nspec][i] >= cmax )
00382 {
00383 fprintf(ioQQQ,
00384 " The log of the flux specified in interpolate pair %li is not within dynamic range of this CPU - please rescale.\n",i);
00385 fprintf(ioQQQ,
00386 " The frequency is %f and the log of the flux is %f.\n\n",
00387 rfield.tNuRyd[rfield.nspec][i] ,
00388 rfield.tFluxLog[rfield.nspec][i]);
00389 lgHit = true;
00390 }
00391 }
00392 if( lgHit )
00393 {
00394 fprintf(ioQQQ,"\n NOTE The log of the flux given in an interpolate command is outside the range of this cpu.\n");
00395 fprintf(ioQQQ," NOTE I will try to renormalize it to be within the range of this cpu, but if I crash, this is a likely reason.\n");
00396 fprintf(ioQQQ," NOTE Note that the interpolate command only is used for the shape of the continuum.\n");
00397 fprintf(ioQQQ," NOTE The order of magnitude of the flux is not used in any way.\n");
00398 fprintf(ioQQQ," NOTE For safety this could be of order unity.\n\n");
00399 }
00400
00401
00402 for( i=npairs+1; i < rfield.nupper; i++ )
00403 {
00404
00405
00406 rfield.tFluxLog[rfield.nspec][i] = 0.;
00407 rfield.tslop[rfield.nspec][i] = 0.;
00408 rfield.tNuRyd[rfield.nspec][i] = 0.;
00409 }
00410
00411
00412 ++rfield.nspec;
00413 if( rfield.nspec >= LIMSPC )
00414 {
00415
00416 fprintf( ioQQQ, " Too many continua entered; increase LIMSPC\n" );
00417 cdEXIT(EXIT_FAILURE);
00418 }
00419
00420 return;
00421 }