cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
opacity_createall.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 /*OpacityCreateAll compute initial set of opacities for all species */
4 /*OpacityCreate1Element generate ionic subshell opacities by calling t_ADfA::Inst().phfit */
5 /*opacity_more_memory allocate more memory for opacity stack */
6 /*Opacity_iso_photo_cs returns photoionization cross section for isoelectronic sequences */
7 /*hmiopc derive total H- H minus opacity */
8 /*rayleh compute Rayleigh scattering cross section for Lya */
9 /*OpacityValenceRescale routine to rescale non-OP valence shell cross sections */
10 /******************************************************************************
11  *NB NB NB NB NB NB NB NB NB NB NB NB NB NB
12  * everything set here must be written to the opacity store files
13  *
14  ****************************************************************************** */
15 #include "cddefines.h"
16 #include "dense.h"
17 #include "continuum.h"
18 #include "iso.h"
19 #include "hydrogenic.h"
20 #include "oxy.h"
21 #include "trace.h"
22 #include "heavy.h"
23 #include "rfield.h"
24 #include "hmi.h"
25 #include "atmdat_adfa.h"
26 #include "save.h"
27 #include "grains.h"
28 #include "hydro_bauman.h"
29 #include "opacity.h"
30 #include "helike_recom.h"
31 #include "h2.h"
32 #include "ipoint.h"
33 #include "mole.h"
34 #include "freebound.h"
35 #include "prt.h"
36 
37 /* limit to number of opacity cells available in the opacity stack*/
38 static long int ndimOpacityStack = 3900000L;
39 
40 /*OpacityCreate1Element generate opacities for entire element by calling t_ADfA::Inst().phfit */
41 STATIC void OpacityCreate1Element(long int nelem);
42 
43 /*opacity_more_memory allocate more memory for opacity stack */
44 STATIC void opacity_more_memory(void);
45 
46 /*hmiopc derive total H- H minus opacity */
47 STATIC double hmiopc(double freq);
48 
49 /*rayleh compute Rayleigh scattering cross section for Lya */
50 STATIC double rayleh(double ener);
51 
52 /*Opacity_iso_photo_cs returns photoionization cross section for isoelectronic sequences */
53 STATIC double Opacity_iso_photo_cs( double energy , long ipISO , long nelem , long index );
54 
55 /*OpacityCreateReilMan generate photoionization cross sections from Reilman and Manson points */
56 STATIC void OpacityCreateReilMan(long int low,
57  long int ihi,
58  const realnum energ[],
59  const realnum cross[],
60  long int ncr,
61  long int *ipop,
62  const char *chLabl);
63 
64 static bool lgRealloc = false;
65 
66 /*OpacityCreatePowerLaw generate array of cross sections using a simple power law fit */
68  /* lower energy limit on continuum mesh */
69  long int ilo,
70  /* upper energy limit on continuum mesh */
71  long int ihi,
72  /* threshold cross section */
73  double cross,
74  /* power law index */
75  double s,
76  /* pointer to opacity offset where this starts */
77  long int *ip);
78 
79 /*ofit compute cross sections for all shells of atomic oxygen */
80 STATIC void ofit(double e,
81  realnum opart[]);
82 
83 /*OpacityValenceRescale routine to rescale non-OP valence shell cross sections for atom */
85  /* element number on C scale */
86  long int nelem ,
87  /* scale factor, must be >= 0. */
88  double scale )
89 {
90 
91  long int ion , nshell , low , ihi , ipop , ip;
92 
93  DEBUG_ENTRY( "OpacityValenceRescale()" );
94 
95  /* return if element is not turned on
96  * >>chng 05 oct 19, this had not been done, so low in the opacity offset below was
97  * not set, and opacity index was negative - only problem when K turned off */
98  if( !dense.lgElmtOn[nelem] )
99  {
100  return;
101  }
102 
103  /* scale better be >= 0. */
104  ASSERT( scale >= 0. );
105 
106  ion = 0;
107  /* this is valence shell on C scale */
108  nshell = Heavy.nsShells[nelem][ion] - 1;
109 
110  /* set lower and upper limits to this range */
111  low = opac.ipElement[nelem][ion][nshell][0];
112  ihi = opac.ipElement[nelem][ion][nshell][1];
113  ipop = opac.ipElement[nelem][ion][nshell][2];
114 
115  /* loop over energy range of this shell */
116  for( ip=low-1; ip < ihi; ip++ )
117  {
118  opac.OpacStack[ip-low+ipop] *= scale;
119  }
120  return;
121 }
122 
124 {
125  long int i,
126  ipISO ,
127  need ,
128  nelem;
129 
130  realnum opart[7];
131 
132  double crs,
133  dx,
134  eps,
135  thres,
136  x;
137 
138  /* >>chng 02 may 29, change to lgOpacMalloced */
139  /* remember whether opacities have ever been evaluated in this coreload
140  static bool lgOpEval = false; */
141 
142  DEBUG_ENTRY( "OpacityCreateAll()" );
143 
144  /* H2+ h2plus h2+ */
145 
146  /* make and print dust opacities
147  * fill in dstab and dstsc, totals, zero if no dust
148  * may be different if different grains are turned on */
149  GrainsInit();
150 
151  /* flag lgOpacMalloced says whether opacity stack has been generated
152  * only do this one time per core load */
153  /* >>chng 02 may 29, from lgOpEval to lgOpacMalloced */
154  if( lgOpacMalloced )
155  {
156  /* this is not the first time code called */
157  if( trace.lgTrace )
158  {
159  fprintf( ioQQQ, " OpacityCreateAll called but NOT evaluated since already done.\n" );
160  }
161  return;
162  }
163 
164  /* create the space for the opacity stack */
165  opac.OpacStack = (double*)MALLOC((size_t)ndimOpacityStack*sizeof(double));
166  lgOpacMalloced = true;
167 
168  if( trace.lgTrace )
169  {
170  fprintf( ioQQQ, " OpacityCreateAll called, evaluating.\n" );
171  }
172 
173  /* zero out opac since this array sometimes addressed before OpacityAddTotal called */
174  for( i=0; i < rfield.nflux_with_check; i++ )
175  {
176  opac.opacity_abs[i] = 0.;
177  }
178 
179  /* nOpacTot is number of opacity cells in OpacStack filled so far by opacity generating routines */
180  opac.nOpacTot = 0;
181 
182  /* photoionization of h, he-like iso electronic sequences */
183  for( ipISO=ipH_LIKE; ipISO<=ipHE_LIKE; ++ipISO )
184  {
185  for( nelem=ipISO; nelem < LIMELM; nelem++ )
186  {
187  iso_sp[ipISO][nelem].HighestLevelOpacStack.resize(0);
188  if( dense.lgElmtOn[nelem] )
189  {
190  long int nupper;
191 
192  /* this is the opacity offset in the general purpose pointer array */
193  /* indices are type, shell. ion, element, so this is the inner shell,
194  * NB - this works for H and He, but the second index should be 1 for Li */
195  opac.ipElement[nelem][nelem-ipISO][0][2] = opac.nOpacTot + 1;
196 
197  fixit("opacities really need to be owned by states or species");
198  // and stored in STL containers so we don't have to mess
199  // with remembering what the upper and lower limits are
200 
201  // all iso states go to high-energy limit of code
202  nupper = rfield.nflux_with_check;
203  for( long index=0; index < iso_sp[ipISO][nelem].numLevels_max; index++ )
204  {
205  /* this is array index to the opacity offset */
206  iso_sp[ipISO][nelem].fb[index].ipOpac = opac.nOpacTot + 1;
207 
208  /* first make sure that first energy point is at least near the limit */
209  /* >>chng 01 sep 23, increased factor form 0.98 to 0.94, needed since cells now go
210  * so far into radio, where resolution is poor */
211  ASSERT( rfield.anu(iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon-1) > 0.94f *
212  iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd );
213 
214  /* number of cells we will need to do this level */
215  need = nupper - iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon + 1;
216  ASSERT( need > 0 );
217 
218  if( opac.nOpacTot + need > ndimOpacityStack )
220 
221  for( i=iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon-1; i < nupper; i++ )
222  {
223  double crs =
224  Opacity_iso_photo_cs( rfield.anu(i) , ipISO , nelem , index );
225  opac.OpacStack[i-iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon+iso_sp[ipISO][nelem].fb[index].ipOpac] = crs;
226  if( index==iso_sp[ipISO][nelem].numLevels_max-1 )
227  iso_sp[ipISO][nelem].HighestLevelOpacStack.push_back( crs );
228  }
229 
230  opac.nOpacTot += need;
231  }
232  }
233  }
234  }
235 
236  /* H2 continuum dissociation opacity */
237  for( diatom_iter diatom = diatoms.begin(); diatom != diatoms.end(); ++diatom )
238  {
239  if( (*diatom)->lgEnabled && mole_global.lgStancil )
240  {
241  for( vector< diss_tran >::iterator tran = (*diatom)->Diss_Trans.begin(); tran != (*diatom)->Diss_Trans.end(); ++tran )
242  {
243  /* choose to integrate from 0.1 to 4 Ryd, data only extends from 0.7 to ~2 Ryd */
244  long lower_limit = ipoint(tran->energies[0]);
245  long upper_limit = ipoint(tran->energies.back());
246  upper_limit = MIN2( upper_limit, rfield.nflux-1 );
247  long ipCont_Diss = opac.nOpacTot + 1;
248  long num_points = 0;
249 
250  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
251  if( opac.nOpacTot + upper_limit - lower_limit + 1 > ndimOpacityStack )
253 
254  for(i = lower_limit; i <= upper_limit; ++i)
255  {
256  opac.OpacStack[ipCont_Diss + num_points - 1] =
257  MolDissocCrossSection( *tran, rfield.anu(i) );
258  ++num_points;
259  }
260  opac.nOpacTot += num_points;
261  }
262  }
263  }
264 
265  /* This check will get us through Klein-Nishina below. */
268 
269  /* Lyman alpha damping wings - Rayleigh scattering */
270  opac.ipRayScat = opac.nOpacTot + 1;
271  for( i=0; i < iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon; i++ )
272  {
274  }
275  opac.nOpacTot += iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon;
276 
277  /* ==============================================================
278  * this block of code defines the electron scattering cross section
279  * for all energies */
280 
281  /* assume Thomson scattering up to ipCKshell, 20.6 Ryd=0.3 keV */
282  opac.iopcom = opac.nOpacTot + 1;
283  for( i=0; i < opac.ipCKshell; i++ )
284  {
285  opac.OpacStack[i-1+opac.iopcom] = SIGMA_THOMSON;
286  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
287  rfield.anu(i)*EVRYD , opac.OpacStack[i-1+opac.iopcom] );*/
288  }
289 
290  /* Klein-Nishina from eqn 7.5,
291  * >>refer Klein-Nishina cs Rybicki and Lightman */
292  for( i=opac.ipCKshell; i < rfield.nflux_with_check; i++ )
293  {
294  dx = rfield.anu(i)/3.7573e4;
295 
296  opac.OpacStack[i-1+opac.iopcom] = SIGMA_THOMSON*3.e0/4.e0*((1.e0 +
297  dx)/POW3(dx)*(2.e0*dx*(1.e0 + dx)/(1.e0 + 2.e0*dx) - log(1.e0+
298  2.e0*dx)) + 1.e0/2.e0/dx*log(1.e0+2.e0*dx) - (1.e0 + 3.e0*
299  dx)/POW3(1.e0 + 2.e0*dx));
300  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
301  rfield.anu(i)*EVRYD , opac.OpacStack[i-1+opac.iopcom] );*/
302  }
304 
305  /* ============================================================== */
306 
307  /* This check will get us through "H- hminus H minus bound-free opacity" below. */
308  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
309  if( opac.nOpacTot + 3*rfield.nflux_with_check - opac.ippr + iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon - hmi.iphmin + 2 > ndimOpacityStack )
311 
312  /* pair production */
313  opac.ioppr = opac.nOpacTot + 1;
314  for( i=opac.ippr-1; i < rfield.nflux_with_check; i++ )
315  {
316  /* pair production heating rate for unscreened H + He
317  * fit to figure 41 of Experimental Nuclear Physics,
318  * Vol1, E.Segre, ed */
319 
320  x = rfield.anu(i)/7.512e4*2.;
321 
322  opac.OpacStack[i-opac.ippr+opac.ioppr] = 5.793e-28*
323  POW2((-0.46737118 + x*(0.349255416 + x*0.002179893))/(1. +
324  x*(0.130471301 + x*0.000524906)));
325  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
326  rfield.anu(i)*EVRYD , opac.OpacStack[i-opac.ippr+opac.ioppr] );*/
327  }
329 
330  /* brems (free-free) opacity */
331  opac.ipBrems = opac.nOpacTot + 1;
332 
333  for( i=0; i < rfield.nflux_with_check; i++ )
334  {
335  /* Inflate precomputed opacity value by 30 dex to avoid underflows */
336  /* free free opacity needs g(ff)*(1-exp(hn/kT))/SQRT(T)*1E-30 */
337  opac.OpacStack[i-1+opac.ipBrems] = FREE_FREE_ABS * 1e30 / POW3(rfield.anu(i));
338  }
340 
341  opac.iphmra = opac.nOpacTot + 1;
342  for( i=0; i < rfield.nflux_with_check; i++ )
343  {
344  /* following is ratio of h minus to neut h bremss opacity */
345  opac.OpacStack[i-1+opac.iphmra] = 0.1175*rfield.anusqrt(i);
346  }
348 
349  opac.iphmop = opac.nOpacTot + 1;
350  for( i=hmi.iphmin-1; i < iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon; i++ )
351  {
352  /* H- hminus H minus bound-free opacity */
354  hmiopc(rfield.anu(i));
355  }
356  opac.nOpacTot += iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon - hmi.iphmin + 1;
357 
358  /* ============================================================== */
359 
360  /* This check will get us through "H2 photoionization cross section" below. */
361  /* >>chng 07 oct 10, by Ryan. Added this check for allotted memory. */
362  for( diatom_iter diatom = diatoms.begin(); diatom != diatoms.end(); ++diatom )
363  {
364  if( opac.nOpacTot + rfield.nflux_with_check - (*diatom)->ip_photo_opac_thresh + 1 > ndimOpacityStack )
366 
367  (*diatom)->ip_photo_opac_offset = opac.nOpacTot + 1;
368  opac.nOpacTot += (*diatom)->OpacityCreate( opac.OpacStack );
369  }
370 
371  /* H2+ H2P h2plus photoabsorption */
372  {
373  /* fits to cross section for photo dist of H_2^+ */
374  const long nCSH2P = 5;
375  static const realnum enh2p[nCSH2P]={6.75f,8.68f,10.54f,12.46f,14.28f};
376  static const realnum csh2p[nCSH2P]={0.24f, 2.5f, 7.1f, 6.0f, 2.7f};
377  if( opac.nOpacTot + opac.ih2pnt[1] - opac.ih2pnt[0] + 1 > ndimOpacityStack )
379  /* >>refer H2+ photodissoc Buckingham, R.A., Reid, S., & Spence, R. 1952, MNRAS 112, 382, 0 K temp */
380  OpacityCreateReilMan(opac.ih2pnt[0],opac.ih2pnt[1],enh2p,csh2p,nCSH2P,&opac.ih2pof, "H2+ ");
381 
382  // Now do an excited superstate of H2+
383  const long nCSH2P_ex = 9;
384  // These opacities are a rough approximation to figure 4 of the following reference, for v=9 of H2+:
385  /* >>refer H2+ photodissoc Dunn, G. H. 1968, Phys.Rev. 172, 1 */
386  static const realnum enh2p_ex[nCSH2P_ex]={0.69f,0.83f,0.95f,1.03f,1.24f,1.38f,1.77f,2.48f,14.28f};
387  static const realnum csh2p_ex[nCSH2P_ex]={1e-5f,1e-4f,0.01f,0.08f, 2.0f,10.0f,20.0f, 8.0f, 1.0f};
390  OpacityCreateReilMan(opac.ih2pnt_ex[0],opac.ih2pnt_ex[1],enh2p_ex,csh2p_ex,nCSH2P_ex,&opac.ih2pof_ex, "H2+*");
391  }
392 
393  /* This check will get us through "HeI singlets neutral helium ground" below. */
394  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
395  if( opac.nOpacTot + rfield.nflux_with_check - iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon + 1 > ndimOpacityStack )
397 
398  /* HeI singlets neutral helium ground */
399  opac.iophe1[0] = opac.nOpacTot + 1;
400  opac.ipElement[ipHELIUM][0][0][2] = opac.iophe1[0];
401  for( i=iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon-1; i < rfield.nflux_with_check; i++ )
402  {
403  crs = t_ADfA::Inst().phfit(2,2,1,rfield.anu(i)*EVRYD);
404  opac.OpacStack[i-iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon+opac.iophe1[0]] =
405  crs*1e-18;
406  }
407  opac.nOpacTot += rfield.nflux_with_check - iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon + 1;
408 
409  /* these are opacity offset points that would be defined in OpacityCreate1Element,
410  * but this routine will not be called for H and He
411  * generate all heavy element opacities, everything heavier than He,
412  * nelem is on the C scale, so Li is 2 */
413  /*>>chng 99 jan 27, do not reevaluate hydrogenic opacity below */
414  for( nelem=2; nelem < LIMELM; nelem++ )
415  {
416  if( dense.lgElmtOn[nelem] )
417  {
418  OpacityCreate1Element(nelem);
419  }
420  }
421 
422  /* option to rescale atoms of some elements that were not done by opacity project
423  * the valence shell - two arguments - element number on C scale, and scale factor */
424  /*>>chng 05 sep 26, fudge factor to get atomic K fraction along well defined line of sight
425  * to be observed value - this is ratio of cross sections, actual value is very uncertain since
426  * differences betweeen Verner & opacity project are huge */
428 
429  /* now add on some special cases, where exicted states, etc, come in */
430  /* Nitrogen
431  * >>refer n1 photo Henry, R., ApJ 161, 1153.
432  * photoionization of excited level of N+ */
433  OpacityCreatePowerLaw(opac.in1[0],opac.in1[1],9e-18,1.75,&opac.in1[2]);
434 
435  /* atomic Oxygen
436  * only do this if 1996 Verner results are used */
438  {
439  /* This check will get us through this loop. */
440  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
441  if( opac.nOpacTot + opac.ipElement[ipOXYGEN][0][2][1] - opac.ipElement[ipOXYGEN][0][2][0] + 1 > ndimOpacityStack )
443 
444  /* integrate over energy range of the valence shell of atomic oxygen*/
445  for( i=opac.ipElement[ipOXYGEN][0][2][0]-1; i < opac.ipElement[ipOXYGEN][0][2][1]; i++ )
446  {
447  /* call special routine to evaluate partial cross section for OI shells */
448  eps = rfield.anu(i)*EVRYD;
449  ofit(eps,opart);
450 
451  /* this will be total cs of all processes leaving shell 3 */
452  crs = opart[0];
453  for( long n=1; n < 6; n++ )
454  {
455  /* add up table of cross sections */
456  crs += opart[n];
457  }
458  /* convert to cgs and overwrite cross sections set by OpacityCreate1Element */
459  crs *= 1e-18;
460  opac.OpacStack[i-opac.ipElement[ipOXYGEN][0][2][0]+opac.ipElement[ipOXYGEN][0][2][2]] = crs;
461  }
462  /* >>chng 02 may 09 - this was a significant error */
463  /* >>chng 02 may 08, by Ryan. This loop did not update total slots filled. */
464  opac.nOpacTot += opac.ipElement[ipOXYGEN][0][2][1] - opac.ipElement[ipOXYGEN][0][2][0] + 1;
465  }
466 
467  /* Henry nubmers for 1S excit state of OI, OP data very sparse */
468  OpacityCreatePowerLaw(opac.ipo1exc[0],opac.ipo1exc[1],4.64e-18,0.,&opac.ipo1exc[2]);
469 
470  /* photoionization of excited level of O2+ 1D making 5007
471  * fit to TopBase Opacity Project cs */
472  OpacityCreatePowerLaw(opac.ipo3exc[0],opac.ipo3exc[1],3.8e-18,0.,&opac.ipo3exc[2]);
473 
474  /* photoionization of excited level of O2+ 1S making 4363 */
475  OpacityCreatePowerLaw(opac.ipo3exc3[0],opac.ipo3exc3[1],5.5e-18,0.01,
476  &opac.ipo3exc3[2]);
477 
478  /* This check will get us through the next two steps. */
479  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
480  if( opac.nOpacTot + iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon - oxy.i2d + 1
481  + iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon - opac.ipmgex + 1 > ndimOpacityStack )
483 
484  /* photoionization to excited states of O+ */
485  opac.iopo2d = opac.nOpacTot + 1;
486  thres = rfield.anu(oxy.i2d-1);
487  for( i=oxy.i2d-1; i < iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon; i++ )
488  {
489  crs = 3.85e-18*(4.4*powpq(rfield.anu(i)/thres,-3,2) - 3.38*
490  powpq(rfield.anu(i)/thres,-5,2));
491 
492  opac.OpacStack[i-oxy.i2d+opac.iopo2d] = crs;
493  }
494  opac.nOpacTot += iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon - oxy.i2d + 1;
495 
496  /* magnesium
497  * photoionization of excited level of Mg+
498  * fit to opacity project data Dima got */
499  opac.ipOpMgEx = opac.nOpacTot + 1;
500  for( i=opac.ipmgex-1; i < iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon; i++ )
501  {
503  (0.2602325880970085 +
504  445.8558249365131*exp(-rfield.anu(i)/0.1009243952792674))*
505  1e-18;
506  }
507  opac.nOpacTot += iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon - opac.ipmgex + 1;
508 
510 
511  /* Calcium
512  * excited states of Ca+ */
514 
515  if( trace.lgTrace )
516  {
517  fprintf( ioQQQ,
518  " OpacityCreateAll return OK, number of opacity cells used in OPSC= %ld and OPSV is dimensioned %ld\n",
520  }
521 
522  /* option to compile opacities into file for later use
523  * this is executed if the 'compile opacities' command is entered */
524  if( opac.lgCompileOpac )
525  {
526  fprintf( ioQQQ, "The COMPILE OPACITIES command is currently not supported\n" );
528  }
529 
530  if( lgRealloc && prt.lgPrintTime )
531  fprintf(ioQQQ,
532  " Please consider revising ndimOpacityStack in OpacityCreateAll, a total of %li cells were needed.\n\n" , opac.nOpacTot);
533  return;
534 }
535 /*OpacityCreatePowerLaw generate array of cross sections using a simple power law fit */
537  /* lower energy limit on continuum mesh */
538  long int ilo,
539  /* upper energy limit on continuum mesh */
540  long int ihi,
541  /* threshold cross section */
542  double cross,
543  /* power law index */
544  double s,
545  /* pointer to opacity offset where this starts */
546  long int *ip)
547 {
548  long int i;
549  double thres;
550 
551  DEBUG_ENTRY( "OpacityCreatePowerLaw()" );
552 
553  /* non-positive cross section is unphysical */
554  ASSERT( cross > 0. );
555 
556  /* place in the opacity stack where we will stuff cross sections */
557  *ip = opac.nOpacTot + 1;
558  ASSERT( *ip > 0 );
559  ASSERT( ilo > 0 );
560  thres = rfield.anu(ilo-1);
561 
562  if( opac.nOpacTot + ihi - ilo + 1 > ndimOpacityStack )
564 
565  for( i=ilo-1; i < ihi; i++ )
566  {
567  opac.OpacStack[i-ilo+*ip] = cross*pow(rfield.anu(i)/thres,-s);
568  }
569 
570  opac.nOpacTot += ihi - ilo + 1;
571  return;
572 }
573 
574 /*OpacityCreateReilMan generate photoionization cross sections from Reilman and Manson points */
575 STATIC void OpacityCreateReilMan(long int low,
576  long int ihi,
577  const realnum energ[],
578  const realnum cross[],
579  long int ncr,
580  long int *ipop,
581  const char *chLabl)
582 {
583  long int i,
584  ics,
585  j;
586 
587  const int NOP = 100;
588  realnum cs[NOP],
589  en[NOP],
590  slope;
591 
592  DEBUG_ENTRY( "OpacityCreateReilMan()" );
593 
594  /* this is the opacity entering routine designed for
595  * the Reilman and Manson tables. It works with incident
596  * photon energy (entered in eV) and cross sections in megabarns
597  * */
598  *ipop = opac.nOpacTot + 1;
599  ASSERT( *ipop > 0 );
600 
601  if( ncr > NOP )
602  {
603  fprintf( ioQQQ, " Too many opacities were entered into OpacityCreateReilMan. Increase the value of NOP.\n" );
604  fprintf( ioQQQ, " chLabl was %4.4s\n", chLabl );
606  }
607  if( ncr < 2 )
608  {
609  fprintf( ioQQQ, " Too few opacities were entered into OpacityCreateReilMan.\n" );
610  fprintf( ioQQQ, " chLabl was %4.4s\n", chLabl );
612  }
613 
614  /* the array CROSS has ordered pairs of elements.
615  * the first is the energy in eV (not Ryd)
616  * and the second is the cross section in megabarns */
617  for( i=0; i < ncr; i++ )
618  {
619  en[i] = energ[i]/13.6f;
620  cs[i] = cross[i]*1e-18f;
621  }
622 
623  ASSERT( low>0 );
624  if( en[0] > rfield.anu(low-1) )
625  {
626  fprintf( ioQQQ,
627  " OpacityCreateReilMan: The entered opacity energy bandwidth is not large enough (low fail).\n" );
628  fprintf( ioQQQ,
629  " The desired energy (Ryd) was%12.5eeV and the lowest entered in the array was%12.5e eV\n",
630  rfield.anu(low-1)*EVRYD, en[0]*EVRYD );
631 
632  fprintf( ioQQQ, " chLabl was %4.4s\n", chLabl );
633  fprintf( ioQQQ, " The original energy (eV) and cross section (mb) arrays follow:\n" );
634  fprintf( ioQQQ, " " );
635 
636  for( i=0; i < ncr; i++ )
637  {
638  fprintf( ioQQQ, "%11.4e", energ[i] );
639  fprintf( ioQQQ, "%11.4e", cross[i] );
640  }
641 
642  fprintf( ioQQQ, "\n" );
644  }
645 
646  slope = (cs[1] - cs[0])/(en[1] - en[0]);
647  ics = 1;
648 
649  if( opac.nOpacTot + ihi - low + 1 > ndimOpacityStack )
651 
652  /* now fill in the opacities using linear interpolation */
653  for( i=low-1; i < ihi; i++ )
654  {
655  if( rfield.anu(i) > en[ics-1] && rfield.anu(i) <= en[ics] )
656  {
657  opac.OpacStack[i-low+*ipop] = cs[ics-1] + slope*(rfield.anu(i) -
658  en[ics-1]);
659  }
660 
661  else
662  {
663  ics += 1;
664  if( ics + 1 > ncr )
665  {
666  fprintf( ioQQQ, " OpacityCreateReilMan: The entered opacity energy bandwidth is not large enough (high fail).\n" );
667  fprintf( ioQQQ, " The entered energy was %10.2eeV and the highest in the array was %10.2eeV\n",
668  rfield.anu(i)*13.6, en[ncr-1]*13.6 );
669  fprintf( ioQQQ, " chLabl was %4.4s\n", chLabl
670  );
671  fprintf( ioQQQ, " The lowest energy enterd in the array was%10.2e eV\n",
672  en[0]*13.65 );
673  fprintf( ioQQQ, " The highest energy ever needed would be%10.2eeV\n",
674  rfield.anu(ihi-1)*13.6 );
675  fprintf( ioQQQ, " The lowest energy needed was%10.2eeV\n",
676  rfield.anu(low-1)*13.6 );
678  }
679 
680  slope = (cs[ics] - cs[ics-1])/(en[ics] - en[ics-1]);
681  if( rfield.anu(i) > en[ics-1] && rfield.anu(i) <= en[ics] )
682  {
683  opac.OpacStack[i-low+*ipop] = cs[ics-1] + slope*(rfield.anu(i) -
684  en[ics-1]);
685  }
686  else
687  {
688  ASSERT( i > 0);
689  fprintf( ioQQQ, " Internal logical error in OpacityCreateReilMan.\n" );
690  fprintf( ioQQQ, " The desired energy (%10.2eeV), I=%5ld, is not within the next energy bound%10.2e%10.2e\n",
691  rfield.anu(i)*13.6, i, en[ics-1], en[ics] );
692 
693  fprintf( ioQQQ, " The previous energy (eV) was%10.2e\n",
694  rfield.anu(i-1)*13.6 );
695 
696  fprintf( ioQQQ, " Here comes the energy array. ICS=%4ld\n",
697  ics );
698 
699  for( j=0; j < ncr; j++ )
700  {
701  fprintf( ioQQQ, "%10.2e", en[j] );
702  }
703  fprintf( ioQQQ, "\n" );
704 
705  fprintf( ioQQQ, " chLabl was %4.4s\n", chLabl );
707  }
708  }
709  }
710  /* >>chng 02 may 09, this was a significant logcal error */
711  /* >>chng 02 may 08, by Ryan. This routine did not update the total slots filled. */
712  opac.nOpacTot += ihi - low + 1;
713  return;
714 }
715 
716 
717 /*ofit compute cross sections for all shells of atomic oxygen */
718 STATIC void ofit(double e,
719  realnum opart[])
720 {
721  static const double y[7][5] = {
722  {8.915,3995.,3.242,10.44,0.0},
723  {11.31,1498.,5.27,7.319,0.0},
724  {10.5,1.059e05,1.263,13.04,0.0},
725  {19.49,48.47,8.806,5.983,0.0},
726  {50.,4.244e04,0.1913,7.012,4.454e-02},
727  {110.5,0.1588,148.3,-3.38,3.589e-02},
728  {177.4,32.37,381.2,1.083,0.0}
729  };
730  static const double eth[7]={13.62,16.94,18.79,28.48,50.,110.5,538.};
731  static const long l[7]={1,1,1,0,1,1,0};
732 
733  DEBUG_ENTRY( "ofit()" );
734  /*compute cross sections for all shells of atomic oxygen
735  * Photoionization of OI
736  * Input parameter: e - photon energy, eV
737  * Output parameters: otot - total photoionization cross section, Mb
738  * opart(1) - 2p-shell photoionization, goes to 4So
739  * opart(2) - 2p-shell photoionization, goes to 2Do
740  * opart(3) - 2p-shell photoionization, goes to 2Po
741  * opart(4) - 2s-shell photoionization
742  * opart(5) - double photoionization, goes to O++
743  * opart(6) - triple photoionization, goes to O+++
744  * opart(7) - 1s-shell photoionization */
745 
746  for( int i=0; i < 7; i++ )
747  {
748  opart[i] = 0.0;
749  }
750 
751  for( int i=0; i < 7; i++ )
752  {
753  if( e >= eth[i] )
754  {
755  // this assert is trivially true, but it helps PGCC
756  ASSERT( i < 7 );
757  double q = 5.5 - 0.5*y[i][3] + l[i];
758 
759  double x = e/y[i][0];
760 
761  opart[i] = (realnum)(y[i][1]*(POW2(x - 1.0) + POW2(y[i][4]))/
762  pow(x,q)/pow(1.0 + sqrt(x/y[i][2]),y[i][3]));
763 
764  }
765  }
766  return;
767 }
768 
769 /******************************************************************************/
770 
771 /*OpacityCreate1Element generate ionic subshell opacities by calling t_ADfA::Inst().phfit */
773  /* atomic number on the C scale, lowest ever called will be Li=2 */
774  long int nelem)
775 {
776  long int ihi,
777  ip,
778  ipop,
779  limit,
780  low,
781  need,
782  nelec,
783  ion,
784  nshell;
785  double cs;
786  double energy;
787 
788  DEBUG_ENTRY( "OpacityCreate1Element()" );
789 
790  /* confirm range of validity of atomic number, Li=2 should be the lightest */
791  ASSERT( nelem >= 2 );
792  ASSERT( nelem < LIMELM );
793 
794  /*>>chng 99 jan 27, no longer redo hydrogenic opacity here */
795  /* for( ion=0; ion <= nelem; ion++ )*/
796  for( ion=0; ion < nelem; ion++ )
797  {
798 
799  /* will be used for a sanity check on number of hits in a cell*/
800  for( ip=0; ip < rfield.nflux_with_check; ip++ )
801  {
802  opac.opacity_abs[ip] = 0.;
803  }
804 
805  /* number of bound electrons */
806  nelec = nelem+1 - ion;
807 
808  /* loop over all shells, from innermost K shell to valence */
809  for( nshell=0; nshell < Heavy.nsShells[nelem][ion]; nshell++ )
810  {
811  /* this is array index for start of this shell within large opacity stack */
812  opac.ipElement[nelem][ion][nshell][2] = opac.nOpacTot + 1;
813 
814  /* this is continuum upper limit to array index for energy range of this shell */
815  limit = opac.ipElement[nelem][ion][nshell][1];
816 
817  /* this is number of cells in continuum needed to store opacity */
818  need = limit - opac.ipElement[nelem][ion][nshell][0] + 1;
819 
820  /* check that opac will have enough frequeny cells */
821  if( opac.nOpacTot + need > ndimOpacityStack )
823 
824  /* set lower and upper limits to this range */
825  low = opac.ipElement[nelem][ion][nshell][0];
826  ihi = opac.ipElement[nelem][ion][nshell][1];
827  ipop = opac.ipElement[nelem][ion][nshell][2];
828 
829  /* make sure indices are within correct bounds,
830  * mainly check on logic for detecting missing shells */
831  ASSERT( low <= ihi || low<5 );
832 
833  /* loop over energy range of this shell */
834  for( ip=low-1; ip < ihi; ip++ )
835  {
836  /* photo energy MAX so that we never eval below threshold */
837  energy = MAX2(rfield.anu(ip)*EVRYD ,
838  t_ADfA::Inst().ph1(nshell,nelec-1,nelem,0));
839 
840  /* the cross section in mega barns */
841  cs = t_ADfA::Inst().phfit(nelem+1,nelec,nshell+1,energy);
842  /* cannot assert that cs is positive since, at edge of shell,
843  * energy might be slightly below threshold and hence zero,
844  * due to finite size of continuum bins */
845  opac.OpacStack[ip-low+ipop] = cs*1e-18;
846 
847  /* add this to total opacity, which we will confirm to be greater than zero below */
848  opac.opacity_abs[ip] += cs;
849  }
850 
851  opac.nOpacTot += ihi - low + 1;
852 
853  /* save pointers option */
854  if( save.lgPunPoint )
855  {
856  fprintf( save.ipPoint, "%3ld%3ld%3ld%10.2e%10.2e%10.2e%10.2e\n",
857  nelem, ion, nshell, rfield.anu(low-1), rfield.anu(ihi-1),
858  opac.OpacStack[ipop-1], opac.OpacStack[ihi-low+ipop-1] );
859  }
860  }
861 
862  ASSERT( Heavy.nsShells[nelem][ion] >= 1 );
863  /*confirm that total opacity is greater than zero */
864  for( ip=opac.ipElement[nelem][ion][Heavy.nsShells[nelem][ion]-1][0]-1;
865  ip < continuum.KshellLimit; ip++ )
866  {
867  ASSERT( opac.opacity_abs[ip] > 0. );
868  }
869 
870  }
871  return;
872 }
873 
874 /*opacity_more_memory allocate more memory for opacity stack */
876 {
877 
878  DEBUG_ENTRY( "opacity_more_memory()" );
879 
880  /* double size */
881  ndimOpacityStack *= 2;
882  double *newptr = (double *)MALLOC( (size_t)ndimOpacityStack*sizeof(double) );
883  memcpy( newptr, opac.OpacStack, ndimOpacityStack*sizeof(double)/2 );
884  free( opac.OpacStack );
885  opac.OpacStack = newptr;
886  if( prt.lgPrintTime )
887  {
888  fprintf( ioQQQ, " NOTE OpacityCreate1Element needed more opacity cells than ndimOpacityStack, please consider increasing it.\n" );
889  fprintf( ioQQQ, " NOTE OpacityCreate1Element doubled memory allocation to %li.\n",ndimOpacityStack );
890  }
891  lgRealloc = true;
892  return;
893 }
894 
895 /*Opacity_iso_photo_cs returns photoionization cross section for isoelectronic sequences */
897  /* photon energy ryd */
898  double EgammaRyd ,
899  /* iso sequence */
900  long ipISO ,
901  /* charge, 0 for H */
902  long nelem ,
903  /* index */
904  long index )
905 {
906  double crs=-DBL_MAX;
907 
908  DEBUG_ENTRY( "Opacity_iso_photo_cs()" );
909 
910  if( ipISO==ipH_LIKE )
911  {
912  if( index==0 )
913  {
914  /* this is the ground state, use Dima's routine, which works in eV
915  * and returns megabarns */
916  double EgammaEV = MAX2(EgammaRyd*(realnum)EVRYD , t_ADfA::Inst().ph1(0,0,nelem,0));
917  crs = t_ADfA::Inst().phfit(nelem+1,1,1,EgammaEV)* 1e-18;
918  /* make sure cross section is reasonable */
919  ASSERT( crs > 0. && crs < 1e-10 );
920  }
921  else if( index < iso_sp[ipISO][nelem].numLevels_max - iso_sp[ipISO][nelem].nCollapsed_max )
922  {
923  /* photon energy relative to threshold */
924  double photon = MAX2( EgammaRyd/iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, 1. + FLT_EPSILON*2. );
925 
926  crs = H_photo_cs( photon , N_(index), L_(index), nelem+1 );
927  /* make sure cross section is reasonable */
928  ASSERT( crs > 0. && crs < 1e-10 );
929  }
930  else if( N_(index) <= NHYDRO_MAX_LEVEL )
931  {
932  /* for first cell, depending on the current resolution of the energy mesh,
933  * the center of the first cell can be below the ionization limit of the
934  * level. do not let the energy fall below this limit */
935  /* This will make sure that we don't call epsilon below threshold,
936  * the factor 1.001 was chosen so that t_ADfA::Inst().hpfit, which works
937  * in terms of Dima's Rydberg constant, is not tripped below threshold */
938  EgammaRyd = MAX2( EgammaRyd , iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd*1.001f );
939 
940  crs = t_ADfA::Inst().hpfit(nelem+1,N_(index),EgammaRyd*EVRYD);
941  /* make sure cross section is reasonable */
942  ASSERT( crs > 0. && crs < 1e-10 );
943  }
944  else
945  {
946  /* photon energy relative to threshold */
947  double photon = MAX2( EgammaRyd/iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, 1. + FLT_EPSILON*2. );
948 
949  /* cross section for collapsed level should be
950  * roughly equal to cross-section for yrast level,
951  * so third parameter is n - 1. */
952  crs = H_photo_cs( photon , N_(index), N_(index)-1, nelem+1 );
953 
954  /* make sure cross section is reasonable */
955  ASSERT( crs > 0. && crs < 1e-10 );
956  }
957  }
958  else if( ipISO==ipHE_LIKE )
959  {
960  EgammaRyd = MAX2( EgammaRyd , iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd);
961  /* this would be a collapsed level */
962  if( index >= iso_sp[ipHE_LIKE][nelem].numLevels_max - iso_sp[ipHE_LIKE][nelem].nCollapsed_max )
963  {
964  long int nup = iso_sp[ipHE_LIKE][nelem].n_HighestResolved_max + index + 1 -
966 
967  /* this is a collapsed level - this is hydrogenic routine and
968  * first he-like energy may not agree exactly with threshold for H */
969  crs = t_ADfA::Inst().hpfit(nelem,nup ,EgammaRyd*EVRYD);
970  /* make sure cross section is reasonable if away from threshold */
971  ASSERT(
972  (EgammaRyd < iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd*1.02) ||
973  (crs > 0. && crs < 1e-10) );
974  }
975  else
976  {
977  long n = N_(index);
978  long l = L_(index);
979  long S = S_(index);
980  /* He_cross_section returns cross section (cm^-2),
981  * given EgammaRyd, the photon energy in Ryd,
982  * quantum numbers n, l, and S,
983  * nelem is charge, equal to 1 for Helium,
984  * this is a wrapper for cross_section */
985  crs = He_cross_section( EgammaRyd, iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, n, l, S, nelem );
986 
987  /* make sure cross section is reasonable */
988  ASSERT( crs > 0. && crs < 1e-10 );
989  }
990  }
991  else
992  TotalInsanity();
993  return(crs);
994 }
995 
996 /*hmiopc derive total H- H minus opacity */
997 static const int NCRS = 33;
998 
999 STATIC double hmiopc(double freq)
1000 {
1001  double energy,
1002  hmiopc_v,
1003  x,
1004  y;
1005  static double y2[NCRS];
1006  static double crs[NCRS]={0.,0.124,0.398,0.708,1.054,1.437,1.805,
1007  2.176,2.518,2.842,3.126,3.377,3.580,3.741,3.851,3.913,3.925,
1008  3.887,3.805,3.676,3.511,3.306,3.071,2.810,2.523,2.219,1.898,
1009  1.567,1.233,.912,.629,.39,.19};
1010  static double ener[NCRS]={0.,0.001459,0.003296,0.005256,0.007351,
1011  0.009595,0.01201,0.01460,0.01741,0.02044,0.02375,0.02735,0.03129,
1012  0.03563,0.04043,0.04576,0.05171,0.05841,0.06601,0.07469,0.08470,
1013  0.09638,0.1102,0.1268,0.1470,0.1723,0.2049,0.2483,0.3090,0.4001,
1014  0.5520,0.8557,1.7669};
1015  static bool lgFirst = true;
1016 
1017  DEBUG_ENTRY( "hmiopc()" );
1018 
1019  /* bound free cross section (x10**-17 cm^2) from Doughty et al
1020  * 1966, MNRAS 132, 255; good agreement with Wishart MNRAS 187, 59p. */
1021 
1022  /* photoelectron energy, add HMINUSIONPOT to get incoming energy (Ryd) */
1023 
1024 
1025  if( lgFirst )
1026  {
1027  /* set up coefficients for spline */
1028  spline(ener,crs,NCRS,2e31,2e31,y2);
1029  lgFirst = false;
1030  }
1031 
1032  energy = freq - HMINUSIONPOT;
1033  if( energy < ener[0] || energy > ener[NCRS-1] )
1034  {
1035  hmiopc_v = 0.;
1036  }
1037  else
1038  {
1039  x = energy;
1040  splint(ener,crs,y2,NCRS,x,&y);
1041  hmiopc_v = y*1e-17;
1042  }
1043  return( hmiopc_v );
1044 }
1045 
1046 /*rayleh compute Rayleigh scattering cross section for Lya */
1047 STATIC double rayleh(double ener)
1048 {
1049  double rayleh_v;
1050 
1051  DEBUG_ENTRY( "rayleh()" );
1052 
1054  /* do hydrogen Rayleigh scattering cross sections;
1055  * fits to
1056  *>>refer Ly scattering Gavrila, M., 1967, Physical Review 163, 147
1057  * and Mihalas radiative damping
1058  *
1059  * >>chng 96 aug 15, changed logic to do more terms for each part of
1060  * rayleigh scattering
1061  * if( ener.lt.0.05 ) then
1062  * rayleh = 8.41e-25 * ener**4 * DampOnFac
1063  * */
1064  if( ener < 0.05 )
1065  {
1066  rayleh_v = (8.41e-25*powi(ener,4) + 3.37e-24*powi(ener,6))*
1067  hydro.DampOnFac;
1068  }
1069 
1070  else if( ener < 0.646 )
1071  {
1072  rayleh_v = (8.41e-25*powi(ener,4) + 3.37e-24*powi(ener,6) +
1073  4.71e-22*powi(ener,14))*hydro.DampOnFac;
1074  }
1075 
1076  else if( ener >= 0.646 && ener < 1.0 )
1077  {
1078  rayleh_v = fabs(0.74959-ener);
1079  rayleh_v = 1.788e5/POW2(FR1RYD*MAX2(0.001,rayleh_v));
1080  /* typical energy between Ly-a and Ly-beta */
1081  rayleh_v = MAX2(rayleh_v,1e-24)*hydro.DampOnFac;
1082  }
1083 
1084  else
1085  {
1086  rayleh_v = 0.;
1087  }
1088  return( rayleh_v );
1089 }
long iopo2d
Definition: opacity.h:299
long int iphmin
Definition: hmi.h:128
t_mole_global mole_global
Definition: mole.cpp:7
bool lgStancil
Definition: mole.h:337
long int ipElement[LIMELM][LIMELM][7][3]
Definition: opacity.h:222
long int ipRayScat
Definition: opacity.h:222
STATIC void opacity_more_memory(void)
double * OpacStack
Definition: opacity.h:163
STATIC void OpacityCreate1Element(long int nelem)
double * opacity_abs
Definition: opacity.h:103
const int ipHE_LIKE
Definition: iso.h:65
NORETURN void TotalInsanity(void)
Definition: service.cpp:1067
bool lgOpacMalloced
Definition: cdinit.cpp:40
t_opac opac
Definition: opacity.cpp:5
t_Heavy Heavy
Definition: heavy.cpp:5
realnum ph1(int i, int j, int k, int l) const
Definition: atmdat_adfa.h:61
void OpacityCreateAll(void)
long int ipo1exc[3]
Definition: opacity.h:222
long ipmgex
Definition: opacity.h:299
const int ipOXYGEN
Definition: cddefines.h:355
long int KshellLimit
Definition: continuum.h:98
void GrainsInit()
Definition: grains.cpp:563
long int nCollapsed_max
Definition: iso.h:518
long int i2d
Definition: oxy.h:38
long int ih2pof
Definition: opacity.h:222
long int ipo3exc[3]
Definition: opacity.h:222
FILE * ioQQQ
Definition: cddefines.cpp:7
long int ipBrems
Definition: opacity.h:222
vector< freeBound > fb
Definition: iso.h:481
#define MIN2(a, b)
Definition: cddefines.h:807
double anu(size_t i) const
Definition: mesh.h:111
static const int NCRS
long int ih2pof_ex
Definition: opacity.h:222
void splint(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y)
Definition: thirdparty.h:173
long int iphmra
Definition: opacity.h:222
t_dense dense
Definition: global.cpp:15
static t_ADfA & Inst()
Definition: cddefines.h:209
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:11
long int nflux_with_check
Definition: rfield.h:51
vector< double > HighestLevelOpacStack
Definition: iso.h:600
t_trace trace
Definition: trace.cpp:5
#define MALLOC(exp)
Definition: cddefines.h:556
long ipoint(double energy_ryd)
Definition: cont_ipoint.cpp:15
long int n_HighestResolved_max
Definition: iso.h:536
#define L_(A_)
Definition: iso.h:23
void spline(const double x[], const double y[], long int n, double yp1, double ypn, double y2a[])
Definition: thirdparty.h:150
long int nsShells[LIMELM][LIMELM]
Definition: heavy.h:28
#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
#define N_(A_)
Definition: iso.h:22
t_continuum continuum
Definition: continuum.cpp:6
phfit_version get_version() const
Definition: atmdat_adfa.h:53
long int ipCKshell
Definition: opacity.h:310
t_rfield rfield
Definition: rfield.cpp:9
long int iophe1[9]
Definition: opacity.h:222
bool lgPunPoint
Definition: save.h:432
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
double anusqrt(size_t i) const
Definition: mesh.h:135
long int iopcom
Definition: opacity.h:222
long ipOpMgEx
Definition: opacity.h:299
vector< diatomics * > diatoms
Definition: h2.cpp:8
t_hydro hydro
Definition: hydrogenic.cpp:5
STATIC void OpacityCreateReilMan(long int low, long int ihi, const realnum energ[], const realnum cross[], long int ncr, long int *ipop, const char *chLabl)
bool lgCompileOpac
Definition: opacity.h:204
#define cdEXIT(FAIL)
Definition: cddefines.h:484
#define S_(A_)
Definition: iso.h:24
FILE * ipPoint
Definition: save.h:431
double powi(double, long int)
Definition: service.cpp:690
bool lgPrintTime
Definition: prt.h:161
STATIC void ofit(double e, realnum opart[])
long int iphmop
Definition: opacity.h:222
long int ioppr
Definition: opacity.h:222
t_prt prt
Definition: prt.cpp:14
bool lgElmtOn[LIMELM]
Definition: dense.h:160
double H_photo_cs(double rel_photon_energy, long int n, long int l, long int iz)
long int nOpacTot
Definition: opacity.h:213
long int ipo3exc3[3]
Definition: opacity.h:222
#define ASSERT(exp)
Definition: cddefines.h:617
long int ippr
Definition: opacity.h:222
const int ipH_LIKE
Definition: iso.h:64
const int LIMELM
Definition: cddefines.h:307
realnum DampOnFac
Definition: hydrogenic.h:134
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
double powpq(double x, int p, int q)
Definition: service.cpp:726
double hpfit(long int iz, long int n, double e)
const int ipHELIUM
Definition: cddefines.h:349
STATIC double Opacity_iso_photo_cs(double energy, long ipISO, long nelem, long index)
long int in1[3]
Definition: opacity.h:222
STATIC double rayleh(double ener)
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 pow(double x, int i)
Definition: cddefines.h:782
#define S(I_, J_)
long int numLevels_max
Definition: iso.h:524
long ica2ex[2]
Definition: opacity.h:299
static bool lgRealloc
STATIC void OpacityValenceRescale(long int nelem, double scale)
#define fixit(a)
Definition: cddefines.h:416
long int ih2pnt[2]
Definition: opacity.h:222
t_hmi hmi
Definition: hmi.cpp:5
double He_cross_section(double EgammaRyd, double EthRyd, long n, long l, long S, long nelem)
#define POW3
Definition: cddefines.h:990
t_save save
Definition: save.cpp:5
static long int ndimOpacityStack
double MolDissocCrossSection(const diss_tran &tran, const double &Mol_Ene)
STATIC double hmiopc(double freq)
const int ipHYDROGEN
Definition: cddefines.h:348
STATIC void OpacityCreatePowerLaw(long int ilo, long int ihi, double cross, double s, long int *ip)
long int nflux
Definition: rfield.h:48
double phfit(long int nz, long int ne, long int is, double e)
long int ih2pnt_ex[2]
Definition: opacity.h:222
const int ipPOTASSIUM
Definition: cddefines.h:366
const int NHYDRO_MAX_LEVEL
Definition: cddefines.h:315
vector< diatomics * >::iterator diatom_iter
Definition: h2.h:13
long ica2op
Definition: opacity.h:299