cloudy  trunk
 All Data Structures 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-2008 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 "parse.h"
10 #include "grains.h"
11 
12 void ParseGrain(char *chCard,
13  bool *lgDSet)
14 {
15  bool lgC15 = false,
16  lgC120 = false,
17  lgEOL,
18  lgLinSet,
19  lgLogLinSet,
20  lgQuoteFound,
21  lgSizeDistribution;
22  char *ptr;
23  GrainPar gp;
24 
25  /*possible name of input file with opacities */
26  char chFile[FILENAME_PATH_LENGTH_2];
27  const char *chOption = NULL;
28  long int i;
29 
30  DEBUG_ENTRY( "ParseGrain()" );
31 
32  *lgDSet = true;
33 
34  /* >>chng 00 dec 20, initialize chFile to empty string..., PvH */
35  chFile[0] = '\0';
36  /* >>chng 01 jan 17, read filename first, it may contain digits that would upset FFmtRead,
37  * as well as other tests that will follow. GetQuote will erase the filename from chCard, PvH */
38  lgQuoteFound = strchr( input.chOrgCard, '\"' ) != NULL;
39  if( lgQuoteFound )
40  {
41  /* this will both scan in whatever label is inside the quotes in OrgCard,
42  * but also remove the contents there and in chCard,
43  * so that following keywords will not trigger off it */
44  GetQuote( chFile, chCard, true );
45  }
46 
47  if( nMatch("GREY",chCard) || nMatch("GRAY",chCard) || nMatch("grey_",chFile) )
48  gp.lgGreyGrain = true;
49  else
50  gp.lgGreyGrain = false;
51 
52  /* now check for the keyword "function" - this is a special case,
53  * where grain abundance varies with depth
54  * if set true then will call routine GrnVryDpth */
55  if( nMatch("FUNC",chCard) )
56  gp.lgAbunVsDepth = true;
57  else
58  gp.lgAbunVsDepth = false;
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( !nMatch("SING",chCard) )
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( nMatch("QHEA",chCard) )
73  gp.lgRequestQHeating = true;
74  else
75  gp.lgRequestQHeating = false;
76 
77  /* the keyword "no qheat" always takes precedence */
78  if( nMatch("O QH",chCard) )
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 = !nMatch(" NO REEV",chCard);
89 
90  /* option to turn off photoelectric heating by grain, NO HEATING */
91  if( nMatch("O HE",chCard) )
92  {
93  phycon.lgPhysOK = false;
94  gv.lgDHetOn = false;
95  }
96 
97  /* option to turn off gas cooling by grain, NO COOLING */
98  if( nMatch("O CO",chCard) )
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  if( (ptr = strstr(chCard,"C120 ")) != NULL )
106  {
107  lgC120 = true;
108  /* erase this keyword, it upsets FFmtRead */
109  strncpy(ptr," ",5);
110  }
111  else if( (ptr = strstr(chCard,"C15 ")) != NULL )
112  {
113  lgC15 = true;
114  /* erase this keyword, it upsets FFmtRead */
115  strncpy(ptr," ",4);
116  }
117 
118  /* log - linear option for grain abundance */
119  lgLogLinSet = false;
120  lgLinSet = false;
121  if( nMatch(" LOG",chCard) )
122  {
123  lgLogLinSet = true;
124  lgLinSet = false;
125  }
126  else if( nMatch("LINE",chCard) )
127  {
128  lgLogLinSet = true;
129  lgLinSet = true;
130  }
131 
132  /* get the grain abundance as the first parameter,
133  * returns 0 if no number, ok since interpreted as log, or unity*/
134  i = 5;
135  gp.dep = FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
136 
137  /* was keyword log or linear on the line? */
138  if( lgLogLinSet )
139  {
140  /* log or linear was specified, which was it */
141  if( lgLinSet )
142  {
143  /* linear quantity entered, check it */
144  if( gp.dep <= 0. )
145  {
146  fprintf( ioQQQ, " Impossible value for linear abundance.\n" );
147  fprintf( ioQQQ, " Abundance entered was%10.2e\n", gp.dep );
148  fprintf( ioQQQ, " Sorry.\n" );
149  cdEXIT(EXIT_FAILURE);
150  }
151  }
152  else
153  {
154  gp.dep = pow(10.,gp.dep);
155  }
156  }
157  else
158  {
159  /* neither log nor linear specified, check sign
160  * force it to be a log - linear if greater than 0 */
161  if( gp.dep <= 0. )
162  {
163  gp.dep = pow(10.,gp.dep);
164  }
165  }
166 
167  if( gp.dep < FLT_MIN )
168  {
169  fprintf( ioQQQ, " Grain abundance entered here (%f) is impossible.\n", gp.dep );
170  cdEXIT(EXIT_FAILURE);
171  }
172 
173  /* it is possible that there is a file name on the command line -
174  * if so then we want to call correct reoutine, and not look for keywords
175  * the signature of a keyword is a pair of quotes - is one present? */
176  if( lgQuoteFound )
177  {
178  /* read the file name that was specified */
179  chOption = "";
180  mie_read_opc(chFile,gp);
181  }
182  else
183  {
184  if( nMatch("ORIO",chCard) )
185  {
186  /* This scales the Orion grain abundance so that the observed
187  * dust to gas ratio that Cloudy predicts is in agreement with
188  * that observed in the Veil,
189  *>>refer grain Abel, N., Brogan, C., Ferland, G., O'Dell, C.R.,
190  *>>refercon Shaw, G., Troland, T., 2004, ApJ, submitted */
191  gp.dep *= 0.85;
192 
193  /* optional keyword ORION to use orion curves for large R grains */
194  /* only turn on one if graphite or silicate is on line, both if not */
195  if( nMatch("GRAP",chCard) )
196  {
197  /* only turn on orion graphite */
198  chOption = "ORION GRAPHITE ";
199  if( lgSizeDistribution )
200  {
201  mie_read_opc("graphite_orion_10.opc",gp);
202  }
203  else
204  {
205  mie_read_opc("graphite_orion_01.opc",gp);
206  }
207  }
208  else if( nMatch("SILI",chCard) )
209  {
210  /* only turn on orion silicate */
211  chOption = "ORION SILICATE ";
212  if( lgSizeDistribution )
213  {
214  mie_read_opc("silicate_orion_10.opc",gp);
215  }
216  else
217  {
218  mie_read_opc("silicate_orion_01.opc",gp);
219  }
220  }
221  else
222  {
223  /* turn both on */
224  chOption = "ORION ";
225  if( lgSizeDistribution )
226  {
227  mie_read_opc("graphite_orion_10.opc",gp);
228  mie_read_opc("silicate_orion_10.opc",gp);
229  }
230  else
231  {
232  mie_read_opc("graphite_orion_01.opc",gp);
233  mie_read_opc("silicate_orion_01.opc",gp);
234  }
235  }
236  }
237 
238  else if( nMatch(" PAH",chCard) )
239  {
240  /* only turn on the large PAH */
241  if( lgC120 )
242  {
243  chOption = "PAH C120 ";
244  mie_read_opc("pah1_0n682.opc",gp);
245  }
246  /* only turn on the small PAH */
247  else if( lgC15 )
248  {
249  chOption = "PAH C15 ";
250  mie_read_opc("pah1_0n341.opc",gp);
251  }
252  /* turn on size-distributed PAHs */
253  else
254  {
255  chOption = "PAH ";
256  if( lgSizeDistribution )
257  {
258  mie_read_opc("pah1_ab08_10.opc",gp);
259  }
260  else
261  {
262  mie_read_opc("pah1_ab08_01.opc",gp);
263  }
264  }
265  }
266 
267  else if( nMatch("GREY",chCard) || nMatch("GRAY",chCard) )
268  {
269  /* grey grains */
270  chOption = "GREY ";
271  if( lgSizeDistribution )
272  {
273  mie_read_opc("grey_ism_10.opc",gp);
274  }
275  else
276  {
277  mie_read_opc("grey_ism_01.opc",gp);
278  }
279  }
280 
281  else if( nMatch(" ISM",chCard) )
282  {
283  if( nMatch("GRAP",chCard) )
284  {
285  /* only turn on ism graphite */
286  chOption = "ISM GRAPHITE ";
287  if( lgSizeDistribution )
288  {
289  mie_read_opc("graphite_ism_10.opc",gp);
290  }
291  else
292  {
293  mie_read_opc("graphite_ism_01.opc",gp);
294  }
295  }
296  else if( nMatch("SILI",chCard) )
297  {
298  /* only turn on orion silicate */
299  chOption = "ISM SILICATE ";
300  if( lgSizeDistribution )
301  {
302  mie_read_opc("silicate_ism_10.opc",gp);
303  }
304  else
305  {
306  mie_read_opc("silicate_ism_01.opc",gp);
307  }
308  }
309  else
310  {
311  /* turn both ISM graphite and silicate on */
312  chOption = "ISM ";
313  if( lgSizeDistribution )
314  {
315  mie_read_opc("graphite_ism_10.opc",gp);
316  mie_read_opc("silicate_ism_10.opc",gp);
317  }
318  else
319  {
320  mie_read_opc("graphite_ism_01.opc",gp);
321  mie_read_opc("silicate_ism_01.opc",gp);
322  }
323  }
324  }
325 
326  /* default case */
327  else
328  {
329  /* turn both ISM graphite and silicate on */
330  chOption = "";
331  if( lgSizeDistribution )
332  {
333  mie_read_opc("graphite_ism_10.opc",gp);
334  mie_read_opc("silicate_ism_10.opc",gp);
335  }
336  else
337  {
338  mie_read_opc("graphite_ism_01.opc",gp);
339  mie_read_opc("silicate_ism_01.opc",gp);
340  }
341  }
342  }
343 
344  /* vary option */
345  if( optimize.lgVarOn )
346  {
348  optimize.vparm[0][optimize.nparm] = (realnum)log10(gp.dep);
350 
351  // now build the input command string with all the necessary options...
352  string command( "GRAIN ABUND=%f LOG " );
353  if( chFile[0] != '\0' )
354  {
355  command += "\"";
356  command += chFile;
357  command += "\" ";
358  }
359 
360  // every branch of the if-statement above must set chOption.
361  // this sentinel is here in case somebody forgets...
362  if( chOption == NULL )
363  TotalInsanity();
364 
365  command += chOption;
366 
367  if( gp.lgAbunVsDepth )
368  command += "FUNCTION ";
369  if( !lgSizeDistribution )
370  command += "SINGLE ";
371  if( gp.lgForbidQHeating )
372  command += "NO QHEAT ";
373  else if( gp.lgRequestQHeating )
374  command += "QHEAT ";
375  if( !gv.lgReevaluate )
376  command += "NO REEVALUATE ";
377  if( !gv.lgDHetOn )
378  command += "NO HEATING ";
379  if( !gv.lgDColOn )
380  command += "NO COOLING ";
381 
382  if( command.length() < static_cast<string::size_type>(FILENAME_PATH_LENGTH_2) )
383  strcpy( optimize.chVarFmt[optimize.nparm], command.c_str() );
384  else
385  {
386  fprintf(ioQQQ," grain command string is too long. This is parse_grain\n");
387  TotalInsanity();
388  }
389 
391  ++optimize.nparm;
392  }
393  return;
394 }

Generated for cloudy by doxygen 1.8.1.1