cloudy  trunk
parse_grain.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 /*ParseGrain parse parameters on grains command */
4 #include "cddefines.h"
5 #include "grainvar.h"
6 #include "phycon.h"
7 #include "input.h"
8 #include "optimize.h"
9 #include "parser.h"
10 #include "grains.h"
11 
13 {
14  bool lgC15 = false,
15  lgC120 = false,
16  lgLinSet,
17  lgLogLinSet,
18  lgQuoteFound,
19  lgSizeDistribution;
20  GrainPar gp;
21 
22  /*possible name of input file with opacities */
23  char chFile[FILENAME_PATH_LENGTH_2];
24  const char *chOption = NULL;
25 
26  DEBUG_ENTRY( "ParseGrain()" );
27 
28  p.m_lgDSet = true;
29 
30  /* >>chng 00 dec 20, initialize chFile to empty string..., PvH */
31  chFile[0] = '\0';
32  /* >>chng 01 jan 17, read filename first, it may contain digits that would upset FFmtRead,
33  * as well as other tests that will follow. GetQuote will erase the filename from chCard, PvH */
34  lgQuoteFound = p.nMatch("\"");
35  if( lgQuoteFound )
36  {
37  /* this will both scan in whatever label is inside the quotes in OrgCard,
38  * but also remove the contents there and in parser buffer,
39  * so that following keywords will not trigger off it */
40  p.GetQuote( chFile, true );
41  }
42 
43  if( p.nMatch("GREY") || p.nMatch("GRAY") || nMatch("grey_", chFile) )
44  gp.lgGreyGrain = true;
45  else
46  gp.lgGreyGrain = false;
47 
48  /* now check for the keyword "function" - this sets the behavior of the grain abundance with depth */
49  if( p.nMatch("FUNC") )
50  {
51  if( p.nMatch("SUBL") )
53  else
55  }
56  else
58 
59  /* check for the keyword "single bin" -
60  * use resolved grain size distributions if not present
61  * NB - logic is backwards here */
62  if( !p.nMatch("SING") )
63  lgSizeDistribution = true;
64  else
65  lgSizeDistribution = false;
66 
67  /* check for the keyword "qheating" -
68  * quantum heating should be turned on */
69  gp.lgForbidQHeating = false;
70 
71  if( p.nMatch("QHEA") )
72  gp.lgRequestQHeating = true;
73  else
74  gp.lgRequestQHeating = false;
75 
76  /* the keyword "no qheat" always takes precedence */
77  if( p.nMatch("NO QH") )
78  {
79  gp.lgForbidQHeating = true;
80  gp.lgRequestQHeating = false;
81  phycon.lgPhysOK = false;
82  }
83 
84  /* option to force constant reevaluation of grain physics -
85  * usually reevaluate grains at all times, but NO REEVALUATE will
86  * save some time but may affect stability */
87  gv.lgReevaluate = !p.nMatch(" NO REEV");
88 
89  /* option to turn off photoelectric heating by grain, NO HEATING */
90  if( p.nMatch("NO HE") )
91  {
92  phycon.lgPhysOK = false;
93  gv.lgDHetOn = false;
94  }
95 
96  /* option to turn off gas cooling by grain, NO COOLING */
97  if( p.nMatch("NO CO") )
98  {
99  phycon.lgPhysOK = false;
100  gv.lgDColOn = false;
101  }
102 
103  /* these are keywords for PAH's, they need to be read before the depletion factor */
104  lgC120 = p.nMatchErase("C120 ");
105  if (!lgC120)
106  {
107  lgC15 = p.nMatchErase("C15 ");
108  }
109 
110  /* log - linear option for grain abundance */
111  lgLogLinSet = false;
112  lgLinSet = false;
113  if( p.nMatch(" LOG") )
114  {
115  lgLogLinSet = true;
116  lgLinSet = false;
117  }
118  else if( p.nMatch("LINE") )
119  {
120  lgLogLinSet = true;
121  lgLinSet = true;
122  }
123 
124  /* get the grain abundance as the first parameter,
125  * returns 0 if no number, ok since interpreted as log, or unity*/
126  gp.dep = p.FFmtRead();
127 
128  /* was keyword log or linear on the line? */
129  if( lgLogLinSet )
130  {
131  /* log or linear was specified, which was it */
132  if( lgLinSet )
133  {
134  /* linear quantity entered, check it */
135  if( gp.dep <= 0. )
136  {
137  fprintf( ioQQQ, " Impossible value for linear abundance.\n" );
138  fprintf( ioQQQ, " Abundance entered was%10.2e\n", gp.dep );
139  fprintf( ioQQQ, " Sorry.\n" );
141  }
142  }
143  else
144  {
145  gp.dep = pow(10.,gp.dep);
146  }
147  }
148  else
149  {
150  /* neither log nor linear specified, check sign
151  * force it to be a log - linear if greater than 0 */
152  if( gp.dep <= 0. )
153  {
154  gp.dep = pow(10.,gp.dep);
155  }
156  }
157 
158  if( gp.dep < FLT_MIN )
159  {
160  fprintf( ioQQQ, " Grain abundance entered here (%f) is impossible.\n", gp.dep );
162  }
163 
164  /* it is possible that there is a file name on the command line -
165  * if so then we want to call correct reoutine, and not look for keywords
166  * the signature of a keyword is a pair of quotes - is one present? */
167  if( lgQuoteFound )
168  {
169  /* read the file name that was specified */
170  chOption = "";
171  mie_read_opc(chFile,gp);
172  }
173  else
174  {
175  if( p.nMatch("ORIO") )
176  {
177  /* This scales the Orion grain abundance so that the observed
178  * dust to gas ratio that Cloudy predicts is in agreement with
179  * that observed in the Veil,
180  *>>refer grain Abel, N., Brogan, C., Ferland, G., O'Dell, C.R.,
181  *>>refercon Shaw, G., Troland, T., 2004, ApJ, submitted */
182  gp.dep *= 0.85;
183 
184  /* optional keyword ORION to use orion curves for large R grains */
185  /* only turn on one if graphite or silicate is on line, both if not */
186  if( p.nMatch("GRAP") )
187  {
188  /* only turn on orion graphite */
189  chOption = "ORION GRAPHITE ";
190  if( lgSizeDistribution )
191  {
192  mie_read_opc("graphite_orion_10.opc",gp);
193  }
194  else
195  {
196  mie_read_opc("graphite_orion_01.opc",gp);
197  }
198  }
199  else if( p.nMatch("SILI") )
200  {
201  /* only turn on orion silicate */
202  chOption = "ORION SILICATE ";
203  if( lgSizeDistribution )
204  {
205  mie_read_opc("silicate_orion_10.opc",gp);
206  }
207  else
208  {
209  mie_read_opc("silicate_orion_01.opc",gp);
210  }
211  }
212  else
213  {
214  /* turn both on */
215  chOption = "ORION ";
216  if( lgSizeDistribution )
217  {
218  mie_read_opc("graphite_orion_10.opc",gp);
219  mie_read_opc("silicate_orion_10.opc",gp);
220  }
221  else
222  {
223  mie_read_opc("graphite_orion_01.opc",gp);
224  mie_read_opc("silicate_orion_01.opc",gp);
225  }
226  }
227  }
228 
229  else if( p.nMatch(" PAH") )
230  {
231  /* only turn on the large PAH */
232  if( lgC120 )
233  {
234  chOption = "PAH C120 ";
235  mie_read_opc("pah1_c120.opc",gp);
236  }
237  /* only turn on the small PAH */
238  else if( lgC15 )
239  {
240  chOption = "PAH C15 ";
241  mie_read_opc("pah1_c15.opc",gp);
242  }
243  /* turn on size-distributed PAHs */
244  else
245  {
246  /* the variable abundance for PAHs is hard wired in GrnStdDpth
247  * the function keyword has no effect?? */
248  chOption = "PAH ";
249  if( lgSizeDistribution )
250  {
251  mie_read_opc("pah1_ab08_10.opc",gp);
252  }
253  else
254  {
255  mie_read_opc("pah1_ab08_01.opc",gp);
256  }
257  }
258  }
259 
260  else if( p.nMatch("GREY") || p.nMatch("GRAY") )
261  {
262  /* grey grains */
263  chOption = "GREY ";
264  if( lgSizeDistribution )
265  {
266  mie_read_opc("grey_ism_10.opc",gp);
267  }
268  else
269  {
270  mie_read_opc("grey_ism_01.opc",gp);
271  }
272  }
273 
274  else if( p.nMatch(" ISM") )
275  {
276  if( p.nMatch("GRAP") )
277  {
278  /* only turn on ism graphite */
279  chOption = "ISM GRAPHITE ";
280  if( lgSizeDistribution )
281  {
282  mie_read_opc("graphite_ism_10.opc",gp);
283  }
284  else
285  {
286  mie_read_opc("graphite_ism_01.opc",gp);
287  }
288  }
289  else if( p.nMatch("SILI") )
290  {
291  /* only turn on orion silicate */
292  chOption = "ISM SILICATE ";
293  if( lgSizeDistribution )
294  {
295  mie_read_opc("silicate_ism_10.opc",gp);
296  }
297  else
298  {
299  mie_read_opc("silicate_ism_01.opc",gp);
300  }
301  }
302  else
303  {
304  /* turn both ISM graphite and silicate on */
305  chOption = "ISM ";
306  if( lgSizeDistribution )
307  {
308  mie_read_opc("graphite_ism_10.opc",gp);
309  mie_read_opc("silicate_ism_10.opc",gp);
310  }
311  else
312  {
313  mie_read_opc("graphite_ism_01.opc",gp);
314  mie_read_opc("silicate_ism_01.opc",gp);
315  }
316  }
317  }
318 
319  /* default case */
320  else
321  {
322  /* turn both ISM graphite and silicate on */
323  chOption = "";
324  if( lgSizeDistribution )
325  {
326  mie_read_opc("graphite_ism_10.opc",gp);
327  mie_read_opc("silicate_ism_10.opc",gp);
328  }
329  else
330  {
331  mie_read_opc("graphite_ism_01.opc",gp);
332  mie_read_opc("silicate_ism_01.opc",gp);
333  }
334  }
335  }
336 
337  /* vary option */
338  if( optimize.lgVarOn )
339  {
341  optimize.vparm[0][optimize.nparm] = (realnum)log10(gp.dep);
343 
344  // now build the input command string with all the necessary options...
345  string command( "GRAIN ABUND=%f LOG " );
346  if( chFile[0] != '\0' )
347  {
348  command += "\"";
349  command += chFile;
350  command += "\" ";
351  }
352 
353  // every branch of the if-statement above must set chOption.
354  // this sentinel is here in case somebody forgets...
355  if( chOption == NULL )
356  TotalInsanity();
357 
358  command += chOption;
359 
360  /* generate keywords to feed to vary form of grains command
361  * this test makes sure that future versions and values
362  * of nDustFunc are implemented here */
363  switch( gp.nDustFunc )
364  {
365  case DF_STANDARD:
366  // nothing to do
367  break;
368  case DF_USER_FUNCTION:
369  command += "FUNCTION ";
370  break;
371  case DF_SUBLIMATION:
372  command += "FUNCTION SUBLIMATION ";
373  break;
374  default:
375  TotalInsanity();
376  }
377 
378  if( !lgSizeDistribution )
379  command += "SINGLE ";
380 
381  if( gp.lgForbidQHeating )
382  command += "NO QHEAT ";
383  else if( gp.lgRequestQHeating )
384  command += "QHEAT ";
385 
386  if( !gv.lgReevaluate )
387  command += "NO REEVALUATE ";
388  if( !gv.lgDHetOn )
389  command += "NO HEATING ";
390  if( !gv.lgDColOn )
391  command += "NO COOLING ";
392 
393  if( command.length() < static_cast<string::size_type>(FILENAME_PATH_LENGTH_2) )
394  strcpy( optimize.chVarFmt[optimize.nparm], command.c_str() );
395  else
396  {
397  fprintf(ioQQQ," grain command string is too long. This is parse_grain\n");
398  TotalInsanity();
399  }
400 
402  ++optimize.nparm;
403  }
404  return;
405 }
Parser::nMatch
bool nMatch(const char *chKey) const
Definition: parser.h:135
DF_SUBLIMATION
@ DF_SUBLIMATION
Definition: grainvar.h:41
t_optimize::vincr
realnum vincr[LIMPAR]
Definition: optimize.h:191
Parser::FFmtRead
double FFmtRead(void)
Definition: parser.cpp:353
t_optimize::nparm
long int nparm
Definition: optimize.h:201
t_input::nRead
long int nRead
Definition: input.h:49
ioQQQ
FILE * ioQQQ
Definition: cddefines.cpp:7
realnum
float realnum
Definition: cddefines.h:103
GrainVar::lgReevaluate
bool lgReevaluate
Definition: grainvar.h:477
GrainVar::lgDHetOn
bool lgDHetOn
Definition: grainvar.h:485
ParseGrain
void ParseGrain(Parser &p)
Definition: parse_grain.cpp:12
t_optimize::lgVarOn
bool lgVarOn
Definition: optimize.h:203
phycon
t_phycon phycon
Definition: phycon.cpp:6
Parser::GetQuote
int GetQuote(char *chLabel, bool lgABORT)
Definition: parser.h:209
input
t_input input
Definition: input.cpp:12
GrainPar::dep
double dep
Definition: grainvar.h:114
GrainPar
Definition: grainvar.h:113
GrainPar::nDustFunc
df_type nDustFunc
Definition: grainvar.h:115
optimize
t_optimize optimize
Definition: optimize.cpp:5
t_optimize::vparm
realnum vparm[LIMEXT][LIMPAR]
Definition: optimize.h:188
t_optimize::chVarFmt
char chVarFmt[LIMPAR][FILENAME_PATH_LENGTH_2]
Definition: optimize.h:263
EXIT_FAILURE
#define EXIT_FAILURE
Definition: cddefines.h:140
Parser
Definition: parser.h:31
t_phycon::lgPhysOK
bool lgPhysOK
Definition: phycon.h:101
cddefines.h
GrainPar::lgGreyGrain
bool lgGreyGrain
Definition: grainvar.h:117
GrainPar::lgRequestQHeating
bool lgRequestQHeating
Definition: grainvar.h:118
optimize.h
TotalInsanity
NORETURN void TotalInsanity(void)
Definition: service.cpp:886
nMatch
long nMatch(const char *chKey, const char *chCard)
Definition: service.cpp:451
t_optimize::nvarxt
long int nvarxt[LIMPAR]
Definition: optimize.h:194
mie_read_opc
void mie_read_opc(const char *, const GrainPar &)
Definition: grains_mie.cpp:1011
GrainVar::lgDColOn
bool lgDColOn
Definition: grainvar.h:490
Parser::nMatchErase
bool nMatchErase(const char *chKey)
Definition: parser.h:158
grains.h
cdEXIT
#define cdEXIT(FAIL)
Definition: cddefines.h:434
Parser::m_lgDSet
bool m_lgDSet
Definition: parser.h:42
GrainPar::lgForbidQHeating
bool lgForbidQHeating
Definition: grainvar.h:116
FILENAME_PATH_LENGTH_2
const int FILENAME_PATH_LENGTH_2
Definition: cddefines.h:249
grainvar.h
DF_USER_FUNCTION
@ DF_USER_FUNCTION
Definition: grainvar.h:40
parser.h
t_optimize::nvfpnt
long int nvfpnt[LIMPAR]
Definition: optimize.h:195
gv
GrainVar gv
Definition: grainvar.cpp:5
phycon.h
DF_STANDARD
@ DF_STANDARD
Definition: grainvar.h:39
input.h
DEBUG_ENTRY
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:684