cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parse_drive.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 /*ParseDrive parse the drive command - drive calls to various subs */
4 /*DrvCaseBHS allow user to query hydrogen A's, asks for up, low level, gives A, drive hyas */
5 /*DrvHyas allow user to query hydrogen A's, asks for up, low level, gives A, drive hyas */
6 /*dgaunt drive gaunt factor routines by letting user query values */
7 #include "cddefines.h"
8 #include "trace.h"
9 #include "hydro_bauman.h"
10 #include "atmdat.h"
11 #include "abund.h"
12 #include "rt_escprob.h"
13 #include "rt.h"
14 #include "mc_escape.h"
15 #include "parser.h"
16 #include "thirdparty.h"
17 #include "atmdat_gaunt.h"
18 
19 /*dgaunt drive gaunt factor routines by letting user query values */
20 STATIC void dgaunt(void);
21 
22 /*DrvHyas allow user to query hydrogen A's, asks for up, low level, gives A, drive hyas */
23 STATIC void DrvHyas(void);
24 
25 /* drive escape probability routines */
26 STATIC void DrvEscP( void );
27 
28 void ParseDrive(Parser &p )
29 {
30  bool lgEOL;
31  long int n,
32  i;
33  double fac,
34  zed;
35 
36  DEBUG_ENTRY( "ParseDrive()" );
37 
38  /* NB evolve all following names to style DrvSomething */
39 
40  /* option to drive cloudy, which one? */
41  if( p.nMatch("FFMT") )
42  {
43  /* free format parser */
44  char chInput[INPUT_LINE_LENGTH];
45  fprintf( ioQQQ, " FFmtRead ParseDrive entered. Enter number.\n" );
46  lgEOL = false;
47  while( !lgEOL )
48  {
49  if( read_whole_line( chInput , (int)sizeof(chInput) , ioStdin ) == NULL )
50  {
51  fprintf( ioQQQ, " ParseDrive.dat error getting magic number\n" );
53  }
54  i = 1;
55  fac = FFmtRead(chInput,&i,sizeof(chInput),&lgEOL);
56  if( lgEOL )
57  {
58  fprintf( ioQQQ, " FFmtRead hit the EOL with no value, return=%10.2e\n",
59  fac );
60  break;
61  }
62  else if( fac == 0. )
63  {
64  break;
65  }
66  else
67  {
68  fprintf( ioQQQ, " FFmtRead returned with value%11.4e\n",
69  fac );
70  }
71  fprintf( ioQQQ, " Enter 0 to stop, or another value.\n" );
72  }
73  fprintf( ioQQQ, " FFmtRead ParseDrive exits.\n" );
74  }
75 
76  else if( p.nMatch("CDLI") )
77  {
78  /* drive cdLine to check that it finds all the right lines, routine is in lines.c */
79  trace.lgDrv_cdLine = true;
80  }
81 
82  else if( p.nMatch(" E1 ") )
83  {
84  // option to drive exponential integral routines
85  // first, special case given in Abramowitz & Stegun
86  double tau = 1.275;
87  for( i=0; i<50; ++i )
88  {
89  fprintf(ioQQQ,"tau\t%.3e\t exp-tau\t%.5e\t e1 tau\t%.5e \t e2 "
90  "\t%.5e \te2n %.5e \t e3\t%.5e \t e4\t%.5e \n",
91  tau, sexp(tau), e1(tau), e2(tau), expn(2, tau),
92  expn(3, tau), expn(4, tau) );
93  tau = exp10( ((double)i/4. - 9.) );
94  }
96  }
97 
98  else if( p.nMatch("ESCA") )
99  {
100  if ( p.nMatch("VALI") )
101  {
102  double tau = p.FFmtRead();
103  double a = p.FFmtRead();
104  if (p.lgEOL())
105  {
106  a = 0.0;
107  }
108  double beta = p.FFmtRead();
109  if (p.lgEOL())
110  {
111  beta = 0.0;
112  }
113  mc_escape(tau, a, beta);
115  }
116 
117  /* option to drive escape probability routines */
118  DrvEscP( );
119  }
120 
121  else if( p.nMatch("HYAS") )
122  {
123  /* option to drive Jason's hydrogen transition probabilities */
124  DrvHyas();
125  }
126 
127  else if( p.nMatch("GAUN") )
128  {
129  /* drive gaunt factor routine */
130  if( p.nMatch("CHEC") )
131  {
132  double Z = p.FFmtRead();
133  if( p.lgEOL() )
134  Z = 1.;
135  else
136  {
137  Z = floor(Z);
138  if( Z <= 0. || Z > LIMELM )
139  {
140  fprintf( ioQQQ, " invalid value for charge %ld\n", long(Z) );
142  }
143  }
144  dgaunt_check(Z);
145  }
146  else
147  dgaunt();
148  }
149 
150  else if( p.nMatch("PUMP") )
151  {
152  if( p.nMatch("VALI") )
153  {
154  double damp = p.FFmtRead();
155  if (p.lgEOL())
156  {
157  damp = 0.0;
158  }
159  DrivePump(damp);
161  }
162  char chInput[INPUT_LINE_LENGTH];
163  lgEOL = false;
164  fprintf( ioQQQ, " Continuum pump ParseDrive entered - Enter log tau\n" );
165  while( !lgEOL )
166  {
167  if( read_whole_line( chInput , (int)sizeof(chInput) , ioStdin ) == NULL )
168  {
169  fprintf( ioQQQ, " Parse Drive error getting optical depth\n" );
171  }
172  /* get tau */
173  i = 1;
174  double tau = FFmtRead(chInput,&i,sizeof(chInput),&lgEOL);
175  if( lgEOL )
176  break;
177  tau = exp10(tau);
178  fprintf( ioQQQ, " Tau =%11.4e\n", tau );
179  double damp = 0.;
180  fac = DrvContPump(tau, damp);
181  fprintf( ioQQQ, " ContPump =%11.4e\n", fac );
182  fprintf( ioQQQ, " Enter null to stop, or another value.\n" );
183  }
184  fprintf( ioQQQ, " ContPump ParseDrive exits.\n" );
185  }
186 
187  else if( p.nMatch("STAR") )
188  {
189  char chInput[INPUT_LINE_LENGTH];
190  /* get starburst abundances */
191  for( i=0; i < 40; i++ )
192  {
193  zed = ((double)i+1.)/4. + 0.01;
194  sprintf( chInput, "starburst, zed=%10.4f", zed );
195  p.setline(chInput);
196  abund_starburst(p);
197  fprintf( ioQQQ, "%8.1e", zed );
198  for(n=0; n < LIMELM; n++)
199  fprintf( ioQQQ, "%8.1e", abund.solar[n] );
200  fprintf( ioQQQ, "\n" );
201  }
202  }
203 
204  else if( p.nMatch("VOIGT") )
205  {
206  string file;
207  bool hasstr = ( p.GetQuote(file) == 0 );
208  FILE *ioVOIGT = ioQQQ;
209  if (hasstr)
210  ioVOIGT = open_data(file.c_str(), "w");
211 
212  if( p.nMatch("TABLE") )
213  {
214  /* create tab-delimited table giving Voigt function */
215  fprintf(ioVOIGT,"x \\ a");
216  const realnum DampLogMin = -4., DampLogMax = 4.01;
217  for( realnum damplog=DampLogMin; damplog<DampLogMax; ++damplog)
218  fprintf(ioVOIGT,"\ta=%.3e",exp10(damplog));
219  fprintf(ioVOIGT , "\n");
220 
221  for( realnum x=-2.; x<5.;x+=0.05)
222  {
223  realnum xlin = exp10(x);
224  fprintf(ioVOIGT,"%.3e",xlin);
225  for( realnum damplog=DampLogMin; damplog<DampLogMax; ++damplog)
226  {
227  realnum xval[1];
228  xval[0] = xlin;
229  realnum damp = exp10(damplog);
230  realnum yval[1];
231  VoigtH(damp,xval,yval,1);
232  fprintf(ioVOIGT , "\t%.3e",yval[0]);
233  }
234  fprintf(ioVOIGT , "\n");
235  }
236  }
237  else
238  {
239  /* Voigt function debugging print - parameter is damping constant a */
240  realnum damp = (realnum)p.FFmtRead();
241  if( p.lgEOL() )
242  {
243  fprintf( ioVOIGT, " The damping constant must appear on the print voigt command. Sorry.\n" );
245  }
246 
247  const long NVOIGT=100;
248  realnum xprofile[NVOIGT], profileVoigtH[NVOIGT];
249  for( long i=0; i<NVOIGT; ++i )
250  xprofile[i] = (realnum)i * 10.f / (realnum)NVOIGT;
251 
252  VoigtH( damp, xprofile, profileVoigtH, NVOIGT );
253 
254  fprintf(ioVOIGT,"\n x VoigtH\n");
255  for( long int i=0; i<NVOIGT; ++i )
256  {
257  fprintf(ioVOIGT,"%.4e %.4e\n", xprofile[i], profileVoigtH[i] );
258  }
259  }
260 
261  if (ioVOIGT != ioQQQ)
262  fclose(ioVOIGT);
264  }
265 
266  else
267  {
268  fprintf( ioQQQ,
269  " Unrecognized key; keys are CDLIne, E1, ESCApe, FFMTread, GAUNt, "
270  "HYAS, PUMP, STAR, and VOIGt. Sorry.\n" );
272  }
273  return;
274 }
275 
276 /*DrvEscP user queries escape probability routines, which return values */
277 STATIC void DrvEscP( void )
278 {
279  char chCard[INPUT_LINE_LENGTH];
280  bool lgEOL;
281  long i;
282  double tau;
283 
284  DEBUG_ENTRY( "DrvEscP()" );
285 
286  /* this routine is enterd with the command escape probability, and
287  * drives the escape probability routine to compare answers */
288  fprintf( ioQQQ, " Enter the log of the one-sided optical depth; line with no number to stop.\n" );
289 
290  lgEOL = false;
291  while( !lgEOL )
292  {
293  if( read_whole_line( chCard , (int)sizeof(chCard) , ioStdin ) == NULL )
294  {
295  break;
296  }
297 
298  i = 1;
299  tau = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
300  if( lgEOL )
301  {
302  break;
303  }
304 
305  tau = exp10(tau);
306  fprintf( ioQQQ, "tau was %e\n", tau );
307  fprintf( ioQQQ, " ESCINC=%11.3e\n", esc_PRD_1side(tau,1e-4) );
308  fprintf( ioQQQ, " ESCCOM=%11.3e\n", esc_CRDwing_1side(tau,1e-4 ) );
309  fprintf( ioQQQ, " ESCA0K2=%11.3e\n", esca0k2(tau) );
310 
311  }
312  return;
313 }
314 
315 /*DrvHyas allow user to query hydrogen A's, asks for up, low level, gives A, drive hyas */
316 STATIC void DrvHyas(void)
317 {
318  char chCard[INPUT_LINE_LENGTH];
319  bool lgEOL;
320  long int i, nHi, lHi, nLo, lLo;
321 
322  DEBUG_ENTRY( "DrvHyas()" );
323 
324  /* this routine is entered with the command DRIVE HYAS, and
325  * drives Jason's hydrogen einstein A routines */
326 
327  nHi = 1;
328  /* nHi never lt 1 */
329  while( nHi != 0 )
330  {
331  fprintf( ioQQQ, " Enter four quantum numbers (n, l, n', l'), null line to stop.\n" );
332  if( read_whole_line( chCard , (int)sizeof(chCard) , ioStdin ) == NULL )
333  {
334  fprintf( ioQQQ, " error getting drvhyas \n" );
336  }
337 
338  i = 1;
339  nHi = (long int)FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
340  if( lgEOL )
341  break;
342 
343  lHi = (long int)FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
344  if( lgEOL )
345  {
346  fprintf( ioQQQ, " must be four numbers!\n" );
347  break;
348  }
349 
350  if( lHi >= nHi )
351  {
352  fprintf( ioQQQ, " l must be less than n!\n" );
353  break;
354  }
355 
356  nLo = (long int)FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
357  if( lgEOL )
358  {
359  fprintf( ioQQQ, " must be four numbers!\n" );
360  break;
361  }
362 
363  lLo = (long int)FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
364  if( lgEOL )
365  {
366  fprintf( ioQQQ, " must be four numbers!\n" );
367  break;
368  }
369 
370  if( lLo >= nLo )
371  {
372  fprintf( ioQQQ, " l must be less than n!\n" );
373  break;
374  }
375 
376  if( nLo > nHi )
377  {
378  long nTemp, lTemp;
379 
380  /* swap hi and lo */
381  nTemp = nLo;
382  lTemp = lLo;
383  nLo = nHi;
384  lLo = lHi;
385  nHi = nTemp;
386  lHi = lTemp;
387  }
388 
389  fprintf( ioQQQ, " A(%3ld,%3ld->%3ld,%3ld)=%11.3e\n",
390  nHi, lHi, nLo, lLo,
391  H_Einstein_A( nHi, lHi, nLo, lLo, 1 ) );
392 
393  }
394  fprintf( ioQQQ, " Driver exits, enter next line.\n" );
395 
396  return;
397 }
398 
399 /*dgaunt drive Gaunt factor routines by letting user query values */
401 {
402  DEBUG_ENTRY( "dgaunt()" );
403 
404  /* this routine is entered with the command DRIVE GAUNT, and
405  * drives the Gaunt factor routine to check range
406  * */
407  char chCard[INPUT_LINE_LENGTH];
408  bool lgEOL;
409 
410  fprintf( ioQQQ, " Enter 0 to input temp, energy, and net charge, or 1 for u, gamma**2, and net charge.\n" );
411  if( read_whole_line( chCard , (int)sizeof(chCard) , ioStdin ) == NULL )
412  {
413  fprintf( ioQQQ, " dgaunt error getting input line\n" );
415  }
416  long i = 1;
417  int inputflag = (int)FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
418 
419  if( inputflag == 0 )
420  {
421  fprintf( ioQQQ, " Enter the temperature (log if <=10), energy (Ryd), and net charge. Null line to stop.\n" );
422  /* >>chng 96 july 07, got rid of statement labels replacing with do while
423  * */
424  long ierror = 0;
425  while( ierror == 0 )
426  {
427  if( read_whole_line( chCard , (int)sizeof(chCard) , ioStdin ) == NULL )
428  {
429  fprintf( ioQQQ, " dgaunt error getting input line\n" );
431  }
432  i = 1;
433  double alogte = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
434  /* the line may be trash but ierror will pick it up */
435  if( lgEOL )
436  {
437  fprintf( ioQQQ, " Gaunt driver exits, enter next line.\n" );
438  break;
439  }
440  /* numbers less than or equal to 10 are the log of the temperature */
441  double TeNew;
442  if( alogte > 10. )
443  TeNew = alogte;
444  else
445  TeNew = exp10(alogte);
446 
447  double enerlin = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
448  if( lgEOL || enerlin == 0. )
449  fprintf( ioQQQ, " Sorry, but there should be two more numbers, energy and charge.\n" );
450 
451  double z = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
452  if( lgEOL || z == 0. )
453  fprintf( ioQQQ, " Sorry, but there should be a third number, charge.\n" );
454 
455  /* This is thermally averaged Gaunt factor */
456  double mygaunt = t_gaunt::Inst().gauntff( long(z), TeNew, enerlin );
457  fprintf( ioQQQ, " Using my routine, Gff= %.4e\n", mygaunt );
458  }
459  }
460  else
461  {
462  /* this routine is entered with the command DRIVE GAUNT, and
463  * drives the Gaunt factor routine to check range
464  * */
465  fprintf( ioQQQ, " Enter log u, log gamma2, and net charge. Null line to stop.\n" );
466  long ierror = 0;
467  while( ierror == 0 )
468  {
469  if( read_whole_line( chCard , (int)sizeof(chCard) , ioStdin ) == NULL )
470  {
471  fprintf( ioQQQ, " dgaunt error getting input line\n" );
473  }
474  i = 1;
475  double logu = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
476  /* the line may be trash but ierror will pick it up */
477  if( lgEOL )
478  {
479  fprintf( ioQQQ, " Gaunt driver exits, enter next line.\n" );
480  break;
481  }
482 
483  double loggamma2 = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
484  if( lgEOL )
485  fprintf( ioQQQ, " Sorry, but there should be two more numbers, log gamma2 and charge.\n" );
486 
487  double z = FFmtRead(chCard,&i,sizeof(chCard),&lgEOL);
488  if( lgEOL )
489  fprintf( ioQQQ, " Sorry, but there should be another number, charge.\n" );
490 
491  /* This is my attempt to calculate thermally averaged Gaunt factors. */
492  double mygaunt = t_gaunt::Inst().gauntff( long(z), TE1RYD*pow2(z)/exp10(loggamma2),
493  pow2(z)*exp10(logu-loggamma2) );
494  fprintf( ioQQQ, " Using my routine, Gff= %.4e\n", mygaunt );
495  }
496  }
497 }
bool nMatch(const char *chKey) const
Definition: parser.h:150
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:765
STATIC void DrvEscP(void)
double FFmtRead(void)
Definition: parser.cpp:472
double exp10(double x)
Definition: cddefines.h:1368
void setline(const char *const card)
Definition: parser.h:82
bool lgDrv_cdLine
Definition: trace.h:115
double DrvContPump(double tau, double damp)
double e1(double x)
void DrivePump(double tau)
int GetQuote(string &chLabel)
Definition: parser.cpp:213
void dgaunt_check(double Z)
sys_float sexp(sys_float x)
Definition: service.cpp:999
FILE * ioQQQ
Definition: cddefines.cpp:7
double expn(int n, double x)
Definition: parser.h:43
static t_gaunt & Inst()
Definition: cddefines.h:209
t_trace trace
Definition: trace.cpp:5
t_abund abund
Definition: abund.cpp:5
void mc_escape(double tau_in, double a, double beta)
Definition: mc_escape.cpp:92
#define STATIC
Definition: cddefines.h:118
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
const int INPUT_LINE_LENGTH
Definition: cddefines.h:301
#define cdEXIT(FAIL)
Definition: cddefines.h:482
void ParseDrive(Parser &p)
Definition: parse_drive.cpp:28
double esc_PRD_1side(double tau, double a)
Definition: rt_escprob.cpp:116
double gauntff(long Z, double Te, double anu)
const int LIMELM
Definition: cddefines.h:308
T pow2(T a)
Definition: cddefines.h:981
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
STATIC void DrvHyas(void)
bool lgEOL(void) const
Definition: parser.h:113
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
void abund_starburst(Parser &p)
double e2(double x)
char * read_whole_line(char *chLine, int nChar, FILE *ioIN)
Definition: service.cpp:70
double esca0k2(double taume)
Definition: rt_escprob.cpp:424
double esc_CRDwing_1side(double tau, double a)
Definition: rt_escprob.cpp:165
double H_Einstein_A(long int n, long int l, long int np, long int lp, long int iz)
STATIC void dgaunt(void)
void VoigtH(realnum a, const realnum v[], realnum y[], int n)
Definition: thirdparty.h:418
FILE * ioStdin
Definition: cddefines.cpp:8
#define EXIT_SUCCESS
Definition: cddefines.h:166
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition: service.cpp:381
realnum solar[LIMELM]
Definition: abund.h:210