00001
00002
00003
00004 #include "cddefines.h"
00005 #include "optimize.h"
00006 #include "abund.h"
00007 #include "dense.h"
00008 #include "input.h"
00009 #include "iso.h"
00010 #include "hmi.h"
00011 #include "mole.h"
00012 #include "elementnames.h"
00013 #include "parse.h"
00014
00015 void ParseElement(char *chCard )
00016 {
00017
00018
00019 static bool lgFirst = true;
00020 static long levels[NISO][LIMELM];
00021 char chCap[INPUT_LINE_LENGTH];
00022 bool lgEOL,
00023 lgEnd,
00024 lgHIT;
00025
00026 bool lgForceLog=false, lgForceLinear=false;
00027
00028 long int i,
00029 nelem,
00030 j,
00031 k;
00032 double param;
00033
00034 DEBUG_ENTRY( "ParseElement()" );
00035
00036
00037 if( lgFirst )
00038 {
00039 lgFirst = false;
00040 for( i=0; i<NISO; ++i )
00041 {
00042 for( nelem=0; nelem<LIMELM; ++nelem )
00043 {
00044 levels[i][nelem] = 0;
00045 }
00046 }
00047 }
00048
00049 abund.lgAbnSolar = false;
00050
00051
00052 if( nMatch("READ",chCard) )
00053 {
00054 abund.npSolar = 0;
00055 for( i=1; i < LIMELM; i++ )
00056 {
00057 input_readarray(chCard,&lgEnd);
00058
00059 if( lgEnd )
00060 {
00061 fprintf( ioQQQ, " Hit EOF while reading element list; use END to end list.\n" );
00062 cdEXIT(EXIT_FAILURE);
00063 }
00064
00065 strcpy( chCap, chCard );
00066 caps(chCap);
00067
00068
00069 if( strncmp(chCap,"END",3) == 0 )
00070 {
00071 return;
00072 }
00073
00074 j = 1;
00075 lgHIT = false;
00076 while( j < LIMELM && !lgHIT )
00077 {
00078 j += 1;
00079
00080 if( strncmp( chCap,elementnames.chElementNameShort[j-1] , 4) == 0 )
00081 {
00082 abund.npSolar += 1;
00083 abund.ipSolar[abund.npSolar-1] = j;
00084 lgHIT = true;
00085 }
00086 }
00087
00088 if( !lgHIT )
00089 {
00090 fprintf( ioQQQ, "%80.80s\n", chCard );
00091 fprintf( ioQQQ, " Sorry, but I did not recognize element name on this line.\n" );
00092 fprintf( ioQQQ, " Here is the list of names I recognize.\n" );
00093 fprintf( ioQQQ, " " );
00094
00095 for( k=2; k <= LIMELM; k++ )
00096 {
00097 fprintf( ioQQQ, "%4.4s\n", elementnames.chElementNameShort[k-1] );
00098 }
00099
00100 cdEXIT(EXIT_FAILURE);
00101 }
00102 }
00103
00104
00105 input_readarray(chCard,&lgEnd);
00106 strcpy( chCap, chCard );
00107 caps(chCap);
00108
00109 if( strncmp(chCap,"END",3) == 0 )
00110 {
00111 return;
00112 }
00113
00114 else
00115 {
00116 fprintf( ioQQQ, " Too many elements were entered.\n" );
00117 fprintf( ioQQQ, " I only know about%3d elements.\n",
00118 LIMELM );
00119 fprintf( ioQQQ, " Sorry.\n" );
00120 cdEXIT(EXIT_FAILURE);
00121 }
00122 }
00123
00124
00125
00126 nelem = GetElem(chCard );
00127
00128 bool lgElementSet = false;
00129 if( nelem >= ipHYDROGEN )
00130 {
00131 lgElementSet = true;
00132
00133 ASSERT( nelem>=0 && nelem < LIMELM );
00134 }
00135
00136
00137 if( nMatch(" LOG",chCard) )
00138 lgForceLog = true;
00139 else if( nMatch("LINE",chCard) )
00140 lgForceLinear = true;
00141
00142 i = 4;
00143 param = FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00144
00145 if( nMatch("SCAL",chCard) )
00146 {
00147
00148 if( lgEOL )
00149 {
00150 fprintf( ioQQQ, " There must be a number on this line.\n" );
00151 fprintf( ioQQQ, " Sorry.\n" );
00152 cdEXIT(EXIT_FAILURE);
00153 }
00154
00155 else
00156 {
00157
00158 if( !lgElementSet )
00159 {
00160 fprintf( ioQQQ,
00161 " ParseElement did not find an element on the following line:\n" );
00162 fprintf( ioQQQ,
00163 "%80.80s\n", chCard );
00164 cdEXIT(EXIT_FAILURE);
00165 }
00166
00167 if( (lgForceLog || param <= 0.) && !lgForceLinear )
00168 {
00169
00170 param = pow(10.,param);
00171 }
00172 abund.ScaleElement[nelem] = (realnum)param;
00173 }
00174 }
00175
00176 else if( nMatch("ABUN",chCard) )
00177 {
00178
00179 if( lgEOL )
00180 {
00181 fprintf( ioQQQ, " There must be a number on this line.\n" );
00182 fprintf( ioQQQ, " Sorry.\n" );
00183 cdEXIT(EXIT_FAILURE);
00184 }
00185
00186 else
00187 {
00188
00189 if( !lgElementSet )
00190 {
00191 fprintf( ioQQQ,
00192 " ParseElement did not find an element on the following line:\n" );
00193 fprintf( ioQQQ,
00194 "%80.80s\n", chCard );
00195 cdEXIT(EXIT_FAILURE);
00196 }
00197 if( lgForceLinear )
00198 {
00199 abund.solar[nelem] = (realnum)param;
00200 }
00201 else
00202 {
00203 abund.solar[nelem] = (realnum)pow(10.,param);
00204 }
00205
00206 if( abund.solar[nelem]> 1. )
00207 {
00208 fprintf( ioQQQ,
00209 " Please check the abundance of this element. It seems high to me.\n" );
00210 }
00211 }
00212 }
00213
00214 else if( nMatch(" OFF",chCard) )
00215 {
00216
00217
00218
00219 if( nMatch( "LIMI",chCard) )
00220 {
00221 if( lgEOL )
00222 {
00223 fprintf( ioQQQ, " There must be an abundances on the ELEMENT OFF LIMIT command.\n" );
00224 fprintf( ioQQQ, " Sorry.\n" );
00225 cdEXIT(EXIT_FAILURE);
00226 }
00227 dense.AbundanceLimit = (realnum)pow(10., param);
00228 }
00229 else
00230 {
00231 if( !lgElementSet )
00232 {
00233 fprintf( ioQQQ,
00234 " ParseElement did not find an element on the following line:\n" );
00235 fprintf( ioQQQ,
00236 "%80.80s\n", chCard );
00237 cdEXIT(EXIT_FAILURE);
00238 }
00239
00240 dense.lgElmtOn[nelem] = false;
00241
00242 dense.IonHigh[nelem] = -1;
00243 dense.lgSetIoniz[nelem] = false;
00244
00245 if( nelem > ipHELIUM )
00246 {
00247 levels[ipHYDROGEN][nelem] = iso.numLevels_max[ipH_LIKE][nelem];
00248 levels[ipHELIUM][nelem] = iso.numLevels_max[ipHE_LIKE][nelem];
00249 iso.numLevels_max[ipH_LIKE][nelem] = 0;
00250 iso.numLevels_max[ipHE_LIKE][nelem] = 0;
00251 }
00252
00253 if( nelem == ipHYDROGEN )
00254 {
00255 fprintf( ioQQQ, " It is not possible to turn hydrogen off.\n" );
00256 fprintf( ioQQQ, " Sorry.\n" );
00257 cdEXIT(EXIT_FAILURE);
00258 }
00259 }
00260 }
00261
00262
00263 else if( nMatch("IONI",chCard) )
00264 {
00265 bool lgLogSet = false;
00266 int ion;
00267 int ihi , low;
00268
00269
00270 if( !lgElementSet )
00271 {
00272 fprintf( ioQQQ,
00273 " ParseElement did not find an element on the following line:\n" );
00274 fprintf( ioQQQ,
00275 "%80.80s\n", chCard );
00276 cdEXIT(EXIT_FAILURE);
00277 }
00278 if( !dense.lgElmtOn[nelem] )
00279 {
00280 fprintf(ioQQQ,"Sorry, you cannot set the ionization of %s since it has been turned off.\n" ,
00281 elementnames.chElementName[nelem] );
00282 cdEXIT(EXIT_FAILURE);
00283 }
00284
00285 i = 4;
00286
00287 dense.lgSetIoniz[nelem] = true;
00288 ion = 0;
00289 while( ion<nelem+2 )
00290 {
00291
00292
00293
00294 dense.SetIoniz[nelem][ion] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00295
00296 if( lgEOL )
00297 break;
00298
00299
00300 if( dense.SetIoniz[nelem][ion] < 0. )
00301 lgLogSet = true;
00302 ++ion;
00303 }
00304
00305
00306 for( i=ion; i<nelem+2; ++i )
00307 dense.SetIoniz[nelem][i] = 0.;
00308
00309
00310 if( lgLogSet )
00311 {
00312 for( i=0; i<ion; ++i )
00313 dense.SetIoniz[nelem][i] = (realnum)pow((realnum)10.f, dense.SetIoniz[nelem][i]);
00314 }
00315
00316
00317 low = 0;
00318 while( dense.SetIoniz[nelem][low]==0 && low < nelem+1 )
00319 ++low;
00320 ihi = nelem+1;
00321 while( dense.SetIoniz[nelem][ihi]==0 && ihi > low )
00322 --ihi;
00323
00324 if( ihi==low && dense.SetIoniz[nelem][ihi]==0 )
00325 {
00326 fprintf(ioQQQ," element ionization command has all zero ionization fractions. This is not possible.\n Sorry\n");
00327 cdEXIT(EXIT_FAILURE);
00328 }
00329 for(i=low; i<=ihi; ++i )
00330 {
00331 if( dense.SetIoniz[nelem][i]==0 )
00332 {
00333 fprintf(ioQQQ," element abundance command has zero abundance between positive values. This is not possible.\n Sorry\n");
00334 cdEXIT(EXIT_FAILURE);
00335 }
00336 }
00337
00338
00339
00340
00341
00342 if( nelem==ipHYDROGEN && !hmi.lgNoH2Mole )
00343 {
00344 fprintf(ioQQQ," Hydrogen ionization has been set, H chemistry is disabled.\n");
00345
00346 hmi.lgNoH2Mole = true;
00347 }
00348
00349
00350
00351 if( mole.lgElem_in_chemistry[nelem] && !co.lgNoCOMole )
00352 {
00353 fprintf(ioQQQ," The ionization of an element in the CO chemistry network has been set, CO chemistry is disabled.\n");
00354
00355 co.lgNoCOMole = true;
00356 }
00357 }
00358
00359
00360
00361 else if( nMatch(" ON ",chCard) )
00362 {
00363
00364 if( !lgElementSet )
00365 {
00366 fprintf( ioQQQ,
00367 " ParseElement did not find an element on the following line:\n" );
00368 fprintf( ioQQQ,
00369 "%80.80s\n", chCard );
00370 cdEXIT(EXIT_FAILURE);
00371 }
00372
00373 dense.lgElmtOn[nelem] = true;
00374
00375 if( levels[ipHYDROGEN][nelem] )
00376 {
00377 iso.numLevels_max[ipH_LIKE][nelem] = levels[ipHYDROGEN][nelem];
00378 iso.numLevels_max[ipHE_LIKE][nelem] = levels[ipHELIUM][nelem];
00379 }
00380 }
00381
00382 else if( nMatch("TABL",chCard) )
00383 {
00384
00385 if( !lgElementSet )
00386 {
00387 fprintf( ioQQQ,
00388 " ParseElement did not find an element on the following line:\n" );
00389 fprintf( ioQQQ,
00390 "%80.80s\n", chCard );
00391 cdEXIT(EXIT_FAILURE);
00392 }
00393
00394 abund.lgAbunTabl[nelem] = true;
00395
00396
00397 abund.lgAbTaON = true;
00398
00399
00400
00401 if( nMatch("DEPT",chCard) )
00402 abund.lgAbTaDepth[nelem] = true;
00403 else
00404 abund.lgAbTaDepth[nelem] = false;
00405
00406
00407 if( nelem == ipHYDROGEN )
00408 {
00409 fprintf( ioQQQ, " cannot change abundance of hydrogen.\n" );
00410 fprintf( ioQQQ, " Sorry.\n" );
00411 cdEXIT(EXIT_FAILURE);
00412 }
00413
00414
00415 input_readarray(chCard,&lgEnd);
00416 i = 1;
00417 abund.AbTabRad[0][nelem] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00418 abund.AbTabFac[0][nelem] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00419
00420 if( lgEOL )
00421 {
00422 fprintf( ioQQQ, " no pairs entered - cannot interpolate\n" );
00423 cdEXIT(EXIT_FAILURE);
00424 }
00425
00426
00427 abund.nAbunTabl = 2;
00428
00429 lgEnd = false;
00430
00431
00432 while( !lgEnd && abund.nAbunTabl < LIMTABD )
00433 {
00434 input_readarray(chCard,&lgEnd);
00435 if( !lgEnd )
00436 {
00437
00438 cap4(chCap , chCard);
00439 if( strncmp(chCap,"END",3) == 0 )
00440 lgEnd = true;
00441 }
00442
00443
00444 if( !lgEnd )
00445 {
00446 i = 1;
00447 abund.AbTabRad[abund.nAbunTabl-1][nelem] =
00448 (realnum)FFmtRead(chCard ,&i,INPUT_LINE_LENGTH,&lgEOL);
00449
00450 abund.AbTabFac[abund.nAbunTabl-1][nelem] =
00451 (realnum)FFmtRead(chCard ,&i,INPUT_LINE_LENGTH,&lgEOL);
00452 abund.nAbunTabl += 1;
00453 }
00454 }
00455
00456 abund.nAbunTabl -= 1;
00457
00458
00459 for( i=1; i < abund.nAbunTabl; i++ )
00460 {
00461
00462 if( abund.AbTabRad[i][nelem] <= abund.AbTabRad[i-1][nelem] )
00463 {
00464 fprintf( ioQQQ, "ParseElement: TABLE ELEMENT TABLE radii "
00465 "must be in increasing order\n" );
00466 cdEXIT(EXIT_FAILURE);
00467 }
00468 }
00469 }
00470
00471 else
00472 {
00473 fprintf( ioQQQ, "ParseElement: ELEMENT command - there must be "
00474 "a keyword on this line.\n" );
00475 fprintf( ioQQQ, " The keys I know about are TABLE, SCALE, _OFF, "
00476 "_ON_, IONIZATION, and ABUNDANCE.\n" );
00477 fprintf( ioQQQ, " Sorry.\n" );
00478 cdEXIT(EXIT_FAILURE);
00479 }
00480
00481
00482 if( optimize.lgVarOn )
00483 {
00484 optimize.nvarxt[optimize.nparm] = 1;
00485
00486 optimize.nvfpnt[optimize.nparm] = input.nRead;
00487
00488 if( nMatch("SCAL",chCard) )
00489 {
00490
00491 sprintf( optimize.chVarFmt[optimize.nparm], "ELEMENT %4.4s SCALE %%f LOG",
00492 elementnames.chElementNameShort[nelem] );
00493
00494
00495 optimize.vparm[0][optimize.nparm] = (realnum)log10(param);
00496 optimize.vincr[optimize.nparm] = 0.2f;
00497 }
00498
00499 else if( nMatch("ABUN",chCard) )
00500 {
00501
00502 sprintf( optimize.chVarFmt[optimize.nparm], "ELEMENT %4.4s ABUND %%f LOG ",
00503 elementnames.chElementNameShort[nelem] );
00504
00505
00506 optimize.vparm[0][optimize.nparm] = (realnum)param;
00507 optimize.vincr[optimize.nparm] = 0.2f;
00508 }
00509 ++optimize.nparm;
00510 }
00511 return;
00512 }