cloudy  trunk
parse_abundances.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 /*ParseAbundances parse and read in composition as set by abundances command */
4 #include "cddefines.h"
5 #include "grains.h"
6 #include "grainvar.h"
7 #include "abund.h"
8 #include "phycon.h"
9 #include "called.h"
10 #include "elementnames.h"
11 #include "input.h"
12 #include "parser.h"
13 
15  /* following set true by grains command,
16  * so this will not set more grains if grains already on. */
17 {
18  bool lgLog;
19  long int i;
20  double absav[LIMELM],
21  chk;
22  GrainPar gp;
23 
24  DEBUG_ENTRY( "ParseAbundances()" );
25 
26  if( p.nMatch("STAR") )
27  {
28  /* Fred Hamann's star burst galaxy mixture -- includes a number which isn't an abundance */
29  abund_starburst(p);
30  return;
31  }
32 
33  absav[0] = p.FFmtRead();
34  /* this branch at least one number on the line - an abundance */
35  if( !p.lgEOL() )
36  {
37  absav[1] = p.FFmtRead();
38  if( p.lgEOL() )
39  {
40  /* this branch, we found one, but not two, numbers -
41  * must be one of a few special cases */
42  if( p.nMatch(" ALL") )
43  {
44  /* special option, all abundances will be this number */
45  if( absav[0] <= 0. )
46  {
47  absav[0] = pow(10.,absav[0]);
48  }
49  for( i=1; i < LIMELM; i++ )
50  {
51  abund.solar[i] = (realnum)absav[0];
52  }
53 
54  }
55  else if( p.nMatch("OLD ") && p.nMatch("SOLA") )
56  {
57  i = (int)absav[0];
58  /* old solar - better be the number "84" on the line */
59  if( i!=84 )
60  {
61  fprintf( ioQQQ,
62  " The only old abundance set I have is for version 84 - %3ld was requested. Sorry.\n",
63  i );
65  }
66  for( i=1; i < LIMELM; i++ )
67  {
68  /* these are the old abundances */
70  abund.solar[i] = abund.OldSolar84[i];
71  }
72  }
73  else if( p.nMatch("GASS10"))
74  {
75  /* Grevesse, Asplund, Sauval, and Scott solar */
76  /* >>refer solar abund Grevesse, N., Asplund, M., Sauval, A. J., & Scott, P. 2010, Ap&SS, 48 */
77  for( i=1; i < LIMELM; i++ )
78  {
79  /* these are the GASS10 solar abundances */
80  abund.SolarSave[i] = abund.GASS10[i];
81  abund.solar[i] = abund.GASS10[i];
82  }
83  }
84  else
85  {
86  fprintf( ioQQQ,
87  " I did not recognize a sub-keyword - options are ALL, OLD SOLAR 84, and GASS10. Sorry.\n");
89  }
90 
91  /* normal return */
92  return;
93  }
94 
95  /* we get here if there is a second number - read in all abundances */
96  for( i=2; i < abund.npSolar; i++ )
97  {
98  absav[i] = p.FFmtRead();
99  if( p.lgEOL() )
100  {
101  /* read CONTINUE line if J scanned off end before reading all abund */
102  do
103  {
104  p.getline();
105  if( p.m_lgEOF )
106  {
107  fprintf( ioQQQ, " There MUST be%3ld abundances entered, there were only%3ld. Sorry.\n",
108  abund.npSolar, i );
110  }
111  } while( p.isComment() );
112 
113  p.echo();
114 
115  if( p.strcmp("CONT") != 0 )
116  {
117  fprintf( ioQQQ, " There MUST be%3ld abundances entered, there were only%3ld. Sorry.\n",
118  abund.npSolar, i );
120  }
121  else
122  {
123  absav[i] = p.FFmtRead();
124  if( p.lgEOL() )
125  {
126  fprintf( ioQQQ, " There MUST be%3ld abundances entered, there were only%3ld. Sorry.\n",
127  abund.npSolar, i);
129  }
130  }
131  }
132  }
133 
134  /* fell through to here after reading in N abundances for N elements
135  * check that there are no more abundances on the line - that would
136  * be an error - a typo */
137  chk = p.FFmtRead();
138  if( !p.lgEOL() || (chk!=0.) )
139  {
140  /* got another number, not lgEOL, so too many numbers */
141  fprintf( ioQQQ, " There were more than %ld abundances entered\n",
142  abund.npSolar );
143  fprintf( ioQQQ, " Could there have been a typo somewhere?\n" );
144  }
145 
146  /* are numbers scale factors, or log of abund rel to H?? */
147  lgLog = false;
148  for( i=0; i < abund.npSolar; i++ )
149  if( absav[i] < 0. )
150  lgLog = true;
151 
152  if( lgLog )
153  {
154  /* entered as log of number rel to hydrogen */
155  for( i=0; i < abund.npSolar; i++ )
156  abund.solar[abund.ipSolar[i]-1] = (realnum)pow(10.,absav[i]);
157  }
158  else
159  {
160  /* scale factors relative to solar */
161  for( i=0; i < abund.npSolar; i++ )
162  abund.solar[abund.ipSolar[i]-1] *= (realnum)absav[i];
163  }
164 
165  /* check whether the abundances are reasonable */
166  for( i=1; i < LIMELM; i++ )
167  {
168  if( abund.solar[i] > 0.2 )
169  {
170  fprintf( ioQQQ, " Is an abundance of %.3e relative to H reasonable for %2.2s?\n",
172  }
173  }
174  return;
175  }
176 
177  /* following set of clauses - no numbers on the line -
178  * use one of several stored abundance sets */
179  if( p.nMatch(" AGB") || p.nMatch("AGB ") || p.nMatch("PLAN") )
180  {
181  /* AGB/planetary nebula abundances */
182  /* only turn on grains if "no grains" is not present */
183  if( !p.nMatch("NO GR") )
184  {
185  /* turn on grains if not already done */
186  if( !p.m_lgDSet )
187  {
188  /* return bins allocated by previous abundances ... commands */
189  gv.clear();
190  /* now allocate new grain bins */
191  gp.dep = 1.;
192  // standard dust to gas ratio
193  gp.nDustFunc = DF_STANDARD;
194  gp.lgRequestQHeating = true;
195  gp.lgForbidQHeating = false;
196  gp.lgGreyGrain = false;
197 
198  /* NO QHEAT option to turn off quantum heating for grains */
199  if( p.nMatch("NO QH") )
200  {
201  gp.lgForbidQHeating = true;
202  gp.lgRequestQHeating = false;
203  phycon.lgPhysOK = false;
204  }
205 
206  /* actually set up the grains */
207  mie_read_opc("graphite_ism_10.opc",gp);
208  mie_read_opc("silicate_ism_10.opc",gp);
209  }
210  }
211 
212  for( i=0; i < LIMELM; i++ )
213  {
214  abund.solar[i] = abund.apn[i];
215  if( !abund.lgElmONapn[i] )
216  {
217  /* turn off elements - do this way to make sure,
218  * that iso sequence limits are handled properly */
219  char chDUMMY[INPUT_LINE_LENGTH];
220  sprintf(chDUMMY,"element %s off ", elementnames.chElementName[i] );
221  p.setline(chDUMMY);
222  ParseElement( p );
223  }
224  }
225  }
226 
227  else if( p.nMatch("CAME") )
228  {
229  /* mix from Cameron 1982, "Essays on Nuclear Astrophysics" */
230  /* now turn off the heavy elements */
231  for( i=0; i < LIMELM; i++ )
232  abund.solar[i] = abund.camern[i];
233  }
234 
235  else if( p.nMatch("CRAB") )
236  {
237  // Crab Nebula "typical" abundances
238  for( i=0; i < LIMELM; i++ )
239  {
240  abund.solar[i] = abund.aCrab[i];
241  if( !abund.lgElmONaCrab[i] )
242  {
243  /* turn off elements - do this way to make sure,
244  * that iso sequence limits are handled properly */
245  char chDUMMY[INPUT_LINE_LENGTH];
246  sprintf(chDUMMY,"element %s off ", elementnames.chElementName[i] );
247  p.setline(chDUMMY);
248  ParseElement( p );
249  }
250  }
251  }
252  else if( p.nMatch("HII ") || p.nMatch("H II") || p.nMatch("ORIO") )
253  {
254  /* H II region abundances - turn on grains by default
255  * "no grains" to not do this */
256  if( !p.nMatch("NO GR") )
257  {
258  /* option to turn on grains */
259  if( !p.m_lgDSet )
260  {
261  /* return bins allocated by previous abundances ... commands */
262  gv.clear();
263  /* now allocate new grain bins */
264  gp.dep = 1.;
265  // standard dust to gas ratio
266  gp.nDustFunc = DF_STANDARD;
267  gp.lgRequestQHeating = true;
268  gp.lgForbidQHeating = false;
269  gp.lgGreyGrain = false;
270 
271  /* NO QHEAT option to turn off quantum heating for grains */
272  if( p.nMatch("NO QH") )
273  {
274  gp.lgForbidQHeating = true;
275  gp.lgRequestQHeating = false;
276  phycon.lgPhysOK = false;
277  }
278  /* This scales the Orion grain abundance so that the observed
279  * dust to gas ratio that Cloudy predicts is in agreement with
280  * that observed in the Veil,
281  *>>refer grain Abel, N., Brogan, C., Ferland, G., O'Dell, C.R.,
282  *>>refercon Shaw, G., Troland, T., 2004, ApJ, submitted */
283  gp.dep *= 0.85;
284 
285  mie_read_opc("graphite_orion_10.opc",gp);
286  mie_read_opc("silicate_orion_10.opc",gp);
287  }
288  }
289 
290  for( i=0; i < LIMELM; i++ )
291  {
292  abund.solar[i] = abund.ahii[i];
293  if( !abund.lgElmONahii[i] )
294  {
295  /* turn off elements - do this way to make sure,
296  * that iso sequence limits are handled properly */
297  char chDUMMY[INPUT_LINE_LENGTH];
298  sprintf(chDUMMY,"element %s off ", elementnames.chElementName[i] );
299  p.setline(chDUMMY);
300  ParseElement( p );
301  }
302  }
303  }
304 
305  else if( p.nMatch("ISM ") || p.nMatch(" ISM") )
306  {
307  /* ISM abundances from Cowie and Songaila Ann Rev '86 */
308  /* only turn on grains if "no grains" is not present */
309  if( !p.nMatch("NO GR") )
310  {
311  if( !p.m_lgDSet )
312  {
313  /* return bins allocated by previous abundances ... commands */
314  gv.clear();
315  /* now allocate new grain bins */
316  gp.dep = 1.;
317  // standard dust to gas ratio
318  gp.nDustFunc = DF_STANDARD;
319  gp.lgRequestQHeating = true;
320  gp.lgForbidQHeating = false;
321  gp.lgGreyGrain = false;
322 
323  /* NO QHEAT option to turn off quantum heating */
324  if( p.nMatch("NO QH") )
325  {
326  gp.lgForbidQHeating = true;
327  gp.lgRequestQHeating = false;
328  phycon.lgPhysOK = false;
329  }
330 
331  /* actually set up the grains */
332  mie_read_opc("graphite_ism_10.opc",gp);
333  mie_read_opc("silicate_ism_10.opc",gp);
334  }
335  }
336 
337  for( i=0; i < LIMELM; i++ )
338  {
339  abund.solar[i] = abund.aism[i];
340  if( !abund.lgElmONaism[i] )
341  {
342  /* turn off elements - do this way to make sure,
343  * that iso sequence limits are handled properly */
344  char chDUMMY[INPUT_LINE_LENGTH];
345  sprintf(chDUMMY,"element %s off ", elementnames.chElementName[i] );
346  p.setline(chDUMMY);
347  ParseElement( p );
348  }
349  }
350  }
351 
352  else if( p.nMatch("NOVA") )
353  {
354  /* Nova Cyg abundances */
355  for( i=0; i < LIMELM; i++ )
356  abund.solar[i] = abund.anova[i];
357  }
358 
359  else if( p.nMatch("PRIM") )
360  {
361  /* roughly primordial abundances: He/H=.072 */
362  for( i=0; i < 4; i++ )
363  {
364  abund.solar[i] = abund.aprim[i];
365  }
366 
367  /* now turn off the heavy elements */
368  for( i=4; i < LIMELM; i++ )
369  {
370  /* turn off heavy elements - do this way to make sure,
371  * that H-like and He-like level limits are handled properly */
372  char chDUMMY[INPUT_LINE_LENGTH];
373  sprintf(chDUMMY,"element %s off ", elementnames.chElementName[i] );
374  p.setline(chDUMMY);
375  ParseElement( p );
376  }
377  }
378 
379  else
380  {
381  fprintf( ioQQQ,
382  " ABUNDances must have GASS10, PLAN, H II, CAMERON, CRAB, NOVA, ALL, STARBURST, OLD SOLAR 84 or PRIMORDIAL. Sorry.\n" );
384  }
385  return;
386 }
t_elementnames::chElementName
char chElementName[LIMELM][CHARS_ELEMENT_NAME]
Definition: elementnames.h:17
t_abund::ipSolar
long int ipSolar[LIMELM]
Definition: abund.h:90
Parser::nMatch
bool nMatch(const char *chKey) const
Definition: parser.h:135
Parser::FFmtRead
double FFmtRead(void)
Definition: parser.cpp:353
Parser::echo
void echo(void) const
Definition: parser.cpp:147
elementnames.h
ParseElement
void ParseElement(Parser &p)
Definition: parse_element.cpp:15
Parser::isComment
bool isComment(void) const
Definition: parser.cpp:93
ioQQQ
FILE * ioQQQ
Definition: cddefines.cpp:7
elementnames
t_elementnames elementnames
Definition: elementnames.cpp:5
realnum
float realnum
Definition: cddefines.h:103
abund.h
Parser::m_lgEOF
bool m_lgEOF
Definition: parser.h:42
phycon
t_phycon phycon
Definition: phycon.cpp:6
t_abund::lgElmONahii
bool lgElmONahii[LIMELM]
Definition: abund.h:60
t_abund::GASS10
realnum GASS10[LIMELM]
Definition: abund.h:48
GrainPar::dep
double dep
Definition: grainvar.h:114
GrainPar
Definition: grainvar.h:113
GrainVar::clear
void clear()
Definition: grainvar.h:464
t_abund::aprim
realnum aprim[LIMELM]
Definition: abund.h:53
t_abund::npSolar
long int npSolar
Definition: abund.h:91
GrainPar::nDustFunc
df_type nDustFunc
Definition: grainvar.h:115
EXIT_FAILURE
#define EXIT_FAILURE
Definition: cddefines.h:140
t_abund::apn
realnum apn[LIMELM]
Definition: abund.h:50
t_abund::camern
realnum camern[LIMELM]
Definition: abund.h:52
Parser
Definition: parser.h:31
Parser::getline
bool getline(void)
Definition: parser.cpp:164
t_abund::aism
realnum aism[LIMELM]
Definition: abund.h:54
t_phycon::lgPhysOK
bool lgPhysOK
Definition: phycon.h:101
cddefines.h
GrainPar::lgGreyGrain
bool lgGreyGrain
Definition: grainvar.h:117
abund_starburst
void abund_starburst(Parser &p)
Definition: abund_starburst.cpp:11
GrainPar::lgRequestQHeating
bool lgRequestQHeating
Definition: grainvar.h:118
t_abund::solar
realnum solar[LIMELM]
Definition: abund.h:65
t_elementnames::chElementSym
char chElementSym[LIMELM][CHARS_ELEMENT_SYM]
Definition: elementnames.h:25
mie_read_opc
void mie_read_opc(const char *, const GrainPar &)
Definition: grains_mie.cpp:1011
grains.h
t_abund::aCrab
realnum aCrab[LIMELM]
Definition: abund.h:55
LIMELM
const int LIMELM
Definition: cddefines.h:258
cdEXIT
#define cdEXIT(FAIL)
Definition: cddefines.h:434
Parser::lgEOL
bool lgEOL(void) const
Definition: parser.h:98
t_abund::lgElmONaCrab
bool lgElmONaCrab[LIMELM]
Definition: abund.h:62
Parser::m_lgDSet
bool m_lgDSet
Definition: parser.h:42
t_abund::OldSolar84
realnum OldSolar84[LIMELM]
Definition: abund.h:47
GrainPar::lgForbidQHeating
bool lgForbidQHeating
Definition: grainvar.h:116
abund
t_abund abund
Definition: abund.cpp:5
t_abund::anova
realnum anova[LIMELM]
Definition: abund.h:49
INPUT_LINE_LENGTH
const int INPUT_LINE_LENGTH
Definition: cddefines.h:254
grainvar.h
Parser::setline
void setline(const char *const card)
Definition: parser.h:69
parser.h
ParseAbundances
void ParseAbundances(Parser &p)
Definition: parse_abundances.cpp:14
gv
GrainVar gv
Definition: grainvar.cpp:5
phycon.h
t_abund::ahii
realnum ahii[LIMELM]
Definition: abund.h:51
t_abund::lgElmONapn
bool lgElmONapn[LIMELM]
Definition: abund.h:59
called.h
Parser::strcmp
int strcmp(const char *s2)
Definition: parser.h:177
DF_STANDARD
@ DF_STANDARD
Definition: grainvar.h:39
t_abund::SolarSave
realnum SolarSave[LIMELM]
Definition: abund.h:46
input.h
DEBUG_ENTRY
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:684
t_abund::lgElmONaism
bool lgElmONaism[LIMELM]
Definition: abund.h:61