cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cont_setintensity.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 /*ContSetIntensity derive intensity of incident continuum */
4 /*extin do extinction of incident continuum as set by extinguish command */
5 /*sumcon sums L and Q for net incident continuum */
6 /*conorm normalize continuum to proper intensity */
7 /*qintr integrates Q for any continuum between two limits, used for normalization */
8 /*pintr integrates L for any continuum between two limits, used for normalization */
9 #include "cddefines.h"
10 #include "iso.h"
11 #include "noexec.h"
12 #include "ionbal.h"
13 #include "hextra.h"
14 #include "trace.h"
15 #include "oxy.h"
16 #include "conv.h"
17 #include "prt.h"
18 #include "heavy.h"
19 #include "rfield.h"
20 #include "phycon.h"
21 #include "called.h"
22 #include "hydrogenic.h"
23 #include "timesc.h"
24 #include "secondaries.h"
25 #include "opacity.h"
26 #include "thermal.h"
27 #include "ipoint.h"
28 #include "atmdat_adfa.h"
29 #include "rt.h"
30 #include "radius.h"
31 #include "geometry.h"
32 #include "grainvar.h"
33 #include "continuum.h"
34 #include "ion_trim.h"
35 #include "freebound.h"
36 #include "dense.h"
37 
38 /*conorm normalize continuum to proper intensity */
39 STATIC void conorm();
40 
41 /*pintr integrates L for any continuum between two limits, used for normalization */
42 STATIC double pintr(double penlo, double penhi);
43 
44 /*qintr integrates Q for any continuum between two limits, used for normalization */
45 STATIC double qintr(double qenlo, double qenhi);
46 
47 /*sumcon sums L and Q for net incident continuum */
48 STATIC void sumcon(long int il,
49  long int ih,
50  realnum *q,
51  realnum *p,
52  realnum *panu);
53 
54 /*extin do extinction of incident continuum as set by extinguish command */
55 STATIC void extin(realnum *ex1ryd);
56 
58 {
59 
60  DEBUG_ENTRY( "IncidentContinuumHere()" );
61  double frac_beam_time;
62  /* fraction of beamed continuum that is constant */
63  double frac_beam_const;
64  /* fraction of continuum that is isotropic */
65  double frac_isotropic;
66 
67  double BigLog = 0.;
68  for( long i = 0; i<rfield.nflux; ++i )
69  {
70  double flux_org = rfield.flux[0][i];
71  double flux_now = ffun( rfield.anu(i) ,
72  &frac_beam_time ,
73  &frac_beam_const ,
74  &frac_isotropic )*rfield.widflx(i)*rfield.ExtinguishFactor[i];
75 
76  double ratio = 1.;
77  if( flux_org>SMALLFLOAT && flux_now>SMALLFLOAT )
78  {
79  ratio = fabs( log10( flux_now / flux_org ) );
80  BigLog = max( ratio , BigLog );
81  }
82  }
83 
84  if( BigLog > 0.01 )
85  fprintf(ioQQQ , "DEBUG diff continua %.2e\n", BigLog );
86  return;
87 }
88 
89 /* called by Cloudy to set up continuum */
91 {
92  bool lgCheckOK;
93 
94  long int i,
95  ip,
96  n;
97 
98  realnum EdenHeav,
99  ex1ryd,
100  factor,
101  occ1,
102  p,
103  p1,
104  p2,
105  p3,
106  p4,
107  p5,
108  p6,
109  p7,
110  p8,
111  pgn,
112  phe,
113  pheii,
114  qgn;
115 
116  realnum xIoniz;
117 
118  double HCaseBRecCoeff,
119  ecrit,
120  tcompr,
121  tcomp,
122  RatioIonizToRecomb,
123  r3ov2;
124 
125  double peak;
126 
127  /* fraction of beamed continuum that is varies with time */
128  double frac_beam_time;
129  /* fraction of beamed continuum that is constant */
130  double frac_beam_const;
131  /* fraction of continuum that is isotropic */
132  double frac_isotropic;
133 
134  long int nelem , ion;
135 
136  DEBUG_ENTRY( "ContSetIntensity()" );
137 
138  /* set continuum */
139  if( trace.lgTrace )
140  {
141  fprintf( ioQQQ, " ContSetIntensity called.\n" );
142  }
143 
144  /* find normalization factors for the continua - this decides whether continuum is
145  * per unit area of luminosity, and which is desired final product */
146  conorm();
147 
148  /* define factors to convert rfeld.flux array into photon occupation array OCCNUM
149  * by multiplication */
150  factor = (realnum)(EN1RYD/PI4/FR1RYD/HNU3C2);
151 
152  /*------------------------------------------------------------- */
153  lgCheckOK = true;
154 
155  for( i=0; i < rfield.nflux_with_check; i++ )
156  {
157  double flux = ffun( rfield.anu(i), &frac_beam_time, &frac_beam_const, &frac_isotropic );
158  ASSERT( fabs(1.-frac_beam_time-frac_beam_const-frac_isotropic) < 10.*FLT_EPSILON );
159 
160  /* This is a fix for ticket #1 */
161  if( flux*rfield.widflx(i) > BIGFLOAT )
162  {
163  fprintf( ioQQQ, "\n Cannot continue. The continuum is far too intense.\n" );
165  }
166 
167  rfield.flux[0][i] = (realnum)(flux*rfield.widflx(i));
168 
169  /* save separation into isotropic constant and beamed, and possibly
170  * time-variable beamed continua */
171  rfield.flux_beam_const[i] = rfield.flux[0][i] * (realnum)frac_beam_const;
172  rfield.flux_beam_time[i] = rfield.flux[0][i] * (realnum)frac_beam_time;
173  rfield.flux_isotropic[i] = rfield.flux[0][i] * (realnum)frac_isotropic;
174 
175  if( rfield.flux[0][i] < 0. )
176  {
177  fprintf( ioQQQ, " negative continuum returned at%6ld%10.2e%10.2e\n",
178  i, rfield.anu(i), rfield.flux[0][i] );
179  lgCheckOK = false;
180  }
181 
182  rfield.ContBoltz[i] = 0.;
183  rfield.ContBoltzHelp1[i] = 0.;
184  rfield.ContBoltzHelp2[i] = 0.;
185  rfield.ContBoltzAvg[i] = 0.;
186  rfield.ConEmitReflec[0][i] = 0.;
187  rfield.ConEmitOut[0][i] = 0.;
188  rfield.convoc[i] = factor/rfield.widflx(i)/rfield.anu2(i);
189  }
190 
191  if( !lgCheckOK )
192  {
193  ShowMe();
195  }
196 
197  if( trace.lgTrace && trace.lgComBug )
198  {
199  fprintf( ioQQQ, "\n\n Compton heating, cooling coefficients \n" );
200  for( i=0; i < rfield.nflux_with_check; i += 2 )
201  {
202  fprintf( ioQQQ, "%6ld%10.2e%10.2e%10.2e", i, rfield.anu(i),
203  rfield.csigh[i], rfield.csigc[i] );
204  }
205  fprintf( ioQQQ, "\n" );
206  }
207 
208  /* extinguish continuum if set on */
209  extin(&ex1ryd);
210 
211  /* now find peak of hydrogen ionizing continuum - for PDR calculations
212  * this will remain equal to 1 since the loop will not execute */
213  prt.ipeak = 1;
214  peak = 0.;
215 
216  for( i=iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon-1; i < rfield.nflux_with_check; i++ )
217  {
218  if( rfield.flux[0][i]*rfield.anu(i)/rfield.widflx(i) > (realnum)peak )
219  {
220  /* prt.ipeak points to largest f_nu at H-ionizing energies
221  * and is passed to other parts of code */
222  /* i+1 to keep ipeak on fortran version of energy array */
223  prt.ipeak = i+1;
224  peak = rfield.flux[0][i]*rfield.anu(i)/rfield.widflx(i);
225  }
226  }
227 
228  /* find highest energy to consider in continuum flux array
229  * peak is the peak product nu*flux */
230  peak = rfield.flux[0][prt.ipeak-1]/rfield.widflx(prt.ipeak-1)*
231  rfield.anu2(prt.ipeak-1);
232 
233  /* say what type of cpu this is, if desired */
234  if( trace.lgTrace )
235  {
236  fprintf( ioQQQ, " ContSetIntensity: The peak of the H-ion continuum is at %.3e Ryd - its value is %.2e\n",
237  rfield.anu(prt.ipeak-1) , peak);
238  }
239 
240  if( peak > 1e38 )
241  {
242  fprintf( ioQQQ, " PROBLEM DISASTER The continuum is too intense to compute. Use a fainter continuum. (This is the nu*f_nu test)\n" );
243  fprintf( ioQQQ, " Sorry.\n" );
245  }
246 
247  /* >>chng 04 oct 10, add this limit - arrays will malloc to nupper, but will add unit
248  * continuum to [nflux] - this must be within array */
251 
252  /* check that continuum defined everywhere - look for zero's and comment if present */
253  continuum.lgCon0 = false;
254  ip = 0;
255  for( i=0; i < rfield.nflux; i++ )
256  {
257  if( rfield.flux[0][i] == 0. )
258  {
259  if( called.lgTalk && !continuum.lgCon0 )
260  {
261  fprintf( ioQQQ, " NOTE Setcon: continuum has zero intensity starting at %11.4e Ryd.\n",
262  rfield.anu(i) );
263  continuum.lgCon0 = true;
264  }
265  ++ip;
266  }
267  }
268 
269  if( continuum.lgCon0 && called.lgTalk )
270  {
271  fprintf( ioQQQ,
272  "%6ld cells in the incident continuum have zero intensity. Problems???\n\n",
273  ip );
274  }
275 
276  /* check for devastating error in the continuum mesh or intensity */
277  lgCheckOK = true;
278  for( i=1; i < rfield.nflux; i++ )
279  {
280  if( rfield.flux[0][i] < 0. )
281  {
282  fprintf( ioQQQ,
283  " PROBLEM DISASTER Continuum has negative intensity at %.4e Ryd=%.2e %4.4s %4.4s\n",
284  rfield.anu(i), rfield.flux[0][i], rfield.chLineLabel[i].c_str(), rfield.chContLabel[i].c_str() );
285  lgCheckOK = false;
286  }
287  else if( rfield.anu(i) <= rfield.anu(i-1) )
288  {
289  fprintf( ioQQQ,
290  " PROBLEM DISASTER cont_setintensity - internal error - continuum energies not in increasing order: energies follow\n" );
291  fprintf( ioQQQ,
292  "%ld %e %ld %e %ld %e\n",
293  i -1 , rfield.anu(i-1), i, rfield.anu(i), i +1, rfield.anu(i+1) );
294  lgCheckOK = false;
295  }
296  }
297 
298  /* either of the ways lgCheckOK would be set true would be a major internal error */
299  if( !lgCheckOK )
300  {
301  ShowMe();
303  }
304 
305  /* turn off recoil ionization if high energy < 190R */
306  if( rfield.anu(rfield.nflux-1) <= 190 )
307  {
308  ionbal.lgCompRecoil = false;
309  }
310 
311  /* sum photons and energy, save mean */
312 
313  /* sum from low energy to Balmer edge */
314  sumcon(1,iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH2p].ipIsoLevNIonCon-1,&rfield.qrad,&prt.pradio,&p1);
315 
316  /* sum over Balmer continuum */
317  sumcon(iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH2p].ipIsoLevNIonCon,iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon-1,&rfield.qbal,&prt.pbal,&p2);
318 
319  /* sum from Lyman edge to HeI edge */
320  sumcon(iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon,
321  iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon-1,&prt.q,&p,&p3);
322 
323  /* sum from HeI to HeII edges */
324  sumcon(iso_sp[ipHE_LIKE][ipHELIUM].fb[0].ipIsoLevNIonCon,
325  iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon-1,&rfield.qhe,&phe,&p4);
326 
327  /* sum from Lyman edge to carbon k-shell */
328  sumcon(iso_sp[ipH_LIKE][ipHELIUM].fb[ipH1s].ipIsoLevNIonCon,opac.ipCKshell-1,&rfield.qheii,&pheii,&p5);
329 
330  /* sum from c k-shell to gamma ray - where pairs start */
332  &prt.xpow , &p6);
333 
334  /* complete sum up to high-energy limit */
336 
337  /* find to estimate photoerosion timescale */
338  n = ipoint(7.35e5);
339  sumcon(n,rfield.nflux,&qgn,&pgn,&p8);
340  timesc.TimeErode = qgn;
341 
342  /* find Compton temp */
343  double TotalPower = (prt.pradio + prt.pbal +
344  p + phe + pheii + prt.xpow + prt.GammaLumin);
345  if( TotalPower>SMALLFLOAT )
346  {
347  tcompr = (p1 + p2 + p3 + p4 + p5 + p6 + p7)/TotalPower;
348  tcomp = tcompr/(4.*6.272e-6);
349  }
350  else
351  {
352  tcompr = 0.;
353  tcomp = 0.;
354  }
355 
356  if( trace.lgTrace )
357  {
358  fprintf( ioQQQ,
359  " mean photon energy=%10.3eR =%10.3eK low, high nu=%12.4e%12.4e\n",
360  tcompr, tcomp, rfield.anumin(0), rfield.anumax(rfield.nflux-1) );
361  }
362 
363  /* this is total power in ionizing radiation, per unit area */
364  prt.powion = p + phe + pheii + prt.xpow + prt.GammaLumin;
365 
366  /* this is the total radiation intensity, erg cm-2 s-1 */
368 
369  /* this is placed into the line stack on the first zone, then
370  * reset to zero, to end up with luminosity in the emission lines array.
371  * at end of iteration it is reset to TotalLumin */
373 
374  /* total H-ionizing photon number, */
376 
377  /* ftotal photon number, all energies */
379 
380  if( prt.powion <= 0. && called.lgTalk )
381  {
382  rfield.lgHionRad = true;
383  fprintf( ioQQQ, " NOTE There is no hydrogen-ionizing radiation.\n" );
384  fprintf( ioQQQ, " Was this intended?\n\n" );
385  /* check if any Balmer ionizing radiation since even metals will be
386  * totally neutral */
387  if( prt.pbal <=0. && called.lgTalk )
388  {
389  fprintf( ioQQQ, " NOTE There is no Balmer continuum radiation.<<<<\n" );
390  fprintf( ioQQQ, " Was this intended?\n\n" );
391  }
392  }
393 
394  else
395  {
396  rfield.lgHionRad = false;
397  }
398 
399  /* option to add energy deposition due to fast neutrons,
400  * entered as fraction of total photon luminosity */
401  if( hextra.lgNeutrnHeatOn )
402  {
403  /* hextra.totneu is erg cm-2 s-1 in neutrons
404  * hextra.effneu - efficiency default is unity */
406  exp10(hextra.frcneu));
407  }
408  else
409  {
410  hextra.totneu = (realnum)0.;
411  }
412 
413  /* temp correspond to energy density, printed in STARTR */
414  phycon.TEnerDen = powpq(continuum.TotalLumin/(4.*STEFAN_BOLTZ),1,4);
415 
416  /* sanity check for single blackbody, that energy density temperature
417  * is smaller than black body temperature */
418  if( rfield.nShape==1 &&
419  strcmp( rfield.chSpType[rfield.nShape-1], "BLACK" )==0 )
420  {
421  /* single black body, now confirm that TEnerDen is less than this temperature,
422  * >>>chng 99 may 02,
423  * in lte these are very very close, factor of 1.00001 allows for numerical
424  * errors, and apparently slightly different atomic coef in different parts
425  * of code. eventaully all mustuse physonst.h and agree exactly */
426  if( phycon.TEnerDen > 1.0001f*rfield.slope[rfield.nShape-1] )
427  {
428  fprintf( ioQQQ,
429  "\n WARNING: The energy density temperature (%g) is greater than the"
430  " black body temperature (%g). This is unphysical.\n\n",
432  }
433  }
434 
435  /* incident continuum nu*f_nu at Hbeta and Ly-alpha */
436  continuum.cn4861 = (realnum)(ffun(0.1875)*HPLANCK*FR1RYD*0.1875*0.1875);
437  continuum.cn1216 = (realnum)(ffun(0.75)*HPLANCK*FR1RYD*0.75*0.75);
440  /* flux density in V, erg / s / cm2 / hz */
441  continuum.fluxv = (realnum)(ffun(0.1643)*HPLANCK*0.1643);
442  continuum.fbeta = (realnum)(ffun(0.1875)*HPLANCK*0.1875*6.167e14);
443 
444  /* flux density nu*Fnu = erg / s / cm2
445  * EX1RYD is optional extinction factor at 1 ryd */
446  prt.fx1ryd = (realnum)(ffun(1.000)*HPLANCK*ex1ryd*FR1RYD);
447 
448  realnum plsFrqConstant = (realnum)(ELEM_CHARGE_ESU/sqrt(PI*ELECTRON_MASS)/FR1RYD);
449  ASSERT( plsFrqConstant > 2.7e-12 && plsFrqConstant < 2.8e-12 );
450 
451  /* check for plasma frequency - then zero out incident continuum
452  * for energies below this
453  * this is critical electron density, shielding of incident continuum
454  * if electron density is greater than this */
455  ecrit = POW2(rfield.anu(0)/plsFrqConstant);
456 
457  if( dense.gas_phase[ipHYDROGEN]*1.2 > ecrit )
458  {
459  rfield.lgPlasNu = true;
460  // This should be electron density, but we don't know that yet.
461  // We use n_H (with 1.2 factor for He) as an ansatz.
462  rfield.plsfrq = plsFrqConstant*sqrt(dense.gas_phase[ipHYDROGEN]*1.2f);
465 
466  /* save max pointer too */
468 
469  /* now loop over all affected energies, setting incident continuum
470  * to zero there, and counting all as reflected */
471  /* >>chng 01 jul 14, from i < ipPlasma to ipPlasma-1 -
472  * when ipPlasma is 1 plasma freq is not on energy scale */
473  for( i=0; i < rfield.ipPlasma-1; i++ )
474  {
475  /* count as reflected incident continuum */
476  rfield.ConRefIncid[0][i] = rfield.flux[0][i];
477  /* set continuum to zero there */
478  rfield.flux_beam_const[i] = 0.;
479  rfield.flux_beam_time[i] = 0.;
480  rfield.flux_isotropic[i] = 0.;
483  }
484  }
485  else
486  {
487  rfield.lgPlasNu = false;
488  /* >>chng 01 jul 14, from 0 to 1 - 1 is the first array element on the F scale,
489  * ipoint would return this, so rest of code assumes ipPlasma is 1 plus correct index */
490  rfield.ipPlasma = 1;
491  rfield.plsfrqmax = 0.;
492  rfield.plsfrq = 0.;
493  }
494 
495  if( rfield.ipPlasma > 1 && called.lgTalk )
496  {
497  fprintf( ioQQQ,
498  " !The plasma frequency is %.2e Ryd. The incident continuum is set to 0 below this.\n",
499  rfield.plsfrq );
500  }
501 
502  rfield.occmax = 0.;
503  rfield.tbrmax = 0.;
504  for( i=0; i < rfield.nflux_with_check; i++ )
505  {
506  /* set up occupation number array */
509  {
511  rfield.occmnu = rfield.anu(i);
512  }
513  /* following product is continuum brightness temperature */
514  if( rfield.OccNumbIncidCont[i]*TE1RYD*rfield.anu(i) > rfield.tbrmax )
515  {
517  rfield.tbrmnu = rfield.anu(i);
518  }
519  /* save continuum for next iteration */
520  rfield.flux_total_incident[0][i] = rfield.flux[0][i];
524  /*fprintf(ioQQQ,"DEBUG type cont %li\t%.3e\t%.2e\t%.2e\t%.2e\t%.2e\n",
525  i, rfield.anu(i),
526  rfield.flux[0][i],rfield.flux_beam_const[i],rfield.flux_beam_time[i],
527  rfield.flux_isotropic[i]);
528  fflush(ioQQQ);*/
529  }
530 
531  /* if continuum brightness temp is large, where does it fall below
532  * 1e4k??? */
533  if( rfield.tbrmax > 1e4 )
534  {
535  i = ipoint(rfield.tbrmnu)-1;
536  while( i < rfield.nflux_with_check-1 && (rfield.OccNumbIncidCont[i]*TE1RYD*
537  rfield.anu(i) > 1e4) )
538  {
539  ++i;
540  }
541  rfield.tbr4nu = rfield.anu(i);
542  }
543  else
544  {
545  rfield.tbr4nu = 0.;
546  }
547 
548  /* if continuum occ num is large, where does it fall below 1? */
549  if( rfield.occmax > 1. )
550  {
551  i = ipoint(rfield.occmnu)-1;
552  while( i < rfield.nflux_with_check && (rfield.OccNumbIncidCont[i] > 1.) )
553  {
554  ++i;
555  }
556  rfield.occ1nu = rfield.anu(i);
557  }
558  else
559  {
560  rfield.occ1nu = 0.;
561  }
562 
563  /* remember if incident radiation field is less than 10*Habing ISM */
564  /* >>chng 06 aug 01, change this test from continuum.TotalLumin to
565  * energy in balmer and ionizing continuum, since this is the true habing field
566  * and is the continuum that interacts with gas. When CMB set this
567  * tests on total did not trigger due to cold blackbody, which has little
568  * effect on gas, other than compton */
569  if( (prt.powion + prt.pbal) < 1.8e-2 )
570  {
571  /* thermal.ConstTemp def is zero, set pos when constant temperature is set */
572  rfield.lgHabing = true;
573  /* >>chng 06 aug 01 also print warning if substantially below Habing, this may be a mistake */
574  if( ((prt.powion + prt.pbal) < 1.8e-12) &&
575  /* this is test for not constant temperature */
577  {
578  fprintf( ioQQQ, "\n >>>\n"
579  " >>> NOTE The incident continuum is surprisingly faint.\n" );
580  fprintf( ioQQQ,
581  " >>> The total energy in the Balmer and Lyman continua is %.2e erg cm-2 s-1.\n"
582  ,(prt.powion + prt.pbal));
583  fprintf( ioQQQ, " >>> This is many orders of magnitude fainter than the ISM galactic background.\n" );
584  fprintf( ioQQQ, " >>> This seems unphysical - please check that the continuum intensity has been properly set.\n" );
585  fprintf( ioQQQ, " >>> YOU MAY BE MAKING A BIG MISTAKE!!\n >>>\n\n\n\n" );
586  }
587  }
588 
589  /* fix ionization parameter (per hydrogen) at inner edge */
591  (dense.gas_phase[ipHYDROGEN]*SPEEDLIGHT));
593  (dense.gas_phase[ipHYDROGEN]*SPEEDLIGHT));
594  if( rfield.uh > 1e10 )
595  {
596  fprintf( ioQQQ, "\n\n"
597  " CAUTION The incident radiation field is surprisingly intense.\n" );
598  fprintf( ioQQQ,
599  " The dimensionless hydrogen ionization parameter is %.2e.\n"
600  , rfield.uh );
601  fprintf( ioQQQ, " This is many orders of magnitude brighter than commonly seen.\n" );
602  fprintf( ioQQQ, " This seems unphysical - please check that the radiation field intensity has been properly set.\n" );
603  fprintf( ioQQQ, " YOU MAY BE MAKING A BIG MISTAKE!!\n\n\n\n\n" );
604  }
605 
606  /* guess first temperature and neutral h density */
607  double TeNew;
608  if( thermal.ConstTemp > 0. )
609  {
610  TeNew = thermal.ConstTemp;
611  }
612  else
613  {
614  if( rfield.uh > 0. )
615  {
616  TeNew = (20000.+log10(rfield.uh)*5000.);
617  TeNew = MAX2(8000. , TeNew );
618  }
619  else
620  {
621  TeNew = 1000.;
622  }
623  }
624  TempChange( TeNew );
625 
626  /* this is an option to stop after printing header only */
627  if( noexec.lgNoExec )
628  return;
629 
630  /* estimate secondary ionization rate - probably 0, but possible extra
631  * SetCsupra set with "set csupra" */
632  /* >>>chng 99 apr 29, added cosmic ray ionization since this is used to get
633  * helium ionization fraction, and was zero in pdr, so He turned off at start,
634  * and never turned back on */
635  /* coef on cryden is from highen.c */
636  for( nelem=ipHYDROGEN; nelem<LIMELM; ++nelem )
637  {
638  for( ion=0; ion<nelem+1; ++ion )
639  {
640  secondaries.csupra[nelem][ion] =
642  }
643  }
644 
645  /*********************************************************************
646  * *
647  * estimate hydrogen's level of ionization *
648  * *
649  *********************************************************************/
650 
651  /* create fake ionization balance, but will conserve number of hydrogens */
652  dense.xIonDense[ipHYDROGEN][0] = 0.;
654  /* this must be zero since PresTotCurrent will do radiation pressure due to H */
655  iso_sp[ipH_LIKE][ipHYDROGEN].st[ipH1s].Pop() = 0.;
656 
657  /* "extra" electrons from command line, or assumed residual electrons */
658  double EdenExtraLocal = dense.EdenExtra +
659  /* if we are in a molecular cloud the current logic could badly fail
660  * do not let electron density fall below 1e-7 of H density */
661  1e-7*dense.gas_phase[ipHYDROGEN];
662  EdenChange( dense.xIonDense[ipHYDROGEN][1] + EdenExtraLocal );
663 
664  /* hydrogen case B recombination coefficient */
665  HCaseBRecCoeff = (-9.9765209 + 0.158607055*phycon.telogn[0] + 0.30112749*
666  phycon.telogn[1] - 0.063969007*phycon.telogn[2] + 0.0012691546*
667  phycon.telogn[3])/(1. + 0.035055422*phycon.telogn[0] -
668  0.037621619*phycon.telogn[1] + 0.0076175048*phycon.telogn[2] -
669  0.00023432613*phycon.telogn[3]);
670  HCaseBRecCoeff = exp10(HCaseBRecCoeff)/phycon.te;
671 
672  double CollIoniz = t_ADfA::Inst().coll_ion_wrapper(0,0,phycon.te);
673 
674  // mean H-ionizing photon energy
675  double PhotonEnergy = 1.;
676  if( rfield.qhtot>SMALLFLOAT )
677  PhotonEnergy = prt.powion/rfield.qhtot/EN1RYD;
678 
679  double OtherIonization = rfield.qhtot*6.3e-18/POW3(PhotonEnergy) +
681 
682  double newEden = dense.eden;
683  long loopCount = 0;
684 
685  do
686  {
687  /* update electron density */
688  EdenChange( newEden );
689  double RatioIoniz =
690  (CollIoniz*dense.eden+OtherIonization)/(HCaseBRecCoeff*dense.eden);
691  if( RatioIoniz<1e-3 )
692  {
693  /* very low ionization solution */
697  ASSERT( dense.xIonDense[ipHYDROGEN][0]>=0. &&
699  ASSERT( dense.xIonDense[ipHYDROGEN][1]>=0. &&
701  //fprintf(ioQQQ,"DEBUG br 1 H0 %.2e\n", dense.xIonDense[ipHYDROGEN][0]);
702  }
703  else if( RatioIoniz>1e3 )
704  {
705  /* very high ionization solution */
709  ASSERT( dense.xIonDense[ipHYDROGEN][0]>=0. &&
711  ASSERT( dense.xIonDense[ipHYDROGEN][1]>=0. &&
713  //fprintf(ioQQQ,"DEBUG br 2 H0 %.2e rat %.2e\n", dense.xIonDense[ipHYDROGEN][0],
714  // dense.gas_phase[ipHYDROGEN]/RatioIoniz);
715  }
716  else
717  {
718  /* intermediate ionization - solve quadratic */
719  double alpha = HCaseBRecCoeff + CollIoniz ;
720  double beta = HCaseBRecCoeff*EdenExtraLocal + OtherIonization +
721  (EdenExtraLocal - dense.gas_phase[ipHYDROGEN])*CollIoniz;
722  double gamma = -dense.gas_phase[ipHYDROGEN]*(OtherIonization+EdenExtraLocal*CollIoniz);
723 
724  double discriminant = POW2(beta) - 4.*alpha*gamma;
725  if( discriminant <0 )
726  {
727  /* oops */
728  fprintf(ioQQQ," DISASTER PROBLEM cont_initensity found negative discriminant.\n");
729  TotalInsanity();
730  }
731 
732  dense.xIonDense[ipHYDROGEN][1] = (realnum)((-beta + sqrt(discriminant))/(2.*alpha));
734  {
735  /* oops */
736  fprintf(ioQQQ," DISASTER PROBLEM cont_initensity found n(H+)>n(H).\n");
737  TotalInsanity();
738  }
741  if( dense.xIonDense[ipHYDROGEN][0]<= 0 )
742  {
743  /* oops */
744  fprintf(ioQQQ," DISASTER PROBLEM cont_initensity found n(H0)<0.\n");
745  TotalInsanity();
746  }
747  //fprintf(ioQQQ,"DEBUG br 3 H0 %.2e\n", dense.xIonDense[ipHYDROGEN][0]);
748  }
749 
750 
751  if( dense.xIonDense[ipHYDROGEN][1] > 1e-30 )
752  {
754  }
755  else
756  {
757  iso_sp[ipH_LIKE][ipHYDROGEN].st[ipH1s].Pop() = 0.;
758  }
759 
760  /* now save estimates of whether induced recombination is going
761  * to be important -this is a code pacesetter since GammaBn is slower
762  * than GammaK */
763  hydro.lgHInducImp = false;
764  for( i=ipH1s; i < iso_sp[ipH_LIKE][ipHYDROGEN].numLevels_max; i++ )
765  {
766  if( rfield.OccNumbIncidCont[iso_sp[ipH_LIKE][ipHYDROGEN].fb[i].ipIsoLevNIonCon-1] > 0.01 )
767  hydro.lgHInducImp = true;
768  }
769 
770  /*******************************************************************
771  * *
772  * estimate helium's level of ionization *
773  * *
774  *******************************************************************/
775 
776  /* only if helium is turned on */
777  if( dense.lgElmtOn[ipHELIUM] )
778  {
779  /* next estimate level of helium singly ionized */
780  xIoniz = (realnum)t_ADfA::Inst().coll_ion_wrapper(1,0,phycon.te);
781  /* >>chng 05 jan 05, add cosmic rays */
782  xIoniz = (realnum)(xIoniz*dense.eden + rfield.qhe*1e-18 + secondaries.csupra[ipHELIUM][1] );
783  double RecTot = HCaseBRecCoeff*dense.eden;
784  RatioIonizToRecomb = xIoniz/RecTot;
785 
786  /* now estimate level of helium doubly ionized */
787  xIoniz = (realnum)t_ADfA::Inst().coll_ion_wrapper(1,1,phycon.te);
788  /* >>chng 05 jan 05, add cosmic rays */
789  xIoniz = (realnum)(xIoniz*dense.eden + rfield.qheii*1e-18 + ionbal.CosRayIonRate );
790 
791  /* rough charge dependence */
792  RecTot *= 4.;
793  r3ov2 = xIoniz/RecTot;
794 
795  /* now set level of helium ionization */
796  if( RatioIonizToRecomb > 0. )
797  {
798  double r1 = dense.gas_phase[ipHELIUM]/(1./RatioIonizToRecomb + 1. + r3ov2);
799  dense.xIonDense[ipHELIUM][1] = (realnum)(r1);
800  dense.xIonDense[ipHELIUM][0] = (realnum)(r1/RatioIonizToRecomb);
801  dense.xIonDense[ipHELIUM][2] = (realnum)(r1*r3ov2);
802  }
803  else
804  {
805  /* no He ionizing radiation */
808  }
809 
810  if( dense.xIonDense[ipHELIUM][2] > 1e-30 )
811  {
813  }
814  else
815  {
816  iso_sp[ipH_LIKE][ipHELIUM].st[ipH1s].Pop() = 0.;
817  }
818  }
819  else
820  {
821  /* case where helium is turned off */
822  dense.xIonDense[ipHELIUM][1] = 0.;
823  dense.xIonDense[ipHELIUM][0] = 0.;
824  dense.xIonDense[ipHELIUM][2] = 0.;
825  iso_sp[ipH_LIKE][ipHELIUM].st[ipH1s].Pop() = 0.;
826  }
827 
828  /* update electron density */
829  newEden = dense.xIonDense[ipHYDROGEN][1] + EdenExtraLocal + dense.xIonDense[ipHELIUM][1] + 2.*dense.xIonDense[ipHELIUM][2];
830 
831  loopCount++;
832  }
833  /* repeat above until guessed and calculated eden agree to at least 0.1%. */
834  while( loopCount < 10 && fabs(newEden/dense.eden - 1.) > 0.001 );
835 
836  if( dense.xIonDense[ipHYDROGEN][0]<0.)
837  TotalInsanity();
838  else if( dense.xIonDense[ipHYDROGEN][0] == 0. )
839  {
840  fprintf(ioQQQ,"PROBLEM the derived atomic hydrogen density is zero.\n");
841  if( dense.gas_phase[ipHYDROGEN]<1e-5 && rfield.uh > 1e10)
842  {
843  fprintf(ioQQQ,"This is almost certainly due to floating point "
844  "limits on this computer.\nThe ionization parameter is very large,"
845  " the density is very small,\nand the H^0 density cannot be"
846  " stored in a double.\n");
847  //cdEXIT( EXIT_FAILURE );
848  }
849  }
850  //ASSERT( dense.xIonDense[ipHYDROGEN][0] >0 && dense.xIonDense[ipHYDROGEN][1]>= 0.);
851 
852  /* update electron density */
853  EdenChange( newEden );
854 
855  if( dense.eden <= SMALLFLOAT )
856  {
857  /* no electrons! */
858  fprintf(ioQQQ,"\n PROBLEM DISASTER - this simulation has no source"
859  " of ionization. The electron density is zero. Consider "
860  "adding a source of ionization such as cosmic rays.\n\n");
862  }
863 
864  /* fix range of stages of ionization */
865  ion_trim_init();
866 
867  // make first estimate of iso continuum lowering
868  for( long ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
869  {
870  for( long nelem=ipISO; nelem<LIMELM; ++nelem)
871  {
872  if( nelem < 2 || dense.lgElmtOn[nelem] )
873  {
875  iso_continuum_lower( ipISO, nelem );
876  }
877  }
878  }
879 
880  /* estimate electrons from heavies, assuming each at least
881  * 1 times ionized */
882  EdenHeav = 0.;
885  for( nelem=ipLITHIUM; nelem < LIMELM; nelem++ )
886  {
887  if( dense.lgElmtOn[nelem] )
888  {
889  if( dense.IonLow[nelem] == 0 && dense.IonHigh[nelem] >=1)
890  {
891  realnum low2dens = dense.xIonDense[nelem][0]+dense.xIonDense[nelem][1];
892  dense.xIonDense[nelem][0] = low2dens * atomFrac;
893  dense.xIonDense[nelem][1] = low2dens * firstIonFrac;
894  }
895  for (long ion=1;ion<dense.IonHigh[nelem];++ion)
896  {
897  EdenHeav += ion*dense.xIonDense[nelem][ion];
898  }
899  }
900  }
901 
902  /* modify estimate of electron density */
903  dense.eden += EdenHeav;
904 
905  /* >>chng 05 jan 05, insure positive eden */
907 
908  if( dense.EdenSet > 0. )
909  {
911  }
912 
915 
916  if( dense.eden < 0. )
917  {
918  fprintf( ioQQQ, " PROBLEM DISASTER Negative electron density results in ContSetIntensity.\n" );
919  fprintf( ioQQQ, "%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e\n",
922  TotalInsanity();
923  }
924 
925  if( dense.EdenSet > 0. )
926  {
928  }
929  else
931 
932  if( trace.lgTrace )
933  {
934  fprintf( ioQQQ,
935  " ContSetIntensity sets initial EDEN to %.4e, contributors H+=%.2e He+, ++= %.2e %.2e Heav %.2e extra %.2e\n",
936  dense.eden ,
939  2.*dense.xIonDense[ipHELIUM][2],
940  EdenHeav,
941  dense.EdenExtra);
942  }
943 
944  // photon occupation number at 1 Ryd - used for printout
945  occ1 = (realnum)(prt.fx1ryd/HNU3C2/PI4/FR1RYD);
946  if( occ1 > 1. )
947  rfield.lgOcc1Hi = true;
948  else
949  rfield.lgOcc1Hi = false;
950 
951  if( trace.lgTrace && trace.lgConBug )
952  {
953  fprintf(ioQQQ,"\ntrace continuum print of %li incident spectral "
954  "components\n", rfield.nShape);
955  fprintf(ioQQQ," # type Illum Beam? 1/cos TimeVary?\n");
957  {
958  fprintf(ioQQQ,"%3li %6s %5i %c %.3f %c\n",
959  rfield.ipSpec ,
965  }
966  fprintf(ioQQQ,"\n");
967 
968  /* print some useful pointers to ionization edges */
969  fprintf( ioQQQ, " H2,1=%5ld%5ld NX=%5ld IRC=%5ld\n",
970  iso_sp[ipH_LIKE][ipHYDROGEN].fb[2].ipIsoLevNIonCon,
971  iso_sp[ipH_LIKE][ipHYDROGEN].fb[ipH1s].ipIsoLevNIonCon,
972  opac.ipCKshell,
974  fprintf( ioQQQ, " CARBON" );
975  for( i=0; i < 6; i++ )
976  fprintf( ioQQQ, "%5ld", Heavy.ipHeavy[ipCARBON][i] );
977  fprintf( ioQQQ, "\n" );
978 
979  fprintf( ioQQQ, " OXY" );
980  for( i=0; i < 8; i++ )
981  fprintf( ioQQQ, "%5ld", Heavy.ipHeavy[ipOXYGEN][i] );
982  fprintf( ioQQQ, "%5ld%5ld%5ld\n", opac.ipo3exc[0],
983  oxy.i2d, oxy.i2p );
984 
985  double sum = 0.;
987  for( i=rfield.ipG0_DB96_lo; i < rfield.ipG0_DB96_hi; i++ )
988  sum += rfield.flux[0][i];
989  fprintf(ioQQQ,"\n Sum DB96 photons %.2e", sum);
990  sum = 0.;
991  for( i=(Heavy.ipHeavy[ipHYDROGEN][0] - 1); i<rfield.nflux; i++ )
992  sum += rfield.flux[0][i];
993  fprintf(ioQQQ,", sum H-ioniz photons %.2e\n", sum);
994 
995 
996  fprintf( ioQQQ, "\n\n PHOTONS PER CELL (NOT RYD)\n" );
997  fprintf( ioQQQ, " nu, flux, wid, occ \n" );
998  for( i=0; i < rfield.nflux; i++ )
999  {
1000  fprintf( ioQQQ, "%4ld%10.2e%10.2e%10.2e%10.2e\n", i,
1001  rfield.anu(i), rfield.flux[0][i], rfield.widflx(i),
1002  rfield.OccNumbIncidCont[i] );
1003  }
1004  fprintf( ioQQQ, " \n" );
1005  }
1006 
1007  /* zero out some continua related to the ots rates,
1008  * prototype and routine in RT_OTS_Update. This is done here since summed cont will
1009  * be set to rfield */
1010  RT_OTS_Zero();
1011 
1012  if( trace.lgTrace )
1013  {
1014  fprintf( ioQQQ, " ContSetIntensity returns, nflux=%5ld anu(nflux)=%11.4e eden=%10.2e\n",
1016  }
1017 
1018  return;
1019 }
1020 
1021 /*sumcon sums L and Q for net incident continuum */
1022 STATIC void sumcon(long int il,
1023  long int ih,
1024  realnum *q,
1025  realnum *p,
1026  realnum *panu)
1027 {
1028  long int i,
1029  iupper; /* used as upper limit to the sum */
1030 
1031  DEBUG_ENTRY( "sumcon()" );
1032 
1033  *q = 0.;
1034  *p = 0.;
1035  *panu = 0.;
1036 
1037  /* soft continua may not go as high as the requested bin */
1038  iupper = MIN2(rfield.nflux,ih);
1039 
1040  for( i=il-1; i < iupper; i++ )
1041  {
1042  /* sum photon number */
1043  *q += rfield.flux[0][i];
1044  /* en1ryd is needed to stop overflow */
1045  /* sum flux */
1046  *p += (realnum)(rfield.flux[0][i]*(rfield.anu(i)*EN1RYD));
1047  /* this sum needed for means */
1048  *panu += (realnum)(rfield.flux[0][i]*(rfield.anu2(i)*EN1RYD));
1049  }
1050 
1051  return;
1052 }
1053 
1054 /*extin do extinction of incident continuum as set by extinguish command */
1055 STATIC void extin(realnum *ex1ryd)
1056 {
1057 
1058  DEBUG_ENTRY( "extin()" );
1059 
1060  /* modify input continuum by leaky absorber
1061  * power law fit to
1062  * >>refer XUV extinction Cruddace, R., Paresce, F., Bowyer, S., & Lampton, M. 1974, ApJ, 187, 497. */
1063  if( rfield.ExtinguishColumnDensity == 0. )
1064  {
1065  *ex1ryd = 1.;
1066 
1067  for( long i=0; i<rfield.nflux_with_check; ++i )
1068  rfield.ExtinguishFactor[i] = 1.;
1069  }
1070  else
1071  {
1072  double absorb = 1. - rfield.ExtinguishLeakage;
1073  double factor = rfield.ExtinguishColumnDensity*
1075  /* extinction at 1 4 Ryd */
1076  *ex1ryd = (realnum)(rfield.ExtinguishLeakage + absorb*sexp(factor));
1077 
1078  // low energy limit of extinction
1080 
1081  for( long i=0; i<low-1; ++i )
1082  rfield.ExtinguishFactor[i] = 1.;
1083 
1084  for( long i=low-1; i < rfield.nflux_with_check; i++ )
1085  {
1086  realnum extfactor = (realnum)(rfield.ExtinguishLeakage + absorb*
1087  sexp(factor*(pow(rfield.anu(i),(double)rfield.ExtinguishEnergyPowerLow))));
1088 
1089  rfield.ExtinguishFactor[i] = extfactor;
1090  rfield.flux_beam_const[i] *= extfactor;
1091  rfield.flux_beam_time[i] *= extfactor;
1092  rfield.flux_isotropic[i] *= extfactor;
1093 
1096  }
1097  }
1098  return;
1099 }
1100 
1101 /*conorm normalize continuum to proper intensity */
1103 {
1104  long int i;
1105  double
1106  diff,
1107  f,
1108  flx1,
1109  flx2,
1110  pentrd,
1111  qentrd;
1112 
1113  DEBUG_ENTRY( "conorm()" );
1114 
1115  /* this is a sanity check, it can't happen */
1116  for( i=0; i < rfield.nShape; i++ )
1117  {
1118  if( strcmp(rfield.chRSpec[i],"UNKN") == 0 )
1119  {
1120  fprintf( ioQQQ, " UNKN spectral normalization cannot happen.\n" );
1121  fprintf( ioQQQ, " conorm punts.\n" );
1123  }
1124 
1125  else if( strcmp(rfield.chRSpec[i],"SQCM") != 0 &&
1126  strcmp(rfield.chRSpec[i],"4 PI") != 0 )
1127  {
1128  fprintf( ioQQQ, " chRSpec must be SQCM or 4 PI, and it was %4.4s. This cannot happen.\n",
1129  rfield.chRSpec[i] );
1130  fprintf( ioQQQ, " conorm punts.\n" );
1132  }
1133 
1134 
1135  /* this sanity check makes sure that atlas.mod or werner.mod grids
1136  * are for the current version of the code */
1137  if( strcmp(rfield.chSpType[i],"VOLK ") == 0 )
1138  {
1140  {
1141  fprintf( ioQQQ,"\n\n PROBLEM DISASTER At least one of the compiled stellar atmosphere"
1142  " grids has been compiled with a different energy grid resolution factor.\n" );
1143  fprintf( ioQQQ, " Please recompile this file using the COMPILE STARS command "
1144  "and make sure that you use the correct SET CONTINUUM RESOLUTION factor.\n" );
1146  }
1147  }
1148  else if( strcmp(rfield.chSpType[i],"READ ") == 0 )
1149  {
1151  {
1152  fprintf( ioQQQ,"\n\n PROBLEM DISASTER The file read by the TABLE READ command "
1153  "has been compiled with a different energy grid resolution factor.\n" );
1154  fprintf( ioQQQ, " Please recompile this file using the SAVE TRANSMITTED CONTINUUM "
1155  "command and use the correct SET CONTINUUM RESOLUTION factor.\n" );
1157  }
1158  }
1159  }
1160 
1161  /* this sanity check is that the grains we have read in from opacity files agree
1162  * with the energy grid in this version of cloudy */
1163  for( size_t nd=0; nd < gv.bin.size(); nd++ )
1164  {
1165  if( !fp_equal( gv.bin[nd]->RSFCheck, rfield.getResolutionScaleFactor() ) )
1166  {
1167  fprintf( ioQQQ,"\n\n PROBLEM DISASTER At least one of the grain opacity files "
1168  "has been compiled with a different energy grid resolution factor.\n" );
1169  fprintf( ioQQQ, " Please recompile this file using the COMPILE GRAINS command "
1170  "and make sure that you use the correct SET CONTINUUM RESOLUTION factor.\n" );
1172  }
1173  }
1174 
1175  /* default is is to predict line intensities,
1176  * but if any continuum specified as luminosity then would override this -
1177  * following two values are correct for intensities */
1178  radius.pirsq = 0.;
1179 
1180  /* check whether ANY luminosities are present */
1181  for( i=0; i < rfield.nShape; i++ )
1182  {
1183  if( strcmp(rfield.chRSpec[i],"4 PI") == 0 )
1184  {
1185  ASSERT( radius.rinner > 0. );
1186  double xLog_radius_inner = log10(radius.rinner);
1187 
1188  /* convert down to intensity */
1189  radius.pirsq = (realnum)(1.0992099 + 2.*xLog_radius_inner);
1190  rfield.totpow[i] -= radius.pirsq;
1191 
1192  if( trace.lgTrace )
1193  {
1194  fprintf( ioQQQ,
1195  " conorm converts continuum %ld from luminosity to intensity.\n",
1196  i );
1197  }
1198  }
1199  }
1200 
1201  /* convert ionization parameters to number of photons, called "q(h)"
1202  * at this stage q(h) and "PHI " are the same */
1203  for( i=0; i < rfield.nShape; i++ )
1204  {
1205  if( strcmp(rfield.chSpNorm[i],"IONI") == 0 )
1206  {
1207  /* the log of the ionization parameter was stored here, this converts
1208  * it to the log of the number of photons per sq cm */
1209  rfield.totpow[i] += log10(dense.gas_phase[ipHYDROGEN]) + log10(SPEEDLIGHT);
1210  strcpy( rfield.chSpNorm[i], "Q(H)" );
1211  if( trace.lgTrace )
1212  {
1213  fprintf( ioQQQ,
1214  " conorm converts continuum %ld from ionizat par to q(h).\n",
1215  i );
1216  }
1217  }
1218  }
1219 
1220  /* convert x-ray ionization parameter xi to intensity */
1221  for( i=0; i < rfield.nShape; i++ )
1222  {
1223  if( strcmp(rfield.chSpNorm[i],"IONX") == 0 )
1224  {
1225  /* this converts it to an intensity */
1226  rfield.totpow[i] += log10(dense.gas_phase[ipHYDROGEN]) - log10(PI4);
1227  strcpy( rfield.chSpNorm[i], "LUMI" );
1228  if( trace.lgTrace )
1229  {
1230  fprintf( ioQQQ, " conorm converts continuum%3ld from x-ray ionizat par to I.\n",
1231  i );
1232  }
1233  }
1234  }
1235 
1236  /* indicate whether we ended up with luminosity or intensity */
1237  if( trace.lgTrace )
1238  {
1239  if( radius.lgPredLumin )
1240  {
1241  fprintf( ioQQQ, " Cloudy will predict lumin into 4pi\n" );
1242  }
1243  else
1244  {
1245  fprintf( ioQQQ, " Cloudy will do surface flux for lumin\n" );
1246  }
1247  }
1248 
1249  /* if intensity per unit area is predicted then geometric
1250  * covering factor must be unity
1251  * variable can also be set elsewhere */
1252  if( !radius.lgPredLumin )
1253  {
1254  geometry.covgeo = 1.;
1255  }
1256 
1257  /* main loop over all continuum shapes to find continuum normalization
1258  * for each one */
1259  for( i=0; i < rfield.nShape; i++ )
1260  {
1261  rfield.ipSpec = i;
1262 
1263  /* check that, if laser, bounds include laser energy */
1264  if( strcmp(rfield.chSpType[rfield.ipSpec],"LASER") == 0 )
1265  {
1266  if( !( rfield.range[rfield.ipSpec][0] < rfield.slope[rfield.ipSpec] &&
1268  {
1269  fprintf(ioQQQ,"PROBLEM DISASTER, a continuum source is a laser at %f Ryd, but the intensity was specified over a range from %f to %f Ryd.\n",
1271  rfield.range[rfield.ipSpec][0],
1272  rfield.range[rfield.ipSpec][1]);
1273  fprintf(ioQQQ,"Please specify the continuum flux where the laser is active.\n");
1275  }
1276  }
1277 
1278  if( trace.lgTrace )
1279  {
1280  long int jj;
1281  fprintf( ioQQQ, " conorm continuum number %ld is shape %s range is %.2e %.2e\n",
1282  i,
1283  rfield.chSpType[i],
1284  rfield.range[i][0],
1285  rfield.range[i][1] );
1286  fprintf( ioQQQ, "the continuum points follow\n");
1287  for( jj=0; jj < min(rfield.ncont[rfield.nShape],100); ++jj )
1288  {
1289  fprintf( ioQQQ, "%li %e %e\n",
1290  jj ,
1291  rfield.tNu[rfield.ipSpec][jj].Ryd(),
1292  rfield.tslop[rfield.ipSpec][jj] );
1293  }
1294  }
1295 
1296  if( strcmp(rfield.chSpNorm[i],"RATI") == 0 )
1297  {
1298  /* option to scale relative to previous continua
1299  * this must come first since otherwise may be too late
1300  * BUT ratio cannot be the first continuum source */
1301  if( trace.lgTrace )
1302  {
1303  fprintf( ioQQQ, " conorm this is ratio to 1st con\n" );
1304  }
1305 
1306  /* check that this is not the first continuum source, we must ratio */
1307  if( i == 0 )
1308  {
1309  fprintf( ioQQQ, " I cant form a ratio if continuum is first source.\n" );
1311  }
1312 
1313  /* first find photon flux and Q of previous continuum */
1314  rfield.ipSpec -= 1;
1315  flx1 = ffun1(rfield.range[i][0])*rfield.spfac[rfield.ipSpec]*
1316  rfield.range[i][0];
1317 
1318  /* check that previous continua were not zero where ratio is formed */
1319  if( flx1 <= 0. )
1320  {
1321  fprintf( ioQQQ, " Previous continua were zero where ratio is desired.\n" );
1323  }
1324 
1325  /* return pointer to previous (correct) value, find F, Q */
1326  rfield.ipSpec += 1;
1327 
1328  /* we want a continuum totpow as powerful, flx is now desired flx */
1329  flx1 *= rfield.totpow[i];
1330 
1331  /*. find flux of this new continuum at that point */
1332  flx2 = ffun1(rfield.range[i][1])*rfield.range[i][1];
1333 
1334  /* this is ratio of desired to actual */
1335  rfield.spfac[i] = flx1/flx2;
1336  if( trace.lgTrace )
1337  {
1338  fprintf( ioQQQ, " conorm ratio will set scale fac to%10.3e at%10.2e Ryd.\n",
1339  rfield.totpow[i], rfield.range[i][0] );
1340  }
1341  }
1342 
1343  else if( strcmp(rfield.chSpNorm[i],"FLUX") == 0 )
1344  {
1345  /* specify flux density
1346  * option to use arbitrary frequency or range */
1347  f = ffun1(rfield.range[i][0]);
1348 
1349  /* make sure this is positive, could be zero if out of range of table,
1350  * or for various forms of insanity */
1351  if( f<=SMALLDOUBLE )
1352  {
1353  fprintf( ioQQQ, "\n\n PROBLEM DISASTER\n The intensity of continuum source %ld is non-positive at the energy used to normalize it (%.3e Ryd). Something is seriously wrong.\n",
1354  i , rfield.range[i][0]);
1355  /* is this a table? if so, is ffun within its bounds? */
1356  if( strcmp(rfield.chSpType[i],"INTER") == 0 )
1357  fprintf( ioQQQ, " This continuum shape given by a table of points - check that the intensity is specified at an energy within the range of that table.\n");
1358  fprintf( ioQQQ, " Also check that the numbers used to specify the shape and intensity do not under or overflow on this cpu.\n\n");
1359 
1361  }
1362 
1363  /* now convert to log in continuum units we shall use */
1364  // EN1RYD/FR1RYD == HPLANCK
1365  f = log10(f) + log10(rfield.range[i][0]*EN1RYD/FR1RYD);
1366  f = rfield.totpow[i] - f;
1367  rfield.spfac[i] = exp10(f);
1368 
1369  if( trace.lgTrace )
1370  {
1371  fprintf( ioQQQ, " conorm will set log fnu to%10.3e at%10.2e Ryd. Factor=%11.4e\n",
1372  rfield.totpow[i], rfield.range[i][0], rfield.spfac[i] );
1373  }
1374  }
1375 
1376  else if( strcmp(rfield.chSpNorm[i],"Q(H)") == 0 ||
1377  strcmp(rfield.chSpNorm[i],"PHI ") == 0 )
1378  {
1379  /* some type of photon density entered */
1380  if( trace.lgTrace )
1381  {
1382  fprintf( ioQQQ, " conorm calling qintr range=%11.3e %11.3e desired val is %11.3e\n",
1383  rfield.range[i][0],
1384  rfield.range[i][1] ,
1385  rfield.totpow[i]);
1386  }
1387 
1388  /* the total number of photons over the specified range in
1389  * the arbitrary system of units that the code save the continuum shape */
1390  ASSERT( rfield.range[i][0] < rfield.range[i][1] );
1391  qentrd = qintr(rfield.range[i][0],rfield.range[i][1]);
1392  /* this is the log of the scale factor that must multiply the
1393  * continuum shape to get the final set of numbers */
1394  diff = rfield.totpow[i] - qentrd;
1395 
1396  if( diff < log10(SMALLDOUBLE) || diff > log10(BIGDOUBLE) )
1397  {
1398  fprintf( ioQQQ, " PROBLEM DISASTER Continuum source specified is too extreme.\n" );
1399  fprintf( ioQQQ,
1400  " The integral over the continuum shape gave (log) %.3e photons, and the command requested (log) %.3e.\n" ,
1401  qentrd , rfield.totpow[i]);
1402  fprintf( ioQQQ,
1403  " The difference in the log is %.3e.\n" ,
1404  diff );
1405  if( diff>0. )
1406  {
1407  fprintf( ioQQQ, " The continuum source is too bright.\n" );
1408  }
1409  else
1410  {
1411  fprintf( ioQQQ, " The continuum source is too faint.\n" );
1412  }
1413  /* explain what happened */
1414  fprintf( ioQQQ, " The usual cause for this problem is an incorrect continuum intensity/luminosity or radius command.\n" );
1415  fprintf( ioQQQ, " There were a total of %li continuum shape commands entered - the problem is with number %li.\n",
1416  rfield.nShape , i+1 );
1418  }
1419 
1420  else
1421  {
1422  rfield.spfac[i] = exp10(diff);
1423  }
1424 
1425  if( trace.lgTrace )
1426  {
1427  fprintf( ioQQQ, " conorm finds Q over range from%11.4e-%11.4e Ryd, integral= %10.4e Factor=%11.4e\n",
1428  rfield.range[i][0],
1429  rfield.range[i][1],
1430  qentrd ,
1431  rfield.spfac[i] );
1432  }
1433  }
1434 
1435  else if( strcmp(rfield.chSpNorm[i],"LUMI") == 0 )
1436  {
1437  /* luminosity entered, special since default is TOTAL lumin */
1438  /*pintr integrates L for any continuum between two limits, used for normalization,
1439  * return units are log of ryd cm-2 s-1, last log conv to ergs */
1440  pentrd = pintr(rfield.range[i][0],rfield.range[i][1]) + log10(EN1RYD);
1441  f = rfield.totpow[i] - pentrd;
1442  rfield.spfac[i] = exp10(f);
1443 
1444  if( trace.lgTrace )
1445  {
1446  fprintf( ioQQQ, " conorm finds luminosity range is %10.3e to %9.3e Ryd, factor is %11.4e\n",
1447  rfield.range[i][0], rfield.range[i][1],
1448  rfield.spfac[i] );
1449  }
1450  }
1451 
1452  else
1453  {
1454  fprintf( ioQQQ, "PROBLEM DISASTER What chSpNorm label is this? =%s=\n", rfield.chSpNorm[i]);
1455  TotalInsanity();
1456  }
1457 
1458  /* spfac used to renormalize SED into flux */
1459  if( fabs(rfield.spfac[i]) <=SMALLDOUBLE )
1460  {
1461  fprintf( ioQQQ, "PROBLEM DISASTER conorm finds infinite continuum scale factor.\n" );
1462  fprintf( ioQQQ, "The continuum is too intense to compute with this cpu.\n" );
1463  fprintf( ioQQQ, "Were the intensity and luminosity commands switched?\n" );
1464  fprintf( ioQQQ, "Sorry, but I cannot go on.\n" );
1466  }
1467  }
1468 
1469  /* this is conversion factor for final units of line intensities or luminosities in printout,
1470  * will be intensities (==0) unless luminosity is to be printed, or flux at Earth
1471  * pirsq is the log of 4 pi r_in^2 */
1472  radius.Conv2PrtInten = exp10((double)radius.pirsq);
1473 
1474  /* >>chng 02 apr 25, add option for slit on aperture command */
1475  if( geometry.iEmissPower == 1 )
1476  {
1477  if( radius.lgPredLumin )
1478  {
1479  /* factor should be divided by 2 r_in (so that 2pi*r_in remains) */
1480  radius.Conv2PrtInten /= (2. * radius.rinner);
1481  }
1482  else
1483  {
1484  /* this is an error - slit requested but radius is not known */
1485  fprintf( ioQQQ, "PROBLEM DISASTER conorm: Aperture slit specified, but not predicting luminosity.\n" );
1486  fprintf( ioQQQ, "conorm: Please specify an inner radius to determine L.\nSorry\n" );
1488  }
1489  }
1490  if( geometry.iEmissPower == 0 && radius.lgPredLumin )
1491  {
1492  /* leave Conv2PrtInten at zero if not predicting luminosity */
1493  radius.Conv2PrtInten = 2.;
1494  }
1495 
1496  /* this is option to give final absolute results as flux observed at Earth */
1498  {
1499  /* this implements the conversion from Q_alpha -> F_alpha
1500  * described in the section on the APERTURE command in Hazy 1 */
1501  if( geometry.iEmissPower == 0 )
1502  radius.Conv2PrtInten *= double(geometry.size)/SQAS_SKY;
1503  else if( geometry.iEmissPower == 1 )
1504  radius.Conv2PrtInten *= double(geometry.size)/(PI4*AS1RAD*radius.distance);
1505  else if( geometry.iEmissPower == 2 )
1507  else
1508  TotalInsanity();
1509  }
1510 
1511  /* normally lines are into 4pi, this is option to do per sr or arcsec^2 */
1512  if( prt.lgSurfaceBrightness )
1513  {
1514  if( radius.pirsq != 0. )
1515  {
1516  /* make sure we are predicting line intensities, not luminosity */
1517  fprintf( ioQQQ, " PROBLEM DISASTER Sorry, but both luminosity and surface brightness have been requested for lines.\n" );
1518  fprintf( ioQQQ, " the PRINT LINE SURFACE BRIGHTNESS command can only be used when lines are predicted per unit cloud area.\n" );
1520  }
1522  {
1523  /* we want final units to be per sr */
1524  radius.Conv2PrtInten /= PI4;
1525  }
1526  else
1527  {
1528  /* we want final units to be per square arcsec */
1529  radius.Conv2PrtInten /= SQAS_SKY;
1530  }
1531  }
1532  return;
1533 }
1534 
1535 /*qintr integrates Q for any continuum between two limits, used for normalization */
1536 STATIC double qintr(double qenlo, double qenhi)
1537 {
1538  DEBUG_ENTRY( "qintr()" );
1539 
1540  /* returns LOG of number of photons over energy interval */
1541 
1542  /* this is copy of logic that occurs three times across code */
1543  ASSERT( qenhi > qenlo );
1544  long ipLo = rfield.ipointC( qenlo );
1545  long ipHi = rfield.ipointC( qenhi );
1546  /* this is actual sum of photons within band */
1547  double sum = 0.;
1548  for( long i=ipLo; i < ipHi; i++ )
1549  sum += ffun1(rfield.anu(i))*rfield.widflx(i);
1550 
1551  if( sum <= 0. )
1552  {
1553  fprintf( ioQQQ, " PROBLEM DISASTER Photon number sum in QINTR is %.3e\n",
1554  sum );
1555  fprintf( ioQQQ, " This source has no ionizing radiation, and the number of ionizing photons was specified.\n" );
1556  fprintf( ioQQQ, " This was continuum source number%3ld\n",
1557  rfield.ipSpec );
1558  fprintf( ioQQQ, " Sorry, but I cannot go on. ANU and FLUX arrays follow. Enjoy.\n" );
1559  fprintf( ioQQQ, "\n\n This error is also caused by an old table read file whose energy mesh does not agree with the code.\n" );
1560  for( long i=0; i < rfield.nflux_with_check; i++ )
1561  {
1562  fprintf( ioQQQ, "%.2e\t%.2e\n",
1563  rfield.anu(i),
1564  rfield.flux[0][i] );
1565  }
1567  }
1568 
1569  return log10(sum);
1570 }
1571 
1572 /*pintr integrates L for any continuum between two limits, used for normalization,
1573  * return units are log of ryd cm-2 s-1 */
1574 STATIC double pintr(double penlo, double penhi)
1575 {
1576  DEBUG_ENTRY( "pintr()" );
1577 
1578  /* computes log of luminosity in radiation over some integral
1579  * answer is in Ryd per sec */
1580 
1581  double sum = 0.;
1582  /* >>chng 02 oct 27, do not call qg32, do same type sum as
1583  * final integration */
1584  /* laser is special since delta function, this is center of laser */
1585  /* >>chng 01 jul 01, was +-21 cells, change to call to ipoint */
1586  long ip1 = rfield.ipointC( penlo );
1587  long ip2 = rfield.ipointC( penhi );
1588 
1589  for( long i=ip1; i < ip2; i++ )
1590  sum += ffun1(rfield.anu(i))*rfield.anu(i)*rfield.widflx(i);
1591 
1592  return ( sum > 0. ) ? log10(sum) : -38.;
1593 }
double TEnerDen
Definition: phycon.h:108
realnum * csigh
Definition: rfield.h:269
realnum q
Definition: prt.h:280
vector< double, allocator_avx< double > > ContBoltz
Definition: rfield.h:124
bool lgBeamed[LIMSPC]
Definition: rfield.h:294
t_thermal thermal
Definition: thermal.cpp:6
realnum * flux_isotropic
Definition: rfield.h:71
bool lgContinuumLoweringEnabled[NISO]
Definition: iso.h:378
realnum TimeErode
Definition: timesc.h:61
realnum size
Definition: geometry.h:77
qList st
Definition: iso.h:482
double ffun(double anu)
Definition: cont_ffun.cpp:14
double exp10(double x)
Definition: cddefines.h:1368
realnum sv4861
Definition: continuum.h:75
const int ipHE_LIKE
Definition: iso.h:65
void iso_continuum_lower(long ipISO, long nelem)
realnum qtot
Definition: rfield.h:341
long int ipG0_DB96_hi
Definition: rfield.h:248
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
double widflx(size_t i) const
Definition: mesh.h:156
double EdenHCorr
Definition: dense.h:227
realnum qbal
Definition: rfield.h:341
realnum * flux_beam_const_save
Definition: rfield.h:200
const double BIGDOUBLE
Definition: cpu.h:249
t_opac opac
Definition: opacity.cpp:5
realnum ** flux
Definition: rfield.h:68
t_Heavy Heavy
Definition: heavy.cpp:5
realnum occ1nu
Definition: rfield.h:455
vector< string > chContLabel
Definition: rfield.h:213
const realnum SMALLFLOAT
Definition: cpu.h:246
t_isoCTRL iso_ctrl
Definition: iso.cpp:9
const int NISO
Definition: cddefines.h:311
double totpow[LIMSPC]
Definition: rfield.h:284
long int IonHigh[LIMELM+1]
Definition: dense.h:130
char chRSpec[LIMSPC][5]
Definition: rfield.h:335
realnum ** flux_total_incident
Definition: rfield.h:199
realnum sv1216
Definition: continuum.h:75
char TorF(bool l)
Definition: cddefines.h:749
const int ipOXYGEN
Definition: cddefines.h:356
bool lgOcc1Hi
Definition: rfield.h:463
long int iEmissPower
Definition: geometry.h:71
const double SMALLDOUBLE
Definition: cpu.h:250
bool lgComBug
Definition: trace.h:37
t_hextra hextra
Definition: hextra.cpp:5
bool lgNeutrnHeatOn
Definition: hextra.h:81
double distance
Definition: radius.h:71
realnum qhe
Definition: rfield.h:341
t_phycon phycon
Definition: phycon.cpp:6
long int i2d
Definition: oxy.h:38
realnum fluxv
Definition: continuum.h:80
realnum effneu
Definition: hextra.h:85
double RSFCheck[LIMSPC]
Definition: rfield.h:327
double coll_ion_wrapper(long int z, long int n, double t)
vector< Energy > tNu[LIMSPC]
Definition: rfield.h:314
double ffun1(double xnu)
Definition: cont_ffun.cpp:110
vector< double, allocator_avx< double > > ContBoltzHelp2
Definition: rfield.h:128
realnum cn4861
Definition: continuum.h:75
sys_float sexp(sys_float x)
Definition: service.cpp:999
double CosRayIonRate
Definition: ionbal.h:127
long int ipo3exc[3]
Definition: opacity.h:223
t_noexec noexec
Definition: noexec.cpp:4
bool lgTemperatureConstant
Definition: thermal.h:44
void ion_trim_init()
Definition: ion_trim.cpp:35
bool lgHInducImp
Definition: hydrogenic.h:132
long int ipEnerGammaRay
Definition: rfield.h:449
realnum covgeo
Definition: geometry.h:45
vector< double, allocator_avx< double > > ContBoltzAvg
Definition: rfield.h:135
realnum pradio
Definition: prt.h:280
FILE * ioQQQ
Definition: cddefines.cpp:7
long ncont[LIMSPC]
Definition: rfield.h:323
double spfac[LIMSPC]
Definition: rfield.h:284
vector< realnum > tslop[LIMSPC]
Definition: rfield.h:315
bool lgTalk
Definition: called.h:12
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
void TempChange(double TempNew, bool lgForceUpdate)
Definition: temp_change.cpp:32
bool lgNoExec
Definition: noexec.h:14
realnum ExtinguishEnergyPowerLow
Definition: rfield.h:81
realnum frcneu
Definition: hextra.h:83
t_dense dense
Definition: global.cpp:15
bool lgTimeVary[LIMSPC]
Definition: rfield.h:290
realnum fx1ryd
Definition: prt.h:280
static t_ADfA & Inst()
Definition: cddefines.h:209
double range[LIMSPC][2]
Definition: rfield.h:331
bool lgHabing
Definition: rfield.h:361
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:11
long int nflux_with_check
Definition: rfield.h:49
realnum ExtinguishConvertColDen2OptDepth
Definition: rfield.h:81
realnum SetCsupra
Definition: secondaries.h:45
double xIonDense[LIMELM][LIMELM+1]
Definition: dense.h:135
t_trace trace
Definition: trace.cpp:5
bool fp_equal(sys_float x, sys_float y, int n=3)
Definition: cddefines.h:854
void RT_OTS_Zero(void)
Definition: rt_ots.cpp:571
t_ionbal ionbal
Definition: ionbal.cpp:8
double rinner
Definition: radius.h:31
realnum ExtinguishLeakage
Definition: rfield.h:81
long int ipG0_DB96_lo
Definition: rfield.h:248
t_geometry geometry
Definition: geometry.cpp:5
size_t ipointC(double anu) const
Definition: mesh.h:161
long ipoint(double energy_ryd)
Definition: cont_ipoint.cpp:15
bool lgConBug
Definition: trace.h:97
long int IonLow[LIMELM+1]
Definition: dense.h:129
double slope[LIMSPC]
Definition: rfield.h:284
realnum pbal
Definition: prt.h:280
#define POW2
Definition: cddefines.h:979
realnum tbrmax
Definition: rfield.h:455
const int ipH1s
Definition: iso.h:29
#define STATIC
Definition: cddefines.h:118
bool lgTrace
Definition: trace.h:12
long int ipPlasma
Definition: rfield.h:436
STATIC void extin(realnum *ex1ryd)
t_continuum continuum
Definition: continuum.cpp:6
long int ipCKshell
Definition: opacity.h:311
bool lgSurfaceBrightness
Definition: prt.h:179
realnum qhtot
Definition: rfield.h:341
double EdenTrue
Definition: dense.h:232
t_rfield rfield
Definition: rfield.cpp:9
realnum * flux_time_beam_save
Definition: rfield.h:200
STATIC double pintr(double penlo, double penhi)
realnum * convoc
Definition: rfield.h:113
float realnum
Definition: cddefines.h:124
realnum uh
Definition: rfield.h:349
#define EXIT_FAILURE
Definition: cddefines.h:168
realnum GammaLumin
Definition: prt.h:289
const realnum BIGFLOAT
Definition: cpu.h:244
Illuminate::IlluminationType Illumination[LIMSPC]
Definition: rfield.h:300
realnum uheii
Definition: rfield.h:352
long max(int a, long b)
Definition: cddefines.h:817
bool lgSurfaceBrightness_SR
Definition: prt.h:179
t_hydro hydro
Definition: hydrogenic.cpp:5
#define cdEXIT(FAIL)
Definition: cddefines.h:482
STATIC double qintr(double qenlo, double qenhi)
bool lgRadiusKnown
Definition: radius.h:122
long min(int a, long b)
Definition: cddefines.h:762
double anu2(size_t i) const
Definition: mesh.h:124
realnum * OccNumbIncidCont
Definition: rfield.h:117
vector< string > chLineLabel
Definition: rfield.h:210
char chSpNorm[LIMSPC][5]
Definition: rfield.h:335
realnum cryden
Definition: hextra.h:24
t_radius radius
Definition: radius.cpp:5
t_timesc timesc
Definition: timesc.cpp:7
double anumin(size_t i) const
Definition: mesh.h:148
t_prt prt
Definition: prt.cpp:14
realnum pirsq
Definition: radius.h:149
realnum ** ConEmitOut
Definition: rfield.h:151
bool lgElmtOn[LIMELM]
Definition: dense.h:160
realnum totneu
Definition: hextra.h:79
bool lgPredLumin
Definition: radius.h:145
realnum gas_phase[LIMELM]
Definition: dense.h:76
double Conv2PrtInten
Definition: radius.h:153
const int ipH2p
Definition: iso.h:31
double TotalLumin
Definition: continuum.h:71
realnum xpow
Definition: prt.h:280
#define ASSERT(exp)
Definition: cddefines.h:613
realnum fbeta
Definition: continuum.h:81
realnum ConstTemp
Definition: thermal.h:56
bool lgCon0
Definition: continuum.h:67
const int ipH_LIKE
Definition: iso.h:64
const int LIMELM
Definition: cddefines.h:308
T pow2(T a)
Definition: cddefines.h:981
void IncidentContinuumHere()
STATIC void sumcon(long int il, long int ih, realnum *q, realnum *p, realnum *panu)
realnum * flux_isotropic_save
Definition: rfield.h:200
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
double powpq(double x, int p, int q)
Definition: service.cpp:630
const int ipHELIUM
Definition: cddefines.h:350
realnum qgam
Definition: prt.h:280
realnum powion
Definition: prt.h:280
realnum ExtinguishColumnDensity
Definition: rfield.h:81
realnum qheii
Definition: rfield.h:341
realnum * csigc
Definition: rfield.h:269
bool lgHionRad
Definition: rfield.h:452
vector< GrainBin * > bin
Definition: grainvar.h:583
realnum EdenHCorr_f
Definition: dense.h:229
vector< double, allocator_avx< double > > ContBoltzHelp1
Definition: rfield.h:127
double eden
Definition: dense.h:201
double totlsv
Definition: continuum.h:71
t_oxy oxy
Definition: oxy.cpp:5
bool lgPrintFluxEarth
Definition: prt.h:175
#define MAX2(a, b)
Definition: cddefines.h:824
bool lgCompRecoil
Definition: ionbal.h:153
realnum * ExtinguishFactor
Definition: rfield.h:80
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
realnum ** csupra
Definition: secondaries.h:33
realnum OpticalDepthScaleFactor[LIMSPC]
Definition: rfield.h:298
long int ipPlasmax
Definition: rfield.h:436
STATIC void conorm()
double telogn[7]
Definition: phycon.h:86
const int ipCARBON
Definition: cddefines.h:354
long int nShape
Definition: rfield.h:306
long int ipSpec
Definition: rfield.h:306
long int numLevels_max
Definition: iso.h:524
realnum EdenSet
Definition: dense.h:214
double anumax(size_t i) const
Definition: mesh.h:152
realnum occmnu
Definition: rfield.h:455
void EdenChange(double EdenNew)
Definition: eden_change.cpp:11
realnum ** ConEmitReflec
Definition: rfield.h:145
realnum * flux_beam_time
Definition: rfield.h:74
GrainVar gv
Definition: grainvar.cpp:5
t_secondaries secondaries
Definition: secondaries.cpp:5
#define POW3
Definition: cddefines.h:986
void ShowMe(void)
Definition: service.cpp:205
realnum * flux_beam_const
Definition: rfield.h:74
double te
Definition: phycon.h:21
long int i2p
Definition: oxy.h:38
realnum plsfrqmax
Definition: rfield.h:430
realnum qrad
Definition: rfield.h:341
realnum qx
Definition: prt.h:280
const int ipHYDROGEN
Definition: cddefines.h:349
realnum plsfrq
Definition: rfield.h:430
long int nflux
Definition: rfield.h:46
const int ipLITHIUM
Definition: cddefines.h:351
bool lgPlasNu
Definition: rfield.h:428
realnum ** ConRefIncid
Definition: rfield.h:157
long int nPositive
Definition: rfield.h:53
realnum tbr4nu
Definition: rfield.h:455
realnum EdenExtra
Definition: dense.h:217
double getResolutionScaleFactor() const
Definition: mesh.h:101
char chSpType[LIMSPC][6]
Definition: rfield.h:335
t_called called
Definition: called.cpp:4
long int ipHeavy[LIMELM][LIMELM]
Definition: heavy.h:11
realnum cn1216
Definition: continuum.h:75
realnum ExtinguishLowEnergyLimit
Definition: rfield.h:81
long int ** ipCompRecoil
Definition: ionbal.h:159
realnum occmax
Definition: rfield.h:455
void ContSetIntensity()
long int ipeak
Definition: prt.h:288
realnum tbrmnu
Definition: rfield.h:455