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