cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parse_atom_h2.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 /*ParseAtomH2 parse information from the atom command line */
4 #include "cddefines.h"
5 #include "hmi.h"
6 #include "h2.h"
7 #include "h2_priv.h"
8 #include "parser.h"
9 #include "thirdparty.h"
10 #include "deuterium.h"
11 
12 /*ParseAtomH2 parse information from the atom command line */
14 {
15  long int j;
16 
17  DEBUG_ENTRY( "ParseAtomH2()" );
18 
19  fixit(); // this must be generalized!!!
20  // easiest way is to create and populate diatoms before parsing,
21  // so we can simply iterator of diatoms and match strings.
22  // probably will want to put label on command line in quotes
23  // and change command to, for example,
24  // diatom "H2"
25  // do that work before entering this routine.
26  diatomics *diatom = NULL;
27 
28  if( p.nMatch(" H2 " ) )
29  {
30  diatom = &h2;
31  /* this command has a 2 in the H2 label - must not parse the two by
32  * accident. Get the first number off the line image, and confirm that
33  * it is a 2 */
34  j = (long int)p.FFmtRead();
35  if( j != 2 )
36  {
37  fprintf( ioQQQ, " Something is wrong with the order of the numbers on this line.\n" );
38  fprintf( ioQQQ, " The first number I encounter should be a 2.\n Sorry.\n" );
40  }
41  }
42  else if( p.nMatch(" HD " ) )
43  {
44  diatom = &hd;
45  // turn deuterium on
46  deut.lgElmtOn = true;
47  }
48 
49  /* the mere calling of this routine turns the large H2 molecule on */
50  diatom->lgEnabled = true;
51 
52  if( p.nMatch("LEVE") )
53  {
54  /* number of electronic levels */
55 
56  /* lgREAD_DATA is false at start of calculation, set true when
57  * space allocated for the H lines. Once done we must ignore all
58  * future changes in the number of levels */
59  if( !diatom->lgREAD_DATA )
60  {
61  diatom->n_elec_states = (long int)p.FFmtRead();
62  if( p.lgEOL() )
63  {
64  if( p.nMatch("LARG") )
65  {
66  /* LARGE is option to use the most number of electronic levels */
67  diatom->n_elec_states = N_ELEC;
68  }
69  else
70  {
71  p.NoNumb("number of electronic levels");
72  }
73  }
74 
75  /* do not allow fewer than 3 - that includes Lyman & Werner bands */
76  if( diatom->n_elec_states < 3 )
77  {
78  fprintf( ioQQQ, " This would be too few electronic levels - resetting to 3.\n" );
79  diatom->n_elec_states = 3;
80  }
81  /* N_ELEC is the greatest number of elec lev possible */
82  else if( diatom->n_elec_states > N_ELEC )
83  {
84  fprintf( ioQQQ,
85  " This would be too many levels, the limit is %i.\n" ,
86  N_ELEC);
88  }
89  }
90  }
91 
92  else if( p.nMatch("LIMI") )
93  {
94  /* the limit to the H2 / Htot ratio -
95  * if smaller than this, do not compute large H2 mole */
96  diatom->H2_to_H_limit = p.FFmtRead();
97  if( p.lgEOL() )
98  {
99  /* did not find a number, either mistake or key " off" */
100  if( p.nMatch( " OFF" ) )
101  {
102  /* turn off limit */
103  diatom->H2_to_H_limit = -1.;
104  }
105  else
106  {
107  p.NoNumb( "limit to the H2 / Htot ratio" );
108  }
109  }
110  else
111  {
112  /* got a number, check if negative and so a log */
113  /* a number <= 0 is the log of the ratio */
114  if( diatom->H2_to_H_limit <= 0. )
115  diatom->H2_to_H_limit = pow(10., diatom->H2_to_H_limit);
116  }
117  }
118  else if( p.nMatch("GBAR" ) )
119  {
120  /* option to either use, or not use, gbar approximation for low X
121  * levels with no collision data - by default it is on */
122  if( p.nMatch(" OFF" ) )
123  {
124  diatom->lgColl_gbar = false;
125  }
126  else if( p.nMatch(" ON " ) )
127  {
128  diatom->lgColl_gbar = true;
129  }
130  else
131  {
132  fprintf( ioQQQ,
133  " The gbar approximation must be off (\" OFF\") or on (\" ON \").\n");
135  }
136  }
137  /* option to turn collisional effects off or on */
138  else if( p.nMatch("COLL" ) )
139  {
140  /* option to turn collisional dissociation off or on */
141  if( p.nMatch("DISS" ) )
142  {
143  /* option to turn collisions off */
144  if( p.nMatch(" ON " ) )
145  {
146  /* this is the default, leave collisions off */
147  diatom->lgColl_dissoc_coll = true;
148  }
149  else
150  {
151  /* default (and only reason for this command) is to turn off collisions */
152  diatom->lgColl_dissoc_coll = false;
153  }
154  }
155  /* option to turn collisional dissociation off or on
156  * >>chng 06 mar 01, had been simply if - so all collisions were turned off
157  * when dissociation collisions turned off -
158  * due to bucket else at end */
159  else if( p.nMatch("ORTH" ) && p.nMatch("PARA" ) )
160  {
161  /* option to turn ortho - para collisions with particles off */
162  if( p.nMatch(" ON " ) )
163  {
164  /* this is the default, leave collisions off */
165  diatom->lgH2_ortho_para_coll_on = true;
166  }
167  else
168  {
169  /* default (and only reason for this command) is to turn off
170  * ortho-para collisions */
171  diatom->lgH2_ortho_para_coll_on = false;
172  }
173  }
174 
175  /* option to turn collisional effects off or on */
176  else if( p.nMatch("GRAI" ) )
177  {
178  /* option to turn collisions off */
179  if( p.nMatch(" ON" ) )
180  {
181  /* this is the default, leave collisions off */
182  diatom->lgH2_grain_deexcitation = true;
183  }
184  else
185  {
186  /* default (and only reason for this command) is to turn off collisions */
187  diatom->lgH2_grain_deexcitation = false;
188  }
189  }
190  else if( p.nMatch(" HE " ) )
191  {
192  /* atom H2 He collisions ORNL (the default), Le BOURlot, and OFF
193  * which data set for He collisions,
194  * Teck Lee et al. ApJ to be submitted */
195  if( p.nMatch(" NEW" ) || p.nMatch("ORNL" ) )
196  {
197  /* use the new coefficients */
198  diatom->lgH2_He_ORNL = true;
199  diatom->coll_source[1].filename = "coll_rates_He_ORNL.dat";
200  }
201  else if( p.nMatch(" OLD" ) || p.nMatch("BOUR" ) )
202  {
203  /* use the coefficients from
204  *>>refer H2 collision Le Bourlot, J., Pineau des Forets,
205  *>>refercon G., & Flower, D.R. 1999, MNRAS, 305, 802*/
206  diatom->lgH2_He_ORNL = false;
207  diatom->coll_source[1].filename = "coll_rates_He_LeBourlot.dat";
208  }
209  else
210  {
211  fprintf( ioQQQ,
212  " I did not find a keyword on this ATOM H2 HE command - I know about the keys ORNL and Le BOURlot\n");
214  }
215  }
216 
217  /*>>chng 08 feb 27, GS*/
218  else if( p.nMatch("ORH2" ) )
219  {
220  /* atom H2 H2ortho collisions ORNL (the default), Le BOURlot, and OFF
221  * which data set for H2 collisions,
222  * Teck Lee et al. ApJ to be submitted */
223  if( p.nMatch("ORNL" ) )
224  {
225  /* use the new coefficients */
226  diatom->lgH2_ORH2_ORNL = true;
227  diatom->coll_source[2].filename = "coll_rates_H2ortho_ORNL.dat";
228  }
229  else if( p.nMatch("BOUR" ) )
230  {
231  /* use the coefficients from
232  *>>refer H2 collision Le Bourlot, J., Pineau des Forets,
233  *>>refercon G., & Flower, D.R. 1999, MNRAS, 305, 802*/
234  diatom->lgH2_ORH2_ORNL = false;
235  diatom->coll_source[2].filename = "coll_rates_H2ortho_LeBourlot.dat";
236  }
237  else
238  {
239  fprintf( ioQQQ,
240  " I did not find a keyword on this ATOM H2 ohH2 command - I know about the keys ORNL and Le BOURlot\n");
242  }
243  }
244 
245  else if( p.nMatch("PAH2" ) )
246  {
247  /* atom H2 H2ortho collisions ORNL (the default), Le BOURlot, and OFF
248  * which data set for He collisions,
249  * Teck Lee et al. ApJ to be submitted */
250  if( p.nMatch("ORNL" ) )
251  {
252  /* use the new coefficients */
253  diatom->lgH2_PAH2_ORNL = true;
254  diatom->coll_source[3].filename = "coll_rates_H2para_ORNL.dat";
255  }
256  else if( p.nMatch("BOUR" ) )
257  {
258  /* use the coefficients from
259  *>>refer H2 collision Le Bourlot, J., Pineau des Forets,
260  *>>refercon G., & Flower, D.R. 1999, MNRAS, 305, 802*/
261  diatom->lgH2_PAH2_ORNL = false;
262  diatom->coll_source[3].filename = "coll_rates_H2para_LeBourlot.dat";
263  }
264  else
265  {
266  fprintf( ioQQQ,
267  " I did not find a keyword on this ATOM H2 paH2 command - I know about the keys ORNL and Le BOURlot\n");
269  }
270  }
271 
272  else
273  {
274  /* option to turn all collisions off */
275  if( p.nMatch(" ON " ) )
276  {
277  /* this is the default, leave collisions on */
278  diatom->lgColl_deexec_Calc = true;
279  }
280  else
281  {
282  /* default (and only reason for this command) is to turn off collisions */
283  diatom->lgColl_deexec_Calc = false;
284  }
285  }
286  }
287 
288  /* set number of levels in matrix, but not trace matrix option */
289  else if( p.nMatch("MATR" ) && !p.nMatch("TRAC" ) )
290  {
291  /* matrix option sets the number of levels that will
292  * be included in the matrix solution */
293  long numLevels = (long)p.FFmtRead();
294  if( p.nMatch(" ALL") )
295  {
296  /* " all" means do all of X, but space has not yet been allocated,
297  * so we do know know how many levels are within X - set special
298  * flag that will be used then this is known */
299  numLevels = -1;
300  }
301  else if( p.lgEOL() && !(p.nMatch(" OFF") || p.nMatch("NONE") ) )
302  {
303  /* this branch hit eol but OFF or NONE is not on line - this is a mistake */
304  fprintf( ioQQQ,
305  " The total number of levels used in the matrix solver must be entered, or keywords ALL or NONE entered.\n Sorry.\n");
307  }
308 
309  diatom->set_numLevelsMatrix( numLevels );
310  /* cannot check less than total number of levels within x since not yet set
311  * We do not certify that matrix limits are greater than 1 -
312  * zero or <0 limits just turns if off, as did the off option */
313  }
314  else if( p.nMatch(" LTE" ) )
315  {
316  /* LTE option causes code to assume LTE for level populations */
317  diatom->lgLTE = true;
318  }
319 
320  else if( p.nMatch("TRAC" ) )
321  {
322  /* these are used to set trace levels of output
323  diatom->n_trace_final = 1;
324  diatom->n_trace_iterations = 2;
325  diatom->n_trace_full = 3;
326  diatom->n_trace_matrix = 4*/
327 
328  /* turns on trace printout - there are multiple levels */
329  if( p.nMatch("FINA" ) )
330  {
331  /* FINAL gives only final information when solver exits */
332  diatom->nTRACE = diatom->n_trace_final;
333  }
334  else if( p.nMatch("ITER" ) )
335  {
336  /* follow iterations within each call */
337  diatom->nTRACE = diatom->n_trace_iterations;
338  }
339  else if( p.nMatch("FULL" ) )
340  {
341  /* full details of solution - this is also the default*/
342  diatom->nTRACE = diatom->n_trace_full;
343  }
344  else if( p.nMatch("MATR" ) )
345  {
346  /* print the matrices used for X */
347  diatom->nTRACE = diatom->n_trace_matrix;
348  }
349  else
350  {
351  /* full details of solution is also the default*/
352  diatom->nTRACE = diatom->n_trace_full;
353  }
354  }
355  else if( p.nMatch("NOIS" ) )
356  {
357  unsigned int iseed;
358  /* check on effects of uncertainties in collision rates */
359  diatom->lgH2_NOISE = true;
360  diatom->lgH2_NOISECOSMIC = true;
361 
362  /* optional mean - default is 0 */
363  diatom->xMeanNoise = p.FFmtRead();
364  if( p.lgEOL() )
365  diatom->xMeanNoise = 0.;
366 
367  /* this is the standard deviation for the mole, with default */
368  diatom->xSTDNoise = p.FFmtRead();
369  if( p.lgEOL() )
370  diatom->xSTDNoise = 0.5;
371 
372  /* this may be a seed for the random number generator. if no seed is
373  * set then use system time, and always get different sequence */
374  iseed = (unsigned int)p.FFmtRead();
375  /* returned 0 if eol hit */
376  if( iseed > 0 )
377  {
378  /* user set seed */
379  init_genrand( iseed );
380  }
381  else
382  {
383  init_genrand( (unsigned)time( NULL ) );
384  }
385  }
386 
387  else if( p.nMatch("THER" ) )
388  {
389  /* change the treatment of the heating - cooling effects of H2,
390  * options are simple (use TH85 expressions) and full (use large molecule)*/
391  if( p.nMatch("SIMP" ) )
392  {
393  hmi.lgH2_Thermal_BigH2 = false;
394  }
395  else if( p.nMatch("FULL" ) )
396  {
397  /* this is the default - use big atom */
398  hmi.lgH2_Thermal_BigH2 = true;
399  }
400  }
401 
402  else if( p.nMatch("CHEM" ) )
403  {
404  /* atom h2 chemistry simple command
405  * change the treatment of the chemistry - formation and destruction,
406  * options are simple (use TH85 expressions) and full (use large molecule)*/
407  if( p.nMatch("SIMP" ) )
408  {
409  hmi.lgH2_Chemistry_BigH2 = false;
410  }
411  else if( p.nMatch("FULL" ) )
412  {
413  /* this is the default - use big atom */
414  hmi.lgH2_Chemistry_BigH2 = true;
415  }
416  }
417 
418  /* there is no final branch - if we do not find a keyword, simply
419  * turn on the H2 molecule */
420  return;
421 }
int nTRACE
Definition: h2_priv.h:396
const int N_ELEC
Definition: h2_priv.h:21
bool nMatch(const char *chKey) const
Definition: parser.h:135
bool lgElmtOn
Definition: deuterium.h:19
double FFmtRead(void)
Definition: parser.cpp:353
bool lgH2_Chemistry_BigH2
Definition: hmi.h:160
long int n_elec_states
Definition: h2_priv.h:406
int n_trace_full
Definition: h2_priv.h:399
t_coll_source coll_source[N_X_COLLIDER]
Definition: h2_priv.h:313
bool lgREAD_DATA
Definition: h2_priv.h:249
double xSTDNoise
Definition: h2_priv.h:388
double H2_to_H_limit
Definition: h2_priv.h:391
void ParseAtomH2(Parser &p)
FILE * ioQQQ
Definition: cddefines.cpp:7
Definition: parser.h:31
int n_trace_matrix
Definition: h2_priv.h:399
bool lgH2_ortho_para_coll_on
Definition: h2_priv.h:369
int n_trace_iterations
Definition: h2_priv.h:399
bool lgLTE
Definition: h2_priv.h:366
bool lgColl_dissoc_coll
Definition: h2_priv.h:359
string filename
Definition: h2_priv.h:56
double xMeanNoise
Definition: h2_priv.h:388
bool lgEnabled
Definition: h2_priv.h:342
bool lgH2_PAH2_ORNL
Definition: h2_priv.h:377
bool lgH2_NOISE
Definition: h2_priv.h:380
#define EXIT_FAILURE
Definition: cddefines.h:144
bool lgH2_He_ORNL
Definition: h2_priv.h:373
#define cdEXIT(FAIL)
Definition: cddefines.h:438
NORETURN void NoNumb(const char *chDesc) const
Definition: parser.cpp:233
diatomics h2("h2", 4100.,&hmi.H2_total, Yan_H2_CS)
bool lgColl_deexec_Calc
Definition: h2_priv.h:356
bool lgH2_grain_deexcitation
Definition: h2_priv.h:363
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
bool lgH2_ORH2_ORNL
Definition: h2_priv.h:376
bool lgH2_Thermal_BigH2
Definition: hmi.h:160
bool lgColl_gbar
Definition: h2_priv.h:353
bool lgH2_NOISECOSMIC
Definition: h2_priv.h:382
diatomics hd("hd", 4100.,&hmi.HD_total, Yan_H2_CS)
t_deuterium deut
Definition: deuterium.cpp:8
bool lgEOL(void) const
Definition: parser.h:98
void init_genrand(unsigned long s)
t_hmi hmi
Definition: hmi.cpp:5
void set_numLevelsMatrix(long numLevels)
void fixit(void)
Definition: service.cpp:991
int n_trace_final
Definition: h2_priv.h:399