cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
prt_lines.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2017 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*lines main routine to put emission line intensities into line stack,
4  * calls lineset1, 2, 3, 4 */
5 /*Drive_cdLine do the drive cdLine command */
6 /*FindStrongestLineLabels find strongest lines contributing to point in continuum energy mesh, output in some save commands */
7 #include "cddefines.h"
8 #include "taulines.h"
9 #include "thermal.h"
10 #include "yield.h"
11 #include "ipoint.h"
12 #include "ionbal.h"
13 #include "cddrive.h"
14 #include "trace.h"
15 #include "prt.h"
16 #include "rt.h"
17 #include "rfield.h"
18 #include "phycon.h"
19 #include "iso.h"
20 #include "hyperfine.h"
21 #include "hydrogenic.h"
22 #include "atmdat.h"
23 #include "lines.h"
24 #include "radius.h"
25 #include "dense.h"
26 #include "lines_service.h"
27 #include "mole.h"
28 #include "oxy.h"
29 #include "continuum.h"
30 #include "fe.h"
31 
32 STATIC void Drive_cdLine( void );
33 STATIC void lines_iron_Ka();
34 
35 void lines(void)
36 {
37  long int i,
38  ipnt,
39  nelem;
40  double f2, sum;
41 
42  DEBUG_ENTRY( "lines()" );
43 
44  /* LineSave.ipass
45  * -1 - space not yet allocated - just count number of lines entered into stack
46  * 0 - first call with space allocated - must create labels and add in wavelengths
47  * +1 - later calls - just add intensity
48  */
49 
50  /* major routines used here:
51  *
52  * PutLine( tarray )
53  * this uses information in tarray to give various
54  * contributions to lines, and their intensities
55  *
56  * PutExtra( extra )
57  * extra is some extra intensity to add to the line
58  * it will go into the totl contribution put out by PutLine,
59  * and this contribution should be indicated by independent
60  * call to linadd
61  * */
62 
63  if( trace.lgTrace )
64  {
65  fprintf( ioQQQ, " lines called\n" );
66  }
67 
68  /* the drive cdline command, which checks that all lines can be pulled out by cdLine */
69  if( trace.lgDrv_cdLine && LineSave.ipass > 0 )
70  Drive_cdLine();
71 
72  /* total luminosity radiated by this model - will be compared with energy in incident
73  * continuum when calculation is complete */
75 
76  /* remember the total free-free heating */
77  fixit("need to get rid of brems_heat_total");
78  // get rid of brems_heat_total entirely (only net heating is added into stack, so use net here to avoid nonsense ratios elsewhere)
79  //thermal.FreeFreeTotHeat += CoolHeavy.brems_heat_total*radius.dVeffAper;
81 
82  /* total Compton heating - cooling */
85 
86  /* up up induced recombination cooling */
87  for( nelem=0; nelem<LIMELM; ++nelem )
88  {
90  }
91 
92  /* nsum is line pointer within large stack of line intensities */
93  LineSave.nsum = 0;
94  LineSave.nComment = 0;
95 
96  /* this is used by lindst to proportion inward and outward. should be 50% for
97  * optically thin line. putline sets this to actual value for particular line
98  * and calls lindst then rests to 50% */
99  rt.fracin = 0.5;
100 
101  /* last arg in call to lindst and linadd is info on line
102  * info is char variable indicating type of line this is
103  * 'c' cooling
104  * 'h' heating
105  * 'i' information only
106  * 'r' recombination line
107  *
108  * all components of lines are entered into the main line stack here
109  * when printing, filters exist to not print Inwd component */
110 
111  /* initialize routine that can generate pointers for forbidden lines,
112  * these are lines that are not transferred otherwise,
113  * in following routines there will be pairs of calls, first to
114  * PntForLine to get pointer, then lindst to add to stack */
115  PntForLine(0.,"FILL",&i);
116 
117  /* evaluate rec coefficient for rec lines of C, N, O
118  * some will be used in LineSet2 and then zeroed out,
119  * others left alone and used below */
121 
122  /* put in something impossible in element 0 of line stack */
123  linadd(0.f,0,"zero",'i' , "null placeholder");
124 
125  /* this is compared with true volume in final. The number can't
126  * actually be unity since this would overflow on a 32 bit machine */
127  /* integrate the volume as a sanity check */
128  linadd( 1.e-10 , 1 , "Unit" , 'i' , "unit integration placeholder");
129  static long int ipOneAng=-1;
130  if( LineSave.ipass<0 )
131  ipOneAng = ipoint( RYDLAM );
132  lindst( 1.e-10 , 1. , "UntD" , ipOneAng , 'i' , false,"unit integration placeholder");
133 
134  /* initial set of general properties */
135  lines_general();
136 
137  /* do all continua */
138  lines_continuum();
139 
140  /* information about grains */
141  lines_grains();
142 
143  /* update all satellite lines */
144  for( long nelem=ipHYDROGEN; nelem < LIMELM; ++nelem )
145  iso_satellite_update(nelem);
146 
147  /* do all hydrogenic ions */
148  lines_hydro();
149 
150  /* enter He-iso sequence lines */
151  lines_helium();
152 
153  /* next come the extra Lyman lines */
154  i = StuffComment( "extra Lyman" );
155  linadd( 0., (realnum)i , "####", 'i' ,
156  "extra Lyman lines ");
157 
158  for( long ipISO=ipH_LIKE; ipISO < NISO; ++ipISO )
159  {
160  /* loop over all iso-electronic sequences */
161  for( long nelem=ipISO; nelem < LIMELM; ++nelem )
162  {
163  if( ! dense.lgElmtOn[nelem] )
164  continue;
165  for( long ipHi=iso_sp[ipISO][nelem].numLevels_max; ipHi < iso_ctrl.nLyman_max[ipISO]; ipHi++ )
166  {
167  if (ExtraLymanLines[ipISO][nelem][ipExtraLymanLines[ipISO][nelem][ipHi]].ipCont() > 0)
168  PutLine(ExtraLymanLines[ipISO][nelem][ipExtraLymanLines[ipISO][nelem][ipHi]],
169  "extra Lyman line");
170  }
171  }
172  }
173 
174 #if 0
175  /* This is Ryan's code for dumping lots of Helium lines according to
176  * quantum number rather than wavelength, principally for comparison with Rob
177  * Bauman's code. */
178  if( iteration > 1 )
179  {
180  fprintf( ioQQQ,"ipHi\tipLo\tnu\tlu\tsu\tnl\tll\tsl\tWL\tintens\n" );
181  for( long ipHi=5; ipHi<= iso_sp[ipHE_LIKE][ipHELIUM].numLevels_local - iso_sp[ipHE_LIKE][ipHELIUM].nCollapsed_local; ipHi++ )
182  {
183  for( long ipLo=0; ipLo<ipHi; ipLo++ )
184  {
185  if( iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).ipCont() > 0 )
186  {
187  double relint, absint;
188 
189  if( cdLine("He 1",
190  iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng(),
191  &relint, &absint ) )
192  {
193  //iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).Hi()->chLabel
194 
195  //if( iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng() < 1.1E4 &&
196  // iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng() > 3.59E3 &&
197  // ipLo!=3 && ipLo!=4 && relint >= 0.0009 )
198  long n=iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].n();
199  long np=iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].n();
200  long l=iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].l();
201  long lp=iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].l();
202  long s=iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].S();
203  long sp=iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].S();
204  if ( ((l== lp+1 || l == lp-1) && l==n-3 && s== sp))//|| ((l == n-1) && s==sp ))
205  {
206  fprintf( ioQQQ,"lines %li\t%li\t%li\t%li\t%li\t%li\t%li\t%li\t%e\t%e\n",
207  ipHi,
208  ipLo,
209  iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].n(),
210  iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].l(),
211  iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].S(),
212  iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].n(),
213  iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].l(),
214  iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].S(),
215  iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng(),
216  relint );
217  }
218  }
219  }
220  }
221  }
222  }
223 #endif
224 
225  // these must come before the old level 1 or 2 lines. we now have the option
226  // to use the external database by default, or turn it off (set chianti off)
227  // and fall back to the old line treatment. When database is off those lines
228  // do not exist. But when database is on the level 1 lines are still evaluated
229  // but with the ion abundance set to zero. If the level 1 lines were entered
230  // into the stack then searches for the line with cdLine would turn up the level 1
231  // line, which would be zero.
232  // The long term goal is to have all lines be external databases & rm level 1&2 liens
233 
234  /* external database lines */
235  i = StuffComment( "database lines" );
236  linadd( 0., (realnum)i , "####", 'i' ,
237  "database lines ");
238  for (int ipSpecies=0; ipSpecies < nSpecies; ++ipSpecies)
239  {
240  for( EmissionList::iterator em=dBaseTrans[ipSpecies].Emis().begin();
241  em != dBaseTrans[ipSpecies].Emis().end(); ++em)
242  {
243  if( (*em).Tran().ipCont() > 0)
244  {
245  /* Set the comment to the database name followed by the
246  * lower and upper indices of the transition energy levels
247  * as they appear in the database input file. */
248  string chComment = "";
249  if( LineSave.ipass == 0 )
250  {
251  chComment = dBaseSpecies[ipSpecies].database
252  + ", " + (*em).Tran().getComment();
253  }
254  PutLine((*em).Tran(), chComment.c_str(), dBaseSpecies[ipSpecies].chLabel);
255  }
256  }
257  }
258 
259  /* level 1 lines */
260  ipnt = StuffComment( "level 1 lines" );
261  linadd( 0., (realnum)ipnt , "####", 'i',
262  " start level 1 lines" );
263 
264  /* do iron Ka */
265  lines_iron_Ka();
266 
267  /* next come some recombination lines */
268  i = StuffComment( "recombination" );
269  linadd( 0., (realnum)i , "####", 'i' ,
270  "recombination lines");
271 
272  /***********************************************************************
273  * large number of C, N, and O recombination lines *
274  *************************************************************************/
275 
276  for( i=0; i < NRECCOEFCNO; i++ )
277  {
278  string chLabel;
279  /* generate label for the line if ipass is -1 or 0 - saved in arrays
280  * so no need to do this during production */
281  if( LineSave.ipass <= 0 )
282  {
283  chLabel = chIonLbl( LineSave.RecCoefCNO[0][i], long(LineSave.RecCoefCNO[0][i]-LineSave.RecCoefCNO[1][i]+1.01) );
284  }
285  else
286  chLabel = " ";
287 
288  /* number of rec per unit vol
289  * do not predict these simple reccombination intensities at high densities
290  * since lines neglect collisional deexciation and line optical depth effects.
291  * They were not intended for high densities or column densities.
292  * As a result they become unphysically bright at high densities and
293  * violate the black body limit. There would be major
294  * energy conservation problems if they were added in the outward beam in
295  * dense simulations.
296  * */
297  if( dense.eden < 1e8 )
298  {
299  nelem = (long)LineSave.RecCoefCNO[0][i]-1;
300  long int ion = (long)(LineSave.RecCoefCNO[0][i]-LineSave.RecCoefCNO[1][i]+2)-1;
301  f2 = LineSave.RecCoefCNO[3][i]*dense.eden*
302  dense.xIonDense[nelem][ion];
303 
304  /* convert to intensity */
305  f2 = f2*HC_ERG_ANG/LineSave.RecCoefCNO[2][i];
306  }
307  else
308  {
309  f2 = 0.;
310  }
311  /* stuff it into the stack */
312  PntForLine(LineSave.RecCoefCNO[2][i], chLabel.c_str(), &ipnt);
313  lindst(f2,wlAirVac(LineSave.RecCoefCNO[2][i]), chLabel.c_str(), ipnt, 'r', true,
314  "recombination line");
315  }
316 
317  /* next come the atom_level2 lines */
318  i = StuffComment( "level2 lines" );
319  linadd( 0., (realnum)i , "####", 'i' ,
320  "level2 lines");
321 
322  /* add in all the other level 2 wind lines
323  * Dima's 6k lines */
324  double ExtraCool = 0.;
325  double BigstExtra = 0.;
326  for( i=0; i < nWindLine; i++ )
327  {
328  if( (*TauLine2[i].Hi()).IonStg() < (*TauLine2[i].Hi()).nelem()+1-NISO )
329  {
330  PutLine(TauLine2[i],"level 2 line");
331  if( TauLine2[i].Coll().cool() > BigstExtra )
332  {
333  BigstExtra = TauLine2[i].Coll().cool();
334  thermal.ipMaxExtra = i+1;
335  }
336  ExtraCool += TauLine2[i].Coll().cool();
337  }
338  }
339  /* keep track of how important this is */
341 
342  /* next come the hyperfine structure lines */
343  i = StuffComment( "hyperfine structure" );
344  linadd( 0., (realnum)i , "####", 'i' ,
345  "hyperfine structure lines ");
346 
347  /* this is total cooling due to all HF lines */
348  linadd( hyperfine.cooling_total, 0., "hfin", 'i' ,
349  "total cooling all hyperfine structure lines ");
350 
351  /* remember largest local cooling for possible printout in comments */
353 
354  /* the hyperfine lines */
355  for( size_t ih=0; ih < HFLines.size(); ih++ )
356  {
357  PutLine(HFLines[ih],
358  "hyperfine structure line");
359  }
360 
361  /* next come the inner shell fluorescent lines */
362  i = StuffComment( "inner shell" );
363  linadd( 0., (realnum)i , "####", 'i' ,
364  "inner shell lines");
365 
366  // Opacity Project satellite lines from data / UTA
367  // the heat component of these lines is the heat per pump, a constant
368  for( size_t i=0; i < UTALines.size(); i++ )
369  {
370  PutLine(UTALines[i], "OP satellite");
371  }
372 
373  /* the group of inner shell fluorescent lines
374  * >>refer all auger Kaastra, J. S. & Mewe, R. 1993, A&AS, 97, 443-482
375  * http://adsabs.harvard.edu/abs/1993A%26AS...97..443K */
376  for( i=0; i < t_yield::Inst().nlines(); ++i )
377  {
378  double xInten =
379  /* density of parent ion, cm-3 */
381  /* photo rate per atom per second, s-1 */
383  /* fluor yield - dimensionless */
384  t_yield::Inst().yield(i) *
385  /* photon energy - ryd, converted into ergs */
386  t_yield::Inst().energy(i) * EN1RYD;
387 
388  /* create label if initializing line stack */
389  string chLabel;
390  if( LineSave.ipass == 0 )
391  {
392  chLabel = chIonLbl( t_yield::Inst().nelem(i)+1, t_yield::Inst().ion_emit(i)+1 );
393 # if 0
394  /* only print yields for atoms */
395  if( t_yield::Inst().ion(i) == 0 && t_yield::Inst().nelem()(i) == ipIRON )
396  fprintf(ioQQQ,"DEBUGyeild\t%s\t%.3f\t%.3e\n",
397  /* line designation, energy in eV, yield */
398  chLabel.c_str() , t_yield::Inst().energy()(i)*EVRYD, t_yield::Inst().yield(i) );
399 # endif
400  }
401 
402  /* the group of inner shell fluorescent lines */
403  lindst(
404  /* intensity of line */
405  xInten,
406  /* wavelength of line in Angstroms */
407  (realnum)RYDLAM / t_yield::Inst().energy(i),
408  /* label */
409  chLabel.c_str() ,
410  /* continuum array offset for line as set in ipoint */
411  t_yield::Inst().ipoint(i),
412  /* type of line - count as a recombination line */
413  'r',
414  /* include line in continuum? */
415  true ,
416  "inner shell line");
417  }
418 
419  /* now do all molecules - do last since so many H2 lines */
420  lines_molecules();
421 
424 
425 
426  /* blends of other lines */
427  i = StuffComment( "blends" );
428 
429  // Enable alternative, hopefully less fragile, route for defining static blends
430  const bool lgBandBlends = false;
431 
432  linadd( 0., (realnum)i , "####", 'i' , "blends ");
433 
434  /*************Magnesium Blends *******************/
435  LinSv *lineMg2 = linadd(0.0,2798,"Blnd",'i',"Blend" );
437  {
438  if (lgBandBlends)
439  {
440  lineMg2->makeBlend("Mg 2",2798.0,10.0);
441  }
442  else
443  {
444  lineMg2->addComponent("Mg 2",2795.53);
445  lineMg2->addComponent("Mg 2",2802.71);
446  }
447  }
448 
449  LinSv *lineMg10 = linadd(0.0,615,"Blnd",'i',"Blend" );
451  {
452  if (lgBandBlends)
453  {
454  lineMg10->makeBlend("Mg10",615.0,15.0);
455  }
456  else
457  {
458  lineMg10->addComponent("Mg10",609.794);
459  lineMg10->addComponent("Mg10",624.943);
460  }
461  }
462 
463  LinSv *lineS2Red = linadd(0.0,6720,"Blnd",'i',"Blend" );
465  {
466  if (lgBandBlends)
467  {
468  lineS2Red->makeBlend("S 2",6720.0,15.0);
469  }
470  else
471  {
472  lineS2Red->addComponent("S 2",6730.82);
473  lineS2Red->addComponent("S 2",6716.44);
474  }
475  }
476 
477  LinSv *lineS2Blue = linadd(0.0,4074,"Blnd",'i',"Blend" );
479  {
480  if (lgBandBlends)
481  {
482  lineS2Blue->makeBlend("S 2",4074.0,10.0);
483  }
484  else
485  {
486  lineS2Blue->addComponent("S 2",4076.35);
487  lineS2Blue->addComponent("S 2",4068.60);
488  }
489  }
490 
491  LinSv *lineS2IR = linadd(0.0,10330,"Blnd",'i',"Blend" );
493  {
494  if (lgBandBlends)
495  {
496  lineS2IR->makeBlend("S 2",10330.0,80.0);
497  }
498  else
499  {
500  lineS2IR->addComponent("S 2",10336.4);
501  lineS2IR->addComponent("S 2",10286.7);
502  lineS2IR->addComponent("S 2",10286.7);
503  lineS2IR->addComponent("S 2",10320.5);
504  }
505  }
506 
507  LinSv *lineS2UV = linadd(0.0,1256,"Blnd",'i',"Blend" );
509  {
510  if (lgBandBlends)
511  {
512  lineS2UV->makeBlend("S 2",1256.0,10.0);
513  }
514  else
515  {
516  lineS2UV->addComponent("S 2",1250.58);
517  lineS2UV->addComponent("S 2",1253.81);
518  lineS2UV->addComponent("S 2",1259.52);
519  }
520  }
521 
522  LinSv *lineS31198 = linadd(0.0,1198,"Blnd",'i',"Blend" );
524  {
525  if (lgBandBlends)
526  {
527  lineS31198->makeBlend("S 3",1198.0,10.0);
528  }
529  else
530  {
531  lineS31198->addComponent("S 3",1190.20);
532  lineS31198->addComponent("S 3",1194.06);
533  lineS31198->addComponent("S 3",1194.45);
534  lineS31198->addComponent("S 3",1200.97);
535  lineS31198->addComponent("S 3",1201.73);
536  lineS31198->addComponent("S 3",1202.12);
537  }
538  }
539 
540  LinSv *lineS31720 = linadd(0.0,1720,"Blnd",'i',"Blend" );
542  {
543  if (lgBandBlends)
544  {
545  lineS31720->makeBlend("S 3",1720.0,20.0);
546  }
547  else
548  {
549  lineS31720->addComponent("S 3",1704.39);
550  lineS31720->addComponent("S 3",1713.11);
551  lineS31720->addComponent("S 3",1728.94);
552  }
553  }
554 
555  LinSv *lineS33722 = linadd(0.0,3722,"Blnd",'i',"Blend" );
557  {
558  if (lgBandBlends)
559  {
560  lineS33722->makeBlend("S 3",3722.0,80.0);
561  }
562  else
563  {
564  lineS33722->addComponent("S 3",3721.63);
565  lineS33722->addComponent("S 3",3797.17);
566  }
567  }
568 
569  LinSv *lineS4UV = linadd(0.0,1406,"Blnd",'i',"Blend" );
571  {
572  if (lgBandBlends)
573  {
574  lineS4UV->makeBlend("S 4",1406.0,20.0);
575  }
576  else
577  {
578  lineS4UV->addComponent("S 4",1404.81);
579  lineS4UV->addComponent("S 4",1398.04);
580  lineS4UV->addComponent("S 4",1423.84);
581  lineS4UV->addComponent("S 4",1416.89);
582  lineS4UV->addComponent("S 4",1406.02);
583  }
584  }
585 
586  LinSv *lineS5UV = linadd(0.0,1199,"Blnd",'i',"Blend" );
588  {
589  if (lgBandBlends)
590  {
591  lineS5UV->makeBlend("S 5",1199.0,15.0);
592  }
593  else
594  {
595  lineS5UV->addComponent("S 5",1199.14);
596  lineS5UV->addComponent("S 5",1188.28);
597  }
598  }
599 
600  LinSv *lineNaD = linadd(0.0,5892,"Blnd",'i',"Blend" );
602  {
603  if (lgBandBlends)
604  {
605  lineNaD->makeBlend("Na 1",5892.0,10.0);
606  }
607  else
608  {
609  lineNaD->addComponent("Na 1",5889.95);
610  lineNaD->addComponent("Na 1",5895.92);
611  }
612  }
613 
614  LinSv *lineAl2 = linadd(0.0,2665,"Blnd",'i',"Blend" );
616  {
617  if (lgBandBlends)
618  {
619  lineAl2->makeBlend("Al 2",2665.0,10.0);
620  }
621  else
622  {
623  lineAl2->addComponent("Al 2",2669.15);
624  lineAl2->addComponent("Al 2",2660.35);
625  }
626  }
627 
628  LinSv *lineAl3 = linadd(0.0,1860,"Blnd",'i',"Blend" );
630  {
631  if (lgBandBlends)
632  {
633  lineAl3->makeBlend("Al 3",1860.0,10.0);
634  }
635  else
636  {
637  lineAl3->addComponent("Al 3",1854.72);
638  lineAl3->addComponent("Al 3",1862.79);
639  }
640  }
641 
642  LinSv *lineAl11 = linadd(0.0,556,"Blnd",'i',"Blend" );
644  {
645  if (lgBandBlends)
646  {
647  lineAl11->makeBlend("Al11",556.0,15.0);
648  }
649  else
650  {
651  lineAl11->addComponent("Al11",550.032);
652  lineAl11->addComponent("Al11",568.122);
653  }
654  }
655 
656  LinSv *lineAr4One = linadd(0.0,4725,"Blnd",'i',"Blend" );
658  {
659  if (lgBandBlends)
660  {
661  lineAr4One->makeBlend("Ar 4",4725.0,20.0);
662  }
663  else
664  {
665  lineAr4One ->addComponent("Ar 4",4740.12);
666  lineAr4One ->addComponent("Ar 4",4711.26);
667  }
668  }
669 
670  LinSv *lineAr4Two = linadd(0.0,2860,"Blnd",'i',"Blend" );
672  {
673  if (lgBandBlends)
674  {
675  lineAr4Two->makeBlend("Ar 4",2860.0,10.0);
676  }
677  else
678  {
679  lineAr4Two ->addComponent("Ar 4",2868.22);
680  lineAr4Two ->addComponent("Ar 4",2853.66);
681  }
682  }
683 
684  LinSv *lineAr4Three = linadd(0.0,7250,"Blnd",'i',"Blend" );
686  {
687  if (lgBandBlends)
688  {
689  lineAr4Three->makeBlend("Ar 4",7250.0,100.0);
690  }
691  else
692  {
693  lineAr4Three ->addComponent("Ar 4",7237.77);
694  lineAr4Three ->addComponent("Ar 4",7332.15);
695  lineAr4Three ->addComponent("Ar 4",7170.70);
696  lineAr4Three ->addComponent("Ar 4",7263.33);
697  }
698  }
699 
700  LinSv *lineSiII = linadd(0.0,2335,"Blnd",'i',"Blend" );
702  {
703  lineSiII->addComponent("Si 2",2334.41);
704  lineSiII->addComponent("Si 2",2328.52);
705  lineSiII->addComponent("Si 2",2350.17);
706  lineSiII->addComponent("Si 2",2344.20);
707  lineSiII->addComponent("Si 2",2334.60);
708  }
709 
710  LinSv *lineSiIII = linadd(0.0,1888,"Blnd",'i',"Blend" );
712  {
713  lineSiIII->addComponent("Si 3",1882.71);
714  lineSiIII->addComponent("Si 3",1892.03);
715  }
716 
717  LinSv *lineSiIV = linadd(0.0,1397,"Blnd",'i',"Blend" );
719  {
720  lineSiIV->addComponent("Si 4",1393.75);
721  lineSiIV->addComponent("Si 4",1402.77);
722  }
723 
724  LinSv *lineNeIV = linadd(0.0, 2424, "Blnd", 'i', "Blend");
726  {
727  lineNeIV->addComponent("Ne 4", 2421.66);
728  lineNeIV->addComponent("Ne 4", 2424.28);
729  }
730 
731  LinSv *lineNeVII = linadd(0.0,895,"Blnd",'i',"Blend" );
733  {
734  lineNeVII->addComponent("Ne 7",887.279);
735  lineNeVII->addComponent("Ne 7",895.174);
736  }
737 
738  LinSv *lineNeVIII = linadd(0.0,774,"Blnd",'i',"Blend" );
740  {
741  lineNeVIII->addComponent("Ne 8",770.410);
742  lineNeVIII->addComponent("Ne 8",780.325);
743  }
744 
745  LinSv *lineClIIIa = linadd(0.0,3350,"Blnd",'i',"Blend" );
747  {
748  lineClIIIa->addComponent("Cl 3",3342.80);
749  lineClIIIa->addComponent("Cl 3",3353.17);
750  }
751 
752  LinSv *lineClIIIb = linadd(0.0,5525,"Blnd",'i',"Blend" );
754  {
755  lineClIIIb->addComponent("Cl 3",5517.71);
756  lineClIIIb->addComponent("Cl 3",5537.87);
757  }
758 
759  LinSv *lineClIIIc = linadd(0.0,8494,"Blnd",'i',"Blend" );
761  {
762  lineClIIIc->addComponent("Cl 3",8433.66);
763  lineClIIIc->addComponent("Cl 3",8480.86);
764  lineClIIIc->addComponent("Cl 3",8500.01);
765  lineClIIIc->addComponent("Cl 3",8547.96);
766  }
767 
768  /*************Calcium Blends *******************/
770  {
771  double eff = dense.eden*dense.xIonDense[ipCALCIUM][2]*5.4e-21/(phycon.te/
773  PntForLine( 3933., "Ca2R", &ipnt);
774  lindst(eff, 3933., "Ca2R", ipnt, 't', false,
775  " recombination contribution to CaII emission" );
776  //LinSv *lineCa2 = linadd(0.0,3933,"Blnd",'i',"Blend" );
777 
778  LinSv *lineCaII8579 = linadd(0.0,8579,"Blnd",'i',"Blend" );
779  lineCaII8579->addComponent("Ca 2",8662.14);
780  lineCaII8579->addComponent("Ca 2",8542.09);
781  lineCaII8579->addComponent("Ca 2",8498.02);
782 
783  LinSv *lineCaII7306 = linadd(0.0,7306,"Blnd",'i',"Blend" );
784  lineCaII7306->addComponent("Ca 2",7291.47);
785  lineCaII7306->addComponent("Ca 2",7323.89);
786 
787  LinSv *lineCaII3933 = linadd(0.0,3933,"Blnd",'i',"Blend" );
788  lineCaII3933->addComponent("Ca 2",3933.66);
789  lineCaII3933->addComponent("Ca 2",3968.47);
790  }
791 
792  /*** CARBON ***/
793  /* Recombination and Pump lines */
794  double pump = 0, fac = 0;
795 
796  /* C 1 1656 */
798  {
799  LinSv *lineCIa = linadd(0.0,1657,"Blnd",'i',"Blend" );
800  lineCIa->addComponent("C 1",1657.01);
801  /* >>chng 97 may 02, added better rec coefficient
802  * C I 1656 recombination, all agents */
803  double rec = LineSave.ipass <= 0 ? 0.0 :
804  GetLineRec(3,1657)*emit_frac(lineCIa->getComponent(0));
805  PntForLine( 1656., "C 1R", &ipnt);
806  lindst(rec, 1656., "C 1R", ipnt, 't', false,
807  " C 1 1656 recomb; n.b. coll deexcitation not in" );
808  lineCIa->addComponent("C 1R",1656);
809  }
810 
811  /* C 1 9850 */
813  {
814  /* >>chng 97 may 02, added better rec coefficient
815  * C 1 9850, recombination contribution rec coefficient from
816  * >>refer C1 rec Escalante, Vladimir, & Victor, G.A., 1990, ApJS 73, 513.
817  * r9850 is correction for collisional deexcitation as in carb cool
818  * >>chng 97 aug 2, had factor of rec, changed to r9850, this
819  * was a big mistake
820  * >>chng 12 nov 11 Now using Escalante 1990 data */
821  double A,B,C,t4;
822  t4 = 1e-4*phycon.te;
823  A = 3.10e-17;
824  B = 0.25;
825  C = -0.41;
826  double c19850WL = 9850.26;
827  double recCoeff = A*pow(t4,-1*B*(1+C*log10(t4)));
828 
829  double volEmis = recCoeff*dense.eden*dense.xIonDense[ipCARBON][1]*HC_ERG_ANG/c19850WL;
830  // RC*eden*xIonDense[nelem][ion]*1.99e-8/wavelength
831 
832  LinSv *lineCIb = linadd(0.0,9850,"Blnd",'i',"Blend" );
833  lineCIb->addComponent("C 1",9824.13);
834  lineCIb->addComponent("C 1",9850.26);
835  double rec = LineSave.ipass <= 0 ? 0.0 :
836  volEmis*emit_frac(lineCIb->getComponent(1)); // 9850.26
837  PntForLine( wlAirVac(9850.), "C 1R", &ipnt);
838  lindst(rec, wlAirVac(9850.), "C 1R", ipnt, 't', false,
839  " C I 9850 recombination contribution" );
840 
841  lineCIb->addComponent("C 1R",9850.);
842  }
843 
844  /* C 2 2326 */
846  {
847  linadd(ionbal.PhotoRate_Shell[ipCARBON][0][1][0]*dense.xIonDense[ipCARBON][0]*0.1*8.6e-12,wlAirVac(2326.),"C 2H",'i' ,
848  " photoproduction, Hofmann and Trefftz");
849  // see 1980A&A....82..256H, 1983A&A...126..415H
850 
851  LinSv *lineCIIb = linadd(0.0,2326,"Blnd",'i',"Blend" );
852  lineCIIb->addComponent("C 2",2324.69);
853  lineCIIb->addComponent("C 2",2323.50);
854  lineCIIb->addComponent("C 2",2328.12);
855  lineCIIb->addComponent("C 2",2326.93);
856  lineCIIb->addComponent("C 2",2325.40);
857  lineCIIb->addComponent("C 2H",2326);
858  }
859 
860  /* C 2 1335 */
862  {
863 
864  LinSv *lineCIIa = linadd(0.0,1335,"Blnd",'i',"Blend" );
865  lineCIIa->addComponent("C 2",1334.53);
866  lineCIIa->addComponent("C 2",1335.66);
867  lineCIIa->addComponent("C 2",1335.71);
868  /* >>chng 97 may 02, better rec coef */
869  /* >>chng 02 jul 01, add function to return emission probability */
870  double rec = LineSave.ipass <= 0 ? 0.0 :
871  GetLineRec(11,1335)*emit_frac(lineCIIa->getComponent(2)); // 1335.71
872  PntForLine( 1335., "C 2R", &ipnt);
873  lindst(rec, 1335., "C 2R", ipnt, 't', false,
874  " C 2 1335 recombination," );
875 
876  lineCIIa->addComponent("C 2R",1335);
877  }
878 
879  /* C 2 3920 */
881  {
882  /* the CII 3918.98/3920.68 and 6578.05/6582.88 multiplets,
883  * contributions by both continuum pumping through XUV line
884  * and recombination */
885  /* this is the driving line, pump is photons cm^-3 s^-1 */
886  if( nWindLine > 0 )
887  {
888  pump = TauLine2[186].Emis().pump()*TauLine2[186].Emis().PopOpc();
889  }
890  else
891  {
892  pump = 0.;
893  }
894 
895  // pumped 3920, count as recomb since does remove energy
896  PntForLine(3920.,"C 2P",&ipnt);
897  lindst(pump*0.387 * 5.08e-12/(1.+dense.eden/1e12) ,3920,"C 2P",ipnt,'r',true ,
898  " CII 3918.98/3920.68 is only pumped, no recombination part");
899 
900  /* convert UV pump rate to intensity with branching ratio and hnu */
901  pump *= 0.305 * 0.387 * 3.02e-12;
902 
903  linadd(pump/(1.+dense.eden/1e12),wlAirVac(6580.),"C 2P",'i',
904  " pumped part of line C II 6580" );
905 
906  LinSv *lineCIIc = linadd(0.0,6580,"Blnd",'i',"Blend" );
907  lineCIIc->addComponent("C 2",6578.05);
908  /* C 2 6580 */
909  double rec = LineSave.ipass <= 0 ? 0.0 :
910  GetLineRec(8, 6580 )*emit_frac(lineCIIc->getComponent(0));
911  PntForLine( wlAirVac(6580.), "C 2R", &ipnt);
912  lindst(rec/(1.+dense.eden/1e12), wlAirVac(6580.), "C 2R", ipnt, 't', false,
913  " recombination part of C II 6580 line " );
914  lineCIIc->addComponent("C 2R",6580);
915  lineCIIc->addComponent("C 2P",6580);
916  }
917 
918  /* C 3 977
919  * recombination contribution from nussbaumer and story 84 */
921  {
922  LinSv *lineCIIIc = linadd(0.0,977,"Blnd",'i',"Blend" );
923  lineCIIIc->addComponent("C 3",977.020);
924  /* >>chng 02 jul 01, add function to compute emission fraction */
925  double rec = LineSave.ipass <= 0 ? 0.0 :
926  GetLineRec(179,977)*emit_frac(lineCIIIc->getComponent(0));
927  PntForLine( 977., "C 3R", &ipnt);
928  lindst(rec, 977., "C 3R", ipnt, 't', false,
929  " dielectronic recombination contribution to C 3 977 " );
930  lineCIIIc->addComponent("C 3R",977);
931  }
932 
933  /* C 3 1909 */
935  {
936  LinSv *lineCIII = linadd(0.0,1909,"Blnd",'i',"Blend" );
937  lineCIII->addComponent("C 3",1908.73);
938  lineCIII->addComponent("C 3",1906.68);
939  /* >>chng 02 jul 01, add function to compute emission fraction */
940  double corr = LineSave.ipass <= 0 ? 0.0 :
941  emit_frac(lineCIII->getComponent(0)); // 1908.73
943 
944  PntForLine( 1909., "C 3R", &ipnt );
945  lindst( 3.1e-19*fac*corr, 1909., "C 3R", ipnt, 't', false,
946  " C 3 1909 recombination from Storey" );
947 
948  lindst(ionbal.PhotoRate_Shell[ipCARBON][1][1][0]*dense.xIonDense[ipCARBON][1]*0.62*corr*1.05e-11,1909,"C 3H",ipnt,'t',false,
949  " C 3 1909 following relax following inner shell photoionization" );
950  lineCIII->addComponent("C 3R",1909);
951  lineCIII->addComponent("C 3H",1909);
952  }
953 
954  /* C 3 1175 */
956  {
957 
958  LinSv *lineCIIIb = linadd(0.0,1176,"Blnd",'i',"Blend" );
959  lineCIIIb->addComponent("C 3",1174.61);
960  lineCIIIb->addComponent("C 3",1174.93);
961  lineCIIIb->addComponent("C 3",1175.26);
962  lineCIIIb->addComponent("C 3",1175.59);
963  lineCIIIb->addComponent("C 3",1175.71);
964  lineCIIIb->addComponent("C 3",1175.99);
965  lineCIIIb->addComponent("C 3",1176.37);
966  lineCIIIb->addComponent("C 3",1176.77);
967 
968  /* >>chng 97 may 02, better rec ocef */
969  /* >>chng 02 jul 01, add function to compute emission fraction */
970  double rec = LineSave.ipass <= 0 ? 0.0 :
971  GetLineRec(178,1176)*emit_frac(lineCIIIb->getComponent(4)); // 1175.71
972  PntForLine( 1175., "C 3R", &ipnt );
973  lindst(rec, 1175., "C 3R", ipnt, 't', false,
974  " dielectronic recombination contribution to C 3 1175 " );
975  lineCIIIb->addComponent("C 3R",1175);
976  }
977 
978  /* C 4 1549 */
980  {
981  LinSv *lineCIV = linadd(0.0,1549,"Blnd",'i',"Blend" );
982  LinSv *lineCIVInwd = linadd(0.0,1549,"Inwd",'i',"inward part of Blend" );
983  lineCIV->addComponent("C 4",1550.78);
984  lineCIV->addComponent("C 4",1548.19);
985 
986  /* recombination C 4 1549 from C 5
987  * >>chng 97 may 02, better rec coef */
988  /* >>chng 02 jul 01, add function to compute emission fraction */
989  double rec = LineSave.ipass <= 0 ? 0.0 :
990  GetLineRec(25,1549)*emit_frac(lineCIV->getComponent(1)); // 1548.19
991  PntForLine( 1549., "C 4R", &ipnt );
992  lindst(rec, 1549., "C 4R", ipnt, 't', false,
993  " recombination C 4 1549 from CV" );
994  lineCIV->addComponent("C 4R",1549);
995 
996  lineCIVInwd->addComponent("Inwd",1550.78);
997  lineCIVInwd->addComponent("Inwd",1548.19);
998  lineCIV->addComponent("C 4R",1549);
999  }
1000 
1001  /*** End of Carbon ***/
1002 
1003  /*** NITROGEN ***/
1004  /* Recombination and Pump lines */
1005 
1006 
1007  /***********************/
1008  /****** N 1 3467 ******/
1009  /*********************/
1011  {
1012  LinSv *lineNI3467 = linadd(0.0,3467,"Blnd",'i',"Blend" );
1013  lineNI3467->addComponent("N 1",3466.50);
1014  lineNI3467->addComponent("N 1",3466.54);
1015  }
1016 
1017  /***********************/
1018  /****** N 1 5199 ******/
1019  /*********************/
1021  {
1022  /**** Terry's addition, recombination from N+ **************/
1023  /* rate coefficient (cm3 s-1) from Table 3 of
1024  *>>refer NI rec Pequignot, D., Petijean, P. & Boisson, C. 1991, A&A, 251, 680 */
1025  double eff_recrate_2D = 1.108e-13 * pow(phycon.te*1e-4, -0.6085) /
1026  (1. - 0.0041 * pow(phycon.te*1e-4, -0.3975) );
1027  double eff_recrate_2P = 0.659e-13 * pow(phycon.te*1e-4, -0.6158);
1028  double fac_n1;
1029  if( dense.xIonDense[ipNITROGEN][0] > 0. )
1031  else
1032  fac_n1 = 0.;
1033 
1034  // assume levels are populated according to statistical weight
1035  double rec14 = eff_recrate_2P * fac_n1 * 2./6.;
1036  double rec15 = eff_recrate_2P * fac_n1 * 4./6.;
1037  double rec13 = eff_recrate_2D * fac_n1 * 4./10.;
1038  double rec12 = eff_recrate_2D * fac_n1 * 6./10.;
1039 
1040  LinSv *lineNI5199 = linadd(0.0,5199,"Blnd",'i',"Blend" );
1041  lineNI5199->addComponent("N 1",5197.90);
1042  lineNI5199->addComponent("N 1",5200.26);
1043 
1044  double emit_frac_5197 = LineSave.ipass <= 0 ? 0.0 :
1045  emit_frac(lineNI5199->getComponent(0)); // 5197.90
1046 
1047  // estimate of recombination contribution to intensity of [NI] 5199
1048  double rec = (rec12+rec13+0.9710*rec14+0.9318*rec15) * dense.xIonDense[ipNITROGEN][0] *
1049  3.82e-12*emit_frac_5197;
1050 
1051  /**** Terry's addition **************/
1052  PntForLine( wlAirVac(5199.), "N 1", &ipnt);
1053  lindst(rec, wlAirVac(5199.), "N 1R", ipnt, 't', true,
1054  " estimate of contribution to [N I] 5199 by recombination" );
1055 
1056  /* this is upper limit to production of 5200 by chemistry - assume every photo dissociation
1057  * populates upper level
1058  * co.nitro_dissoc_rate is the total N photo dissociation rate, cm-3 s-1 */
1059  // count as recombination since removes energy but is not coolng
1060  double chem = mole.dissoc_rate("N") * 3.82e-12 * emit_frac_5197;
1061  lindst( chem, wlAirVac(5199.), "N 1C", ipnt, 'r', true,
1062  " upper limit to [N I] 5199 produced by chemistry" );
1063 
1064  /* this is upper limit to production of 5200 by charge transfer -
1065  * atmdat.HCharExcRecTo_N0_2D is the rate coefficient (cm3 s-1) for N+(3P) + H0 -> H+ + N0(2D) */
1067  3.82e-12 * emit_frac_5197;
1068  lindst( ctRate, wlAirVac(5199.), "N 1T", ipnt, 'r', true,
1069  " upper limit to [N I] 5199 produced by charge transfer" );
1070 
1071  // // estimate of pumping contribution to 5200 doublet
1072  // lindst( nitro.pump5199, 5199, "Pump", ipnt, 'r', true,
1073  // " estimate of contribution to [N I] 5199 by FUV pumping" );
1074 
1075 
1076  lineNI5199->addComponent("N 1R",5199);
1077  lineNI5199->addComponent("N 1C",5199);
1078  lineNI5199->addComponent("N 1T",5199);
1079  }
1080 
1081 
1082  /************************/
1083  /****** N 1 10403 ******/
1084  /**********************/
1086  {
1087  LinSv *lineNI10403 = linadd(0.0,10403,"Blnd",'i',"Blend" );
1088  lineNI10403->addComponent("N 1",10397.7);
1089  lineNI10403->addComponent("N 1",10398.2);
1090  lineNI10403->addComponent("N 1",10407.2);
1091  lineNI10403->addComponent("N 1",10407.6);
1092  }
1093 
1094  /***********************/
1095  /****** N 2 6584 ******/
1096  /*********************/
1097 
1098  /* May be a combination of lines 1D - 3P */
1099  double efficn2 = 4e-3/(4e-3 + 5.18e-6*dense.eden/phycon.sqrte);
1100  double rec = 8e-22/(phycon.te70/phycon.te03/phycon.te03)*efficn2;
1101  PntForLine( 6584., "N 2R", &ipnt );
1102  lindst( rec*dense.xIonDense[ipNITROGEN][2]*dense.eden, 6584., "N 2R", ipnt, 't', false,
1103  " N 2 6584 alone, recombination contribution" );
1104 
1105  /***********************/
1106  /****** N 2 5755 ******/
1107  /*********************/
1108  if( atmdat.lgdBaseSourceExists[ipNITROGEN][1] )
1109  {
1110  /* helium charge transfer from
1111  >>refer n2 CT Sun Sadeghpour, Kirby Dalgarno and Lafyatis, CfA preprint 4208 */
1112  double ctRate = 1.8e-11*dense.xIonDense[ipHELIUM][0]*dense.xIonDense[ipNITROGEN][2]*1.146/(1.146 +
1113  0.87*dense.cdsqte)*3.46e-12;
1114 
1115  PntForLine(5755.,"N 2",&ipnt);
1116 
1117  lindst(ctRate,wlAirVac(5755.),"N 2T",ipnt,'r',true,
1118  " N 2 5755 charge transfer contribution " );
1119 
1120  LinSv *lineNII5755 = linadd(0.0,5755,"Blnd",'i',"Blend" );
1121  lineNII5755->addComponent("N 2",5754.61);
1122 
1123  /* >>chng 01 jul 09, add recombination contribution to 5755 */
1124  /* >>refer n2 rec Liu, X.W., Storey, P.J., Barlow, M.J., Danziger, I.J., Cohen, M.,
1125  * >>refercon & Bryce, M., 2000, MNRAS, 312, 585 */
1126  /* they give intensity in terms of hbeta intensity as their equation 1 */
1127  if( dense.xIonDense[ipHYDROGEN][1] > SMALLFLOAT )
1128  {
1129  /* this test on >0 is necessary because for sims with no H-ionizing radiation
1130  * the H+ density is initially zero */
1131  /* H beta recombination, assuming old case B, needed since HS tables have
1132  * only a narrow temperature range - at this point units are ergs cm^3 s-1 */
1133  double HBeta = (exp10(-20.89 - 0.10612*POW2(phycon.alogte - 4.4)))/phycon.te;
1134 
1135  /* now convert to ergs cm-3 s-1
1136  * >>chng 05 mar 17, this step was missing, so recombination intensity off by density squared,
1137  * bug reported by Marcelo Castellanos */
1138  HBeta *= dense.eden * dense.xIonDense[ipHYDROGEN][1];
1139 
1140  /* CoolHeavy.xN2_A3_tot is fraction of excitations that produce a photon
1141  * and represents the correction for collisional deexcitation */
1142  /*>>chng 05 dec 16, Liu et al. (2000) eqn 1 uses t = Te/10^4 K, not Te so phycon.te30
1143  * is too large: (10^4)^0.3 = 16 - div by 15.8489 - bug caught by Kevin Blagrave */
1144  rec = LineSave.ipass <= 0 ? 0.0 :
1145  emit_frac(lineNII5755->getComponent(0) )* // 5754.61 *
1146  HBeta * 3.19 * phycon.te30 / 15.84893 *
1147  dense.xIonDense[ipNITROGEN][2]/dense.xIonDense[ipHYDROGEN][1];
1148  }
1149  else
1150  {
1151  rec = 0.;
1152  }
1153 
1154  lindst( rec ,wlAirVac(5755.),"N 2R",ipnt,'t',true,
1155  " N 2 5755 recombination contribution" );
1156 
1157  lineNII5755->addComponent("N 2T",5755);
1158  lineNII5755->addComponent("N 2R",5755);
1159  }
1160 
1161  /***********************/
1162  /****** N 2 1085 ******/
1163  /*********************/
1164  if( atmdat.lgdBaseSourceExists[ipNITROGEN][1] )
1165  {
1166 
1167  LinSv *lineNII1085 = linadd(0.0,1085,"Blnd",'i',"Blend" );
1168  lineNII1085->addComponent("N 2",1083.99);
1169  lineNII1085->addComponent("N 2",1084.56);
1170  lineNII1085->addComponent("N 2",1084.58);
1171  lineNII1085->addComponent("N 2",1085.53);
1172  lineNII1085->addComponent("N 2",1085.55);
1173  lineNII1085->addComponent("N 2",1085.70);
1174 
1175  double rec = LineSave.ipass <= 0 ? 0.0 :
1176  GetLineRec(201,1085)*emit_frac(lineNII1085->getComponent(5)); // 1085.70
1177  /* Collisional suppression from emit_frac_db of 1085A may not be accurate.
1178  * It is based on the strongest line in the blend.*/
1179  PntForLine( 1085., "N 2R", &ipnt );
1180  lindst( MAX2(0.,rec), 1085., "N 2R", ipnt, 't', false,
1181  " dielectronic recombination contribution to N 2 1085" );
1182  lineNII1085->addComponent("N 2R",1085);
1183  }
1184 
1185  /***********************/
1186  /****** N 3 1750 ******/
1187  /*********************/
1188  LinSv *lineNIIIa = linadd(0.0,1750,"Blnd",'i',"Blend" );
1189  if (atmdat.lgdBaseSourceExists[ipNITROGEN][2])
1190  {
1191  lineNIIIa->addComponent("N 3",1746.82);
1192  lineNIIIa->addComponent("N 3",1748.65);
1193  lineNIIIa->addComponent("N 3",1749.67);
1194  lineNIIIa->addComponent("N 3",1752.16);
1195  lineNIIIa->addComponent("N 3",1753.99);
1196  }
1197 
1198  /***********************/
1199  /****** N 3 990 *******/
1200  /*********************/
1201  if( atmdat.lgdBaseSourceExists[ipNITROGEN][2] )
1202  {
1203  LinSv *lineNIIIb = linadd(0.0,990,"Blnd",'i',"Blend" );
1204  lineNIIIb->addComponent("N 3",989.799);
1205  lineNIIIb->addComponent("N 3",991.511);
1206  lineNIIIb->addComponent("N 3",991.577);
1207 
1208  double rec = LineSave.ipass <= 0 ? 0.0 :
1209  GetLineRec(216,991)*emit_frac(lineNIIIb->getComponent(0)); // 989.799
1210 
1211  PntForLine( 990., "N 3R", &ipnt );
1212  lindst(rec, 990., "N 3R", ipnt, 't', false,
1213  " part of N 3 990 due to recombination " );
1214 
1215  lineNIIIb->addComponent("N 3R",990);
1216  }
1217 
1218  /***********************/
1219  /****** N 4 765* ******/
1220  /*********************/
1221  if( atmdat.lgdBaseSourceExists[ipNITROGEN][3] )
1222  {
1223 
1224  LinSv *lineNIV765 = linadd(0.0,765,"Blnd",'i',"Blend" );
1225  lineNIV765->addComponent("N 4",765.147);
1226 
1227  /* >>chng 97 may 02, better expression for dielectronic recombination */
1228  /* >>chng 02 jul 01, add function to get emission fraction */
1229  double rec = LineSave.ipass <= 0 ? 0.0 :
1230  GetLineRec(287,765)*emit_frac(lineNIV765->getComponent(0)); // 765.147
1231 
1232  /* dielectronic recombination contribution from Nussbaumer and Storey 1984 */
1233  PntForLine( 765., "N 4R", &ipnt );
1234  lindst( MAX2(0.,rec), 765., "N 4R", ipnt, 't', false,
1235  " N 4 765 recombination," );
1236  lineNIV765->addComponent("N 4R",765);
1237  }
1238 
1239  /***********************/
1240  /****** N 4 1486 ******/
1241  /*********************/
1242  if( atmdat.lgdBaseSourceExists[ipNITROGEN][3] )
1243  {
1244  LinSv *lineNIV1486 = linadd(0.0,1486,"Blnd",'i',"Blend" );
1245  lineNIV1486->addComponent("N 4",1483.32);
1246  lineNIV1486->addComponent("N 4",1486.50);
1247  }
1248 
1249  /***********************/
1250  /****** N 5 1240 ******/
1251  /*********************/
1252  LinSv *lineNV = linadd(0.0,1240,"Blnd",'i',"Blend" );
1253  if (atmdat.lgdBaseSourceExists[ipNITROGEN][4])
1254  {
1255  lineNV->addComponent("N 5",1238.82);
1256  lineNV->addComponent("N 5",1242.805);
1257  }
1258  /***********************/
1259  /****** N 5 1240 ******/
1260  /*********************/
1261  LinSv *lineNVInwd = linadd(0.0,1240,"Inwd",'i',"inward part of Blend" );
1262  if (atmdat.lgdBaseSourceExists[ipNITROGEN][4])
1263  {
1264  lineNVInwd->addComponent("Inwd",1238.82);
1265  lineNVInwd->addComponent("Inwd",1242.805);
1266  }
1267  /*** End of Nitrogen ***/
1268 
1269  /*** OXYGEN***/
1270  /* Recombination and Pump lines */
1271 
1272  /***********************/
1273  /****** O 1 1304 ******/
1274  /*********************/
1276  {
1277  LinSv *lineOI1304 = linadd(0.0,1304,"Blnd",'i',"Blend" );
1278  lineOI1304->addComponent("O 1",1302.17);
1279  lineOI1304->addComponent("O 1",1304.86);
1280  lineOI1304->addComponent("O 1",1306.03);
1281  }
1282 
1283  /***********************/
1284  /****** O 1 6300 ******/
1285  /*********************/
1287  {
1288  LinSv *lineOI6300 = linadd(0.0,6300,"Blnd",'i',"Blend" );
1289  lineOI6300->addComponent("O 1",6300.30);
1290  lineOI6300->addComponent("O 1",6363.78);
1291  lineOI6300->addComponent("O 1",6391.73);
1292  }
1293 
1294  /***********************/
1295  /****** O 1 8446 ******/
1296  /*********************/
1298  {
1299  LinSv *lineOI8446 = linadd(0.0,8446,"Blnd",'i',"Blend" );
1300  lineOI8446->addComponent("O 1",8446.25);
1301  lineOI8446->addComponent("O 1",8446.36);
1302  lineOI8446->addComponent("O 1",8446.76);
1303  }
1304 
1305  /***********************/
1306  /****** O 2 Setup *****/
1307  /*********************/
1308 
1309  double rec7323 , rec7332, rec3730 , rec3726 , rec2471, reco23tot , reco22tot;
1310 
1311  static const bool debug2471 = false;
1312  static const bool debug7323 = false;
1313  static const bool debug7332 = false;
1314 
1316  {
1317 
1318  /***********************/
1319  /****** O 2 2471 *****/
1320  /*********************/
1321  LinSv *lineOII2471 = linadd(0.0,2471,"Blnd",'i',"Blend" );
1322  lineOII2471->addComponent("O 2",2470.22);
1323  lineOII2471->addComponent("O 2",2470.34);
1324  /**********************/
1325 
1326  /***********************/
1327  /****** O 2 3726 *****/
1328  /*********************/
1329  LinSv *lineOII3726 = linadd(0.0,3726,"Blnd",'i',"Blend" );
1330  lineOII3726->addComponent("O 2",3726.03);
1331  /*********************/
1332 
1333  /***********************/
1334  /****** O 2 3728 *****/
1335  /*********************/
1336  LinSv *lineOII3728 = linadd(0.0,3728,"Blnd",'i',"Blend" );
1337  lineOII3728->addComponent("O 2",3728.81);
1338  /********************/
1339 
1340  /***********************/
1341  /****** O 2 7323 *****/
1342  /*********************/
1343  LinSv *lineOII7323 = linadd(0.0,7323,"Blnd",'i',"Blend" );
1344  lineOII7323->addComponent("O 2",7318.92);
1345  lineOII7323->addComponent("O 2",7319.99);
1346  /*********************/
1347 
1348  /***********************/
1349  /****** O 2 7332 *****/
1350  /*********************/
1351  LinSv *lineOII7332 = linadd(0.0,7332,"Blnd",'i',"Blend" );
1352  lineOII7332->addComponent("O 2",7329.67);
1353  lineOII7332->addComponent("O 2",7330.73);
1354  /*********************/
1355 
1356 
1357  /* total recombination to 2P^o, the highest two levels of the 5-level atom,
1358  * which produces the 7325 multiplet, last factor accounts for coll deexcitation
1359  * this implements equation 2 of
1360  * refer o2 rec Liu, X-W., Storey, P.J., Barlow, M.J., Danziger, I.J.,
1361  * refercon Cohen, M., & Bryce, M., 2000, MNRAS, 312, 585 */
1362  /* >>chng 05 dec 29, from first eqn, or unknown origin, to second, from indicated
1363  * reference. They agreed within 20% */
1364 
1365 
1366  /* Get lines in ergs/s to replace CoolHeavy.Oxxxx */
1367  double chO2471 = 0.0;
1368  double chO7323 = 0.0;
1369  double chO7332 = 0.0;
1370  double chO3726 = 0.0;
1371  double chO3730 = 0.0;
1372  double O2_Lev45_rad = 0.0;
1373  double O2_Lev45_coll = 0.0;
1374  double O2_Lev23_rad = 0.0;
1375  double O2_Lev23_coll = 0.0;
1376  if (LineSave.ipass > 0 )
1377  {
1378  TransitionProxy tr;
1379  tr = lineOII2471->getComponent(0);
1380  if (tr.associated())
1381  {
1382  chO2471 += tr.Emis().xObsIntensity();
1383  }
1384  tr = lineOII2471->getComponent(1);
1385  if (tr.associated())
1386  {
1387  chO2471 += tr.Emis().xObsIntensity();
1388  }
1389  tr = lineOII7323->getComponent(0);
1390  if (tr.associated())
1391  {
1392  chO7323 += tr.Emis().xObsIntensity();
1393  }
1394  tr = lineOII7323->getComponent(1);
1395  if (tr.associated())
1396  {
1397  chO7323 += tr.Emis().xObsIntensity();
1398  }
1399  tr = lineOII7332->getComponent(0);
1400  if (tr.associated())
1401  {
1402  chO7332 += tr.Emis().xObsIntensity();
1403  }
1404  tr = lineOII7332->getComponent(1);
1405  if (tr.associated())
1406  {
1407  chO7332 += tr.Emis().xObsIntensity();
1408  }
1409  tr = lineOII3726->getComponent(0);
1410  if (tr.associated())
1411  {
1412  chO3726 += tr.Emis().xObsIntensity();
1413  }
1414  tr = lineOII3728->getComponent(0);
1415  if (tr.associated())
1416  {
1417  chO3730 += tr.Emis().xObsIntensity();
1418  }
1419 
1420  //Radiative decays per second of 7319.99 and 7329.67
1421  //Collisional decays per second of 7319.99 and 7329.67
1422  tr = lineOII7323->getComponent(1);
1423  if (tr.associated())
1424  {
1425  O2_Lev45_rad += tr.Hi()->Pop()*tr.Emis().Aul();
1426  O2_Lev45_coll += tr.Hi()->Pop()*tr.Coll().ColUL(colliders);
1427  }
1428  tr = lineOII7332->getComponent(0);
1429  if (tr.associated())
1430  {
1431  O2_Lev45_rad += tr.Hi()->Pop()*tr.Emis().Aul();
1432  O2_Lev45_coll += tr.Hi()->Pop()*tr.Coll().ColUL(colliders);
1433  }
1434 
1435  //Radiative decays per second of 3726.03 and 3728.81
1436  //Collisional decays per second of 3726.03 and 3728.81
1437  tr = lineOII3726->getComponent(0);
1438  if (tr.associated())
1439  {
1440  O2_Lev23_rad += tr.Hi()->Pop()*tr.Emis().Aul();
1441  O2_Lev23_coll += tr.Hi()->Pop()*tr.Coll().ColUL(colliders);
1442  }
1443  tr = lineOII3728->getComponent(0);
1444  if (tr.associated())
1445  {
1446  O2_Lev23_rad += tr.Hi()->Pop()*tr.Emis().Aul();
1447  O2_Lev23_coll += tr.Hi()->Pop()*tr.Coll().ColUL(colliders);
1448  }
1449  }
1450  double chO3727 = chO3726 + chO3730;
1451  double chO7325 = chO7323 + chO7332;
1452 
1453  //This replaces CoolHeavy.O2_A3_tot
1454  double O2_Lev45_radTot = O2_Lev45_rad/SDIV(O2_Lev45_rad + O2_Lev45_coll);
1455 
1456  //This replaces CoolHeavy.O2_A2_tot
1457  //FIX THIS: both rad and coll should have 3 lines
1458  double O2_Lev23_radTot = O2_Lev23_rad/SDIV(O2_Lev23_rad + O2_Lev23_coll);
1459 
1460  if( dense.xIonDense[ipHYDROGEN][1] > SMALLFLOAT )
1461  {
1462  double HBeta = (exp10(-20.89 - 0.10612*POW2(phycon.alogte - 4.4)))/phycon.te;
1463  HBeta *= dense.eden * dense.xIonDense[ipHYDROGEN][1];
1464  /* this test is necessary because for sims with no H-ionizing radiation
1465  * the H+ density is initially zero */
1466 
1467  reco23tot = O2_Lev45_radTot * HBeta *
1468  9.36 * phycon.te40*phycon.te04 / 57.544 * dense.xIonDense[ipOXYGEN][2]/dense.xIonDense[ipHYDROGEN][1];
1469  }
1470  else
1471  {
1472  reco23tot = 0.;
1473  }
1474 
1475  if(debug2471 || debug7323 || debug7332 )
1476  {
1477  fprintf(ioQQQ,"reco23tot\t%e\n",reco23tot);
1478  fprintf(ioQQQ,"O2_Lev45_radTot\t%e\t%e\t%e\n",O2_Lev45_radTot,O2_Lev45_rad,O2_Lev45_coll);
1479  }
1480 
1481  sum = chO2471*2471./7325. + chO7323 + chO7332;
1482  if( sum > SMALLFLOAT )
1483  {
1484  /* assume effective branching ratio according to predicted intensities from 5-lev atom*/
1485  reco23tot /= sum;
1486  }
1487  else
1488  {
1489  reco23tot = 0.;
1490  }
1491  /* these are now ergs per sec unit vol for each transition */
1492 
1493  if(debug2471 || debug7323 || debug7332 )
1494  {
1495  fprintf(ioQQQ,"reco23tot\t%e\tsum\t%e\n",reco23tot,sum);
1496  }
1497 
1498  rec7332 = reco23tot * chO7332;
1499  linadd(rec7332,wlAirVac(7332.),"O 2R",'i'," P1/2-D3/2 and P3/2-D3/2 together " );
1500 
1501  rec7323 = reco23tot * chO7323;
1502  linadd(rec7323,wlAirVac(7323.),"O 2R",'i'," P1/2-D5/2 and P3/2-D5/2 together " );
1503 
1504 
1505  /* total recombination to 2D^o, the middle two levels of the 5-level atom,
1506  * which produces the 3727 multiplet, last factor accounts for coll deexcit */
1507  reco22tot = 1.660e-10 / ( phycon.sqrte * phycon.te03 * phycon.te005 ) *
1508  dense.eden * dense.xIonDense[ipOXYGEN][2] * O2_Lev23_radTot;
1509  /* assume effective branching ratio according to predicted intensities from 5-lev atom*/
1510  sum = chO3726 + chO3730;
1511  // It would be better to have a physically-based branching ratio as fallback...
1512  realnum fracO3726 = (realnum) safe_div(chO3726, sum, 0.5),
1513  fracO3730 = (realnum) safe_div(chO3730, sum, 0.5);
1514  /* these are now ergs per sec unit vol for each transition */
1515  rec3726 = reco22tot * fracO3726 * 5.34e-12;
1516  rec3730 = reco22tot * fracO3730 * 5.34e-12;
1517 
1518 
1519  /***********************/
1520  /****** O 2 833 *****/
1521  /*********************/
1522 
1523  LinSv *lineOII833 = linadd(0.0,833,"Blnd",'i',"Blend" );
1524  lineOII833->addComponent("O 2",832.758);
1525  lineOII833->addComponent("O 2",833.330);
1526  lineOII833->addComponent("O 2",834.465);
1527 
1528  /***********************/
1529  /****** O 2 3727 *****/
1530  /*********************/
1531 
1532  /* O II 3727 produced by photoionization OF O0 */
1533  oxy.s3727 = (realnum)((oxy.s3727 + oxy.s7325*0.5)*5.34e-12*
1534  9.7e-5/(9.7e-5 + dense.eden*1.15e-6/phycon.sqrte));
1535 
1536  linadd(oxy.s3727,3727,"O 2H",'i',
1537  " line produced by photoionization of Oo; already in TOTL" );
1538 
1539  linadd( rec3726 ,3726,"O 2R",'i'," D3/2 - S3/2 transition" );
1540 
1541  PntForLine( 3729., "O 2R", &ipnt );
1542  lindst( rec3730 ,3729., "O 2R", ipnt, 't', false,
1543  " recombination contribution refer o2 rec Liu, X-W., Storey, P.J., Barlow, M.J., Danziger, I.J.,refercon Cohen, M., & Bryce, M., 2000, MNRAS, 312, 585 recombination contributions five level atom calculations; D5/2 - S3/2 " );
1544 
1545  linadd(chO3727+rec3726+rec3730+oxy.s3727,3727,"Blnd",'i',
1546  " O II 3727, all lines of multiplet together" );
1547 
1548  /***********************/
1549  /****** O 2 2471 Cont**/
1550  /*********************/
1551 
1552  rec2471 = reco23tot * chO2471*2471./7325. * 8.05e-12/2.72e-12;
1553  linadd(rec2471,wlAirVac(2471.),"O 2R",'i', " both 2P 1/2 and 3/2 to ground " );
1554  lineOII2471->addComponent("O 2R",2471);
1555 
1556  /***********************/
1557  /****** O 2 7325 *****/
1558  /*********************/
1559 
1560  oxy.s7325 = (realnum)(oxy.s7325*2.72e-12*0.34/(0.34 + dense.eden*
1561  6.04e-6/phycon.sqrte));
1562 
1563  linadd(oxy.s7325,7325,"O 2H",'i',
1564  " line produced by photoionization of Oo;" );
1565 
1566  linadd(chO7325+rec7323+rec7332,7325,"Blnd",'i',
1567  " O II 7325, all lines of multiplet together" );
1568 
1569  /***********************/
1570  /****** O 2 7332 Cont**/
1571  /*********************/
1572  lineOII7332->addComponent("O 2R",7332);
1573 
1574  /***********************/
1575  /****** O 2 7323 Cont**/
1576  /*********************/
1577  lineOII7323->addComponent("O 2R",7323);
1578 
1579  /***********************/
1580  /****** O 2 P and R ***/
1581  /*********************/
1582 
1583  /* the OII multiplets,
1584  * contributions by both continuum pumping through XUV line
1585  * and recombination */
1586  /* this is the driving line, pump is photons cm^-3 s^-1 */
1587  if( nWindLine > 0 )
1588  {
1589  pump = TauLine2[387].Emis().pump()*TauLine2[387].Emis().PopOpc();
1590  }
1591  else
1592  {
1593  pump = 0.;
1594  }
1595 
1596 
1597  PntForLine(3120.,"O 2",&ipnt);
1598  lindst(pump*0.336 * 6.37e-12/(1.+dense.eden/1e12) ,3120,"O 2P",ipnt,'r',true,
1599  " OII 3113.62 - 3139.68 (8 lines) are only pumped, no recombination part" );
1600 
1601  PntForLine(3300.,"O 2",&ipnt);
1602  lindst(pump*0.147 * 6.03e-12/(1.+dense.eden/1e12) ,3300,"O 2P",ipnt,'r',true,
1603  " OII 3277.56 - 3306.45 (6 lines) are only pumped, no recombination part" );
1604 
1605  PntForLine(3762.,"O 2",&ipnt);
1606  lindst(pump*0.087 * 5.29e-12/(1.+dense.eden/1e12) ,3762,"O 2P",ipnt,'r',true,
1607  " OII 3739.76/3762.47/3777.42 (3 lines) are only pumped, no recombination part" );
1608 
1609  /* recombination and specific pump for OII 4638.86-4696.35 (8 lines) */
1610  rec = GetLineRec(82, 4651 );
1611  PntForLine( 4651.,"O 2",&ipnt);
1612  lindst(rec, 4651.,"O 2R",ipnt,'t',true,
1613  " O II 4651 total recombination, 4638.86-4696.35 (8 lines) " );
1614 
1615  /* convert UV pump rate to intensity with branching ratio and hnu recombination
1616  * part of O II 4651 line */
1617  linadd(pump* 0.336 * 0.933 * 4.27e-12/(1.+dense.eden/1e12),4651,"O 2P",'i',
1618  " pumped part of line O II 4651 " );
1619 
1620  /***********************/
1621  /****** O 2 4341 *****/
1622  /*********************/
1623 
1624  LinSv *lineOII4341 = linadd(0.0,4341,"Blnd",'i',"Blend" );
1625  //lineOII4341->addComponent("O 2",4341);
1626  //Outside default levels
1627 
1628  /* recombination and specific pump for OII 4317.14-4366.89 (6 lines) */
1629  rec = GetLineRec(83, 4341 );
1630 
1631  PntForLine( wlAirVac(4341.), "O 2R", &ipnt );
1632  lindst(rec/(1.+dense.eden/1e12), wlAirVac(4341.), "O 2R", ipnt, 't', false,
1633  " recombination contribution to O II 4341 line " );
1634 
1635  linadd(pump* 0.147 * 0.661 * 4.58e-12/(1.+dense.eden/1e12),wlAirVac(4341.),"O 2P",'i',
1636  " pumped part of line O II 4341 " );
1637 
1638  lineOII4341->addComponent("O 2P",4341);
1639  lineOII4341->addComponent("O 2R",4341);
1640 
1641  /***********************/
1642  /****** O 2 3736 *****/
1643  /*********************/
1644  LinSv *lineOII3736 = linadd(0.0,3736,"Blnd",'i',"Blend" );
1645  //lineOII3736->addComponent("O 2",3736);
1646  //Outside default levels
1647 
1648  /* recombination and specific pump for OII 3712.74/3727.32/3749.48 (3 lines) */
1649  double rec = GetLineRec(84, 3736 );
1650  /* convert UV pump rate to intensity with branching ratio and hnu */
1651 
1652  PntForLine( wlAirVac(3736.), "O 2R", &ipnt );
1653  lindst(rec/(1.+dense.eden/1e12), wlAirVac(3736.), "O 2R", ipnt, 't', false,
1654  " recombination part of O II 3736 line " );
1655  linadd(pump* 0.087 * 0.763 * 5.33e-12/(1.+dense.eden/1e12),wlAirVac(3736.),"O 2P",'i',
1656  " pumped part of line O II 3736" );
1657 
1658  lineOII3736->addComponent("O 2P",3736);
1659  lineOII3736->addComponent("O 2R",3736);
1660  }
1661 
1662 
1663  /***********************/
1664  /****** O 3 1666 *****/
1665  /*********************/
1667  {
1668  LinSv *lineOIII1666 = linadd(0.0,1666,"Blnd",'i',"Blend" );
1669  lineOIII1666->addComponent("O 3",1666.15);
1670  lineOIII1666->addComponent("O 3",1660.81);
1671 
1672  double efac = 0.0;
1673  if (LineSave.ipass > 0)
1674  {
1675  efac = (emit_frac(lineOIII1666->getComponent(0)) +
1676  emit_frac(lineOIII1666->getComponent(1)))*0.5;
1677  }
1678 
1679  linadd(ionbal.PhotoRate_Shell[ipOXYGEN][3][1][0]*dense.xIonDense[ipOXYGEN][1]*0.3*1.20e-11*efac,1665,"O 3H",'i',
1680  " contribution to OIII 1665 due to inner shell (2s^2) ionization " );
1681 
1682  linadd(oxy.AugerO3*1.20e-11*efac*0.27,1665,"O 3A",'i',
1683  " contribution to OIII 1665 due to K-shell ionization " );
1684 
1685 
1686  lineOIII1666->addComponent("O 3H",1665);
1687  lineOIII1666->addComponent("O 3A",1665);
1688  }
1689 
1690  /***********************/
1691  /****** O 3 5007 *****/
1692  /*********************/
1694  {
1695  LinSv *lineOIII5007 = linadd(0.0,5007,"Blnd",'i',"Blend" );
1696  lineOIII5007->addComponent("O 3",5006.84);
1697  lineOIII5007->addComponent("O 3",4958.91);
1698  lineOIII5007->addComponent("O 3",4931.23);
1699 
1700  /* o iii 5007+4959, As 96 NIST */
1701  /*The cs of the transitions 3P0,1,2 to 1D2 are added together to give oiii_cs3P1D2 */
1702  /*the cs of the transition 1D2-1S0 is mentioned as oiii_cs1D21S0*/
1703  /*The cs of the transitions 3P0,1,2 to 1S0 are added together to give oiii_cs3P1S0*/
1704  double aeff = 0.027242 + oxy.d5007r;
1705  //double a21 = aeff - oxy.d5007r;
1706 
1707  realnum d5007t = 0.0;
1708  if (LineSave.ipass > 0)
1709  {
1710  TransitionProxy tr = lineOIII5007->getComponent(0);
1711  if ( tr.associated())
1712  {
1713  d5007t += (realnum)(tr.Emis().xObsIntensity()*oxy.d5007r/aeff);
1714  }
1715  }
1716 
1717  linadd(d5007t/1.25,5007,"LOST",'i',
1718  " O III 5007 lost through excited state photo" );
1719  }
1720 
1721 
1722  /***********************/
1723  /****** O 3 4363 *****/
1724  /*********************/
1726  {
1727  /* collisional quenching ratio */
1728  double effec = 1.6/(1.6 + 0.9*dense.cdsqte);
1729 
1730  /* O III 4363 recombination, coefficient from Burgess and Seaton */
1731  double r4363 = 6.3e-21/(phycon.te70*phycon.te10)*dense.eden*dense.xIonDense[ipOXYGEN][3]*effec;
1732 
1733  /* charge exchange,
1734  * >>refer O3 CT Dalgarno+Sternberg ApJ Let 257, L87.
1735  * scaled to agree with
1736  * >>refer O3 CT Gargaud et al AA 208, 251, (1989) */
1737  double ct4363 = phycon.sqrte*1.3e-12*4.561e-12*dense.xIonDense[ipHYDROGEN][0]*dense.xIonDense[ipOXYGEN][3]*
1738  effec;
1739 
1740  PntForLine(4363.,"O 3",&ipnt);
1741 
1742  lindst(r4363,wlAirVac(4363.),"O 3R",ipnt,'t',true,
1743  " O III 4363 recombination, coefficient from Burgess and Seaton " );
1744 
1745  linadd(ct4363,wlAirVac(4363.),"O 3C",'i' ,
1746  " call linadd( c4363*0.236 , 2321 , 'O 3','c') charge exchange, Dalgarno+Sternberg ApJ Let 257, L87. ");
1747 
1748  LinSv *lineOIII4363 = linadd(0.0,4363,"Blnd",'i',"Blend" );
1749  lineOIII4363->addComponent("O 3",4363.21);
1750  lineOIII4363->addComponent("O 3C",4363);
1751  lineOIII4363->addComponent("O 3R",4363);
1752  }
1753 
1754 
1755  /***********************/
1756  /****** O 3 5592 *****/
1757  /*********************/
1759  {
1760  linadd(dense.xIonDense[ipHYDROGEN][0]*dense.xIonDense[ipOXYGEN][3]*0.225*3.56e-12*1.34e-11*phycon.sqrte,
1761  wlAirVac(5592.),"O 3C",'i'," charge exchange rate, D+S " );
1762 
1763  LinSv *lineOIII5592 = linadd(0.0,5592,"Blnd",'i',"Blend" );
1764  lineOIII5592->addComponent("O 3",5592);
1765  lineOIII5592->addComponent("O 3C",5592);
1766  }
1767 
1768 
1769  /***********************/
1770  /****** O 3 835 ******/
1771  /*********************/
1773  {
1774  LinSv *lineOIII835 = linadd(0.0,835,"Blnd",'i',"Blend" );
1775 
1776  //3P-3D
1777  lineOIII835->addComponent("O 3",832.929);
1778  lineOIII835->addComponent("O 3",833.715);
1779  lineOIII835->addComponent("O 3",833.749);
1780  lineOIII835->addComponent("O 3",835.059);
1781  lineOIII835->addComponent("O 3",835.092);
1782  lineOIII835->addComponent("O 3",835.289);
1783 
1784  /* >>chng 97 may 02, better rec contribution */
1785  double rec = LineSave.ipass <= 0 ? 0.0 : GetLineRec(331,835)*emit_frac(lineOIII835->getComponent(3));
1786 
1787  PntForLine( 835., "O 3R", &ipnt );
1788  lindst(MAX2(0.,rec), 835., "O 3R", ipnt, 't', false,
1789  " O III 834A, dielectronic recombination only" );
1790 
1791  lineOIII835->addComponent("O 3R",835);
1792  }
1793 
1794  /***********************/
1795  /****** O 4 1402 ******/
1796  /*********************/
1798  {
1799  linadd(ionbal.PhotoRate_Shell[ipOXYGEN][2][1][0]*dense.xIonDense[ipOXYGEN][2]*0.43*1.42e-11,1401,"O 4H",'i',
1800  " inner shell photoionization, relaxation " );
1801 
1802  LinSv *lineOIV1402 = linadd(0.0,1402,"Blnd",'i',"Blend" );
1803  lineOIV1402->addComponent("O 4",1397.20);
1804  lineOIV1402->addComponent("O 4",1399.77);
1805  lineOIV1402->addComponent("O 4",1401.16);
1806  lineOIV1402->addComponent("O 4",1404.78);
1807  lineOIV1402->addComponent("O 4",1407.38);
1808  lineOIV1402->addComponent("O 4H",1401);
1809  }
1810 
1811  /***********************/
1812  /****** O 4 789 ******/
1813  /*********************/
1815  {
1816  LinSv *lineOIV789 = linadd(0.0,789,"Blnd",'i',"Blend" );
1817  lineOIV789->addComponent("O 4",787.710);
1818  lineOIV789->addComponent("O 4",790.114);
1819  lineOIV789->addComponent("O 4",790.201);
1820 
1821  /* >>chng 97 may 02, better rec contribution */
1822  double rec = LineSave.ipass <= 0 ? 0.0 : GetLineRec(378,789)*emit_frac(lineOIV789->getComponent(2));
1823  PntForLine( 789., "O 4R", &ipnt );
1824  lindst(MAX2(0.,rec), 789., "O 4R", ipnt, 't', false,
1825  " O IV 789A, dielectronic recombination only" );
1826 
1827  lineOIV789->addComponent("O 4R",789);
1828  }
1829 
1830 
1831 
1832  /***********************/
1833  /****** O 5 630 ******/
1834  /*********************/
1836  {
1837  LinSv *lineOV630 = linadd(0.0,630,"Blnd",'i',"Blend" );
1838  lineOV630->addComponent("O 5",629.732);
1839 
1840  /* >>chng 97 may 02, better rec contribution */
1841  double rec = LineSave.ipass <= 0 ? 0.0 : GetLineRec(466,630)*emit_frac(lineOV630->getComponent(0));
1842 
1843  PntForLine( 630., "O 5R", &ipnt );
1844  lindst(MAX2(0.,rec), 630., "O 5R", ipnt, 't', false,
1845  " O V 630A, dielectronic recombination only" );
1846 
1847  lineOV630->addComponent("O 5R",630);
1848  }
1849 
1850  /***********************/
1851  /****** O 5 1218 ******/
1852  /*********************/
1854  {
1855  LinSv *lineOV1218 = linadd(0.0,1218,"Blnd",'i',"Blend" );
1856  lineOV1218->addComponent("O 5",1213.81);
1857  lineOV1218->addComponent("O 5",1218.34);
1858  }
1859 
1860  /***********************/
1861  /****** O 6 1035 ******/
1862  /*********************/
1864  {
1865  LinSv *lineOVI1035 = linadd(0.0,1035,"Blnd",'i',"Blend" );
1866  lineOVI1035->addComponent("O 6",1031.91);
1867  lineOVI1035->addComponent("O 6",1037.62);
1868 
1869  LinSv *lineInwd1035 = linadd(0.0,1035,"Inwd",'i',"Blend" );
1870  lineInwd1035->addComponent("O 6",1031.91);
1871  lineInwd1035->addComponent("O 6",1037.62);
1872  }
1873 
1874  /* add up line intensities for certain set of lines,
1875  * must come after all lines defined */
1876  sum = PrtLineSum();
1877  /* zero out the location that will receive this information,
1878  * remember that memory not allocated until ipass >= 0 */
1879  if( LineSave.ipass > 0 )
1880  LineSave.lines[LineSave.nsum].SumLineZero();
1881  /* optional sum of certain emission lines, set with "print sum" */
1882  linadd(sum/radius.dVeffAper,0,"Stoy",'i' ,
1883  "Stoy method energy sum ");
1884 
1885  /* >>chng 06 jan 03, confirm that number of lines never changes once we have
1886  * created the labels */
1887  {
1888  static long nLineSave=-1 , ndLineSave=-1;
1889  if( LineSave.ipass == 0 )
1890  {
1891  nLineSave = LineSave.nsum;
1892  ndLineSave = LineSave.nsum;
1893  LineSave.setSortWL();
1894  }
1895  else if( LineSave.ipass > 0 )
1896  {
1897  /* this can't happen */
1898  if( nLineSave<= 0 || ndLineSave < 0 )
1899  TotalInsanity();
1900 
1901  /* now make sure that we have the same number of lines as we had previously
1902  * created labels. This would not pass if we did not add in exactly the same
1903  * number of lines on each pass */
1904  if( nLineSave != LineSave.nsum )
1905  {
1906  fprintf( ioQQQ, "DISASTER number of lines in LineSave.nsum changed between pass 0 and 1 - this is impossible\n" );
1907  fprintf( ioQQQ, "DISASTER LineSave.nsum is %li and nLineSave is %li\n",
1908  LineSave.nsum ,
1909  nLineSave);
1910  ShowMe();
1912  }
1913  if( ndLineSave != LineSave.nsum )
1914  {
1915  fprintf( ioQQQ, "DISASTER number of lines in LineSave.nsum changed between pass 0 and 1 - this is impossible\n" );
1916  fprintf( ioQQQ, "DISASTER LineSave.nsum is %li and ndLineSave is %li\n",
1917  LineSave.nsum ,
1918  ndLineSave);
1919  ShowMe();
1921  }
1922  }
1923  }
1924 
1925  if( trace.lgTrace )
1926  {
1927  fprintf( ioQQQ, " lines returns\n" );
1928  }
1929  return;
1930 }
1931 
1932 /*Drive_cdLine do the drive cdLine command */
1933 STATIC void Drive_cdLine( void )
1934 {
1935  long int j;
1936  bool lgMustPrintHeader = true;
1937  double absval , rel;
1938 
1939  DEBUG_ENTRY( "Drive_cdLine()" );
1940 
1941  for( j=1; j < LineSave.nsum; j++ )
1942  {
1943  if( cdLine( LineSave.lines[j].chALab() , LineSave.lines[j].wavelength() , &absval , &rel ) <= 0 )
1944  {
1945  /* print header if first miss */
1946  if( lgMustPrintHeader )
1947  {
1948  fprintf(ioQQQ,"n\tlabel\n");
1949  lgMustPrintHeader = false;
1950  }
1951 
1952  fprintf(ioQQQ,"%li\t%s\n", j, LineSave.lines[j].label().c_str() );
1953  }
1954  }
1955  fprintf( ioQQQ, " Thanks for checking on the cdLine routine!\n" );
1957 }
1958 
1960 {
1961  DEBUG_ENTRY( "cool_iron_Ka()" );
1962 
1963  if( trace.lgTrace )
1964  {
1965  fprintf( ioQQQ, " cool_iron_Ka called\n" );
1966  }
1967 
1968 
1969  double fela = 0.;
1970  /* recombination Ka */
1971  if( dense.lgElmtOn[ipIRON] )
1972  {
1973  /* these lines added to outlin in metdif - following must be false
1974  * fela = xLyaHeavy(nelem,nelem)*dense.xIonDense(nelem,nelem+1) */
1976  }
1977 
1978  /* >>chng 02 jan 14, add grain fe to this sum */
1979  /* total intensity of K-alpha line */
1980  /*linadd((fe.fekcld+fe.fegrain)*1.03e-8+(fe.fekhot+fela)*1.11e-8,2,"FeKa",'i' );*/
1981  if( dense.lgElmtOn[ipIRON] )
1982  {
1983  lindst((fe.fekcld+fe.fegrain)*1.03e-8+(fe.fekhot+fela)*1.11e-8,1.78f,"FeKa",
1984  iso_sp[ipH_LIKE][ipIRON].trans(ipH2p,ipH1s).ipCont(),'i',false,
1985  "total intensity of K-alpha line" );
1986  }
1987 
1988  linadd(fela*1.11e-8,2,"FeLr",'i' ,
1989  " recombination from fully stripped ion ");
1990 
1991  /* >>chng 03 aug 14, label changed from TotH to AugH to be like rest total hot iron Ka; */
1992  linadd((fe.fekhot+fela)*1.11e-8,2,"AugH",'i' ,
1993  " Auger hot iron, assumes case b for H and He-like ");
1994 
1995  linadd(fe.fekcld*1.03e-8,2,"AugC",'i',
1996  " Auger production of cold iron, less than or 17 times ionized " );
1997 
1998  linadd(fe.fegrain*1.03e-8,2,"AugG",'i' ,
1999  " grain production of cold iron ");
2000 
2001  if( trace.lgTrace )
2002  {
2003  fprintf( ioQQQ, " cool_iron_Ka returns\n" );
2004  }
2005  return;
2006 }
void setSortWL()
Definition: lines.cpp:282
int nshell(long n) const
Definition: yield.h:61
int ion(long n) const
Definition: yield.h:60
long int ipMaxExtra
Definition: thermal.h:163
double cintot
Definition: hydrogenic.h:128
double htot
Definition: thermal.h:169
t_atmdat atmdat
Definition: atmdat.cpp:6
int nelem(long n) const
Definition: yield.h:59
t_thermal thermal
Definition: thermal.cpp:6
string chIonLbl(const TransitionProxy &t)
Definition: transition.cpp:230
const int ipMAGNESIUM
Definition: cddefines.h:359
size_t size(void) const
Definition: transition.h:331
double power
Definition: thermal.h:169
qList st
Definition: iso.h:482
double te03
Definition: phycon.h:58
TransitionList UTALines("UTALines",&AnonStates)
double exp10(double x)
Definition: cddefines.h:1383
const int ipHE_LIKE
Definition: iso.h:65
double comtot
Definition: rfield.h:277
double emit_frac(const TransitionProxy &t)
Definition: transition.cpp:88
NORETURN void TotalInsanity(void)
Definition: service.cpp:1067
realnum GBarMax
Definition: thermal.h:162
realnum fekhot
Definition: fe.h:11
t_fe fe
Definition: fe.cpp:5
bool lgDrv_cdLine
Definition: trace.h:115
const int ipARGON
Definition: cddefines.h:365
t_hyperfine hyperfine
Definition: hyperfine.cpp:5
double cooling_total
Definition: hyperfine.h:62
double FreeFreeTotHeat
Definition: thermal.h:178
const realnum SMALLFLOAT
Definition: cpu.h:246
t_isoCTRL iso_ctrl
Definition: iso.cpp:9
const int NISO
Definition: cddefines.h:310
double RecomInducCool_Rate
Definition: iso.h:584
const int NRECCOEFCNO
Definition: atmdat_adfa.h:7
double cdsqte
Definition: dense.h:246
const int ipOXYGEN
Definition: cddefines.h:355
const int ipCHLORINE
Definition: cddefines.h:364
void lindst(double xEmiss, realnum wavelength, const char *chLab, long int ipnt, char chInfo, bool lgOutToo, const char *chComment)
TransitionList HFLines("HFLines",&AnonStates)
t_phycon phycon
Definition: phycon.cpp:6
t_LineSave LineSave
Definition: lines.cpp:9
FILE * ioQQQ
Definition: cddefines.cpp:7
TransitionList TauLine2("TauLine2",&AnonStates)
void lines_continuum(void)
realnum energy(long n) const
Definition: yield.h:63
long int nSpecies
Definition: taulines.cpp:22
vector< LinSv > lines
Definition: lines.h:132
const int ipSULPHUR
Definition: cddefines.h:363
void PntForLine(double wavelength, const char *chLabel, long int *ipnt)
t_dense dense
Definition: global.cpp:15
realnum AugerO3
Definition: oxy.h:31
double te005
Definition: phycon.h:58
static t_ADfA & Inst()
Definition: cddefines.h:209
bool associated() const
Definition: transition.h:54
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:11
void lines(void)
Definition: prt_lines.cpp:35
double xIonDense[LIMELM][LIMELM+1]
Definition: dense.h:135
long int iteration
Definition: cddefines.cpp:16
t_trace trace
Definition: trace.cpp:5
t_ionbal ionbal
Definition: ionbal.cpp:8
realnum fegrain
Definition: fe.h:15
bool lgdBaseSourceExists[LIMELM][LIMELM+1]
Definition: atmdat.h:452
ColliderList colliders(dense)
const int ipIRON
Definition: cddefines.h:373
long ipoint(double energy_ryd)
Definition: cont_ipoint.cpp:15
long int nLyman_max[NISO]
Definition: iso.h:352
const TransitionProxy getComponent(long ind)
Definition: lines.h:215
#define POW2
Definition: cddefines.h:983
double energy(const genericState &gs)
const int ipH1s
Definition: iso.h:29
#define STATIC
Definition: cddefines.h:118
bool lgTrace
Definition: trace.h:12
void lines_hydro(void)
EmissionList::reference Emis() const
Definition: transition.h:447
LinSv * linadd(double xEmiss, realnum wavelength, const char *chLab, char chInfo, const char *chComment)
multi_arr< int, 3 > ipExtraLymanLines
Definition: taulines.cpp:24
void iso_satellite_update(long nelem)
t_mole_local mole
Definition: mole.cpp:8
t_rfield rfield
Definition: rfield.cpp:9
void lines_helium(void)
double HCharExcRecTo_N0_2D
Definition: atmdat.h:307
long & ipCont() const
Definition: transition.h:489
realnum s7325
Definition: oxy.h:34
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
int ipoint(long n) const
Definition: yield.h:74
qList::iterator Hi() const
Definition: transition.h:435
t_hydro hydro
Definition: hydrogenic.cpp:5
double cmheat
Definition: rfield.h:277
#define cdEXIT(FAIL)
Definition: cddefines.h:484
const int ipNEON
Definition: cddefines.h:357
double totcol
Definition: thermal.h:130
int nlines() const
Definition: yield.h:76
realnum wlAirVac(double wlAir)
sys_float safe_div(sys_float x, sys_float y, sys_float res_0by0)
Definition: cddefines.h:1015
realnum fracin
Definition: rt.h:174
long nWindLine
Definition: cdinit.cpp:19
static bool lgMustPrintHeader
Definition: save_line.cpp:264
t_radius radius
Definition: radius.cpp:5
void lines_general(void)
double heating(long nelem, long ion)
Definition: thermal.h:186
double **** PhotoRate_Shell
Definition: ionbal.h:109
bool lgElmtOn[LIMELM]
Definition: dense.h:160
TransitionProxy trans(const long ipHi, const long ipLo)
Definition: iso.h:473
const int ipSILICON
Definition: cddefines.h:361
const int ipH2p
Definition: iso.h:31
double GetLineRec(long int ip, long int lWl)
Definition: transition.cpp:107
void PutLine(const TransitionProxy &t, const char *chComment, const char *chLabelTemp, const ExtraInten &extra)
Definition: transition.cpp:315
void lines_molecules(void)
long int nComment
Definition: lines.h:90
const int ipALUMINIUM
Definition: cddefines.h:360
const int ipCALCIUM
Definition: cddefines.h:367
const int ipNITROGEN
Definition: cddefines.h:354
long int cdLine(const char *chLabel, realnum wavelength, double *relint, double *absint)
Definition: cddrive.cpp:1069
const int ipH_LIKE
Definition: iso.h:64
vector< vector< TransitionList > > ExtraLymanLines
Definition: taulines.cpp:25
const int LIMELM
Definition: cddefines.h:307
realnum RecCoefCNO[4][NRECCOEFCNO]
Definition: lines.h:126
CollisionProxy Coll() const
Definition: transition.h:463
double te40
Definition: phycon.h:58
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
void addComponent(const char *species, const double wavelength)
Definition: lines.cpp:193
const int ipHELIUM
Definition: cddefines.h:349
double te10
Definition: phycon.h:58
realnum cooling_max
Definition: hyperfine.h:65
vector< species > dBaseSpecies
Definition: taulines.cpp:15
double eden
Definition: dense.h:201
t_oxy oxy
Definition: oxy.cpp:5
#define MAX2(a, b)
Definition: cddefines.h:828
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
double te70
Definition: phycon.h:58
double dissoc_rate(const char chSpecies[]) const
double & xObsIntensity() const
Definition: emission.h:533
STATIC void Drive_cdLine(void)
Definition: prt_lines.cpp:1933
realnum d5007r
Definition: oxy.h:19
sys_float SDIV(sys_float x)
Definition: cddefines.h:1006
double alogte
Definition: phycon.h:92
double pow(double x, int i)
Definition: cddefines.h:782
const int ipCARBON
Definition: cddefines.h:353
#define S(I_, J_)
realnum s3727
Definition: oxy.h:34
void SpeciesBandsAccum()
void SpeciesPseudoContAccum()
long int nsum
Definition: lines.h:87
void rec_lines(double t, realnum r[][NRECCOEFCNO])
double sqrte
Definition: phycon.h:58
realnum yield(long n) const
Definition: yield.h:65
#define fixit(a)
Definition: cddefines.h:416
double PrtLineSum(void)
Definition: prt_linesum.cpp:72
void ShowMe(void)
Definition: service.cpp:205
vector< TransitionList > dBaseTrans
Definition: taulines.cpp:18
double te
Definition: phycon.h:21
realnum fekcld
Definition: fe.h:11
const int ipHYDROGEN
Definition: cddefines.h:348
double te04
Definition: phycon.h:58
STATIC void lines_iron_Ka()
Definition: prt_lines.cpp:1959
void makeBlend(const char *species, const double wavelength, const double width)
Definition: lines.cpp:209
realnum & Aul() const
Definition: emission.h:668
Definition: lines.h:157
long int numLevels_local
Definition: iso.h:529
long int nCollapsed_local
Definition: iso.h:519
double te30
Definition: phycon.h:58
double ColUL(const ColliderList &colls) const
Definition: collision.h:106
long int ipass
Definition: lines.h:96
EmissionList & Emis()
Definition: transition.h:363
double dVeffAper
Definition: radius.h:92
const int ipSODIUM
Definition: cddefines.h:358
double ctot
Definition: thermal.h:130
void lines_grains(void)
long int StuffComment(const char *chComment)
Definition: prt_final.cpp:1943
t_rt rt
Definition: rt.cpp:5