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-2022 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 "version.h"
36 #include "prt.h"
37 
38 /* limit to number of opacity cells available in the opacity stack*/
39 static long int ndimOpacityStack = 4200000L;
40 
41 /*OpacityCreate1Element generate opacities for entire element by calling t_ADfA::Inst().phfit */
42 STATIC void OpacityCreate1Element(long int nelem);
43 
44 /*opacity_more_memory allocate more memory for opacity stack */
45 STATIC void opacity_more_memory(void);
46 
47 /*hmiopc derive total H- H minus opacity */
48 STATIC double hmiopc(double freq);
49 
50 /*rayleh compute Rayleigh scattering cross section for Lya */
51 STATIC double rayleh(double ener);
52 
53 /*Opacity_iso_photo_cs returns photoionization cross section for isoelectronic sequences */
54 STATIC double Opacity_iso_photo_cs( double energy , long ipISO , long nelem , long index );
55 
56 /*OpacityCreateReilMan generate photoionization cross sections from Reilman and Manson points */
57 STATIC void OpacityCreateReilMan(long int low,
58  long int ihi,
59  const realnum energ[],
60  const realnum cross[],
61  long int ncr,
62  long int *ipop,
63  const char *chLabl);
64 
65 static bool lgRealloc = false;
66 
67 /*OpacityCreatePowerLaw generate array of cross sections using a simple power law fit */
69  /* lower energy limit on continuum mesh */
70  long int ilo,
71  /* upper energy limit on continuum mesh */
72  long int ihi,
73  /* threshold cross section */
74  double cross,
75  /* power law index */
76  double s,
77  /* pointer to opacity offset where this starts */
78  long int *ip);
79 
80 /*ofit compute cross sections for all shells of atomic oxygen */
81 STATIC void ofit(double e,
82  realnum opart[]);
83 
84 /*OpacityValenceRescale routine to rescale non-OP valence shell cross sections for atom */
86  /* element number on C scale */
87  long int nelem ,
88  /* scale factor, must be >= 0. */
89  double scale )
90 {
91 
92  long int ion , nshell , low , ihi , ipop , ip;
93 
94  DEBUG_ENTRY( "OpacityValenceRescale()" );
95 
96  /* return if element is not turned on
97  * >>chng 05 oct 19, this had not been done, so low in the opacity offset below was
98  * not set, and opacity index was negative - only problem when K turned off */
99  if( !dense.lgElmtOn[nelem] )
100  {
101  return;
102  }
103 
104  /* scale better be >= 0. */
105  ASSERT( scale >= 0. );
106 
107  ion = 0;
108  /* this is valence shell on C scale */
109  nshell = Heavy.nsShells[nelem][ion] - 1;
110 
111  /* set lower and upper limits to this range */
112  low = opac.ipElement[nelem][ion][nshell][0];
113  ihi = opac.ipElement[nelem][ion][nshell][1];
114  ipop = opac.ipElement[nelem][ion][nshell][2];
115 
116  /* loop over energy range of this shell */
117  for( ip=low-1; ip < ihi; ip++ )
118  {
119  opac.OpacStack[ip-low+ipop] *= scale;
120  }
121  return;
122 }
123 
125 {
126  long int i,
127  ipISO ,
128  need ,
129  nelem;
130 
131  realnum opart[7];
132 
133  double crs,
134  dx,
135  eps,
136  thres,
137  x;
138 
139  /* >>chng 02 may 29, change to lgOpacMalloced */
140  /* remember whether opacities have ever been evaluated in this coreload
141  static bool lgOpEval = false; */
142 
143  DEBUG_ENTRY( "OpacityCreateAll()" );
144 
145  /* H2+ h2plus h2+ */
146 
147  /* make and print dust opacities
148  * fill in dstab and dstsc, totals, zero if no dust
149  * may be different if different grains are turned on */
150  GrainsInit();
151 
152  /* flag lgOpacMalloced says whether opacity stack has been generated
153  * only do this one time per core load */
154  /* >>chng 02 may 29, from lgOpEval to lgOpacMalloced */
155  if( lgOpacMalloced )
156  {
157  /* this is not the first time code called */
158  if( trace.lgTrace )
159  {
160  fprintf( ioQQQ, " OpacityCreateAll called but NOT evaluated since already done.\n" );
161  }
162  return;
163  }
164 
165  /* create the space for the opacity stack */
166  opac.OpacStack = (double*)MALLOC((size_t)ndimOpacityStack*sizeof(double));
167  lgOpacMalloced = true;
168 
169  if( trace.lgTrace )
170  {
171  fprintf( ioQQQ, " OpacityCreateAll called, evaluating.\n" );
172  }
173 
174  /* zero out opac since this array sometimes addressed before OpacityAddTotal called */
175  for( i=0; i < rfield.nflux_with_check; i++ )
176  {
177  opac.opacity_abs[i] = 0.;
178  }
179 
180  /* nOpacTot is number of opacity cells in OpacStack filled so far by opacity generating routines */
181  opac.nOpacTot = 0;
182 
183  /* photoionization of h, he-like iso electronic sequences */
184  for( ipISO=ipH_LIKE; ipISO<=ipHE_LIKE; ++ipISO )
185  {
186  for( nelem=ipISO; nelem < LIMELM; nelem++ )
187  {
188  iso_sp[ipISO][nelem].HighestLevelOpacStack.resize(0);
189  if( dense.lgElmtOn[nelem] )
190  {
191  long int nupper;
192 
193  /* this is the opacity offset in the general purpose pointer array */
194  /* indices are type, shell. ion, element, so this is the inner shell,
195  * NB - this works for H and He, but the second index should be 1 for Li */
196  opac.ipElement[nelem][nelem-ipISO][0][2] = opac.nOpacTot + 1;
197 
198  fixit("opacities really need to be owned by states or species");
199  // and stored in STL containers so we don't have to mess
200  // with remembering what the upper and lower limits are
201 
202  // all iso states go to high-energy limit of code
203  nupper = rfield.nflux_with_check;
204  for( long index=0; index < iso_sp[ipISO][nelem].numLevels_max; index++ )
205  {
206  /* this is array index to the opacity offset */
207  iso_sp[ipISO][nelem].fb[index].ipOpac = opac.nOpacTot + 1;
208 
209  /* first make sure that first energy point is at least near the limit */
210  long ipThresh = iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon-1;
211  ASSERT( rfield.anumin(ipThresh) <= iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd &&
212  rfield.anumax(ipThresh) >= iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd );
213 
214  /* number of cells we will need to do this level */
215  need = nupper - ipThresh;
216  ASSERT( need > 0 );
217 
218  if( opac.nOpacTot + need > ndimOpacityStack )
220 
221  for( i=ipThresh; i < nupper; i++ )
222  {
223  double crs = Opacity_iso_photo_cs( rfield.anu(i) , ipISO , nelem , index );
224  opac.OpacStack[i-iso_sp[ipISO][nelem].fb[index].ipIsoLevNIonCon+iso_sp[ipISO][nelem].fb[index].ipOpac] = crs;
225  if( index==iso_sp[ipISO][nelem].numLevels_max-1 )
226  iso_sp[ipISO][nelem].HighestLevelOpacStack.push_back( crs );
227  }
228 
229  opac.nOpacTot += need;
230  }
231  }
232  }
233  }
234 
235  /* H2 continuum dissociation opacity */
236  for( diatom_iter diatom = diatoms.begin(); diatom != diatoms.end(); ++diatom )
237  {
238  if( (*diatom)->lgEnabled && mole_global.lgStancil )
239  {
240  for( vector< diss_tran >::iterator tran = (*diatom)->Diss_Trans.begin(); tran != (*diatom)->Diss_Trans.end(); ++tran )
241  {
242  /* choose to integrate from 0.1 to 4 Ryd, data only extends from 0.7 to ~2 Ryd */
243  long lower_limit = ipoint(tran->energies[0]);
244  long upper_limit = ipoint(tran->energies.back());
245  upper_limit = MIN2( upper_limit, rfield.nflux-1 );
246  long ipCont_Diss = opac.nOpacTot + 1;
247  long num_points = 0;
248 
249  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
250  if( opac.nOpacTot + upper_limit - lower_limit + 1 > ndimOpacityStack )
252 
253  for(i = lower_limit; i <= upper_limit; ++i)
254  {
255  opac.OpacStack[ipCont_Diss + num_points - 1] =
256  MolDissocCrossSection( *tran, rfield.anu(i) );
257  ++num_points;
258  }
259  opac.nOpacTot += num_points;
260  }
261  }
262  }
263 
264  /* This check will get us through Klein-Nishina below. */
267 
268  /* Lyman alpha damping wings - Rayleigh scattering */
269  opac.ipRayScat = opac.nOpacTot + 1;
270  for( i=0; i < iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon; i++ )
271  {
273  }
274  opac.nOpacTot += iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon;
275 
276  /* ==============================================================
277  * this block of code defines the electron scattering cross section
278  * for all energies */
279 
280  /* assume Thomson scattering up to ipCKshell, 20.6 Ryd=0.3 keV */
281  opac.iopcom = opac.nOpacTot + 1;
282  for( i=0; i < opac.ipCKshell; i++ )
283  {
284  opac.OpacStack[i-1+opac.iopcom] = SIGMA_THOMSON;
285  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
286  rfield.anu(i)*EVRYD , opac.OpacStack[i-1+opac.iopcom] );*/
287  }
288 
289  /* Klein-Nishina from eqn 7.5,
290  * >>refer Klein-Nishina cs Rybicki and Lightman */
291  for( i=opac.ipCKshell; i < rfield.nflux_with_check; i++ )
292  {
293  dx = rfield.anu(i)/3.7573e4;
294 
295  opac.OpacStack[i-1+opac.iopcom] = SIGMA_THOMSON*3.e0/4.e0*((1.e0 +
296  dx)/POW3(dx)*(2.e0*dx*(1.e0 + dx)/(1.e0 + 2.e0*dx) - log(1.e0+
297  2.e0*dx)) + 1.e0/2.e0/dx*log(1.e0+2.e0*dx) - (1.e0 + 3.e0*
298  dx)/POW3(1.e0 + 2.e0*dx));
299  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
300  rfield.anu(i)*EVRYD , opac.OpacStack[i-1+opac.iopcom] );*/
301  }
303 
304  /* ============================================================== */
305 
306  /* This check will get us through "H- hminus H minus bound-free opacity" below. */
307  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
308  if( opac.nOpacTot + 3*rfield.nflux_with_check - opac.ippr + iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon - hmi.iphmin + 2 > ndimOpacityStack )
310 
311  /* pair production */
312  opac.ioppr = opac.nOpacTot + 1;
313  for( i=opac.ippr-1; i < rfield.nflux_with_check; i++ )
314  {
315  /* pair production heating rate for unscreened H + He
316  * fit to figure 41 of Experimental Nuclear Physics,
317  * Vol1, E.Segre, ed */
318 
319  x = rfield.anu(i)/7.512e4*2.;
320 
321  opac.OpacStack[i-opac.ippr+opac.ioppr] = 5.793e-28*
322  POW2((-0.46737118 + x*(0.349255416 + x*0.002179893))/(1. +
323  x*(0.130471301 + x*0.000524906)));
324  /*fprintf(ioQQQ,"%.3e\t%.3e\n",
325  rfield.anu(i)*EVRYD , opac.OpacStack[i-opac.ippr+opac.ioppr] );*/
326  }
328 
329  /* brems (free-free) opacity */
330  opac.ipBrems = opac.nOpacTot + 1;
331 
332  for( i=0; i < rfield.nflux_with_check; i++ )
333  {
334  /* Inflate precomputed opacity value by 30 dex to avoid underflows */
335  /* free free opacity needs g(ff)*(1-exp(hn/kT))/SQRT(T)*1E-30 */
336  opac.OpacStack[i-1+opac.ipBrems] = FREE_FREE_ABS * 1e30 / POW3(rfield.anu(i));
337  }
339 
340  opac.iphmra = opac.nOpacTot + 1;
341  for( i=0; i < rfield.nflux_with_check; i++ )
342  {
343  /* following is ratio of h minus to neut h bremss opacity */
344  opac.OpacStack[i-1+opac.iphmra] = 0.1175*rfield.anusqrt(i);
345  }
347 
348  opac.iphmop = opac.nOpacTot + 1;
349  for( i=hmi.iphmin-1; i < iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon; i++ )
350  {
351  /* H- hminus H minus bound-free opacity */
353  hmiopc(rfield.anu(i));
354  }
355  opac.nOpacTot += iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon - hmi.iphmin + 1;
356 
357  /* ============================================================== */
358 
359  /* This check will get us through "H2 photoionization cross section" below. */
360  /* >>chng 07 oct 10, by Ryan. Added this check for allotted memory. */
361  for( diatom_iter diatom = diatoms.begin(); diatom != diatoms.end(); ++diatom )
362  {
363  if( opac.nOpacTot + rfield.nflux_with_check - (*diatom)->ip_photo_opac_thresh + 1 > ndimOpacityStack )
365 
366  (*diatom)->ip_photo_opac_offset = opac.nOpacTot + 1;
367  opac.nOpacTot += (*diatom)->OpacityCreate( opac.OpacStack );
368  }
369 
370  /* H2+ H2P h2plus photoabsorption */
371  {
372  /* fits to cross section for photo dist of H_2^+ */
373  const long nCSH2P = 5;
374  static const realnum enh2p[nCSH2P]={6.75f,8.68f,10.54f,12.46f,14.28f};
375  static const realnum csh2p[nCSH2P]={0.24f, 2.5f, 7.1f, 6.0f, 2.7f};
376  if( opac.nOpacTot + opac.ih2pnt[1] - opac.ih2pnt[0] + 1 > ndimOpacityStack )
378  /* >>refer H2+ photodissoc Buckingham, R.A., Reid, S., & Spence, R. 1952, MNRAS 112, 382, 0 K temp */
379  OpacityCreateReilMan(opac.ih2pnt[0],opac.ih2pnt[1],enh2p,csh2p,nCSH2P,&opac.ih2pof, "H2+ ");
380 
381  // Now do an excited superstate of H2+
382  const long nCSH2P_ex = 9;
383  // These opacities are a rough approximation to figure 4 of the following reference, for v=9 of H2+:
384  /* >>refer H2+ photodissoc Dunn, G. H. 1968, Phys.Rev. 172, 1 */
385  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};
386  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};
389  OpacityCreateReilMan(opac.ih2pnt_ex[0],opac.ih2pnt_ex[1],enh2p_ex,csh2p_ex,nCSH2P_ex,&opac.ih2pof_ex, "H2+*");
390  }
391 
392  /* This check will get us through "HeI singlets neutral helium ground" below. */
393  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
394  if( opac.nOpacTot + rfield.nflux_with_check - iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon + 1 > ndimOpacityStack )
396 
397  /* HeI singlets neutral helium ground */
398  opac.iophe1[0] = opac.nOpacTot + 1;
399  opac.ipElement[ipHELIUM][0][0][2] = opac.iophe1[0];
400  for( i=iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon-1; i < rfield.nflux_with_check; i++ )
401  {
402  crs = t_ADfA::Inst().phfit(2,2,1,rfield.anu(i)*EVRYD);
403  opac.OpacStack[i-iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon+opac.iophe1[0]] =
404  crs*1e-18;
405  }
406  opac.nOpacTot += rfield.nflux_with_check - iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon + 1;
407 
408  /* these are opacity offset points that would be defined in OpacityCreate1Element,
409  * but this routine will not be called for H and He
410  * generate all heavy element opacities, everything heavier than He,
411  * nelem is on the C scale, so Li is 2 */
412  /*>>chng 99 jan 27, do not reevaluate hydrogenic opacity below */
413  for( nelem=2; nelem < LIMELM; nelem++ )
414  {
415  if( dense.lgElmtOn[nelem] )
416  {
417  OpacityCreate1Element(nelem);
418  }
419  }
420 
421  /* option to rescale atoms of some elements that were not done by opacity project
422  * the valence shell - two arguments - element number on C scale, and scale factor */
423  /*>>chng 05 sep 26, fudge factor to get atomic K fraction along well defined line of sight
424  * to be observed value - this is ratio of cross sections, actual value is very uncertain since
425  * differences betweeen Verner & opacity project are huge */
427 
428  /* now add on some special cases, where exicted states, etc, come in */
429  /* Nitrogen
430  * >>refer n1 photo Henry, R., ApJ 161, 1153.
431  * photoionization of excited level of N+ */
432  OpacityCreatePowerLaw(opac.in1[0],opac.in1[1],9e-18,1.75,&opac.in1[2]);
433 
434  /* atomic Oxygen
435  * only do this if 1996 Verner results are used */
437  {
438  /* This check will get us through this loop. */
439  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
440  if( opac.nOpacTot + opac.ipElement[ipOXYGEN][0][2][1] - opac.ipElement[ipOXYGEN][0][2][0] + 1 > ndimOpacityStack )
442 
443  /* integrate over energy range of the valence shell of atomic oxygen*/
444  for( i=opac.ipElement[ipOXYGEN][0][2][0]-1; i < opac.ipElement[ipOXYGEN][0][2][1]; i++ )
445  {
446  /* call special routine to evaluate partial cross section for OI shells */
447  eps = rfield.anu(i)*EVRYD;
448  ofit(eps,opart);
449 
450  /* this will be total cs of all processes leaving shell 3 */
451  crs = opart[0];
452  for( long n=1; n < 6; n++ )
453  {
454  /* add up table of cross sections */
455  crs += opart[n];
456  }
457  /* convert to cgs and overwrite cross sections set by OpacityCreate1Element */
458  crs *= 1e-18;
459  opac.OpacStack[i-opac.ipElement[ipOXYGEN][0][2][0]+opac.ipElement[ipOXYGEN][0][2][2]] = crs;
460  }
461  /* >>chng 02 may 09 - this was a significant error */
462  /* >>chng 02 may 08, by Ryan. This loop did not update total slots filled. */
463  opac.nOpacTot += opac.ipElement[ipOXYGEN][0][2][1] - opac.ipElement[ipOXYGEN][0][2][0] + 1;
464  }
465 
466  /* Henry nubmers for 1S excit state of OI, OP data very sparse */
467  OpacityCreatePowerLaw(opac.ipo1exc[0],opac.ipo1exc[1],4.64e-18,0.,&opac.ipo1exc[2]);
468 
469  /* photoionization of excited level of O2+ 1D making 5007
470  * fit to TopBase Opacity Project cs */
471  OpacityCreatePowerLaw(opac.ipo3exc[0],opac.ipo3exc[1],3.8e-18,0.,&opac.ipo3exc[2]);
472 
473  /* photoionization of excited level of O2+ 1S making 4363 */
474  OpacityCreatePowerLaw(opac.ipo3exc3[0],opac.ipo3exc3[1],5.5e-18,0.01,
475  &opac.ipo3exc3[2]);
476 
477  /* This check will get us through the next two steps. */
478  /* >>chng 02 may 08, by Ryan. Added this and other checks for allotted memory. */
479  if( opac.nOpacTot + iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon - oxy.i2d + 1
480  + iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon - opac.ipmgex + 1 > ndimOpacityStack )
482 
483  /* photoionization to excited states of O+ */
484  opac.iopo2d = opac.nOpacTot + 1;
485  thres = rfield.anu(oxy.i2d-1);
486  for( i=oxy.i2d-1; i < iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon; i++ )
487  {
488  crs = 3.85e-18*(4.4*powpq(rfield.anu(i)/thres,-3,2) - 3.38*
489  powpq(rfield.anu(i)/thres,-5,2));
490 
491  opac.OpacStack[i-oxy.i2d+opac.iopo2d] = crs;
492  }
493  opac.nOpacTot += iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon - oxy.i2d + 1;
494 
495  /* magnesium
496  * photoionization of excited level of Mg+
497  * fit to opacity project data Dima got */
498  opac.ipOpMgEx = opac.nOpacTot + 1;
499  for( i=opac.ipmgex-1; i < iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon; i++ )
500  {
502  (0.2602325880970085 +
503  445.8558249365131*exp(-rfield.anu(i)/0.1009243952792674))*
504  1e-18;
505  }
506  opac.nOpacTot += iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon - opac.ipmgex + 1;
507 
509 
510  /* Calcium
511  * excited states of Ca+ */
513 
514  if( trace.lgTrace )
515  {
516  fprintf( ioQQQ,
517  " OpacityCreateAll return OK, number of opacity cells used in OPSC= %ld and OPSV is dimensioned %ld\n",
519  }
520 
521  /* option to compile opacities into file for later use
522  * this is executed if the 'compile opacities' command is entered */
523  if( opac.lgCompileOpac )
524  {
525  fprintf( ioQQQ, "The COMPILE OPACITIES command is currently not supported\n" );
527  }
528 
529  if( !( t_version::Inst().lgRelease || t_version::Inst().lgReleaseBranch ) && lgRealloc && prt.lgPrintTime )
530  fprintf(ioQQQ,
531  " Please consider revising ndimOpacityStack=%li in OpacityCreateAll, a total of %li cells were needed.\n\n" ,
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  /* only print on development branch - if we must resize often then should consider
887  * changing default. The comment in the release version causes concern.
888  */
889  if( !( t_version::Inst().lgRelease || t_version::Inst().lgReleaseBranch ) && prt.lgPrintTime )
890  {
891  fprintf( ioQQQ, " NOTE OpacityCreate1Element needed more opacity cells than ndimOpacityStack, please consider increasing it.\n" );
892  fprintf( ioQQQ, " NOTE OpacityCreate1Element doubled memory allocation to %li.\n",ndimOpacityStack );
893  }
894  lgRealloc = true;
895  return;
896 }
897 
898 /*Opacity_iso_photo_cs returns photoionization cross section for isoelectronic sequences */
900  /* photon energy ryd */
901  double EgammaRyd ,
902  /* iso sequence */
903  long ipISO ,
904  /* charge, 0 for H */
905  long nelem ,
906  /* index */
907  long index )
908 {
909  double crs=-DBL_MAX;
910 
911  DEBUG_ENTRY( "Opacity_iso_photo_cs()" );
912 
913  if( ipISO==ipH_LIKE )
914  {
915  if( index==0 )
916  {
917  /* this is the ground state, use Dima's routine, which works in eV
918  * and returns megabarns */
919  double EgammaEV = MAX2(EgammaRyd*(realnum)EVRYD , t_ADfA::Inst().ph1(0,0,nelem,0));
920  crs = t_ADfA::Inst().phfit(nelem+1,1,1,EgammaEV)* 1e-18;
921  /* make sure cross section is reasonable */
922  ASSERT( crs > 0. && crs < 1e-10 );
923  }
924  else if( index < iso_sp[ipISO][nelem].numLevels_max - iso_sp[ipISO][nelem].nCollapsed_max )
925  {
926  /* photon energy relative to threshold */
927  double photon = MAX2( EgammaRyd/iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, 1. + FLT_EPSILON*2. );
928 
929  crs = H_photo_cs( photon , N_(index), L_(index), nelem+1 );
930  /* make sure cross section is reasonable */
931  ASSERT( crs > 0. && crs < 1e-10 );
932  }
933  else if( N_(index) <= NHYDRO_MAX_LEVEL )
934  {
935  /* for first cell, depending on the current resolution of the energy mesh,
936  * the center of the first cell can be below the ionization limit of the
937  * level. do not let the energy fall below this limit */
938  /* This will make sure that we don't call epsilon below threshold,
939  * the factor 1.001 was chosen so that t_ADfA::Inst().hpfit, which works
940  * in terms of Dima's Rydberg constant, is not tripped below threshold */
941  EgammaRyd = MAX2( EgammaRyd , iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd*1.001f );
942 
943  crs = t_ADfA::Inst().hpfit(nelem+1,N_(index),EgammaRyd*EVRYD);
944  /* make sure cross section is reasonable */
945  ASSERT( crs > 0. && crs < 1e-10 );
946  }
947  else
948  {
949  /* photon energy relative to threshold */
950  double photon = MAX2( EgammaRyd/iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, 1. + FLT_EPSILON*2. );
951 
952  /* cross section for collapsed level should be
953  * roughly equal to cross-section for yrast level,
954  * so third parameter is n - 1. */
955  crs = H_photo_cs( photon , N_(index), N_(index)-1, nelem+1 );
956 
957  /* make sure cross section is reasonable */
958  ASSERT( crs > 0. && crs < 1e-10 );
959  }
960  }
961  else if( ipISO==ipHE_LIKE )
962  {
963  EgammaRyd = MAX2( EgammaRyd , iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd);
964  /* this would be a collapsed level */
965  if( index >= iso_sp[ipHE_LIKE][nelem].numLevels_max - iso_sp[ipHE_LIKE][nelem].nCollapsed_max )
966  {
967  long int nup = iso_sp[ipHE_LIKE][nelem].n_HighestResolved_max + index + 1 -
969 
970  /* this is a collapsed level - this is hydrogenic routine and
971  * first he-like energy may not agree exactly with threshold for H */
972  crs = t_ADfA::Inst().hpfit(nelem,nup ,EgammaRyd*EVRYD);
973  /* make sure cross section is reasonable if away from threshold */
974  ASSERT(
975  (EgammaRyd < iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd*1.02) ||
976  (crs > 0. && crs < 1e-10) );
977  }
978  else
979  {
980  long n = N_(index);
981  long l = L_(index);
982  long S = S_(index);
983  /* He_cross_section returns cross section (cm^-2),
984  * given EgammaRyd, the photon energy in Ryd,
985  * quantum numbers n, l, and S,
986  * nelem is charge, equal to 1 for Helium,
987  * this is a wrapper for cross_section */
988  crs = He_cross_section( EgammaRyd, iso_sp[ipISO][nelem].fb[index].xIsoLevNIonRyd, n, l, S, nelem );
989 
990  /* make sure cross section is reasonable */
991  ASSERT( crs > 0. && crs < 1e-10 );
992  }
993  }
994  else
995  TotalInsanity();
996  return(crs);
997 }
998 
999 /*hmiopc derive total H- H minus opacity */
1000 static const int NCRS = 33;
1001 
1002 STATIC double hmiopc(double freq)
1003 {
1004  double energy,
1005  hmiopc_v,
1006  x,
1007  y;
1008  static double y2[NCRS];
1009  static double crs[NCRS]={0.,0.124,0.398,0.708,1.054,1.437,1.805,
1010  2.176,2.518,2.842,3.126,3.377,3.580,3.741,3.851,3.913,3.925,
1011  3.887,3.805,3.676,3.511,3.306,3.071,2.810,2.523,2.219,1.898,
1012  1.567,1.233,.912,.629,.39,.19};
1013  static double ener[NCRS]={0.,0.001459,0.003296,0.005256,0.007351,
1014  0.009595,0.01201,0.01460,0.01741,0.02044,0.02375,0.02735,0.03129,
1015  0.03563,0.04043,0.04576,0.05171,0.05841,0.06601,0.07469,0.08470,
1016  0.09638,0.1102,0.1268,0.1470,0.1723,0.2049,0.2483,0.3090,0.4001,
1017  0.5520,0.8557,1.7669};
1018  static bool lgFirst = true;
1019 
1020  DEBUG_ENTRY( "hmiopc()" );
1021 
1022  /* bound free cross section (x10**-17 cm^2) from Doughty et al
1023  * 1966, MNRAS 132, 255; good agreement with Wishart MNRAS 187, 59p. */
1024 
1025  /* photoelectron energy, add HMINUSIONPOT to get incoming energy (Ryd) */
1026 
1027 
1028  if( lgFirst )
1029  {
1030  /* set up coefficients for spline */
1031  spline(ener,crs,NCRS,2e31,2e31,y2);
1032  lgFirst = false;
1033  }
1034 
1035  energy = freq - HMINUSIONPOT;
1036  if( energy < ener[0] || energy > ener[NCRS-1] )
1037  {
1038  hmiopc_v = 0.;
1039  }
1040  else
1041  {
1042  x = energy;
1043  splint(ener,crs,y2,NCRS,x,&y);
1044  hmiopc_v = y*1e-17;
1045  }
1046  return( hmiopc_v );
1047 }
1048 
1049 /*rayleh compute Rayleigh scattering cross section for Lya */
1050 STATIC double rayleh(double ener)
1051 {
1052  double rayleh_v;
1053 
1054  DEBUG_ENTRY( "rayleh()" );
1055 
1057  /* do hydrogen Rayleigh scattering cross sections;
1058  * fits to
1059  *>>refer Ly scattering Gavrila, M., 1967, Physical Review 163, 147
1060  * and Mihalas radiative damping
1061  *
1062  * >>chng 96 aug 15, changed logic to do more terms for each part of
1063  * rayleigh scattering
1064  * if( ener.lt.0.05 ) then
1065  * rayleh = 8.41e-25 * ener**4 * DampOnFac
1066  * */
1067  if( ener < 0.05 )
1068  {
1069  rayleh_v = (8.41e-25*powi(ener,4) + 3.37e-24*powi(ener,6))*
1070  hydro.DampOnFac;
1071  }
1072 
1073  else if( ener < 0.646 )
1074  {
1075  rayleh_v = (8.41e-25*powi(ener,4) + 3.37e-24*powi(ener,6) +
1076  4.71e-22*powi(ener,14))*hydro.DampOnFac;
1077  }
1078 
1079  else if( ener >= 0.646 && ener < 1.0 )
1080  {
1081  rayleh_v = fabs(0.74959-ener);
1082  rayleh_v = 1.788e5/POW2(FR1RYD*MAX2(0.001,rayleh_v));
1083  /* typical energy between Ly-a and Ly-beta */
1084  rayleh_v = MAX2(rayleh_v,1e-24)*hydro.DampOnFac;
1085  }
1086 
1087  else
1088  {
1089  rayleh_v = 0.;
1090  }
1091  return( rayleh_v );
1092 }
long iopo2d
Definition: opacity.h:300
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:223
long int ipRayScat
Definition: opacity.h:223
STATIC void opacity_more_memory(void)
double * OpacStack
Definition: opacity.h:164
STATIC void OpacityCreate1Element(long int nelem)
double * opacity_abs
Definition: opacity.h:104
const int ipHE_LIKE
Definition: iso.h:65
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
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:223
long ipmgex
Definition: opacity.h:300
const int ipOXYGEN
Definition: cddefines.h:356
long int KshellLimit
Definition: continuum.h:98
void GrainsInit()
Definition: grains.cpp:558
long int nCollapsed_max
Definition: iso.h:518
long int i2d
Definition: oxy.h:38
long int ih2pof
Definition: opacity.h:223
long int ipo3exc[3]
Definition: opacity.h:223
FILE * ioQQQ
Definition: cddefines.cpp:7
long int ipBrems
Definition: opacity.h:223
vector< freeBound > fb
Definition: iso.h:481
#define MIN2(a, b)
Definition: cddefines.h:803
double anu(size_t i) const
Definition: mesh.h:120
static const int NCRS
long int ih2pof_ex
Definition: opacity.h:223
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:223
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:49
vector< double > HighestLevelOpacStack
Definition: iso.h:600
t_trace trace
Definition: trace.cpp:5
#define MALLOC(exp)
Definition: cddefines.h:554
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:979
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:311
t_rfield rfield
Definition: rfield.cpp:9
long int iophe1[9]
Definition: opacity.h:223
bool lgPunPoint
Definition: save.h:450
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
double anusqrt(size_t i) const
Definition: mesh.h:144
long int iopcom
Definition: opacity.h:223
long ipOpMgEx
Definition: opacity.h:300
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:205
#define cdEXIT(FAIL)
Definition: cddefines.h:482
#define S_(A_)
Definition: iso.h:24
FILE * ipPoint
Definition: save.h:449
double powi(double, long int)
Definition: service.cpp:594
bool lgPrintTime
Definition: prt.h:161
STATIC void ofit(double e, realnum opart[])
long int iphmop
Definition: opacity.h:223
double anumin(size_t i) const
Definition: mesh.h:148
long int ioppr
Definition: opacity.h:223
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:214
long int ipo3exc3[3]
Definition: opacity.h:223
#define ASSERT(exp)
Definition: cddefines.h:613
long int ippr
Definition: opacity.h:223
const int ipH_LIKE
Definition: iso.h:64
const int LIMELM
Definition: cddefines.h:308
realnum DampOnFac
Definition: hydrogenic.h:135
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
double powpq(double x, int p, int q)
Definition: service.cpp:630
double hpfit(long int iz, long int n, double e)
const int ipHELIUM
Definition: cddefines.h:350
STATIC double Opacity_iso_photo_cs(double energy, long ipISO, long nelem, long index)
long int in1[3]
Definition: opacity.h:223
STATIC double rayleh(double ener)
t_oxy oxy
Definition: oxy.cpp:5
#define MAX2(a, b)
Definition: cddefines.h:824
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
#define S(I_, J_)
long int numLevels_max
Definition: iso.h:524
long ica2ex[2]
Definition: opacity.h:300
static bool lgRealloc
STATIC void OpacityValenceRescale(long int nelem, double scale)
double anumax(size_t i) const
Definition: mesh.h:152
#define fixit(a)
Definition: cddefines.h:417
long int ih2pnt[2]
Definition: opacity.h:223
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:986
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:349
STATIC void OpacityCreatePowerLaw(long int ilo, long int ihi, double cross, double s, long int *ip)
long int nflux
Definition: rfield.h:46
double phfit(long int nz, long int ne, long int is, double e)
long int ih2pnt_ex[2]
Definition: opacity.h:223
const int ipPOTASSIUM
Definition: cddefines.h:367
const int NHYDRO_MAX_LEVEL
Definition: cddefines.h:316
vector< diatomics * >::iterator diatom_iter
Definition: h2.h:13
long ica2op
Definition: opacity.h:300