cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
species.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2013 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 #include "cddefines.h"
4 #include "lines_service.h"
5 #include "taulines.h"
6 #include "trace.h"
7 #include "string.h"
8 #include "input.h"
9 #include "thirdparty.h"
10 #include "dense.h"
11 #include "atmdat.h"
12 #include "mole.h"
13 #include "elementnames.h"
14 #include "version.h"
15 
16 /*File nemala.cpp was developed by Humeshkar B Nemala as a part of his thesis work during the Summer of 2007*/
17 /* Initially the code has been developed to read in energy levels,radiative and
18  * collisional data from the CHIANTI and LEIDEN databases. The idea is to extend it to more databases.
19  * In the case of the Leiden database there is a single .dat file which has the energy levels information,
20  * radiative and collisional data, with the data corresponding to each collider coming one after the other.
21  * In the case of CHIANTI, the energy levels data, radiative data and collision data are present in seperate files.
22  * While LEIDEN gives collisional rate coefficients, CHIANTI gives collisional strengths.
23  * In the case of CHIANTI only two colliders are used:electrons and protons. They appear as separate files.
24  * The electron collision strengths files are always expected to be there. A flag is set and data processed
25  * if the file on proton collision strengths is available.*/
26 
27 /* There is an initialization file called species.ini which tells Cloudy what kind of data is to be used */
28 /* Structures are created separately to hold the transition data,radiative and collisional data */
29 /* The collisional structures are different for different databases depending upon whether */
30 /* collisional strengths or collisional rate coefficients are used.Finally a superstructure is constructed to hold */
31 /* the total collisional rate obtained by considering all the colliders */
32 /* The colliders considered are electron,proton,Atomic Hydrogen,He,He+,He++,Ortho Molecular Hydrogen,Para Molecular Hydrogen and Molecular Hydrogen */
33 STATIC void states_popfill(void);
34 STATIC void states_nelemfill(void);
35 STATIC void database_prep(int);
36 STATIC void set_fractionation( species *sp );
37 STATIC void states_propprint(void);
38 /*SpeciesJunk set all elements of species struc to dangerous values */
39 STATIC void SpeciesJunk( species *sp );
40 
41 #define DEBUGSTATE false
42 void database_readin( void )
43 {
44  int i,intNoSp;
45 
46  FILE *ioMASTERLIST, *ioVERSION;
47 
48  char *chToken;
49 
50  char chLine[FILENAME_PATH_LENGTH_2],
51  chDLine[FILENAME_PATH_LENGTH_2],
52  chPath[FILENAME_PATH_LENGTH_2] = "";
53 
54  const int MAX_NUM_SPECIES = 1000;
55 
56  char chLabels[MAX_NUM_SPECIES][CHARS_SPECIES];
57  char chLabelsOrig[MAX_NUM_SPECIES][CHARS_SPECIES];
58  char chPaths[MAX_NUM_SPECIES][FILENAME_PATH_LENGTH_2];
59 
60  static int nCalled = 0;
61  long nSpeciesLAMDA, nSpeciesSTOUT, nSpeciesCHIANTI;
62 
63  DEBUG_ENTRY( "database_readin()" );
64 
65  /* only do this once. */
66  if( nCalled > 0 )
67  {
68  return;
69  }
70 
71  /* this is first call, increment the nCalled counterso never do this again */
72  ++nCalled;
73 
74  // read masterlists, count number of species
75  nSpecies = 0;
76 
78  //
79  // Read LAMDA masterlist
80  //
82 
83  /* count how many lines are in the file, ignoring all lines
84  * starting with '#':This would give the number of molecules */
85  nSpeciesLAMDA = 0;
86 
87  if( atmdat.lgLamdaOn )
88  {
89  long numModelsNotUsed = 0;
90  strcpy( chPath, "lamda" );
91  strcat( chPath, input.chDelimiter );
92  strcat( chPath, "masterlist" );
93  ioMASTERLIST = open_data( chPath, "r" );
94 
95  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
96  {
97  fprintf( ioQQQ, " database_readin could not read first line of LAMDA masterlist.\n");
99  }
100 
101  do
102  {
103  if ((chLine[0]!='#') && (chLine[0]!='\n')&&(chLine[0]!='\t')&&(chLine[0]!='\r'))
104  {
105  strcpy(chDLine, chLine);
106  chToken = strtok(chDLine," \t\n");
107  if( findspecies( chToken ) != null_mole ||
108  ( chToken[1]=='-' && findspecies( chToken+2 ) != null_mole ) )
109  {
110  ASSERT( nSpecies + 1 <= MAX_NUM_SPECIES );
111  ASSERT( nSpeciesLAMDA + 1 <= MAX_NUM_SPECIES );
112  ASSERT( strlen(chToken) < CHARS_SPECIES );
113  strcpy( chLabels[nSpecies], chToken );
114  chLabels[nSpecies][CHARS_SPECIES-1] = '\0';
115 
116  // path is, for example, LAMDA/no.dat
117  strcpy( chPaths[nSpecies], "lamda" );
118  strcat( chPaths[nSpecies], input.chDelimiter );
119  chToken = strtok( NULL," \t\n" );
120  strcat( chPaths[nSpecies], chToken );
121  ++nSpecies;
122  ++nSpeciesLAMDA;
123  }
124  else
125  ++numModelsNotUsed;
126  }
127  }
128  while( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) != NULL );
129 
130  /* \todo 1 - save this and stuff as note since not really a "PROBLEM" but worth reporting */
131  //if( !t_version::Inst().lgRelease && numModelsNotUsed > 0 )
132  // fprintf( ioQQQ, "\n PROBLEM - %li LAMDA models could not be found in chemistry network.\n\n\n", numModelsNotUsed );
133 
134  fclose(ioMASTERLIST);
135  }
136 
138  //
139  // Read CDMS/JPL masterlist
140  //
141  // These data files are in LAMDA format
142  //
144 
145  if( atmdat.lgCalpgmOn )
146  {
147  long numModelsNotUsed = 0;
148  strcpy( chPath, "cdms+jpl" );
149  strcat( chPath, input.chDelimiter );
150  strcat( chPath, "masterlist" );
151  ioMASTERLIST = open_data( chPath, "r" );
152 
153  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
154  {
155  fprintf( ioQQQ, " database_readin could not read first line of CDMS/JPL masterlist.\n");
157  }
158 
159  do
160  {
161  if ((chLine[0]!='#') && (chLine[0]!='\n')&&(chLine[0]!='\t')&&(chLine[0]!='\r'))
162  {
163  strcpy(chDLine, chLine);
164  chToken = strtok(chDLine," \t\n");
165  // hacks for alternative dialects...
166  if( strcmp( chToken, "SH" ) == 0 )
167  strcpy( chToken, "HS" );
168  if( strcmp( chToken, "SH+" ) == 0 )
169  strcpy( chToken, "HS+" );
170  if( strcmp( chToken, "CCH" ) == 0 )
171  strcpy( chToken, "C2H" );
172  if( findspecies( chToken ) != null_mole ||
173  ( chToken[1]=='-' && findspecies( chToken+2 ) != null_mole ) )
174  {
175  ASSERT( nSpecies + 1 <= MAX_NUM_SPECIES );
176  ASSERT( nSpeciesLAMDA + 1 <= MAX_NUM_SPECIES );
177  strcpy( chLabels[nSpecies], chToken );
178  chLabels[nSpecies][CHARS_SPECIES-1] = '\0';
179 
180  strcpy( chPaths[nSpecies], "cdms+jpl" );
181  strcat( chPaths[nSpecies], input.chDelimiter );
182  chToken = strtok( NULL," \t\n" );
183  strcat( chPaths[nSpecies], chToken );
184  ++nSpecies;
185  ++nSpeciesLAMDA;
186  }
187  else
188  ++numModelsNotUsed;
189  }
190  }
191  while( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) != NULL );
192 
193  // if( !t_version::Inst().lgRelease && numModelsNotUsed > 0 )
194  // fprintf( ioQQQ, "\nPROBLEM - %li CDMS/JPL models could not be found in chemistry network.\n\n",
195  // numModelsNotUsed );
196 
197  fclose(ioMASTERLIST);
198  }
199 
201  //
202  // Read STOUT masterlist and VERSION
203  //
205  nSpeciesSTOUT = 0;
206  if( atmdat.lgStoutOn )
207  {
208  // default location of Stout masterlist file
209  strcpy( chPath, "stout" );
210  strcat( chPath, input.chDelimiter );
211  strcat( chPath, "masterlist" );
212  strcat( chPath, input.chDelimiter );
213 
214  strcat( chPath, atmdat.chStoutFile );
215 
216  // first try local directory, then data/SED
217  if( (ioMASTERLIST = fopen( atmdat.chStoutFile , "r" ) ) == NULL )
218  {
219  ioMASTERLIST = open_data( chPath, "r" );
220  }
221 
222  // magic number
223  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
224  {
225  fprintf( ioQQQ, " database_readin could not read first line of stout.ini.\n");
227  }
228 
229  bool lgEOLST;
230  long int ipST = 1;
231  long int nYrRdST = (long)FFmtRead(chLine,&ipST,sizeof(chLine),&lgEOLST);
232  long int nMonRdST = (long)FFmtRead(chLine,&ipST,sizeof(chLine),&lgEOLST);
233  long int nDayRdST = (long)FFmtRead(chLine,&ipST,sizeof(chLine),&lgEOLST);
234 
235  static long int nYrST =11 , nMonST = 10, nDayST = 25;
236  if( ( nYrRdST != nYrST ) || ( nMonRdST != nMonST ) || ( nDayRdST != nDayST ) )
237  {
238  fprintf( ioQQQ,
239  " I expected to find the number %2.2li %2.2li %2.2li and got %2.2li %2.2li %2.2li instead.\n" ,
240  nYrST , nMonST , nDayST , nYrRdST , nMonRdST , nDayRdST );
241  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
243  }
244  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
245  {
246  fprintf( ioQQQ, " database_readin could not read first line of CHIANTI masterlist.\n");
248  }
249 
250  do
251  {
252  strcpy(chDLine, chLine);
253  chToken = strtok(chDLine," \n");
254  if ((chLine[0]!='#') && (chLine[0]!='\n')&&(chLine[0]!='\t')&&(chLine[0]!='\r'))
255  {
256  ASSERT( nSpecies + 1 <= MAX_NUM_SPECIES );
257  ASSERT( nSpeciesSTOUT + 1 <= MAX_NUM_SPECIES );
258  strcpy( chLabels[nSpecies], chToken );
259  strcpy( chLabelsOrig[nSpecies], chLabels[nSpecies] );
260 
261  char *chElement, chTokenTemp[7];
262  strcpy( chTokenTemp, chToken );
263  chElement = strtok(chTokenTemp," \n");
264  chElement = strtok(chTokenTemp,"_");
265  uncaps( chElement );
266 
267 // printf("STOUT:%s\n",chLabels[nSpecies]);
268 
269  // path is, for example, CHIANTI/ar/ar_10/ar_10
270  // we will append extensions later
271  strcpy( chPaths[nSpecies], "stout" );
272  strcat( chPaths[nSpecies], input.chDelimiter );
273  strcat( chPaths[nSpecies], chElement );
274  strcat( chPaths[nSpecies], input.chDelimiter );
275  strcat( chPaths[nSpecies], chLabels[nSpecies] );
276  strcat( chPaths[nSpecies], input.chDelimiter );
277  strcat( chPaths[nSpecies], chLabels[nSpecies] );
278 
279  ASSERT( isalpha(chToken[0]) );
280  long cursor=0;
281  chLabels[nSpecies][0] = chToken[0];
282  if( isalpha(chToken[1]) )
283  {
284  chLabels[nSpecies][1] = chToken[1];
285  cursor = 2;
286  }
287  else
288  {
289  chLabels[nSpecies][1] = ' ';
290  cursor = 1;
291  }
292 
293  ASSERT( chToken[cursor++]=='_' );
294  ASSERT( isdigit(chToken[cursor]) );
295 
296  if( isdigit(chToken[cursor+1]) )
297  {
298  chLabels[nSpecies][2] = chToken[cursor++];
299  chLabels[nSpecies][3] = chToken[cursor++];
300  }
301  else
302  {
303  chLabels[nSpecies][2] = ' ';
304  chLabels[nSpecies][3] = chToken[cursor++];
305  }
306  chLabels[nSpecies][4] = '\0';
307  ASSERT( chToken[cursor]=='\0' || chToken[cursor]=='d' );
308 
309  // now capitalize the first letter
310  chLabels[nSpecies][0] = toupper( chLabels[nSpecies][0] );
311  ++nSpecies;
312  ++nSpeciesSTOUT;
313  }
314  }
315  while( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) != NULL );
316  fclose(ioMASTERLIST);
317  }
318 
319 
321  //
322  // Read CHIANTI masterlist and VERSION
323  //
325 
326  nSpeciesCHIANTI = 0;
327 
328  if( atmdat.lgChiantiOn )
329  {
330  char chPathSave[FILENAME_PATH_LENGTH_2];
331  strcpy( chPath, "chianti" );
332  strcat( chPath, input.chDelimiter );
333  //Preserve the path /chianti/ with chPathSave
334  //Start reading in the chianti version number
335  strcpy( chPathSave , chPath );
336  strcat(chPath,"VERSION");
337  ioVERSION = open_data(chPath,"r");
338  if( read_whole_line( chLine , (int)sizeof(chLine) , ioVERSION ) == NULL )
339  {
340  fprintf( ioQQQ, " database_readin could not read first line of the Chianti VERSION.\n");
342  }
343  fclose(ioVERSION);
344  // chianti version - string since can contain letters
345  strncpy(atmdat.chVersion,chLine,atmdat.iVersionLength);
346  // remove newline we may captured
347  long len = strlen(atmdat.chVersion);
348  if( atmdat.chVersion[len-1] == '\n' )
349  atmdat.chVersion[len-1] = '\0';
350  // may have been null earlier in string, but make sure terminated at limit
352  //Restore the previous chPath
353  strcpy(chPath,chPathSave);
354  // Read in the masterlist
355  strcat( chPath, "masterlist" );
356  strcat( chPath, input.chDelimiter );
357  // save copy
358  strcpy( chPathSave , chPath );
359 
360  // our subset of Chianti
361  strcat( chPath, atmdat.chCloudyChiantiFile );
362 
363  // first try local directory, then data/chianti
364  if( (ioMASTERLIST = fopen( atmdat.chCloudyChiantiFile , "r" ) ) == NULL )
365  {
366  ioMASTERLIST = open_data( chPath, "r" );
367  }
368 
369  // magic number
370  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
371  {
372  fprintf( ioQQQ, " database_readin could not read first line of CloudyChianti.ini.\n");
374  }
375 
376  bool lgEOL;
377  long int ip = 1;
378  long int nYrRd = (long)FFmtRead(chLine,&ip,sizeof(chLine),&lgEOL);
379  long int nMonRd = (long)FFmtRead(chLine,&ip,sizeof(chLine),&lgEOL);
380  long int nDayRd = (long)FFmtRead(chLine,&ip,sizeof(chLine),&lgEOL);
381 
382  static long int nYr=11 , nMon = 10, nDay = 3;
383  if( ( nYrRd != nYr ) || ( nMonRd != nMon ) || ( nDayRd != nDay ) )
384  {
385  fprintf( ioQQQ,
386  " database_readin: the version of CloudyChianti.ini is not the current version.\n" );
387  fprintf( ioQQQ,
388  " database_readin obtain the current version from the Cloudy web site.\n" );
389  fprintf( ioQQQ,
390  " I expected to find the number %2.2li %2.2li %2.2li and got %2.2li %2.2li %2.2li instead.\n" ,
391  nYr , nMon , nDay , nYrRd , nMonRd , nDayRd );
392  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
394  }
395 
396  if( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) == NULL )
397  {
398  fprintf( ioQQQ, " database_readin could not read first line of CHIANTI masterlist.\n");
400  }
401 
402  do
403  {
404 
405  if ((chLine[0]!='#') && (chLine[0]!='\n')&&(chLine[0]!='\t')&&(chLine[0]!='\r'))
406  {
407  strcpy(chDLine, chLine);
408  chToken = strtok(chDLine," \n");
409 
410  fixit(); //insert logic here to exclude some ions (for example, iso sequences)
411  // exclude for now the satellite lines (denoted by a "d" after the label
412  //if( chToken[3]=='d' || chToken[4]=='d' || chToken[5]=='d' )
413  if( chToken[3]!='d' && chToken[4]!='d' && chToken[5]!='d' )
414  {
415  ASSERT( nSpecies + 1 <= MAX_NUM_SPECIES );
416  ASSERT( nSpeciesCHIANTI + 1 <= MAX_NUM_SPECIES );
417  strcpy( chLabels[nSpecies], chToken );
418  strcpy( chLabelsOrig[nSpecies], chLabels[nSpecies]);
419 
420  bool skipSpecies = false;
421 
422  //Check for duplicate species with Stout
423  for( int j = nSpeciesLAMDA; j < nSpecies; j++)
424  {
425  if( strcmp( chLabelsOrig[j], chLabelsOrig[nSpecies] ) == 0)
426  {
427  printf("Skipping the Chianti version of %s, using Stout version\n",chLabels[nSpecies]);
428  skipSpecies = true;
429  break;
430  }
431  }
432  if( skipSpecies)
433  continue;
434 
435  char *chElement, chTokenTemp[7];
436  strcpy( chTokenTemp, chToken );
437  chElement = strtok(chTokenTemp," \n");
438  chElement = strtok(chTokenTemp,"_");
439  uncaps( chElement );
440 
441  // path is, for example, CHIANTI/ar/ar_10/ar_10
442  // we will append extensions later
443  strcpy( chPaths[nSpecies], "chianti" );
444  strcat( chPaths[nSpecies], input.chDelimiter );
445  strcat( chPaths[nSpecies], chElement );
446  strcat( chPaths[nSpecies], input.chDelimiter );
447  strcat( chPaths[nSpecies], chLabels[nSpecies] );
448  strcat( chPaths[nSpecies], input.chDelimiter );
449  strcat( chPaths[nSpecies], chLabels[nSpecies] );
450 
451  ASSERT( isalpha(chToken[0]) );
452  long cursor=0;
453  chLabels[nSpecies][0] = chToken[0];
454  if( isalpha(chToken[1]) )
455  {
456  chLabels[nSpecies][1] = chToken[1];
457  cursor = 2;
458  }
459  else
460  {
461  chLabels[nSpecies][1] = ' ';
462  cursor = 1;
463  }
464 
465  ASSERT( chToken[cursor++]=='_' );
466  ASSERT( isdigit(chToken[cursor]) );
467 
468  if( isdigit(chToken[cursor+1]) )
469  {
470  chLabels[nSpecies][2] = chToken[cursor++];
471  chLabels[nSpecies][3] = chToken[cursor++];
472  }
473  else
474  {
475  chLabels[nSpecies][2] = ' ';
476  chLabels[nSpecies][3] = chToken[cursor++];
477  }
478  chLabels[nSpecies][4] = '\0';
479  ASSERT( chToken[cursor]=='\0' || chToken[cursor]=='d' );
480 
481  // now capitalize the first letter
482  chLabels[nSpecies][0] = toupper( chLabels[nSpecies][0] );
483  ++nSpecies;
484  ++nSpeciesCHIANTI;
485  }
486  }
487  }
488  while( read_whole_line( chLine , (int)sizeof(chLine) , ioMASTERLIST ) != NULL );
489 
490  fclose(ioMASTERLIST);
491  }
492 
493  /* no species found, nothing to do */
494  if( nSpecies==0 )
495  return;
496 
497  /*Initialization of the dBaseSpecies Structure*/
498  dBaseSpecies = (species *)MALLOC( (unsigned long)nSpecies*sizeof(species));
499 
500  /*Initialization of the collisional rates array structure*/
501  AtmolCollRateCoeff.reserve( nSpecies );
502  AtmolCollSplines = (CollSplinesArray****)MALLOC((unsigned long)nSpecies *sizeof(CollSplinesArray***));
503  StoutCollData = (StoutColls****)MALLOC((unsigned long)nSpecies *sizeof(StoutColls***));
504 
505  /*Mallocing here takes care of the number of colliders*/
506  for( i=0; i<nSpecies; i++ )
507  {
508  AtmolCollRateCoeff.reserve( i, ipNCOLLIDER );
509  }
510  AtmolCollRateCoeff.alloc();
511 
512  // malloc state and transition arrays
513  dBaseStates.resize(nSpecies);
514  ipdBaseTrans.resize(nSpecies);
515 
516  for( i = 0; i < nSpecies; i++ )
517  {
518  dBaseTrans.push_back(TransitionList("dBaseTrans",&dBaseStates[i]));
519  SpeciesJunk( &dBaseSpecies[i] );
520  // label should be a minimum of 4 characters long
521  size_t los = max(4,strlen(chLabels[i]));
522  ASSERT( los >= 4 && los <= 7 );
523  dBaseSpecies[i].chLabel = new char[los+1];
524  strcpy(dBaseSpecies[i].chLabel,chLabels[i]);
525  dBaseSpecies[i].lgActive = true;
526 
527  /* set type and isotopologue fractions */
529 
530  // set_fractionation trims off "p-","o-", etc. Now have set label. Check size.
531  los = (int)strlen( dBaseSpecies[i].chLabel );
532  ASSERT( los < CHARS_SPECIES );
533 
534  // pad label to at least four characters.
535  if( dBaseSpecies[i].chLabel[2]=='\0' )
536  {
537  dBaseSpecies[i].chLabel[2]=' ';
538  dBaseSpecies[i].chLabel[3]=' ';
539  dBaseSpecies[i].chLabel[4]='\0';
540  }
541  else if( dBaseSpecies[i].chLabel[3]=='\0' )
542  {
543  dBaseSpecies[i].chLabel[3]=' ';
544  dBaseSpecies[i].chLabel[4]='\0';
545  }
546 
547  if( i<nSpeciesLAMDA )
548  {
549  // Read in LAMDA data files
550  atmdat_LAMDA_readin( i, chPaths[i] );
551  }
552  else if( i < nSpeciesLAMDA + nSpeciesSTOUT )
553  {
554  atmdat_STOUT_readin( i, chPaths[i] );
555  }
556  else if( i < nSpeciesLAMDA + nSpeciesSTOUT + nSpeciesCHIANTI )
557  {
558  // Read in CHIANTI data files
559  atmdat_CHIANTI_readin( i, chPaths[i] );
560  }
561  else
562  TotalInsanity();
563  }
564 
565  states_popfill();
567 
568  /*Setting nelem of the states to an arbitrary value*/
569  /*Loop over species*/
570  for( intNoSp=0; intNoSp<nSpecies; intNoSp++ )
571  {
572  database_prep(intNoSp);
573  AllTransitions.push_back(dBaseTrans[intNoSp]);
574  }
575 
576  /*To print the states*/
577  if(DEBUGSTATE)
579  return;
580 }
581 
583 {
584  DEBUG_ENTRY("set_fractionation()");
585 
586  char chToken[3];
587 
588  sp->fracIsotopologue = 1.f;
589  //types include "p-", "o-", "e-", and "a-"
590  strncpy( chToken, sp->chLabel, 2 );
591  chToken[2] = '\0';
592  if( strcmp( "p-", chToken )==0 )
593  sp->fracType = 0.25f;
594  else if( strcmp( "o-", chToken )==0 )
595  sp->fracType = 0.75f;
596  else if( strcmp( "e-", chToken )==0 )
597  sp->fracType = 0.5f;
598  else if( strcmp( "a-", chToken )==0 )
599  sp->fracType = 0.5f;
600  else
601  sp->fracType = 1.0f;
602 
603  fixit(); // what fraction should e-type and a-type Methanol have? Assume 50/50 for now.
604 
605  // Now scrape the type specifier off the label.
606  if( sp->chLabel[1]=='-')
607  memmove(sp->chLabel,sp->chLabel+2,strlen(sp->chLabel+2)+1);
608 
609  return;
610 }
611 
612 /*This function zeros the population of all states */
614 {
615  DEBUG_ENTRY( "states_popfill()" );
616 
617  for( long i=0; i<nSpecies; i++)
618  {
619  for( long j=0; j<dBaseSpecies[i].numLevels_max; j++)
620  {
621  dBaseStates[i][j].Pop() = 0.;
622  }
623  }
624  return;
625 }
626 
627 /*This function fills the nelem and IonStg fields */
629 {
630  DEBUG_ENTRY( "states_nelemfill()" );
631 
632  for( long i=0; i<nSpecies; i++ )
633  {
634  long nelem = 0, IonStg;
635  char chLabelChemical[CHARS_SPECIES];
636 
637  if( dBaseSpecies[i].lgMolecular )
638  {
639  fixit();
640  /* these should never be used if lgMolecular
641  *set to dangerous values instead of unity. */
642  nelem = -1;
643  IonStg = -1;
644  strcpy( chLabelChemical, dBaseSpecies[i].chLabel );
645  }
646  else
647  {
648  char chToken[3];
649  strncpy( chToken, dBaseSpecies[i].chLabel, 2 );
650  chToken[2] = '\0';
651  strcpy( chLabelChemical, chToken );
652  if( chLabelChemical[1]==' ' )
653  chLabelChemical[1] = '\0';
654  for( long ipElement=0; ipElement<LIMELM; ipElement++ )
655  {
656  if( strcmp( elementnames.chElementSym[ipElement], chToken )==0 )
657  {
658  nelem = ipElement + 1;
659  break;
660  }
661  }
662  ASSERT( nelem > 0 && nelem <= LIMELM );
663  strncpy( chToken, dBaseSpecies[i].chLabel + 2, 2 );
664  IonStg = atoi(chToken);
665  char chStage[5] = {'\0'};
666  if( IonStg==2 )
667  sprintf( chStage, "+" );
668  else if( IonStg>1 )
669  sprintf( chStage, "+%li", IonStg-1 );
670  strcat( chLabelChemical, chStage );
671  ASSERT( IonStg >= 1 && IonStg <= nelem+1 );
672  //Prevent importing of iso-sequences from Chianti
673  if( nelem - IonStg < NISO )
674  {
675  fprintf(ioQQQ, " PROBLEM: Cannot use Chianti model for %s%li\n",elementnames.chElementSym[nelem-1],IonStg);
676  fprintf(ioQQQ, " Iso-sequences are handled by our own model.\n");
678  }
680  // do not evaluate our cooling if we are using Chianti for this species
681 
682  if( dBaseTrans[i].chLabel() == "Chianti" )
683  {
684  dense.lgIonChiantiOn[nelem-1][IonStg-1] = true;
685  }
686  else if( dBaseTrans[i].chLabel() == "Stout" )
687  {
688  dense.lgIonStoutOn[nelem-1][IonStg-1] = true;
689  }
690  else
691  {
692  TotalInsanity();
693  }
694 
696  {
697  // used in cool_dima to indicate whether to include line
698  // with shorter wl than these databases
699  dense.maxWN[nelem-1][IonStg-1] = dBaseSpecies[i].maxWN;
700  }
701  else
702  {
703  dense.maxWN[nelem-1][IonStg-1] = 0.;
704  }
705  }
706 
707  molecule *sp = findspecies(chLabelChemical);
708  if( sp == null_mole )
709  {
710  dBaseSpecies[i].index = INT_MAX;
711  if( nelem-1 >= ipHYDROGEN && dense.lgElmtOn[nelem-1] )
712  fprintf(ioQQQ," PROBLEM: could not find species %li - %s\n",i,
713  chLabelChemical );
714  }
715  else
716  {
717  dBaseSpecies[i].index = sp->index;
718  mole.species[ sp->index ].levels = &dBaseStates[i];
719  mole.species[ sp->index ].lines = &dBaseTrans[i];
720  }
721 
722  for( long j=0; j<dBaseSpecies[i].numLevels_max; j++ )
723  {
724  dBaseStates[i][j].nelem() = nelem;
725  dBaseStates[i][j].IonStg() = IonStg;
726  }
727  }
728  return;
729 }
730 
731 /*This function prints the various properties of states*/
733 {
734  DEBUG_ENTRY( "states_propprint()" );
735 
736  for( long i=0; i<nSpecies; i++ )
737  {
738  printf("The species is %s \n",dBaseSpecies[i].chLabel);
739  printf("The data output is in the following format \n");
740  printf("Label Energy St.wt Pop Lifetime\n");
741 
742  for( long j=0; j<dBaseSpecies[i].numLevels_max; j++ )
743  {
744  printf("This is the %ld state \n",j);
745  printf("%s %f %f %f %e \n",dBaseStates[i][j].chLabel(),
746  dBaseStates[i][j].energy().WN(),
747  dBaseStates[i][j].g(),
748  dBaseStates[i][j].Pop(),
749  dBaseStates[i][j].lifetime());
750  }
751  }
752  return;
753 }
754 
755 
756 STATIC void database_prep(int intSpIndex)
757 {
758  vector<realnum> fsumAs(dBaseSpecies[intSpIndex].numLevels_max,SMALLFLOAT);
759 
760  DEBUG_ENTRY( "database_prep()" );
761 
762  /*Get the lifetimes*/
763  for( EmissionList::iterator em = dBaseTrans[intSpIndex].Emis().begin();
764  em != dBaseTrans[intSpIndex].Emis().end(); ++em)
765  {
766  fsumAs[(*em).Tran().ipHi()] += (*em).Aul();
767  (*em).iRedisFun() = ipPRD;
768  }
769 
770  dBaseStates[intSpIndex][0].lifetime()= BIGFLOAT;
771  for( int ipHi=1; ipHi < dBaseSpecies[intSpIndex].numLevels_max; ipHi++ )
772  {
773  dBaseStates[intSpIndex][ipHi].lifetime() = 1./fsumAs[ipHi];
774  }
775  return;
776 }
777 
778 /*SpeciesJunk set all elements of species struc to dangerous values */
780 {
781  sp->chLabel = NULL;
782  set_NaN(sp->fmolweight);
784  set_NaN(sp->fracType);
785  sp->lgMolecular = false;
786  sp->numLevels_local = -INT_MAX;
787  sp->numLevels_max = -INT_MAX;
788 
789  return;
790 }
STATIC void database_prep(int)
Definition: species.cpp:756
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:616
t_atmdat atmdat
Definition: atmdat.cpp:6
struct t_species species
Definition: cddefines.h:1228
bool lgStoutHybrid
Definition: atmdat.h:243
molecule * null_mole
const int FILENAME_PATH_LENGTH_2
Definition: cddefines.h:253
char chStoutFile[FILENAME_PATH_LENGTH]
Definition: atmdat.h:268
NORETURN void TotalInsanity(void)
Definition: service.cpp:886
t_input input
Definition: input.cpp:12
void set_NaN(sys_float &x)
Definition: cpu.cpp:673
bool lgStoutOn
Definition: atmdat.h:241
const realnum SMALLFLOAT
Definition: cpu.h:178
STATIC void set_fractionation(species *sp)
Definition: species.cpp:582
const int NISO
Definition: cddefines.h:265
StoutColls **** StoutCollData
Definition: taulines.cpp:20
char * chLabel
Definition: cddefines.h:1239
t_dense dense
Definition: dense.cpp:24
vector< multi_arr< int, 2 > > ipdBaseTrans
Definition: taulines.cpp:16
void atmdat_STOUT_readin(long intNS, char *chFileName)
static double * g
Definition: species2.cpp:28
double maxWN[LIMELM][LIMELM+1]
Definition: dense.h:134
FILE * ioQQQ
Definition: cddefines.cpp:7
multi_arr< CollRateCoeffArray, 2 > AtmolCollRateCoeff
Definition: taulines.cpp:18
Definition: mole.h:132
long int nSpecies
Definition: taulines.cpp:21
STATIC void states_propprint(void)
Definition: species.cpp:732
char chVersion[iVersionLength]
Definition: atmdat.h:265
t_elementnames elementnames
Definition: elementnames.cpp:5
void uncaps(char *chCard)
Definition: service.cpp:263
long index
Definition: cddefines.h:1241
char toupper(char c)
Definition: cddefines.h:704
#define MALLOC(exp)
Definition: cddefines.h:505
bool lgIonChiantiOn[LIMELM][LIMELM+1]
Definition: dense.h:128
double maxWN
Definition: cddefines.h:1261
bool lgChiantiHybrid
Definition: atmdat.h:233
long numLevels_local
Definition: cddefines.h:1245
static char chElement[NPUNLM][5]
Definition: save_colden.cpp:12
bool lgChiantiOn
Definition: atmdat.h:231
#define STATIC
Definition: cddefines.h:101
bool lgCalpgmOn
Definition: atmdat.h:247
char chCloudyChiantiFile[FILENAME_PATH_LENGTH]
Definition: atmdat.h:271
bool lgActive
Definition: cddefines.h:1259
t_mole_local mole
Definition: mole.cpp:7
molecule * findspecies(const char buf[])
valarray< class molezone > species
Definition: mole.h:355
#define EXIT_FAILURE
Definition: cddefines.h:144
const realnum BIGFLOAT
Definition: cpu.h:176
long max(int a, long b)
Definition: cddefines.h:779
realnum AtomicWeight[LIMELM]
Definition: dense.h:75
bool lgElmtOn[LIMELM]
Definition: dense.h:146
#define cdEXIT(FAIL)
Definition: cddefines.h:438
int index
Definition: mole.h:169
CollSplinesArray **** AtmolCollSplines
Definition: taulines.cpp:19
species * dBaseSpecies
Definition: taulines.cpp:14
STATIC void states_nelemfill(void)
Definition: species.cpp:628
STATIC void SpeciesJunk(species *sp)
Definition: species.cpp:779
char chElementSym[LIMELM][CHARS_ELEMENT_SYM]
Definition: elementnames.h:25
realnum fracIsotopologue
Definition: cddefines.h:1255
#define ASSERT(exp)
Definition: cddefines.h:582
bool lgIonStoutOn[LIMELM][LIMELM+1]
Definition: dense.h:131
bool lgMolecular
Definition: cddefines.h:1249
const int LIMELM
Definition: cddefines.h:262
long numLevels_max
Definition: cddefines.h:1243
void atmdat_LAMDA_readin(long intNS, char *chFileName)
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
char chDelimiter[3]
Definition: input.h:42
#define DEBUGSTATE
Definition: species.cpp:41
STATIC void states_popfill(void)
Definition: species.cpp:613
realnum fracType
Definition: cddefines.h:1253
vector< qList > dBaseStates
Definition: taulines.cpp:15
void database_readin(void)
Definition: species.cpp:42
realnum fmolweight
Definition: cddefines.h:1247
void atmdat_CHIANTI_readin(long intNS, char *chFileName)
const int ipPRD
Definition: cddefines.h:294
vector< TransitionList > AllTransitions
Definition: taulines.cpp:8
char * read_whole_line(char *chLine, int nChar, FILE *ioIN)
Definition: service.cpp:70
bool lgLamdaOn
Definition: atmdat.h:239
vector< TransitionList > dBaseTrans
Definition: taulines.cpp:17
const int ipHYDROGEN
Definition: cddefines.h:309
void fixit(void)
Definition: service.cpp:991
static const int iVersionLength
Definition: atmdat.h:263
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition: service.cpp:381