cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mole_h2_io.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 /*H2_ParseSave parse the save h2 command */
4 /*H2_PunchDo save some properties of the large H2 molecule */
5 /*chMolBranch returns a char with the spectroscopic branch of a transition */
6 /*H2_Prt_line_tau print line optical depths, called from premet in response to print line optical depths command*/
7 /*H2_PunchLineStuff include H2 lines in punched optical depths, etc, called from SaveLineStuff */
8 /*H2_Punch_line_data save line data for H2 molecule */
9 /*H2_Read_hminus_distribution read distribution function for H2 population following formation from H minus */
10 /*H2_ReadDissprob read dissociation probabilities and kinetic energies for all electronic levels */
11 /*H2_ReadEnergies read energies for all electronic levels */
12 /*H2_ReadTransprob read transition probabilities */
13 /*H2_Prt_Zone print H2 info into zone results, called from prtzone for each printed zone */
14 /*H2_ParseSave parse the save h2 command */
15 /*H2_Prt_column_density print H2 info into zone results, called from prtzone for each printed zone */
16 /*H2_LinesAdd add in explicit lines from the large H2 molecule, called by lines_molecules */
17  /*cdH2_Line returns 1 if we found the line,
18  * or false==0 if we did not find the line because ohoto-para transition
19  * or upper level has lower energy than lower level */
20 #include "cddefines.h"
21 #include "physconst.h"
22 #include "save.h"
23 #include "hmi.h"
24 #include "prt.h"
25 #include "secondaries.h"
26 #include "grainvar.h"
27 #include "input.h"
28 #include "phycon.h"
29 #include "rfield.h"
30 #include "hyperfine.h"
31 #include "thermal.h"
32 #include "lines.h"
33 #include "lines_service.h"
34 #include "mole.h"
35 #include "dense.h"
36 #include "radius.h"
37 #include "colden.h"
38 #include "taulines.h"
39 #include "h2.h"
40 #include "h2_priv.h"
41 #include "cddrive.h"
42 #include "doppvel.h"
43 #include "doppvel.h"
44 #include "parser.h"
45 
47 
48 /*H2_LinesAdd add in explicit lines from the large H2 molecule, called by lines_molecules */
50 {
51  /* H2 not on, so space not allocated */
52  if( !lgEnabled )
53  return;
54 
55  DEBUG_ENTRY( "H2_LinesAdd()" );
56 
57  if( strcmp( "H2 ", label.c_str() ) == 0 )
58  {
59  /* >>chng 05 nov 04, make info copies of these lines up here
60  * these are among the strongest lines in the 2 micron window and some have nearly the same
61  * wavelength as far weaker lines that may come before them in the line stack. in that case
62  * cdLine would find the much weaker line with the same wavelength.
63  * put strong H2 lines first so that line search will find these, and not far weaker
64  * lines with nearly the same wavelength - these will be duplicated in the output but
65  * these are here for into (the 'i') so does no harm
66  */
67 
68  /* >>chng 05 dec 22, had hand entered wavelength in A as second parameter. This gave
69  * rounded off result when set line precision 5 was used. now uses same logic that
70  * PutLine will eventually use - simply enter same wl in Ang */
71  /* 1-0 S(4) - 18910 */
72  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][6] ][ ipEnergySort[0][0][4] ] ], "H2 ", 'i', false, "H2 line");
73  /* 1-0 S(3) - 19570 */
74  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][5] ][ ipEnergySort[0][0][3] ] ], "H2 ", 'i', false, "H2 line");
75  /* 1-0 S(2) - 20330 */
76  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][4] ][ ipEnergySort[0][0][2] ] ], "H2 ", 'i', false, "H2 line");
77  /* 1-0 S1) - 21210 */
78  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][3] ][ ipEnergySort[0][0][1] ] ], "H2 ", 'i', false, "H2 line");
79  /* 1-0 S(0) - 22230 */
80  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][2] ][ ipEnergySort[0][0][0] ] ], "H2 ", 'i', false, "H2 line");
81  /* start Q branch - selection rule requires that J be non-zero, so no Q(0) */
82  /* 1-0 Q(2) - 24130 */
83  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][2] ][ ipEnergySort[0][0][2] ] ], "H2 ", 'i', false, "H2 line");
84  /* 1-0 Q(1) - 24060 */
85  lindst( trans[ ipTransitionSort[ ipEnergySort[0][1][1] ][ ipEnergySort[0][0][1] ] ], "H2 ", 'i', false, "H2 line");
86  }
87 
88 
89  for( TransitionList::iterator tr = trans.begin(); tr != rad_end; ++tr )
90  {
91  qList::iterator Hi = ( (*tr).Hi() );
92  if( (*Hi).n() >= nElecLevelOutput ) continue;
93  qList::iterator Lo = ( (*tr).Lo() );
94  /* all ground vib state rotation lines - first is J to J-2 */
95  PutLine( *tr, "diatoms lines", label.c_str() );
96  if( LineSave.ipass == 0 )
97  {
98  H2_SaveLine[(*Hi).n()][(*Hi).v()][(*Hi).J()][(*Lo).n()][(*Lo).v()][(*Lo).J()] = 0.;
99  }
100  else if( LineSave.ipass == 1 )
101  {
102  H2_SaveLine[(*Hi).n()][(*Hi).v()][(*Hi).J()][(*Lo).n()][(*Lo).v()][(*Lo).J()] +=
103  (realnum)( radius.dVeffAper * (*tr).Emis().xIntensity() );
104  }
105  }
106 
107  return;
108 }
109 
110 /*H2_ParseSave parse the save h2 command */
112  char *chHeader)
113 {
114  DEBUG_ENTRY( "H2_ParseSave()" );
115 
116  save.whichDiatomToPrint[save.nsave] = &(*this);
117 
118  /* this provides info on the large H2 molecule */
119  if( p.nMatch("COLU") )
120  {
121  /* save column density */
122  strcpy( save.chSave[save.nsave], "H2cl" );
123 
124  /* this is an option to scan off highest vib and rot states
125  * to save pops - first is limit to vibration, then rotation
126  * if no number is entered then 0 is set and all levels punched */
127  /* now get vib limit */
129  "H2 vibration state",0.0);
130 
131  /* highest rotation */
133  "H2 rotation state",0.0);
134  /* this says whether to save triplets or a matrix for output -
135  * default is triplets, so only check for matrix */
136  if( p.nMatch( "MATR" ) )
137  {
138  /* matrix */
139  save.punarg[save.nsave][2] = 1;
140  sprintf( chHeader, "#vib\trot\tcolumn density\n" );
141  }
142  else
143  {
144  /* triplets */
145  save.punarg[save.nsave][2] = -1;
146  sprintf( chHeader, "#vib\trot\tEner(K)\tcolden\tcolden/stat wght\tLTE colden\tLTE colden/stat wght\n" );
147  }
148  }
149  else if( p.nMatch("COOL") )
150  {
151  /* heating and cooling rates */
152  strcpy( save.chSave[save.nsave], "H2co" );
153  sprintf( chHeader,
154  "#H2 depth\ttot cool\tTH Sol\tBig Sol\tTH pht dis\tpht dis\tTH Xcool\tXcool \n" );
155  }
156 
157  else if( p.nMatch("CREA") )
158  {
159  /* H2 creation rates */
160  fprintf( ioQQQ, " This command has been superseded by the \"creation\" option of the \"save chemistry rates\" command.\n" );
161  fprintf( ioQQQ, " Sorry.\n" );
163  }
164  else if( p.nMatch("DEST") )
165  {
166  /* save H2 destruction - output destruction rates */
167  fprintf( ioQQQ, " This command has been superseded by the \"destruction\" option of the \"save chemistry rates\" command.\n" );
168  fprintf( ioQQQ, " Sorry.\n" );
170  }
171 
172  else if( p.nMatch("HEAT") )
173  {
174  /* heating and cooling rates */
175  strcpy( save.chSave[save.nsave], "H2he" );
176  sprintf( chHeader,
177  "#H2 depth\ttot Heat\tHeat(big)\tHeat(TH85)\tDissoc(Big)\tDissoc(TH85) \n" );
178  }
179 
180  else if( p.nMatch("LEVE") )
181  {
182  /* save H2 level energies */
183  strcpy( save.chSave[save.nsave], "H2le" );
184  sprintf( chHeader,
185  "#H2 v\tJ\tenergy(wn)\tstat wght\tSum As" );
186  char chHoldit[chN_X_COLLIDER+12];
187  for( int nColl=0; nColl<N_X_COLLIDER; ++nColl )
188  {
189  /* labels for all colliders */
190  sprintf(chHoldit,"\tCritDen %s",chH2ColliderLabels[nColl]);
191  strcat( chHeader , chHoldit );
192  }
193  strcat( chHeader , "\n" );
194  }
195 
196  else if( p.nMatch("LINE") )
197  {
198  /* save H2 lines - all in X */
199  strcpy( save.chSave[save.nsave], "H2ln" );
200  sprintf( chHeader,
201  "#H2 line\tEhi\tVhi\tJhi\tElo\tVlo\tJlo\twl(mic)\twl(lab)\tlog L or I\tI/Inorm\tExcit(hi, K)\tg_u h nu * Aul\n" );
202  /* first optional number changes the threshold of weakest line to print*/
203  /* fe2thresh is intensity relative to normalization line,
204  * normally Hbeta, and is set to zero in zero.c */
205 
206  /* threshold for faintest line to save, default is 1e-4 of norm line */
208  "faintest line to save",1e-4);
209 
210  /* lines from how many electronic states? default is one, just X, and is
211  * obtained with GROUND keyword. ALL will produce all lines from all levels.
212  * else, if a number is present, will be the number. if no number, no keyword,
213  * appear then just ground */
214  if( p.nMatch( "ELEC" ) )
215  {
216  if( p.nMatch(" ALL") )
217  {
218  /* all electronic levels - when done, will set upper limit, the
219  * number of electronic levels actually computed, don't know this yet,
220  * so signify with negative number */
221  nElecLevelOutput = -1;
222  }
223  else if( p.nMatch("GROU") )
224  {
225  /* just the ground electronic state */
226  nElecLevelOutput = 1;
227  }
228  else
229  {
231  "electronic levels for output",1.0);
232  }
233  }
234  }
235 
236  else if( p.nMatch(" PDR") )
237  {
238  /* creation and destruction processes */
239  strcpy( save.chSave[save.nsave], "H2pd" );
240  sprintf( chHeader, "#H2 creation, destruction. \n" );
241  }
242  else if( p.nMatch("POPU") )
243  {
244  /* save populations */
245  strcpy( save.chSave[save.nsave], "H2po" );
246 
247  /* this is an option to scan off highest vib and rot states
248  * to save pops - first is limit to vibration, then rotation
249  * if no number is entered then 0 is set and all levels punched */
250  /* now get vib lim */
252  "highest H2 save vibration state",0.0);
253 
254  /* this is limit to rotation quantum index */
256  "highest H2 save rotation state",0.0);
257 
258  if( p.nMatch( "ZONE" ) )
259  {
260  /* save v=0 pops for each zone, all along one line */
261  save.punarg[save.nsave][2] = 0;
262  sprintf( chHeader, "#depth\torth\tpar\te=1 rel pop\te=2 rel pop\tv,J rel pops\n" );
263  }
264  else
265  {
266  /* will not do zone output, only output at the end of the calculation
267  * now check whether to save triplets or a matrix for output -
268  * default is triplets, so only check for matrix */
269  if( p.nMatch( "MATR" ) )
270  {
271  /* matrix */
272  save.punarg[save.nsave][2] = 1;
273  sprintf( chHeader, "#vib\trot\tpops\n" );
274  }
275  else
276  {
277  /* triplets */
278  save.punarg[save.nsave][2] = -1;
279  sprintf( chHeader, "#vib\trot\ts\tenergy(wn)\tpops/H2\told/H2\tpops/g/H2\tdep coef\tFin(Col)\tFout(col)\tRCout\tRRout\tRCin\tRRin\n" );
280  }
281  }
282  }
283 
284  else if( p.nMatch("RATE") )
285  {
286  /* save h2 rates - creation and destruction rates */
287  strcpy( save.chSave[save.nsave], "H2ra" );
288  sprintf( chHeader,
289  "#depth\tN(H2)\tN(H2)/u(H2)\tA_V(star)\tn(Eval)"
290  "\tH2/Htot\trenorm\tfrm grn\tfrmH-\tdstTH85\tBD96\tELWERT\tBigH2\telec->H2g\telec->H2s"
291  "\tG(TH85)\tG(DB96)\tCR\tEleclife\tShield(BD96)\tShield(H2)\tBigh2/G0(spc)\ttot dest"
292  "\tHeatH2Dish_TH85\tHeatH2Dexc_TH85\tHeatDish_BigH2\tHeatDexc_BigH2\thtot\n" );
293  }
294  else if( p.nMatch("SOLO") )
295  {
296  /* rate of Solomon process then fracs of exits from each v, J level */
297  strcpy( save.chSave[save.nsave], "H2so" );
298  sprintf( chHeader,
299  "#depth\tSol tot\tpump/dissoc\tpump/dissoc BigH2\tavH2g\tavH2s\tH2g chem/big H2\tH2s chem/big H2\tfrac H2g BigH2\tfrac H2s BigH2\teHi\tvHi\tJHi\tvLo\tJLo\tfrac\twl(A)\n" );
300  }
301  else if( p.nMatch("SPEC") )
302  {
303  /* special save command*/
304  strcpy( save.chSave[save.nsave], "H2sp" );
305  sprintf( chHeader,
306  "#depth\tspecial\n" );
307  }
308  else if( p.nMatch("TEMP") )
309  {
310  /* various temperatures for neutral/molecular gas */
311  strcpy( save.chSave[save.nsave], "H2te" );
312  sprintf( chHeader,
313  "#depth\tH2/H\tn(1/0)\tn(ortho/para)\tT(1/0)\tT(2/0)\tT(3/0)\tT(3/1)\tT(4/0)\tT(kin)\tT(21cm)\tT_sum(1/0)\tT_sum(2/0)\tT_sum(3/0)\tT_sum(3/1)\tT_sum(4/0) \n");
314  }
315  else if( p.nMatch("THER") )
316  {
317  /* thermal heating cooling processes involving H2 */
318  strcpy( save.chSave[save.nsave], "H2th" );
319  sprintf( chHeader,
320  "#depth\tH2/H\tn(1/0)\tn(ortho/para)\tT(1/0)\tT(2/0)\tT(3/0)\tT(3/1)\tT(4/0)\tT(kin)\tT(21cm)\tT_sum(1/0)\tT_sum(2/0)\tT_sum(3/0)\tT_sum(3/1)\tT_sum(4/0) \n");
321  }
322  else
323  {
324  fprintf( ioQQQ,
325  " There must be a second key; they are RATE, LINE, COOL, COLUMN, _PDR, SOLOmon, TEMP, and POPUlations\n" );
327  }
328  return;
329 }
330 
331 
332 /*H2_Prt_Zone print H2 info into zone results, called from prtzone for each printed zone */
334 {
335  /* no print if H2 not turned on, or not computed for these conditions */
336  if( !lgEnabled || !nCall_this_zone )
337  return;
338 
339  DEBUG_ENTRY( "H2_Prt_Zone()" );
340 
341  fprintf( ioQQQ, " %s density ", label.c_str() );
342  fprintf(ioQQQ,PrintEfmt("%9.2e", (*dense_total)));
343 
344  fprintf( ioQQQ, " orth/par");
345  fprintf(ioQQQ,PrintEfmt("%9.2e", ortho_density / SDIV( para_density )));
346 
347  fprintf( ioQQQ, " v0 J=0,3");
348  fprintf(ioQQQ,PrintEfmt("%9.2e", states[ ipEnergySort[0][0][0] ].Pop() / (*dense_total)));
349  fprintf(ioQQQ,PrintEfmt("%9.2e", states[ ipEnergySort[0][0][1] ].Pop() / (*dense_total)));
350  fprintf(ioQQQ,PrintEfmt("%9.2e", states[ ipEnergySort[0][0][2] ].Pop() / (*dense_total)));
351  fprintf(ioQQQ,PrintEfmt("%9.2e", states[ ipEnergySort[0][0][3] ].Pop() / (*dense_total)));
352 
353  fprintf( ioQQQ, " TOTv=0,3");
354  fprintf(ioQQQ,PrintEfmt("%9.2e", pops_per_vib[0][0] / (*dense_total)));
355  fprintf(ioQQQ,PrintEfmt("%9.2e", pops_per_vib[0][1] / (*dense_total)));
356  fprintf(ioQQQ,PrintEfmt("%9.2e", pops_per_vib[0][2] / (*dense_total)));
357  fprintf(ioQQQ,PrintEfmt("%9.2e", pops_per_vib[0][3] / (*dense_total)));
358  fprintf( ioQQQ, "\n");
359  return;
360 }
361 
363 {
364  /* no print if H2 not turned on, or not computed for these conditions */
365  if( !lgEnabled || !nCall_this_zone )
366  return;
367 
368  DEBUG_ENTRY( "H2_PrtDepartCoef()" );
369 
370  // print departure coefficients
371  fprintf( ioQQQ, " %s departure coefficients\n", label.c_str() );
372  for( long iElec=0; iElec<n_elec_states; ++iElec )
373  {
374  fprintf( ioQQQ, "%li electronic\n", iElec );
375  for( long iVib=0; iVib<=nVib_hi[iElec]; ++iVib )
376  {
377  for( long iRot=0; iRot<Jlowest[iElec]; ++iRot )
378  fprintf( ioQQQ, " -----" );
379  for( long iRot=Jlowest[iElec]; iRot<=nRot_hi[iElec][iVib]; ++iRot )
380  {
381  long i = ipEnergySort[iElec][iVib][iRot];
382  fprintf( ioQQQ, " %5.3f", depart[i] );
383  }
384  fprintf( ioQQQ, "\n" );
385  }
386  fprintf( ioQQQ, "\n" );
387  if( iElec==0 )
388  break;
389  }
390 
391  return;
392 }
393 
394 /*H2_Prt_column_density print H2 info into zone results, called from prtzone for each printed zone */
396  /* this is stream used for io, is stdout when called by final,
397  * is save unit when save output generated */
398  FILE *ioMEAN )
399 
400 {
401  int iVibHi;
402 
403  /* no print if H2 not turned on, or not computed for these conditions */
404  if( !lgEnabled || !nCall_this_zone )
405  return;
406 
407  DEBUG_ENTRY( "H2_Prt_column_density()" );
408 
409  fprintf( ioMEAN, " H2 total ");
410  fprintf(ioMEAN,"%7.3f", log10(SDIV(ortho_colden + para_colden)));
411 
412  fprintf( ioMEAN, " H2 ortho ");
413  fprintf(ioMEAN,"%7.3f", log10(SDIV(ortho_colden)));
414 
415  fprintf( ioMEAN, " para");
416  fprintf(ioMEAN,"%7.3f", log10(SDIV(para_colden)));
417 
418  iVibHi = 0;
419  fprintf( ioMEAN, " v0 J=0,3");
420  fprintf(ioMEAN,"%7.3f", log10(SDIV(H2_X_colden[iVibHi][0])));
421  fprintf(ioMEAN,"%7.3f", log10(SDIV(H2_X_colden[iVibHi][1])));
422  fprintf(ioMEAN,"%7.3f", log10(SDIV(H2_X_colden[iVibHi][2])));
423  fprintf(ioMEAN,"%7.3f", log10(SDIV(H2_X_colden[iVibHi][3])));
424 
425  return;
426 }
427 
428 
429 /*H2_ReadTransprob read transition probabilities */
430 void diatomics::H2_ReadTransprob( long int nelec , TransitionList &trns)
431 {
432  const char* cdDATAFILE[N_ELEC] =
433  {
434  "transprob_X.dat",
435  "transprob_B.dat",
436  "transprob_C_plus.dat",
437  "transprob_C_minus.dat",
438  "transprob_B_primed.dat",
439  "transprob_D_plus.dat",
440  "transprob_D_minus.dat"
441  };
442  FILE *ioDATA;
443  char chLine[FILENAME_PATH_LENGTH_2];
444  long int i, n1, n2, n3;
445  long int iVibHi , iVibLo , iRotHi , iRotLo , iElecHi , iElecLo;
446  bool lgEOL;
447 
448  DEBUG_ENTRY( "H2_ReadTransprob()" );
449 
450  /* now open the data file */
451  char chPath[FILENAME_PATH_LENGTH_2];
452  strcpy( chPath, path.c_str() );
453  strcat( chPath, input.chDelimiter );
454  strcat( chPath, cdDATAFILE[nelec] );
455  ioDATA = open_data( chPath , "r" );
456 
457  /* read the first line and check that magic number is ok */
458  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
459  {
460  fprintf( ioQQQ, " H2_ReadTransprob could not read first line of %s\n", cdDATAFILE[nelec]);
462  }
463  i = 1;
464  /* magic number */
465  n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
466  n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
467  n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
468 
469  /* magic number
470  * the following is the set of numbers that appear at the start of level1.dat 01 08 10 */
471  if( ( n1 != 2 ) || ( n2 != 4 ) || ( n3 != 29 ) )
472  {
473  fprintf( ioQQQ,
474  " H2_ReadTransprob: the version of %s is not the current version.\n", cdDATAFILE[nelec] );
475  fprintf( ioQQQ,
476  " I expected to find the number 2 4 29 and got %li %li %li instead.\n" ,
477  n1 , n2 , n3 );
478  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
480  }
481 
482  long nlines = 0;
483  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
484  {
485  /* skip comment */
486  if( chLine[0]=='#' )
487  continue;
488  if( chLine[0]=='\n' || chLine[0]=='\0' || chLine[0]==' ' )
489  break;
490 
491  double Aul;
492  int n = sscanf(chLine,"%li\t%li\t%li\t%li\t%li\t%li\t%le",
493  &iElecHi , &iVibHi ,&iRotHi , &iElecLo , &iVibLo , &iRotLo , &Aul );
494  ASSERT( n == 7 );
495  ASSERT( iElecHi == nelec );
496  ASSERT( iElecHi < N_ELEC );
497  ASSERT( iElecLo < N_ELEC );
498 
499  /* check that we actually included the levels in the model representation */
500  if( iVibHi <= nVib_hi[iElecHi] &&
501  iVibLo <= nVib_hi[iElecLo] &&
502  iRotHi <= nRot_hi[iElecHi][iVibHi] &&
503  iRotLo <= nRot_hi[iElecLo][iVibLo])
504  {
505  long ipHi = ipEnergySort[iElecHi][iVibHi][iRotHi];
506  long ipLo = ipEnergySort[iElecLo][iVibLo][iRotLo];
507  double ener = states[ipHi].energy().WN() - states[ipLo].energy().WN();
508  long lineIndex = ipTransitionSort[ipHi][ipLo];
509 
510  /* only lines that have real Aul are added to stack. */
511  trns[lineIndex].AddLine2Stack();
512  trns[lineIndex].Emis().Aul() = (realnum)Aul;
513 
514  /* say that this line exists */
515  lgH2_radiative[ipHi][ipLo] = true;
516  ++nlines;
517 
518  /* prints transitions with negative energies - should not happen */
519  if( ener <= 0. )
520  {
521  fprintf(ioQQQ,"negative energy H2 transition\t%li\t%li\t%li\t%li\t%.2e\t%.2e\n",
522  iVibHi,iVibLo,iRotHi,iRotLo,Aul,ener);
523  ShowMe();
525  }
526  }
527  }
528  if( nTRACE >= n_trace_full )
529  fprintf(ioQQQ," There are a total of %li lines in the entire H2 molecule.\n", nlines );
530 
531  fclose( ioDATA );
532  return;
533 }
534 
535 #if 0
536 /*H2_Read_Cosmicray_distribution read distribution function for H2 population following cosmic ray collisional excitation */
537 void H2_Read_Cosmicray_distribution(void)
538 {
539  //CR_PRINT (false), CR_X (1), CR_VIB(15), CR_J(10), CR_EXIT(3)
540 
541  /*>>refer H2 cr excit Tine, S., Lepp, S., Gredel, R., & Dalgarno, A. 1997, ApJ, 481, 282 */
542  FILE *ioDATA;
543  char chLine[FILENAME_PATH_LENGTH_2];
544  long int i, n1, n2, n3, iVib , iRot;
545  long neut_frac;
546  bool lgEOL;
547 
548  DEBUG_ENTRY( "H2_Read_Cosmicray_distribution()" );
549 
550  /* now open the data file */
551  char chPath[FILENAME_PATH_LENGTH_2];
552  strcpy( chPath, path.c_str() );
553  strcat( chPath, input.chDelimiter );
554  strcat( chPath, "H2_CosmicRay_collision.dat" );
555  ioDATA = open_data( chPath, "r" );
556 
557  /* read the first line and check that magic number is ok */
558  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
559  {
560  fprintf( ioQQQ, " H2_Read_Cosmicray_distribution could not read first line of %s\n", "H2_Cosmic_collision.dat");
562  }
563 
564  i = 1;
565  /* magic number */
566  n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
567  n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
568  n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
569 
570  /* magic number
571  * the following is the set of numbers that appear at the start of H2_Cosmic_collision.dat 01 21 03 */
572  if( ( n1 != 1 ) || ( n2 != 21 ) || ( n3 != 3 ) )
573  {
574  fprintf( ioQQQ,
575  " H2_Read_Cosmicray_distribution: the version of %s is not the current version.\n", "H2_Cosmic_collision.dat" );
576  fprintf( ioQQQ,
577  " I expected to find the number 1 21 3 and got %li %li %li instead.\n" ,
578  n1 , n2 , n3 );
579  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
581  }
582 
583  /* read until not a comment */
584  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
585  BadRead();
586 
587  while( chLine[0]=='#' )
588  {
589  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
590  BadRead();
591  }
592 
593  iRot = 1;
594  iVib = 1;
595  neut_frac = 0;
596  while( iVib >= 0 )
597  {
598  long int j_minus_ji;
599  double a[10];
600 
601  sscanf(chLine,"%li\t%li\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
602  &iVib ,&j_minus_ji , &a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9]
603  );
604  /* negative iVib says end of data */
605  if( iVib < 0 )
606  continue;
607 
608  /* cr_rate[CR_X][CR_VIB][CR_J][CR_EXIT];*/
609  /* check that we actually included the levels in the model representation */
610  ASSERT( iVib < CR_VIB );
611  ASSERT( j_minus_ji == -2 || j_minus_ji == +2 || j_minus_ji == 0 );
612  ASSERT( neut_frac < CR_X );
613 
614  /* now make i_minus_ji an array index */
615  j_minus_ji = 1 + j_minus_ji/2;
616  ASSERT( j_minus_ji>=0 && j_minus_ji<=2 );
617 
618  /* option to add Gaussian random mole */
619  for( iRot=0; iRot<CR_J; ++iRot )
620  {
621  cr_rate[neut_frac][iVib][iRot][j_minus_ji] = (realnum)a[iRot];
622  }
623  if( lgH2_NOISECOSMIC )
624  {
625  realnum r;
626  r = (realnum)RandGauss( xMeanNoise , xSTDNoise );
627 
628  for( iRot=0; iRot<CR_J; ++iRot )
629  {
630  cr_rate[neut_frac][iVib][iRot][j_minus_ji] *= (realnum)pow(10.,(double)r);
631  }
632  }
633 
634  if( CR_PRINT )
635  {
636  fprintf(ioQQQ,"cr rate\t%li\t%li", iVib , j_minus_ji );
637  for( iRot=0; iRot<CR_J; ++iRot )
638  {
639  fprintf(ioQQQ,"\t%.3e", cr_rate[neut_frac][iVib][iRot][j_minus_ji] );
640  }
641  fprintf(ioQQQ,"\n" );
642  }
643 
644  /* now get next line */
645  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
646  BadRead();
647  while( chLine[0]=='#' )
648  {
649  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
650  BadRead();
651  }
652  }
653  fclose( ioDATA );
654 
655  return;
656 }
657 #endif
658 
660 {
661 public:
662  bool operator<( const level_tmp& second ) const
663  {
664  if( eWN < second.eWN )
665  return true;
666  else
667  return false;
668  }
669  long n, v, J;
670  double eWN;
671 };
672 
673 /*H2_ReadEnergies read energies for all electronic levels */
675 {
676  DEBUG_ENTRY( "H2_ReadEnergies()" );
677 
678  vector<int> n, v, J;
679  vector<double>eWN;
680 
681  for( long nelec=0; nelec<n_elec_states; ++nelec )
682  {
683  /* get energies out of files */
684  H2_ReadEnergies(nelec,n,v,J,eWN);
685  }
686 
687  vector<level_tmp> levels;
688  levels.resize( n.size() );
689  ASSERT( levels.size() > 0 );
690  for( unsigned i = 0; i < n.size(); ++i )
691  {
692  levels[i].n = n[i];
693  levels[i].v = v[i];
694  levels[i].J = J[i];
695  levels[i].eWN = eWN[i];
696  }
697 
698  // now get levels in energy order (comparison done by operator< of level_tmp class)
699  sort( levels.begin(), levels.end() );
700 
701  // populate states
702  for( vector<level_tmp>::iterator lev = levels.begin(); lev != levels.end(); ++lev )
703  {
704  states.resize( states.size() + 1 );
705  long i = states.size() - 1;
706  states[i].n() = lev->n;
707  states[i].v() = lev->v;
708  states[i].J() = lev->J;
709  states[i].energy().set( lev->eWN, "cm^-1" );
710  /* NB this must be kept parallel with nelem and ionstag in transition struc,
711  * since that struc expects to find the abundances here - abund set in hmole.c */
712  states[i].nelem() = -1;
713  /* this does not mean anything for a molecule */
714  states[i].IonStg() = -1;
715  strcpy( states[i].chLabel(), label.c_str() );
716  }
717 
718  ASSERT( states.size() > 0 );
719  ASSERT( states.size() == levels.size() );
720 
721  for( long nelec=0; nelec<n_elec_states; ++nelec )
722  {
723  ASSERT( nLevels_per_elec[nelec] > 0 );
724  ASSERT( nVib_hi[nelec] > 0 );
725  ASSERT( nVib_hi[nelec] > Jlowest[nelec] );
726 
727  nRot_hi[nelec].resize( nVib_hi[nelec]+1 );
728  nRot_hi[nelec] = 0;
729  }
730 
731  for( qList::const_iterator st = states.begin(); st != states.end(); ++st )
732  {
733  nRot_hi[ (*st).n() ][ (*st).v() ] = MAX2( nRot_hi[ (*st).n() ][ (*st).v() ], (*st).J() );
734  }
735 
736  return;
737 }
738 
739 void diatomics::H2_ReadEnergies( long int nelec, vector<int>& n, vector<int>& v, vector<int>&J, vector<double>& eWN )
740 {
741  DEBUG_ENTRY("diatomics::H2_ReadEnergies()");
742  const char* cdDATAFILE[N_ELEC] =
743  {
744  "energy_X.dat",
745  "energy_B.dat",
746  "energy_C_plus.dat",
747  "energy_C_minus.dat",
748  "energy_B_primed.dat",
749  "energy_D_plus.dat",
750  "energy_D_minus.dat"
751  };
752  /* now open the data file */
753  char chPath[FILENAME_PATH_LENGTH_2];
754  strcpy( chPath, path.c_str() );
755  strcat( chPath, input.chDelimiter );
756  strcat( chPath, cdDATAFILE[nelec] );
757  FILE *ioDATA = open_data( chPath, "r" );
758 
759  char chLine[FILENAME_PATH_LENGTH_2];
760  long int i, n1, n2, n3;
761  bool lgEOL;
762 
763  /* read the first line and check that magic number is ok */
764  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
765  {
766  fprintf( ioQQQ, " H2_ReadEnergies could not read first line of %s\n", cdDATAFILE[nelec]);
768  }
769  i = 1;
770  /* magic number */
771  n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
772  n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
773  n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
774 
775  /* magic number
776  * the following is the set of numbers that appear at the start of level1.dat 01 08 10 */
777  if( ( n1 != 2 ) || ( n2 != 4 ) || ( n3 != 29 ) )
778  {
779  fprintf( ioQQQ,
780  " H2_ReadEnergies: the version of %s is not the current version.\n", cdDATAFILE[nelec] );
781  fprintf( ioQQQ,
782  " I expected to find the number 2 4 29 and got %li %li %li instead.\n" ,
783  n1 , n2 , n3 );
784  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
786  }
787 
788  /* this will count the number of levels within each electronic state */
789  nLevels_per_elec[nelec] = 0;
790  nVib_hi[nelec] = 0;
791  Jlowest[nelec] = LONG_MAX;
792 
793  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
794  {
795  /* skip comment */
796  if( chLine[0]=='#' )
797  continue;
798  if( chLine[0]=='\n' || chLine[0]=='\0' || chLine[0]==' ' )
799  break;
800  long iVib, iRot;
801  double energyWN;
802  int nReads = sscanf(chLine,"%li\t%li\t%le", &iVib, &iRot, &energyWN );
803  ASSERT( nReads == 3 );
804  ASSERT( iVib >= 0 );
805  ASSERT( iRot >= 0 );
806  ASSERT( energyWN > 0. || (nelec==0 && iVib==0 && iRot==0 ) );
807 
808  n.push_back( nelec );
809  v.push_back( iVib );
810  J.push_back( iRot );
811  eWN.push_back( energyWN );
812 
813  // update limits
814  nVib_hi[nelec] = MAX2( nVib_hi[nelec], iVib );
815  Jlowest[nelec] = MIN2( Jlowest[nelec], iRot );
816  /* increment number of levels within this electronic state */
817  ++nLevels_per_elec[nelec];
818  }
819 
820  ASSERT( n.size() > 0 );
821  ASSERT( nLevels_per_elec[nelec] > 0 );
822  ASSERT( nVib_hi[nelec] > 0 );
823  ASSERT( nVib_hi[nelec] > Jlowest[nelec] );
824 
825  fclose( ioDATA );
826 
827  return;
828 }
829 
830 /*H2_ReadDissocEnergies read energies for all electronic levels */
832 {
833  const char* cdDATAFILE = "energy_dissoc.dat";
834  FILE *ioDATA;
835  char chLine[FILENAME_PATH_LENGTH_2];
836  long int i, n1, n2, n3;
837  bool lgEOL;
838 
839  DEBUG_ENTRY( "H2_ReadDissocEnergies()" );
840 
841  /* now open the data file */
842  char chPath[FILENAME_PATH_LENGTH_2];
843  strcpy( chPath, path.c_str() );
844  strcat( chPath, input.chDelimiter );
845  strcat( chPath, cdDATAFILE );
846  ioDATA = open_data( chPath, "r" );
847 
848  /* read the first line and check that magic number is ok */
849  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
850  {
851  fprintf( ioQQQ, " H2_ReadDissocEnergies could not read first line of %s\n", cdDATAFILE );
853  }
854  i = 1;
855  /* magic number */
856  n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
857  n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
858  n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
859 
860  /* magic number
861  * the following is the set of numbers that appear at the start of level1.dat 01 08 10 */
862  if( ( n1 != 2 ) || ( n2 != 4 ) || ( n3 != 29 ) )
863  {
864  fprintf( ioQQQ,
865  " H2_ReadDissocEnergies: the version of %s is not the current version.\n", cdDATAFILE );
866  fprintf( ioQQQ,
867  " I expected to find the number 2 4 29 and got %li %li %li instead.\n" ,
868  n1 , n2 , n3 );
869  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
871  }
872 
873  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
874  {
875  /* skip comment */
876  if( chLine[0]=='#' )
877  continue;
878  if( chLine[0]=='\n' || chLine[0]=='\0' || chLine[0]==' ' )
879  break;
880  long iElec;
881  double energyWN;
882  int n = sscanf(chLine,"%li\t%le", &iElec, &energyWN );
883  ASSERT( n == 2 );
884  ASSERT( iElec >= 0 );
885  ASSERT( iElec < N_ELEC );
886  ASSERT( energyWN > 0. );
887  H2_DissocEnergies[iElec] = energyWN;
888  }
889  fclose( ioDATA );
890 
891  return;
892 }
893 
894 /*H2_ReadDissprob read dissociation probabilities and kinetic energies for all electronic levels */
895 void diatomics::H2_ReadDissprob( long int nelec )
896 {
897  const char* cdDATAFILE[N_ELEC] =
898  {
899  "dissprob_X.dat",/* this does not exist and nelec == 0 is not valid */
900  "dissprob_B.dat",
901  "dissprob_C_plus.dat",
902  "dissprob_C_minus.dat",
903  "dissprob_B_primed.dat",
904  "dissprob_D_plus.dat",
905  "dissprob_D_minus.dat"
906  };
907  char chLine[FILENAME_PATH_LENGTH_2];
908  bool lgEOL;
909 
910  DEBUG_ENTRY( "H2_ReadDissprob()" );
911 
912  ASSERT( nelec > 0 );
913 
914  /* now open the data file */
915  char chPath[FILENAME_PATH_LENGTH_2];
916  strcpy( chPath, path.c_str() );
917  strcat( chPath, input.chDelimiter );
918  strcat( chPath, cdDATAFILE[nelec] );
919  FILE *ioDATA = open_data( chPath, "r" );
920 
921  /* read the first line and check that magic number is ok */
922  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
923  {
924  fprintf( ioQQQ, " H2_ReadDissprob could not read first line of %s\n", cdDATAFILE[nelec]);
926  }
927  long i = 1;
928  /* magic number */
929  long n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
930  long n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
931  long n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
932 
933  /* magic number
934  * the following is the set of numbers that appear at the start of level1.dat 01 08 10 */
935  if( ( n1 != 3 ) || ( n2 != 2 ) || ( n3 != 11 ) )
936  {
937  fprintf( ioQQQ,
938  " H2_ReadDissprob: the version of %s is not the current version.\n", cdDATAFILE[nelec] );
939  fprintf( ioQQQ,
940  " I expected to find the number 3 2 11 and got %li %li %li instead.\n" ,
941  n1 , n2 , n3 );
942  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
944  }
945 
946  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
947  {
948  /* skip comment */
949  if( chLine[0]=='#' )
950  continue;
951  if( chLine[0]=='\n' || chLine[0]=='\0' || chLine[0]==' ' )
952  break;
953 
954  long iVib, iRot;
955  double a, b;
956  i = 1;
957  sscanf(chLine,"%li\t%li\t%le\t%le",
958  &iVib, &iRot,
959  /* dissociation probability */
960  &a ,
961  /* dissociation kinetic energy - eV not ergs */
962  &b);
963 
964  /* these have to agree if data file is valid */
965  //ASSERT( iVib >= 0 );
966  //ASSERT( iVib <= nVib_hi[nelec] );
967  //ASSERT( iRot >= Jlowest[nelec] );
968  //ASSERT( iRot <= nRot_hi[nelec][iVib] );
969  if( ( iVib < 0 ) ||
970  ( iVib > nVib_hi[nelec] ) ||
971  ( iRot < Jlowest[nelec] ) ||
972  ( iRot > nRot_hi[nelec][iVib] ) )
973  continue;
974 
975  /* dissociation probability */
976  H2_dissprob[nelec][iVib][iRot] = (realnum)a;
977  /* dissociation kinetic energy - eV not ergs */
978  H2_disske[nelec][iVib][iRot] = (realnum)b;
979  }
980  fclose( ioDATA );
981  return;
982 }
983 
984 
985 /*H2_Read_hminus_distribution read distribution function for H2 population following formation from H minus */
987 {
988  FILE *ioDATA;
989  char chLine[FILENAME_PATH_LENGTH_2];
990  long int i, n1, n2, n3, iVib , iRot;
991  bool lgEOL;
992  double sumrate[nTE_HMINUS] = {0};
993  /* set true for lots of printout */
994  const bool lgH2HMINUS_PRT = false;
995 
996  DEBUG_ENTRY( "H2_Read_hminus_distribution()" );
997 
998  /* now open the data file */
999  char chPath[FILENAME_PATH_LENGTH_2];
1000  strcpy( chPath, path.c_str() );
1001  strcat( chPath, input.chDelimiter );
1002  strcat( chPath, "hminus_deposit.dat" );
1003  ioDATA = open_data( chPath, "r" );
1004 
1005  /* read the first line and check that magic number is ok */
1006  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
1007  {
1008  fprintf( ioQQQ, " H2_Read_hminus_distribution could not read first line of %s\n", chPath );
1010  }
1011 
1012  i = 1;
1013  /* magic number */
1014  n1 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
1015  n2 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
1016  n3 = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
1017 
1018  /* magic number
1019  * the following is the set of numbers that appear at the start of H2_hminus_deposit.dat 01 08 10 */
1020  if( ( n1 != 2 ) || ( n2 != 10 ) || ( n3 != 17 ) )
1021  {
1022  fprintf( ioQQQ,
1023  " H2_Read_hminus_distribution: the version of %s is not the current version.\n", chPath );
1024  fprintf( ioQQQ,
1025  " I expected to find the number 2 10 17 and got %li %li %li instead.\n" ,
1026  n1 , n2 , n3 );
1027  fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
1029  }
1030 
1031  /* read until not a comment */
1032  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
1033  BadRead();
1034 
1035  while( chLine[0]=='#' )
1036  {
1037  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
1038  BadRead();
1039  }
1040 
1041  iRot = 1;
1042  iVib = 1;
1043  while( iVib >= 0 )
1044  {
1045  /* set true to print rates */
1046 
1047  double a[nTE_HMINUS] , ener;
1048  sscanf(chLine,"%li\t%li\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
1049  &iVib ,&iRot , &ener, &a[0],&a[1],&a[2] , &a[3],&a[4],&a[5] ,&a[6]
1050  );
1051  /* negative iVib says end of data */
1052  if( iVib < 0 )
1053  continue;
1054 
1055  /* check that we actually included the levels in the model representation */
1056  ASSERT( iVib <= nVib_hi[0] &&
1057  iRot <= nRot_hi[0][iVib] );
1058 
1059  if( lgH2HMINUS_PRT )
1060  fprintf(ioQQQ,"hminusss\t%li\t%li", iVib , iRot );
1061  for( i=0; i<nTE_HMINUS; ++i )
1062  {
1063  H2_X_hminus_formation_distribution[i][iVib][iRot] = (realnum)pow(10.,-a[i]);
1064  sumrate[i] += H2_X_hminus_formation_distribution[i][iVib][iRot];
1065  if( lgH2HMINUS_PRT )
1066  fprintf(ioQQQ,"\t%.3e", H2_X_hminus_formation_distribution[i][iVib][iRot] );
1067  }
1068  if( lgH2HMINUS_PRT )
1069  fprintf(ioQQQ,"\n" );
1070 
1071  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
1072  BadRead();
1073  while( chLine[0]=='#' )
1074  {
1075  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
1076  BadRead();
1077  }
1078  }
1079  fclose( ioDATA );
1080 
1081  if( lgH2HMINUS_PRT )
1082  {
1083  /* print total rate */
1084  fprintf(ioQQQ," total H- formation rate ");
1085  /* convert temps to log */
1086  for(i=0; i<nTE_HMINUS; ++i )
1087  {
1088  fprintf(ioQQQ,"\t%.3e" , sumrate[i]);
1089  }
1090  fprintf(ioQQQ,"\n" );
1091  }
1092 
1093  /* convert to dimensionless factors that add to unity */
1094  for( iVib=0; iVib<=nVib_hi[0]; ++iVib )
1095  {
1096  for( iRot=Jlowest[0]; iRot<=nRot_hi[0][iVib]; ++iRot )
1097  {
1098  for(i=0; i<nTE_HMINUS; ++i )
1099  {
1100  H2_X_hminus_formation_distribution[i][iVib][iRot] /= (realnum)sumrate[i];
1101  }
1102  }
1103  }
1104 
1105  if( lgH2HMINUS_PRT )
1106  {
1107  /* print total rate */
1108  fprintf(ioQQQ," H- distribution function ");
1109  for( iVib=0; iVib<=nVib_hi[0]; ++iVib )
1110  {
1111  for( iRot=Jlowest[0]; iRot<=nRot_hi[0][iVib]; ++iRot )
1112  {
1113  fprintf(ioQQQ,"%li\t%li", iVib , iRot );
1114  for(i=0; i<nTE_HMINUS; ++i )
1115  {
1116  fprintf(ioQQQ,"\t%.3e", H2_X_hminus_formation_distribution[i][iVib][iRot] );
1117  }
1118  fprintf(ioQQQ,"\n" );
1119  }
1120  }
1121  }
1122  return;
1123 }
1124 
1125 /* ===================================================================== */
1126 /*H2_Punch_line_data save line data for H2 molecule */
1128  /* io unit for save */
1129  FILE* ioPUN ,
1130  /* save all levels if true, only subset if false */
1131  bool lgDoAll )
1132 {
1133  if( !lgEnabled )
1134  return;
1135 
1136  DEBUG_ENTRY( "H2_Punch_line_data()" );
1137 
1138  if( lgDoAll )
1139  {
1140  fprintf( ioQQQ,
1141  " H2_Punch_line_data ALL option not implemented in H2_Punch_line_data yet 1\n" );
1143  }
1144  else
1145  {
1146  bool lgPrint = false;
1147  fprintf( ioPUN, "#Eu\tVu\tJu\tEl\tVl\tJl\tWL\tgl\tgu\tgf\tA\tCS\tn(crt)\n" );
1148  /* save line date, looping over all possible lines */
1149  for( TransitionList::iterator tr = trans.begin(); tr != trans.end(); ++tr )
1150  {
1151  if( (*tr).ipCont() <= 0 )
1152  continue;
1153  (*tr).Coll().col_str() = 0.;
1154  qList::iterator Hi = ( (*tr).Hi() );
1155  qList::iterator Lo = ( (*tr).Lo() );
1156  /* print quantum indices */
1157  fprintf(ioPUN,"%2li\t%2li\t%2li\t%2li\t%2li\t%2li\t",
1158  (*Hi).n(), (*Hi).v(), (*Hi).J(),
1159  (*Lo).n(), (*Lo).v(), (*Lo).J() );
1160  Save1LineData( *tr, ioPUN, false , lgPrint);
1161  }
1162 
1163  fprintf( ioPUN , "\n");
1164  }
1165  return;
1166 }
1167 
1168 /*H2_PunchLineStuff include H2 lines in punched optical depths, etc, called from SaveLineStuff */
1169 void diatomics::H2_PunchLineStuff( FILE * io , realnum xLimit , long index)
1170 {
1171  if( !lgEnabled )
1172  return;
1173 
1174  DEBUG_ENTRY( "H2_PunchLineStuff()" );
1175 
1176  /* loop over all possible lines */
1177  for( TransitionList::iterator tr = trans.begin(); tr != trans.end(); ++tr )
1178  {
1179  if( (*tr).ipCont() <= 0 )
1180  continue;
1181  Save1Line( *tr, io, xLimit, index, GetDopplerWidth(2.f*dense.AtomicWeight[ipHYDROGEN]));
1182  }
1183 
1184  return;
1185 }
1186 
1187 
1188 /*H2_Prt_line_tau print line optical depths, called from premet in response to print line optical depths command*/
1190 {
1191  if( !lgEnabled )
1192  return;
1193 
1194  DEBUG_ENTRY( "H2_Prt_line_tau()" );
1195 
1196  /* loop over all possible lines */
1197  for( TransitionList::iterator tr = trans.begin(); tr != trans.end(); ++tr )
1198  {
1199  if( (*tr).ipCont() <= 0 )
1200  continue;
1201  prme( false, *tr );
1202  }
1203 
1204  return;
1205 }
1206 
1207 
1208 /*chMolBranch returns a char with the spectroscopic branch of a transition */
1209 STATIC char chMolBranch( long iRotHi , long int iRotLo )
1210 {
1211  /* these are the spectroscopic branches */
1212  char chBranch[5] = {'O','P','Q','R','S'};
1213  /* this is the index within the chBranch array */
1214  int ip = 2 + (iRotHi - iRotLo);
1215  if( ip<0 || ip>=5 )
1216  {
1217  fprintf(ioQQQ," chMolBranch called with insane iRotHi=%li iRotLo=%li ip=%i\n",
1218  iRotHi , iRotLo , ip );
1219  ip = 0;
1220  }
1221 
1222  return( chBranch[ip] );
1223 }
1224 
1225 /*H2_PunchDo save some properties of the large H2 molecule */
1226 void diatomics::H2_PunchDo( FILE* io , char chJOB[] , const char chTime[] , long int ipPun )
1227 {
1228  DEBUG_ENTRY( "H2_PunchDo()" );
1229 
1230  /* which job are we supposed to do? This routine is active even when H2 is not turned on
1231  * so do not test on lgEnabled initially */
1232 
1233  /* H2 populations computed in last zone -
1234  * give all of molecule in either matrix or triplet format */
1235  if( (strcmp( chJOB , "H2po" ) == 0) && (strcmp(chTime,"LAST") == 0) &&
1236  (save.punarg[ipPun][2] != 0) )
1237  {
1238  /* >>chng 04 feb 19, do not save if H2 not yet evaluated */
1239  if( lgEnabled && lgEvaluated )
1240  {
1241  long iVibHi= 0;
1242  long iRotHi = 0;
1243  long iElecHi=0;
1244  long LimVib, LimRot;
1245  /* the limit to the number of vibration levels punched -
1246  * default is all, but first two numbers on save h2 pops command
1247  * reset limit */
1248  /* this is limit to vibration */
1249  if( save.punarg[ipPun][0] > 0 )
1250  {
1251  LimVib = (long)save.punarg[ipPun][0];
1252  }
1253  else
1254  {
1255  LimVib = nVib_hi[iElecHi];
1256  }
1257 
1258  /* first save the current ortho, para, and total H2 density */
1259  fprintf(io,"%i\t%i\t%.3e\tortho\n",
1260  103 ,
1261  103 ,
1262  ortho_density );
1263  fprintf(io,"%i\t%i\t%.3e\tpara\n",
1264  101 ,
1265  101 ,
1266  para_density );
1267  fprintf(io,"%i\t%i\t%.3e\ttotal\n",
1268  0 ,
1269  0 ,
1270  (*dense_total) );
1271 
1272  /* now save the actual populations, first part both matrix and triplets */
1273  for( iVibHi=0; iVibHi<=LimVib; ++iVibHi )
1274  {
1275  /* this is limit to rotation quantum index */
1276  if( save.punarg[ipPun][1] > 0 )
1277  {
1278  LimRot = (long)MIN2(
1279  save.punarg[ipPun][1] , (realnum)nRot_hi[iElecHi][iVibHi]);
1280  }
1281  else
1282  {
1283  LimRot = nRot_hi[iElecHi][iVibHi];
1284  }
1285  if( save.punarg[ipPun][2] > 0 )
1286  {
1287  long int i;
1288  /* this option save matrix */
1289  if( iVibHi == 0 )
1290  {
1291  fprintf(io,"vib\\rot");
1292  /* this is first vib, so make row of rot numbs */
1293  for( i=0; i<=LimRot; ++i )
1294  {
1295  fprintf(io,"\t%li",i);
1296  }
1297  fprintf(io,"\n");
1298  }
1299  fprintf(io,"%li",iVibHi );
1300  for( iRotHi=Jlowest[iElecHi]; iRotHi<=LimRot; ++iRotHi )
1301  {
1302  fprintf(io,"\t%.3e",
1303  states[ ipEnergySort[iElecHi][iVibHi][iRotHi] ].Pop()/(*dense_total) );
1304  }
1305  fprintf(io,"\n" );
1306  }
1307  else if( save.punarg[ipPun][2] < 0 )
1308  {
1309  /* this option save triplets - the default */
1310  for( iRotHi=Jlowest[iElecHi]; iRotHi<=LimRot; ++iRotHi )
1311  {
1312  /* this will say whether ortho or para,
1313  * H2_lgOrtho is 0 or 1 depending on whether or not ortho,
1314  * so chlgPara[H2_lgOrtho] gives P or O for printing */
1315  const char chlgPara[2]={'P','O'};
1316  const long ipHi = ipEnergySort[iElecHi][iVibHi][iRotHi];
1317 
1318  /* intensity, relative to normalization line, for faintest line to save */
1319  fprintf(io,"%li\t%li\t%c\t%.1f\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\n",
1320  /* upper vibration and rotation quantum numbers */
1321  iVibHi , iRotHi ,
1322  /* an 'O' or 'P' for ortho or para */
1323  chlgPara[H2_lgOrtho[iElecHi][iVibHi][iRotHi]],
1324  /* the level excitation energy in wavenumbers */
1325  states[ipHi].energy().WN(),
1326  /* actual population relative to total H2 */
1327  states[ipHi].Pop()/(*dense_total) ,
1328  /* old level populations for comparison */
1329  H2_old_populations[iElecHi][iVibHi][iRotHi]/(*dense_total) ,
1330  /* populations per h2 and per statistical weight */
1331  states[ipHi].Pop()/(*dense_total)/H2_stat[iElecHi][iVibHi][iRotHi] ,
1332  /* LTE departure coefficient */
1333  /* >>chng 05 jan 26, missing factor of H2 abundance LTE is norm to unity, not tot abund */
1334  states[ipHi].Pop()/SDIV(H2_populations_LTE[iElecHi][iVibHi][iRotHi]*(*dense_total) ) ,
1335  /* fraction of exits that were collisional */
1336  H2_col_rate_out[iVibHi][iRotHi]/SDIV(H2_col_rate_out[iVibHi][iRotHi]+H2_rad_rate_out[0][iVibHi][iRotHi]) ,
1337  /* fraction of entries that were collisional */
1338  H2_col_rate_in[iVibHi][iRotHi]/SDIV(H2_col_rate_in[iVibHi][iRotHi]+H2_rad_rate_in[iVibHi][iRotHi]),
1339  /* collisions out */
1340  H2_col_rate_out[iVibHi][iRotHi],
1341  /* radiation out */
1342  H2_rad_rate_out[0][iVibHi][iRotHi] ,
1343  /* radiation out */
1344  H2_col_rate_in[iVibHi][iRotHi],
1345  /* radiation in */
1346  H2_rad_rate_in[iVibHi][iRotHi]
1347  );
1348  }
1349  }
1350  }
1351  }
1352  }
1353  /* save H2 populations for each zone
1354  * populations of v=0 for each zone */
1355  else if( (strcmp( chJOB , "H2po" ) == 0) && (strcmp(chTime,"LAST") != 0) &&
1356  (save.punarg[ipPun][2] == 0) )
1357  {
1358  /* >>chng 04 feb 19, do not save if h2 not yet evaluated */
1359  if( lgEnabled && lgEvaluated )
1360  {
1361  fprintf(io,"%.5e\t%.3e\t%.3e", radius.depth_mid_zone ,
1363  /* rel pops of first two excited electronic states */
1364  fprintf(io,"\t%.3e\t%.3e",
1365  pops_per_elec[1] , pops_per_elec[2]);
1366  long iElecHi = 0;
1367  long iVibHi = 0;
1368  long LimVib, LimRot;
1369  /* this is limit to vibration quantum index */
1370  if( save.punarg[ipPun][0] > 0 )
1371  {
1372  LimVib = (long)save.punarg[ipPun][1];
1373  }
1374  else
1375  {
1376  LimVib = nRot_hi[iElecHi][iVibHi];
1377  }
1378  LimVib = MIN2( LimVib , nVib_hi[iElecHi] );
1379  /* this is limit to rotation quantum index */
1380  if( save.punarg[ipPun][1] > 0 )
1381  {
1382  LimRot = (long)save.punarg[ipPun][1];
1383  }
1384  else
1385  {
1386  LimRot = nRot_hi[iElecHi][iVibHi];
1387  }
1388  for( iVibHi = 0; iVibHi<=LimVib; ++iVibHi )
1389  {
1390  fprintf(io,"\tv=%li",iVibHi);
1391  long int LimRotVib = MIN2( LimRot , nRot_hi[iElecHi][iVibHi] );
1392  for( long iRotHi=Jlowest[iElecHi]; iRotHi<=LimRotVib; ++iRotHi )
1393  {
1394  fprintf(io,"\t%.3e",
1395  states[ ipEnergySort[iElecHi][iVibHi][iRotHi] ].Pop()/(*dense_total) );
1396  }
1397  }
1398  fprintf(io,"\n");
1399  }
1400  }
1401 
1402  /* save column densities */
1403  else if( (strcmp( chJOB , "H2cl" ) == 0) && (strcmp(chTime,"LAST") == 0) )
1404  {
1405  long iVibHi= 0;
1406  long iRotHi = 0;
1407  long iElecHi=0;
1408  long LimVib, LimRot;
1409  /* the limit to the number of vibration levels punched -
1410  * default is all, but first two numbers on save h2 pops command
1411  * reset limit */
1412  /* this is limit to vibration */
1413  if( save.punarg[ipPun][0] > 0 )
1414  {
1415  LimVib = (long)save.punarg[ipPun][0];
1416  }
1417  else
1418  {
1419  LimVib = nVib_hi[iElecHi];
1420  }
1421 
1422  /* first save ortho and para populations */
1423  fprintf(io,"%i\t%i\t%.3e\tortho\n",
1424  103 ,
1425  103 ,
1426  ortho_colden );
1427  fprintf(io,"%i\t%i\t%.3e\tpara\n",
1428  101 ,
1429  101 ,
1430  para_colden );
1431  /* total H2 column density */
1432  fprintf(io,"%i\t%i\t%.3e\ttotal\n",
1433  0 ,
1434  0 ,
1436 
1437  /* save level column densities */
1438  for( iVibHi=0; iVibHi<=LimVib; ++iVibHi )
1439  {
1440  if( lgEnabled )
1441  {
1442  /* this is limit to rotation quantum index */
1443  if( save.punarg[ipPun][1] > 0 )
1444  {
1445  LimRot = (long)save.punarg[ipPun][1];
1446  }
1447  else
1448  {
1449  LimRot = nRot_hi[iElecHi][iVibHi];
1450  }
1451  if( save.punarg[ipPun][2] > 0 )
1452  {
1453  long int i;
1454  /* save matrix */
1455  if( iVibHi == 0 )
1456  {
1457  fprintf(io,"vib\\rot");
1458  /* this is first vib, so make row of rot numbs */
1459  for( i=0; i<=LimRot; ++i )
1460  {
1461  fprintf(io,"\t%li",i);
1462  }
1463  fprintf(io,"\n");
1464  }
1465  fprintf(io,"%li",iVibHi );
1466  for( iRotHi=Jlowest[iElecHi]; iRotHi<=LimRot; ++iRotHi )
1467  {
1468  fprintf(io,"\t%.3e",
1469  H2_X_colden[iVibHi][iRotHi]/(*dense_total) );
1470  }
1471  fprintf(io,"\n" );
1472  }
1473  else
1474  {
1475  /* save triplets - the default */
1476  for( iRotHi=Jlowest[iElecHi]; iRotHi<=LimRot; ++iRotHi )
1477  {
1478  fprintf(io,"%li\t%li\t%.1f\t%.3e\t%.3e\t%.3e\t%.3e\n",
1479  iVibHi ,
1480  iRotHi ,
1481  /* energy relative to 0,0, T1CM converts wavenumber to K */
1482  states[ ipEnergySort[iElecHi][iVibHi][iRotHi] ].energy().K(),
1483  /* these are column densities for actual molecule */
1484  H2_X_colden[iVibHi][iRotHi] ,
1485  H2_X_colden[iVibHi][iRotHi]/H2_stat[iElecHi][iVibHi][iRotHi] ,
1486  /* these are same column densities but for LTE populations */
1487  H2_X_colden_LTE[iVibHi][iRotHi] ,
1488  H2_X_colden_LTE[iVibHi][iRotHi]/H2_stat[iElecHi][iVibHi][iRotHi]);
1489  }
1490  }
1491  }
1492  }
1493  }
1494  else if( (strcmp(chJOB , "H2pd" ) == 0) && (strcmp(chTime,"LAST") != 0) )
1495  {
1496  /* save PDR
1497  * output some PDR information (densities, rates) for each zone */
1498  fprintf(io,"%.5e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
1499  /* depth in cm */
1501  /* the computed ortho and para densities */
1502  ortho_density ,
1503  para_density ,
1504  /* the Lyman Werner band dissociation, Tielens & Hollenbach */
1506  /* the Lyman Werner band dissociation, Bertoldi & Draine */
1508  /* the Lyman Werner band dissociation, big H2 mole */
1510  }
1511  else if( (strcmp(chJOB , "H2co" ) == 0) && (strcmp(chTime,"LAST") != 0) )
1512  {
1513  /* save H2 cooling - do heating cooling for each zone old new H2 */
1514  fprintf(io,"%.5e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
1515  /* depth in cm */
1517  /* total cooling, equal to total heating */
1518  thermal.ctot ,
1519  /* H2 destruction by Solomon process, TH85 rate */
1521  /* H2 destruction by Solomon process, big H2 model rate */
1524  /* H2 photodissociation heating, eqn A9 of Tielens & Hollenbach 1985a */
1526  /* heating due to dissociation of electronic excited states */
1527  HeatDiss ,
1528  /* cooling (usually neg and so heating) due to collisions within X */
1530  HeatDexc
1531  );
1532 
1533  }
1534 
1535  else if( (strcmp(chJOB , "H2le" ) == 0) && (strcmp(chTime,"LAST") == 0) )
1536  {
1537  /* save H2 levels */
1538  for( long int ipHi=0; ipHi < nLevels_per_elec[0]; ipHi++ )
1539  {
1540  long iRotHi = ipRot_H2_energy_sort[ipHi];
1541  long iVibHi = ipVib_H2_energy_sort[ipHi];
1542  long int nColl;
1543  double Asum , Csum[N_X_COLLIDER];
1544  Asum = 0;
1545  for( nColl=0; nColl<N_X_COLLIDER; ++nColl )
1546  Csum[nColl] = 0.;
1547  for( long int ipLo=0; ipLo<ipHi; ++ipLo )
1548  {
1549  /* all lower levels */
1550  long iRotLo = ipRot_H2_energy_sort[ipLo];
1551  long iVibLo = ipVib_H2_energy_sort[ipLo];
1552  EmissionProxy em = trans[ ipTransitionSort[ipHi][ipLo] ].Emis();
1553 
1554  /* radiative decays down */
1555  if( ( abs(iRotHi-iRotLo) == 2 || (iRotHi-iRotLo) == 0 ) && iVibLo <= iVibHi &&
1556  lgH2_radiative[ipHi][ipLo] )
1557  {
1558  Asum += em.Aul() * ( em.Pesc() + em.Pdest() + em.Pelec_esc() );
1559  }
1560  /* all collisions down */
1561  mr3ci H2cr = CollRateCoeff.begin(ipHi,ipLo);
1562  for( nColl=0; nColl<N_X_COLLIDER; ++nColl )
1563  Csum[nColl] += H2cr[nColl];
1564  }
1565 
1566  /* save H2 level energies */
1567  fprintf(io,"%li\t%li\t%.2f\t%li\t%.3e",
1568  iVibHi , iRotHi,
1569  states[ipHi].energy().WN(),
1570  (long)states[ipHi].g(),
1571  Asum );
1572  for( nColl=0; nColl<N_X_COLLIDER; ++nColl )
1573  /* sum over all lower levels */
1574  fprintf(io,"\t%.3e",Csum[nColl]);
1575  fprintf(io,"\n");
1576  }
1577  }
1578 
1579  else if( (strcmp(chJOB , "H2ra" ) == 0) && (strcmp(chTime,"LAST") != 0) )
1580  {
1581  /* save h2 rates - some rates and lifetimes */
1582  double sumpop = 0. , sumlife = 0.;
1583 
1584  /* this block, find lifetime against photo excitation into excited electronic states */
1585  if( lgEnabled && lgEvaluated )
1586  {
1587  /* only do if radiative transition exists */
1588  for( TransitionList::iterator tr = trans.begin(); tr != rad_end; ++tr )
1589  {
1590  qList::iterator Lo = ( (*tr).Lo() );
1591  if( (*Lo).n() > 0 || (*Lo).v() > 0 )
1592  continue;
1593  sumlife += (*tr).Emis().pump() * (*(*tr).Lo()).Pop();
1594  sumpop += (*(*tr).Lo()).Pop();
1595  }
1596  }
1597 
1598  /* continue output from save h2 rates command */
1599  /* find photoexcitation rates from v=0 */
1600  /* PDR information for each zone */
1601  fprintf(io,
1602  "%.5e\t%.3e\t%.3e\t%.3e\t%li",
1603  /* depth in cm */
1605  /* the column density (cm^-2) in H2 */
1607  /* this is a special form of column density - should be proportional
1608  * to total shielding */
1610  /* visual extinction due to dust alone, of point source (star)*/
1612  /* number of large molecule evaluations in this zone */
1613  nCall_this_zone );
1614  fprintf(io,
1615  "\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e",
1616  /* total H2 fraction */
1618  /* chemistry renorm factor */
1620  /* rate H2 forms on grains */
1622  /* rate H2 forms by H minus route */
1623  findspecieslocal("H-")->den*1.35e-9,
1624  /* H2 destruction by Solomon process, TH85 rate */
1626  /* H2 destruction by Solomon process, Bertoldi & Draine rate */
1628  /* H2 destruction by Solomon process, Elwert et al. in preparation */
1630  /* H2 destruction by Solomon process, big H2 model rate */
1632  /* rate s-1 H2 electronic excit states decay into H2g */
1634  /* rate s-1 H2 electronic excit states decay into H2s */
1636  );
1637  fprintf(io,
1638  "\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e",
1639  /* The TH85 estimate of the radiation field relative to the Habing value */
1641  /* The DB96 estimate of the radiation field relative to the Habing value */
1643  /* cosmic ray ionization rate */
1644  secondaries.csupra[ipHYDROGEN][0]*0.93,
1645  sumlife/SDIV( sumpop ) ,
1650  fprintf(io,
1651  "\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
1654  HeatDiss,
1655  HeatDexc,
1656  thermal.htot);
1657  }
1658  /* save h2 solomon */
1659  else if( (strcmp(chJOB , "H2so" ) == 0) && (strcmp(chTime,"LAST") != 0) )
1660  {
1661  /* remember as many as nSOL lines contributing to total Solomon process */
1662  const int nSOL = 100;
1663  double sum, one;
1664  long int jlosave[nSOL] , ivlosave[nSOL],
1665  iehisave[nSOL] ,jhisave[nSOL] , ivhisave[nSOL],
1666  nsave,
1667  ipOrdered[nSOL];
1668  int nFail;
1669  realnum fsave[nSOL], wlsave[nSOL];
1670  /* Solomon process, and where it came from */
1671  fprintf(io,"%.5e\t%.3e",
1672  /* depth in cm */
1674  /* H2 destruction by Solomon process, big H2 model rate */
1677  sum = 0.;
1678  /* find sum of all radiative exits from X into excited electronic states */
1679  if( lgEnabled && lgEvaluated )
1680  {
1681  for( TransitionList::iterator tr = trans.begin(); tr != rad_end; ++tr )
1682  {
1683  qList::iterator Lo = ( (*tr).Lo() );
1684  if( (*Lo).n() > 0 )
1685  continue;
1686  sum += (*(*tr).Lo()).Pop() * (*tr).Emis().pump();
1687  }
1688 
1689  /* make sure it is safe to div by sum */
1690  sum = SDIV( sum );
1691  nsave = 0;
1692  /* now loop back over X and print all those which contribute more than frac of the total */
1693  const double frac = 0.01;
1694  /* only do if radiative transition exists */
1695  for( TransitionList::iterator tr = trans.begin(); tr != rad_end; ++tr )
1696  {
1697  qList::iterator Lo = ( (*tr).Lo() );
1698  if( (*Lo).n() > 0 )
1699  continue;
1700  one = (*(*tr).Lo()).Pop() * (*tr).Emis().pump();
1701  if( one/sum > frac && nsave<nSOL)
1702  {
1703  qList::iterator Hi = ( (*tr).Hi() );
1704  fsave[nsave] = (realnum)(one/sum);
1705  jlosave[nsave] = (*Lo).J();
1706  ivlosave[nsave] = (*Lo).v();
1707  jhisave[nsave] = (*Hi).J();
1708  ivhisave[nsave] = (*Hi).v();
1709  iehisave[nsave] = (*Hi).n();
1710  wlsave[nsave] = (*tr).WLAng();
1711  ++nsave;
1712  }
1713  }
1714 
1715  /* now sort by decreasing importance */
1716  /*spsort netlib routine to sort array returning sorted indices */
1717  spsort(
1718  /* input array to be sorted */
1719  fsave,
1720  /* number of values in x */
1721  nsave,
1722  /* permutation output array */
1723  ipOrdered,
1724  /* flag saying what to do - 1 sorts into increasing order, not changing
1725  * the original routine */
1726  -1,
1727  /* error condition, should be 0 */
1728  &nFail);
1729 
1730  /* print ratio of pumps to dissociations - this is 9:1 in TH85 */
1731  /*>>chng 05 jul 20, TE, save average energy in H2s and renormalization factors for H2g and H2s */
1732  /* >>chng 05 sep 16, TE, chng denominator to do g and s with proper dissoc rates */
1733  fprintf(io,"\t%.3f\t%.3f\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e",
1734  /* this is sum of photons and CRs */
1735  (sum + secondaries.csupra[ipHYDROGEN][0]*2.02f)/SDIV((Solomon_dissoc_rate_g * findspecieslocal("H2")->den +
1736  Solomon_dissoc_rate_s * findspecieslocal("H2*")->den) ),
1737  /* this is sum of photons and CRs */
1741  findspecieslocal("H2")->den/SDIV(H2_den_g), findspecieslocal("H2*")->den/SDIV(H2_den_s),
1742  H2_den_g/SDIV((*dense_total)), H2_den_s/SDIV((*dense_total))
1743  );
1744  for( long i=0; i<nsave; ++i )
1745  {
1746  long ip = ipOrdered[i];
1747  /*lint -e644 not init */
1748  fprintf(io,"\t%li\t%li\t%li\t%li\t%li\t%.3f\t%.3f",
1749  iehisave[ip],ivhisave[ip],jhisave[ip],ivlosave[ip] , jlosave[ip] , fsave[ip] , wlsave[ip] );
1750  /*lint +e644 not init */
1751  }
1752  fprintf(io,"\n");
1753  }
1754  }
1755 
1756  else if( (strcmp(chJOB , "H2te" ) == 0) && (strcmp(chTime,"LAST") != 0) )
1757  {
1758  /* save h2 temperatures */
1759  double pop_ratio10,pop_ratio20,pop_ratio30,pop_ratio31,pop_ratio40;
1760  double T10,T20,T30,T31,T40;
1761  /* subscript"sum" denotes integrated quantities */
1762  double T10_sum,T20_sum,T30_sum,T31_sum,T40_sum;
1763  double pop_ratio10_sum,pop_ratio20_sum,pop_ratio30_sum,pop_ratio31_sum,pop_ratio40_sum;
1764  if( lgEnabled && nCall_this_zone )
1765  {
1766  double pop0 = states[0].Pop();
1767  double pop1 = states[1].Pop();
1768  double pop2 = states[2].Pop();
1769  double pop3 = states[3].Pop();
1770  double pop4 = states[4].Pop();
1771 
1772  double energyK = states[1].energy().K() - states[0].energy().K();
1773  /* the ratio of populations of J=1 to 0 */
1774  pop_ratio10 = pop1/SDIV(pop0);
1775  pop_ratio10_sum = H2_X_colden[0][1]/SDIV(H2_X_colden[0][0]);
1776  /* the corresponding temperature */
1777  T10 = -170.5/log(SDIV(pop_ratio10) * H2_stat[0][0][0]/H2_stat[0][0][1]);
1778  T10_sum = -170.5/log(SDIV(pop_ratio10_sum) * H2_stat[0][0][0]/H2_stat[0][0][1]);
1779 
1780  energyK = states[2].energy().K() - states[0].energy().K();
1781  pop_ratio20 = pop2/SDIV(pop0);
1782  T20 = -energyK/log(SDIV(pop_ratio20) * H2_stat[0][0][0]/H2_stat[0][0][2]);
1783 
1784  pop_ratio20_sum = H2_X_colden[0][2]/SDIV(H2_X_colden[0][0]);
1785  T20_sum = -energyK/log(SDIV(pop_ratio20_sum) * H2_stat[0][0][0]/H2_stat[0][0][2]);
1786 
1787  energyK = states[3].energy().K() - states[0].energy().K();
1788  pop_ratio30 = pop3/SDIV(pop0);
1789  T30 = -energyK/log(SDIV(pop_ratio30) * H2_stat[0][0][0]/H2_stat[0][0][3]);
1790 
1791  pop_ratio30_sum = H2_X_colden[0][3]/SDIV(H2_X_colden[0][0]);
1792  T30_sum = -energyK/log(SDIV(pop_ratio30_sum) * H2_stat[0][0][0]/H2_stat[0][0][3]);
1793 
1794  energyK = states[3].energy().K() - states[1].energy().K();
1795  pop_ratio31 = pop3/SDIV(pop1);
1796  T31 = -energyK/log(SDIV(pop_ratio31) * H2_stat[0][0][1]/H2_stat[0][0][3]);
1797 
1798  pop_ratio31_sum = H2_X_colden[0][3]/SDIV(H2_X_colden[0][1]);
1799  T31_sum = -energyK/log(SDIV(pop_ratio31_sum) * H2_stat[0][0][1]/H2_stat[0][0][3]);
1800 
1801  energyK = states[4].energy().K() - states[0].energy().K();
1802  pop_ratio40 = pop4/SDIV(pop0);
1803  T40 = -energyK/log(SDIV(pop_ratio40) * H2_stat[0][0][0]/H2_stat[0][0][4]);
1804 
1805  pop_ratio40_sum = H2_X_colden[0][4]/SDIV(H2_X_colden[0][0]);
1806  T40_sum = -energyK/log(SDIV(pop_ratio40_sum) * H2_stat[0][0][0]/H2_stat[0][0][4]);
1807  }
1808  else
1809  {
1810  pop_ratio10 = 0.;
1811  pop_ratio10_sum = 0.;
1812  T10 = 0.;
1813  T20 = 0.;
1814  T30 = 0.;
1815  T31 = 0.;
1816  T40 = 0.;
1817  T10_sum = 0.;
1818  T20_sum = 0.;
1819  T30_sum = 0.;
1820  T31_sum = 0.;
1821  T40_sum = 0.;
1822  }
1823 
1824  /* various temperatures for neutral/molecular gas */
1825  fprintf( io,
1826  "%.5e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\t%.3e\n" ,
1827  /* depth in cm */
1829  /* total H2 fraction */
1831  /* ratio of populations of 1 to 0 only */
1832  pop_ratio10 ,
1833  /* sum of all ortho and para */
1835  T10,T20,T30,T31,T40,
1836  phycon.te ,
1837  hyperfine.Tspin21cm,T10_sum,T20_sum,T30_sum,T31_sum,T40_sum );
1838  }
1839  else if( (strcmp(chJOB , "H2ln" ) == 0) && (strcmp(chTime,"LAST") == 0) )
1840  {
1841  /* save H2 lines - output the full emission-line spectrum */
1842  double thresh;
1843  double renorm;
1844  /* first test, is H2 turned on? Second test, have lines arrays
1845  * been set up - nsum is negative if abort occurs before lines
1846  * are set up */
1847  if( lgEnabled && LineSave.nsum > 0)
1848  {
1849  ASSERT( LineSave.ipNormWavL >= 0 );
1850  /* get the normalization line */
1852  renorm = LineSave.ScaleNormLine/
1854  else
1855  renorm = 1.;
1856 
1857  if( renorm > SMALLFLOAT )
1858  {
1859  /* this is threshold for faintest line, normally 0, set with
1860  * number on save H2 command */
1861  thresh = thresh_punline_h2/(realnum)renorm;
1862  }
1863  else
1864  thresh = 0.f;
1865 
1866  /* save H2 line intensities at end of iteration
1867  * nElecLevelOutput is electronic level with 1 for ground, so this loop is < nElecLevelOutput */
1868  for( TransitionList::iterator tr = trans.begin(); tr != rad_end; ++tr )
1869  {
1870  qList::iterator Hi = ( (*tr).Hi() );
1871  qList::iterator Lo = ( (*tr).Lo() );
1872  long iElecHi = (*Hi).n();
1873  long iVibHi = (*Hi).v();
1874  long iRotHi = (*Hi).J();
1875  long iElecLo = (*Lo).n();
1876  long iVibLo = (*Lo).v();
1877  long iRotLo = (*Lo).J();
1878  if( iElecHi >= nElecLevelOutput )
1879  continue;
1880  if( H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo] > thresh )
1881  {
1882  /* air wavelength in microns */
1883  /* WLAng contains correction for index of refraction of air */
1884  double wl = (*tr).WLAng()/1e4;
1885  fprintf(io, "%li-%li %c(%li)", iVibHi, iVibLo, chMolBranch( iRotHi, iRotLo ), iRotLo );
1886  fprintf( io, "\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld", iElecHi , iVibHi , iRotHi , iElecLo , iVibLo , iRotLo);
1887  /* WLAng contains correction for index of refraction of air */
1888  fprintf( io, "\t%.7f\t", wl );
1889  /*prt_wl print floating wavelength in Angstroms, in output format */
1890  prt_wl( io , (*tr).WLAng() );
1891  /* the log of the line intensity or luminosity */
1892  fprintf( io, "\t%.3f\t%.3e",
1893  log10(MAX2(1e-37,H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo])) + radius.Conv2PrtInten,
1894  H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo]*renorm );
1895  /* excitation energy of upper level in K */
1896  fprintf( io, "\t%.3f", (*Hi).energy().K() );
1897  /* the product g_hi h nu * Aul */
1898  fprintf( io, "\t%.3e", (*tr).Emis().Aul() * (*tr).EnergyErg() * (*(*tr).Hi()).g() );
1899  fprintf( io, "\n");
1900  }
1901  }
1902  }
1903  }
1904  else if( (strcmp(chJOB , "H2sp" ) == 0) )
1905  {
1906  fprintf( io, "PUT SOMETHING HERE!\n" );
1907  }
1908  return;
1909 }
1910  /*cdH2_Line determines intensity and luminosity of and H2 line. The first
1911  * six arguments give the upper and lower quantum designation of the levels.
1912  * The function returns 1 if we found the line,
1913  * and false==0 if we did not find the line because ohoto-para transition
1914  * or upper level has lower energy than lower level */
1915 long int cdH2_Line(
1916  /* indices for the upper level */
1917  long int iElecHi,
1918  long int iVibHi ,
1919  long int iRotHi ,
1920  /* indices for lower level */
1921  long int iElecLo,
1922  long int iVibLo ,
1923  long int iRotLo ,
1924  /* linear intensity relative to normalization line*/
1925  double *relint,
1926  /* log of luminosity or intensity of line */
1927  double *absint )
1928 {
1929  DEBUG_ENTRY( "cdH2_Line()" );
1930  return h2.getLine( iElecHi, iVibHi, iRotHi, iElecLo, iVibLo, iRotLo, relint, absint );
1931 };
1932 
1933 long int diatomics::getLine( long iElecHi, long iVibHi, long iRotHi, long iElecLo, long iVibLo, long iRotLo, double *relint, double *absint )
1934 {
1935 
1936  DEBUG_ENTRY( "diatomics::getline()" );
1937 
1938  /* these will be return values if we can't find the line */
1939  *relint = 0.;
1940  *absint = 0.;
1941 
1942  /* for now both electronic levels must be zero */
1943  if( iElecHi!=0 || iElecLo!=0 )
1944  {
1945  return 0;
1946  }
1947 
1948  long ipHi = ipEnergySort[iElecHi][iVibHi][iRotHi];
1949  long ipLo = ipEnergySort[iElecLo][iVibLo][iRotLo];
1950 
1951  /* check that energy of first level is higher than energy of second level */
1952  if( states[ipHi].energy().WN() < states[ipLo].energy().WN() )
1953  {
1954  return 0;
1955  }
1956 
1957  /* check that ortho-para does not change */
1958  if( H2_lgOrtho[iElecHi][iVibHi][iRotHi] - H2_lgOrtho[iElecLo][iVibLo][iRotLo] != 0 )
1959  {
1960  return 0;
1961  }
1962 
1963  /* exit if lines does not exist */
1964  if( !lgH2_radiative[ipHi][ipLo] )
1965  {
1966  return 0;
1967  }
1968 
1969  ASSERT( LineSave.ipNormWavL >= 0 );
1970  /* does the normalization line have a positive intensity*/
1971  if( LineSv[LineSave.ipNormWavL].SumLine[0] > 0. )
1972  {
1973  *relint = H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo]/
1975  }
1976  else
1977  {
1978  *relint = 0.;
1979  }
1980 
1981  /* return log of line intensity if it is positive */
1982  if( H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo] > 0. )
1983  {
1984  *absint = log10(H2_SaveLine[iElecHi][iVibHi][iRotHi][iElecLo][iVibLo][iRotLo]) +
1986  }
1987  else
1988  {
1989  /* line intensity is actually zero, return small number */
1990  *absint = -37.;
1991  }
1992  /* this indicates success */
1993  return 1;
1994 }
1995 
1996 void diatomics::set_numLevelsMatrix( long numLevels )
1997 {
1998  if( !lgREAD_DATA )
1999  nXLevelsMatrix = numLevels;
2000 }
2001 
multi_arr< double, 2 > H2_rad_rate_in
Definition: h2_priv.h:650
#define MIN2
Definition: cddefines.h:765
int nTRACE
Definition: h2_priv.h:396
char chH2ColliderLabels[N_X_COLLIDER][chN_X_COLLIDER]
Definition: h2_priv.h:588
static realnum thresh_punline_h2
Definition: mole_h2_io.cpp:46
iterator begin(size_type i1)
multi_arr< double, 2 > H2_col_rate_out
Definition: h2_priv.h:649
const int N_ELEC
Definition: h2_priv.h:21
bool nMatch(const char *chKey) const
Definition: parser.h:135
multi_arr< realnum, 3 > H2_dissprob
Definition: h2_priv.h:629
realnum punarg[LIMPUN][3]
Definition: save.h:254
void prt_wl(FILE *ioOUT, realnum wl)
Definition: prt.cpp:13
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:616
t_thermal thermal
Definition: thermal.cpp:5
t_colden colden
Definition: colden.cpp:5
realnum & Pelec_esc() const
Definition: emission.h:533
double H2_DissocEnergies[N_ELEC]
Definition: h2_priv.h:606
void lindst(double xInten, realnum wavelength, const char *chLab, long int ipnt, char chInfo, bool lgOutToo, const char *chComment)
void H2_Punch_line_data(FILE *ioPUN, bool lgDoAll)
const int FILENAME_PATH_LENGTH_2
Definition: cddefines.h:253
t_input input
Definition: input.cpp:12
long int n_elec_states
Definition: h2_priv.h:406
t_hyperfine hyperfine
Definition: hyperfine.cpp:5
const realnum SMALLFLOAT
Definition: cpu.h:178
double eWN
Definition: mole_h2_io.cpp:670
int n_trace_full
Definition: h2_priv.h:399
double average_energy_s
Definition: h2_priv.h:284
multi_arr< double, 2 > pops_per_vib
Definition: h2_priv.h:597
double H2_rate_destroy
Definition: hmi.h:21
#define MAX2
Definition: cddefines.h:786
#define PrintEfmt(F, V)
Definition: cddefines.h:1476
double ctot
Definition: thermal.h:110
bool lgREAD_DATA
Definition: h2_priv.h:249
valarray< long > ipVib_H2_energy_sort
Definition: h2_priv.h:684
long int Jlowest[N_ELEC]
Definition: h2_priv.h:613
double ortho_colden
Definition: h2_priv.h:325
const int nTE_HMINUS
Definition: h2_priv.h:18
double H2_Solomon_dissoc_rate_TH85_H2s
Definition: hmi.h:99
bool lgEvaluated
Definition: h2_priv.h:307
t_phycon phycon
Definition: phycon.cpp:6
t_LineSave LineSave
Definition: lines.cpp:5
t_dense dense
Definition: dense.cpp:24
void H2_Prt_column_density(FILE *ioMEAN)
Definition: mole_h2_io.cpp:395
double H2_Solomon_dissoc_rate_BD96_H2g
Definition: hmi.h:95
multi_arr< realnum, 3 >::const_iterator mr3ci
iterator begin(void)
Definition: transition.h:305
static double * g
Definition: species2.cpp:28
int nElecLevelOutput
Definition: h2_priv.h:346
FILE * ioQQQ
Definition: cddefines.cpp:7
double H2_den_g
Definition: h2_priv.h:679
molezone * findspecieslocal(const char buf[])
void prme(const bool lgReset, const TransitionProxy &t)
Definition: prt_met.cpp:97
double HeatH2Dish_TH85
Definition: hmi.h:129
void H2_Read_hminus_distribution(void)
Definition: mole_h2_io.cpp:986
double H2_Solomon_dissoc_rate_BD96_H2s
Definition: hmi.h:101
TransitionList trans
Definition: h2_priv.h:563
void resize(size_t i)
Definition: quantumstate.h:83
Definition: parser.h:31
long int nsave
Definition: save.h:222
double H2_Solomon_dissoc_rate_TH85_H2g
Definition: hmi.h:93
double SumLine[4]
Definition: lines.h:125
double Solomon_dissoc_rate_g
Definition: h2_priv.h:261
multi_arr< realnum, 3 > CollRateCoeff
Definition: h2_priv.h:618
const double *const dense_total
Definition: h2_priv.h:586
multi_arr< realnum, 3 > H2_stat
Definition: h2_priv.h:638
multi_arr< long int, 3 > ipEnergySort
Definition: h2_priv.h:687
multi_arr< double, 3 > H2_old_populations
Definition: h2_priv.h:634
multi_arr< realnum, 3 > H2_disske
Definition: h2_priv.h:630
double ortho_density
Definition: h2_priv.h:316
bool operator<(const level_tmp &second) const
Definition: mole_h2_io.cpp:662
void H2_ReadEnergies()
Definition: mole_h2_io.cpp:674
double para_density
Definition: h2_priv.h:316
multi_arr< realnum, 3 > H2_X_hminus_formation_distribution
Definition: h2_priv.h:682
LinSv * LineSv
Definition: cdinit.cpp:70
long int nLevels_per_elec[N_ELEC]
Definition: h2_priv.h:615
#define STATIC
Definition: cddefines.h:101
bool lgEnabled
Definition: h2_priv.h:342
double H2_den_s
Definition: h2_priv.h:679
long int cdH2_Line(long int iElecHi, long int iVibHi, long int iRotHi, long int iElecLo, long int iVibLo, long int iRotLo, double *relint, double *absint)
multi_arr< double, 3 > H2_populations_LTE
Definition: h2_priv.h:636
string label
Definition: h2_priv.h:568
long int nCall_this_zone
Definition: h2_priv.h:338
string path
Definition: h2_priv.h:570
void H2_Prt_Zone(void)
Definition: mole_h2_io.cpp:333
t_rfield rfield
Definition: rfield.cpp:8
const int N_X_COLLIDER
Definition: h2_priv.h:13
float realnum
Definition: cddefines.h:107
#define EXIT_FAILURE
Definition: cddefines.h:144
multi_arr< realnum, 2 > H2_X_colden_LTE
Definition: h2_priv.h:659
multi_arr< bool, 2 > lgH2_radiative
Definition: h2_priv.h:711
long int nXLevelsMatrix
Definition: h2_priv.h:692
realnum & Pesc() const
Definition: emission.h:523
size_t size() const
Definition: quantumstate.h:116
void H2_PrtDepartCoef(void)
Definition: mole_h2_io.cpp:362
realnum AtomicWeight[LIMELM]
Definition: dense.h:75
void H2_LinesAdd(void)
Definition: mole_h2_io.cpp:49
#define cdEXIT(FAIL)
Definition: cddefines.h:438
multi_arr< realnum, 6 > H2_SaveLine
Definition: h2_priv.h:707
multi_arr< double, 3 > H2_rad_rate_out
Definition: h2_priv.h:631
diatomics h2("h2", 4100.,&hmi.H2_total, Yan_H2_CS)
realnum GetDopplerWidth(realnum massAMU)
double depth_mid_zone
Definition: radius.h:22
double HeatH2Dexc_TH85
Definition: hmi.h:129
double average_energy_g
Definition: h2_priv.h:283
double RandGauss(double xMean, double s)
Definition: service.cpp:1643
t_radius radius
Definition: radius.cpp:5
void PutLine(const TransitionProxy &t, const char *chComment, const char *chLabelTemp)
Definition: transition.cpp:449
double extin_mag_V_point
Definition: rfield.h:277
double HeatDexc
Definition: h2_priv.h:287
realnum UV_Cont_rel2_Draine_DB96_depth
Definition: hmi.h:73
iterator end(void)
Definition: transition.h:309
realnum gas_phase[LIMELM]
Definition: dense.h:71
double Conv2PrtInten
Definition: radius.h:147
iterator end()
Definition: quantumstate.h:345
realnum & Pdest() const
Definition: emission.h:543
#define ASSERT(exp)
Definition: cddefines.h:582
double HeatDiss
Definition: h2_priv.h:286
double Tspin21cm
Definition: hyperfine.h:47
void H2_ReadTransprob(long int nelec, TransitionList &trans)
Definition: mole_h2_io.cpp:430
double htot
Definition: thermal.h:149
long int ipNormWavL
Definition: lines.h:81
STATIC char chMolBranch(long iRotHi, long int iRotLo)
realnum coldenH2_ov_vel
Definition: colden.h:43
long int getLine(long iElecHi, long iVibHi, long iRotHi, long iElecLo, long iVibLo, long iRotLo, double *relint, double *absint)
qList states
Definition: h2_priv.h:562
#define ipCOL_H2g
Definition: colden.h:16
void H2_PunchLineStuff(FILE *io, realnum xLimit, long index)
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
realnum UV_Cont_rel2_Habing_spec_depth
Definition: hmi.h:63
double Solomon_dissoc_rate_s
Definition: h2_priv.h:262
iterator begin()
Definition: quantumstate.h:337
char chDelimiter[3]
Definition: input.h:42
multi_arr< long int, 2 > ipTransitionSort
Definition: h2_priv.h:688
void H2_PunchDo(FILE *io, char chJOB[], const char chTime[], long int ipPun)
diatomics * whichDiatomToPrint[LIMPUN]
Definition: save.h:226
double getNumberDefault(const char *chDesc, double fdef)
Definition: parser.cpp:282
double Solomon_elec_decay_g
Definition: h2_priv.h:265
void H2_Prt_line_tau(void)
realnum UV_Cont_rel2_Habing_TH85_depth
Definition: hmi.h:63
TransitionList::iterator rad_end
Definition: h2_priv.h:564
void Save1LineData(const TransitionProxy &t, FILE *io, bool lgCS_2, bool &lgPrint)
void H2_ReadDissocEnergies(void)
Definition: mole_h2_io.cpp:831
realnum ** csupra
Definition: secondaries.h:21
valarray< long > nRot_hi[N_ELEC]
Definition: h2_priv.h:610
double pops_per_elec[N_ELEC]
Definition: h2_priv.h:617
double Solomon_elec_decay_s
Definition: h2_priv.h:266
sys_float SDIV(sys_float x)
Definition: cddefines.h:956
double para_colden
Definition: h2_priv.h:325
double H2_renorm_chemistry
Definition: h2_priv.h:600
valarray< long > ipRot_H2_energy_sort
Definition: h2_priv.h:686
char * read_whole_line(char *chLine, int nChar, FILE *ioIN)
Definition: service.cpp:70
long int nsum
Definition: lines.h:62
GrainVar gv
Definition: grainvar.cpp:5
t_secondaries secondaries
Definition: secondaries.cpp:5
t_hmi hmi
Definition: hmi.cpp:5
void set_numLevelsMatrix(long numLevels)
void ShowMe(void)
Definition: service.cpp:181
t_save save
Definition: save.cpp:5
double te
Definition: phycon.h:11
double H2_Solomon_dissoc_rate_ELWERT_H2g
Definition: hmi.h:96
void H2_ReadDissprob(long int nelec)
Definition: mole_h2_io.cpp:895
const int ipHYDROGEN
Definition: cddefines.h:309
realnum & Aul() const
Definition: emission.h:613
realnum colden[NCOLD]
Definition: colden.h:38
double getNumberDefaultNegImplLog(const char *chDesc, double fdef)
Definition: parser.cpp:336
vector< double > depart
Definition: h2_priv.h:699
long int nVib_hi[N_ELEC]
Definition: h2_priv.h:608
char chSave[LIMPUN][5]
Definition: save.h:225
void H2_ParseSave(Parser &p, char *chHeader)
Definition: mole_h2_io.cpp:111
long int ipass
Definition: lines.h:75
NORETURN void BadRead(void)
Definition: service.cpp:901
EmissionList & Emis()
Definition: transition.h:329
multi_arr< double, 2 > H2_col_rate_in
Definition: h2_priv.h:648
double dVeffAper
Definition: radius.h:87
double rate_h2_form_grains_used_total
Definition: grainvar.h:574
const int chN_X_COLLIDER
Definition: h2_priv.h:15
multi_arr< realnum, 2 > H2_X_colden
Definition: h2_priv.h:657
void spsort(realnum x[], long int n, long int iperm[], int kflag, int *ier)
Definition: service.cpp:1100
double ScaleNormLine
Definition: lines.h:94
void Save1Line(const TransitionProxy &t, FILE *io, realnum xLimit, long index, realnum DopplerWidth)
Definition: save_do.cpp:4347
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition: service.cpp:381
multi_arr< bool, 3 > H2_lgOrtho
Definition: h2_priv.h:640
#define ipCOL_H2s
Definition: colden.h:18