cloudy  trunk
highen.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2013 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*highen do high energy radiation field - gas interaction, Compton scattering, etc */
4 #include "cddefines.h"
5 #include "physconst.h"
6 #include "trace.h"
7 #include "heavy.h"
8 #include "radius.h"
9 #include "magnetic.h"
10 #include "hextra.h"
11 #include "thermal.h"
12 #include "dense.h"
13 #include "doppvel.h"
14 #include "ionbal.h"
15 #include "rfield.h"
16 #include "opacity.h"
17 #include "gammas.h"
18 #include "highen.h"
19 #include "pressure.h"
20 
21 void highen( void )
22 {
23  long int i,
24  ion,
25  nelem;
26 
27  double CosRayDen,
28  crsphi,
29  heatin,
30  sqthot;
31 
32  double hin;
33 
34  DEBUG_ENTRY( "highen()" );
35 
36 
37  /**********************************************************************
38  *
39  * COMPTON RECOIL IONIZATION
40  *
41  * bound electron scattering of >2.3 kev photons if neutral
42  * lgComptonOn usually t, f if "NO COMPTON EFFECT" command given
43  * lgCompRecoil usually t, f if "NO RECOIL IONIZATION" command given
44  *
45  **********************************************************************/
46 
47  /* lgComptonOn turned false with no compton command,
48  * lgCompRecoil - no recoil ionization */
50  {
51  for( nelem=0; nelem<LIMELM; ++nelem )
52  {
53  for( ion=0; ion<nelem+1; ++ion )
54  {
55  ionbal.CompRecoilIonRate[nelem][ion] = 0.;
56  ionbal.CompRecoilHeatRate[nelem][ion] = 0.;
57  if( dense.xIonDense[nelem][ion] > 0. )
58  {
59  /* recoil ionization starts at 194 Ryd = 2.6 keV */
60  /* this is the ionization potential of the valence shell */
61  /* >>chng 02 may 27, lower limit is now 1 beyond actual threshold
62  * since recoil energy at threshold was very small, sometimes negative */
63  for( i=ionbal.ipCompRecoil[nelem][ion]; i < rfield.nflux; ++i)
64  {
65  double recoil_energy;
66  crsphi = opac.OpacStack[i-1+opac.iopcom] * rfield.SummedCon[i] *
67  /* this is number of electrons in valence shell of this ion */
68  ionbal.nCompRecoilElec[nelem-ion];
69 
70  /* direct hydrogen ionization due to compton scattering,
71  * does not yet include secondaries,
72  * last term accounts for number of valence electrons that contribute */
73  ionbal.CompRecoilIonRate[nelem][ion] += crsphi;
74 
75  /* recoil energy in Rydbergs
76  * heating modified for suprathermal secondaries below; ANU2=ANU**2 */
77  /* >>chng 02 mar 27, use general formula for recoil energy */
78  /*energy = 2.66e-5*rfield.anu2[i] - 1.;*/
79  recoil_energy = rfield.anu2[i] /
81  Heavy.Valence_IP_Ryd[nelem][ion];
82 
83  /* heating is in rydbergs because SecIon2PrimaryErg, SecExcitLya2PrimaryErg, HeatEfficPrimary in ryd */
84  ionbal.CompRecoilHeatRate[nelem][ion] += crsphi*recoil_energy;
85  }
86  /* net heating rate, per atom, convert ryd/sec/cm3 to ergs/sec/atom */
87  ionbal.CompRecoilHeatRate[nelem][ion] *= EN1RYD;
88 
89  ASSERT( ionbal.CompRecoilHeatRate[nelem][ion] >= 0.);
90  ASSERT( ionbal.CompRecoilIonRate[nelem][ion] >= 0.);
91  }
92  }
93  }
94  }
95  else
96  {
97  for( nelem=0; nelem<LIMELM; ++nelem )
98  {
99  for( ion=0; ion<nelem+1; ++ion )
100  {
101  ionbal.CompRecoilIonRate[nelem][ion] = 0.;
102  ionbal.CompRecoilHeatRate[nelem][ion] = 0.;
103  }
104  }
105  }
106 
107  /**********************************************************************
108  *
109  * COSMIC RAYS
110  *
111  * heating and ionization by cosmic rays, other relativistic particles
112  * CRYDEN=density (1/CM**3), neutral rate assumes 15ev total
113  * energy loss, 13.6 into ionization, 1.4 into heating
114  * units erg/sec/cm**3
115  * iff not specified, CRTEMP is 2.6E9K
116  *
117  **********************************************************************/
118 
119  if( hextra.cryden > 0. )
120  {
121  ASSERT( hextra.crtemp > 0. );
122  /* this is current cosmic ray density, as determined from original density times
123  * possible dependence on radius */
125  {
126  /* >>chng 06 jun 02, add this option
127  * this is case where cr are in equipartition with magnetic field -
128  * set with COSMIC RAY EQUIPARTITION command */
129  CosRayDen = hextra.background_density *
130  /* ratio of energy density in current B to typical galactic
131  * galactic background energy density of 1.8 eV cm-3 is from
132  *>>refer cr background Webber, W.R. 1998, ApJ, 506, 329 */
134  (CR_EDEN_GAL_BACK_EV_CMM3/*1.8eV cm-3*/ * EN1EV/*erg eV-1*/ );
135  }
136  else
137  {
138  /* this is usual case, CR density may depend on radius, usually does not */
139  CosRayDen = hextra.cryden*pow(radius.Radius/radius.rinner,(double)hextra.crpowr);
140  }
141 
142  /* cosmic ray energy density rescaled by ratio to background ion rate and B field */
144  (CR_EDEN_GAL_BACK_EV_CMM3/*1.8eV cm-3*/ * EN1EV/*erg eV-1*/ );
145 
146  /* related to current temperature, when thermal */
147  sqthot = sqrt(hextra.crtemp);
148 
149  /* rate hot electrons heat cold ones, Balbus and McKee 1982
150  * units erg sec^-1 cm^-3,
151  * in sumheat we will multipy this rate by sum of neturals, but for this
152  * term we actually want eden, so mult by eden over sum of neut */
153  ionbal.CosRayHeatThermalElectrons = 5.5e-14/sqthot*CosRayDen;
154 
155  /* ionization rate; Balbus and McKee */
156  ionbal.CosRayIonRate = 1.22e-4/sqthot*
157  log(2.72*pow(hextra.crtemp/1e8,0.097))*CosRayDen;
158 
159  /* option for thermal CRs, first is the usual (and default) relativistic case */
160  if( hextra.crtemp > 2e9 )
161  {
162  /* usual circumstance; relativistic cosmic rays,
163  * cosmic ray ionization rate s-1 cm-3; ext rel limit */
164  ionbal.CosRayIonRate *= 3.;
165 
166  }
167  else
168  {
169  /* option for thermal cosmic rays */
170  ionbal.CosRayIonRate *= 10.;
171  }
172  /* >>chng 04 jan 27, from 0.093 to 2.574 as per following */
173  /* cr heating from Table 1 of
174  *>>refer cr heating Wolfire et al.1995, ApJ, 443, 152
175  * For every ionization due to cosmic rays, ~35eV of heat is added
176  * to the system. This manifests itself in the ionbal.CosRayHeatNeutralParticles term
177  * by the 2.574*EN1RYD term, which is just the energy in ergs in 35 eV.
178  * Change made by Nick Abel and Gargi Shaw, 04 Jan 27. In heatsum
179  * we multiply by the number of secondaries that occur */
181 
182  if( trace.lgTrace )
183  {
184  fprintf( ioQQQ, " highen: cosmic ray density;%10.2e CRion rate;%10.2e CR heat rate=;%10.2e CRtemp;%10.2e\n",
186  }
187  }
188  else
189  {
190  ionbal.CosRayIonRate = 0.;
192  }
193  /* >>chng 06 may 23, Penning ionization
194  ionbal.CosRayIonRate += 1e-9 *
195  iso_sp[ipHE_LIKE][ipHELIUM].st[ipHe2s3S].Pop; */
196 
197  /*fprintf(ioQQQ,"DEBUG cr %.2f %.3e %.3e %.3e\n",
198  fnzone,
199  hextra.cryden ,
200  ionbal.CosRayIonRate ,
201  ionbal.CosRayHeatNeutralParticles );*/
202 
203  /**********************************************************************
204  *
205  * add on extra heating due to turbulence, goes into [1] of [x][0][11][0]
206  *
207  **********************************************************************/
208 
209  /* TurbHeat added with hextra command, DispScale added with turbulence dissipative */
210  if( (hextra.TurbHeat+DoppVel.DispScale) != 0. )
211  {
212  /* turbulent heating only goes into the low-energy heat of this element */
213  /* >>>>chng 00 apr 28, functional form of radius dependence had bee turrad/depth
214  * and so went to infinity at the illuminated face. Changed to current form as
215  * per Ivan Hubeny comment */
216  if( hextra.lgHextraDepth )
217  {
218  /* if turrad is >0 then vary heating with depth */
221 
222  /* >>chng 00 aug 16, added option for heating from back side */
223  if( hextra.turback != 0. )
224  {
227  }
228  }
229  else if( hextra.lgHextraDensity )
230  {
231  /* depends on density */
234  }
235  else if( hextra.lgHextraSS )
236  {
237  /* with SS disk model */
240  pow((double)hextra.HextraSSradius,-3.0),0.5);
241  }
242  /* this is turbulence dissipate command */
243  else if( DoppVel.DispScale > 0. )
244  {
245  double turb = DoppVel.TurbVel * sexp( radius.depth / DoppVel.DispScale );
246  /* if turrad is >0 then vary heating with depth */
247  /* >>chng 01 may 10, add extra factor of length over 1e13 cm */
248  ionbal.ExtraHeatRate = 3.45e-28 / 2.82824 * turb * turb * turb *
249  ( dense.gas_phase[ipHYDROGEN] / 1e10 ) / (DoppVel.DispScale/1e13);
250  }
251  else
252  {
253  /* constant extra heating */
255  }
256  }
257 
258  else
259  {
260  ionbal.ExtraHeatRate = 0.;
261  }
262 
263  /**********************************************************************
264  *
265  * option to add on fast neutron heating, goes into [0] & [2] of [x][0][11][0]
266  *
267  **********************************************************************/
268  if( hextra.lgNeutrnHeatOn )
269  {
270  /* hextra.totneu is energy flux erg cm-2 s-1
271  * CrsSecNeutron is 4E-26 cm^-2, cross sec for stopping rel neutrons
272  * this is heating erg s-1 due to fast neutrons, assumed to secondary ionize */
273  /* neutrons assumed to only secondary ionize */
275  }
276  else
277  {
279  }
280 
281 
282  /**********************************************************************
283  *
284  * pair production in elec field of nucleus
285  *
286  **********************************************************************/
287  t_phoHeat photoHeat;
289  ionbal.PairProducPhotoRate[1] = photoHeat.HeatLowEnr;
290  ionbal.PairProducPhotoRate[2] = photoHeat.HeatHiEnr;
291 
292  /**********************************************************************
293  *
294  * Compton energy exchange
295  *
296  **********************************************************************/
297  rfield.cmcool = 0.;
298  rfield.cmheat = 0.;
299  heatin = 0.;
300  /* lgComptonOn usually t, turns off Compton */
301  if( rfield.lgComptonOn )
302  {
303  for( i=0; i < rfield.nflux; i++ )
304  {
305 
306  /* Compton cooling
307  * CSIGC is Tarter expression times ANU(I)*3.858E-25
308  * 6.338E-6 is k in inf mass Rydbergs, still needs factor of TE */
309  rfield.comup[i] = (double)(rfield.flux[0][i]+rfield.ConInterOut[i]+
310  rfield.outlin[0][i]+ rfield.outlin_noplot[i])*rfield.csigc[i]*(dense.eden*4.e0*
311  6.338e-6*1e-15);
312 
313  rfield.cmcool += rfield.comup[i];
314 
315  /* Compton heating
316  * CSIGH is Tarter expression times ANU(I)**2 * 3.858E-25
317  * CMHEAT is just spontaneous, HEATIN is just induced */
318  rfield.comdn[i] = (double)(rfield.flux[0][i]+rfield.ConInterOut[i]+
319  rfield.outlin[0][i]+ rfield.outlin_noplot[i])*rfield.csigh[i]*dense.eden*1e-15;
320 
321  /* induced Compton heating */
322  hin = (double)(rfield.flux[0][i]+rfield.ConInterOut[i]+rfield.outlin[0][i]+rfield.outlin_noplot[i])*
324  rfield.comdn[i] += hin;
325  heatin += hin;
326 
327  /* following is total compton heating */
328  rfield.cmheat += rfield.comdn[i];
329  }
330 
331  /* remember how important induced compton heating is */
332  if( rfield.cmheat > 0. )
333  {
335  }
336 
337  if( trace.lgTrace && trace.lgComBug )
338  {
339  fprintf( ioQQQ, " HIGHEN: COOL num=%8.2e HEAT num=%8.2e\n",
341  }
342  }
343 
344  /* save compton heating rate into main heating save array,
345  * no secondary ionizations from compton heating cooling */
346  thermal.heating[0][19] = rfield.cmheat;
347 
348  if( trace.lgTrace && trace.lgComBug )
349  {
350  fprintf( ioQQQ,
351  " HIGHEN finds heating fracs= frac(compt)=%10.2e "
352  " f(pair)%10.2e totHeat=%10.2e\n",
353  thermal.heating[0][19]/thermal.htot,
354  thermal.heating[0][21]/thermal.htot,
355  thermal.htot );
356  }
357  return;
358 }
thermal.h
t_hextra::turback
realnum turback
Definition: hextra.h:43
t_ionbal::lgCompRecoil
bool lgCompRecoil
Definition: ionbal.h:149
t_phoHeat::HeatLowEnr
double HeatLowEnr
Definition: thermal.h:174
t_hextra::background_density
realnum background_density
Definition: hextra.h:28
t_dense::eden
double eden
Definition: dense.h:190
t_ionbal::PairProducPhotoRate
double PairProducPhotoRate[3]
Definition: ionbal.h:141
dense
t_dense dense
Definition: dense.cpp:24
t_hextra::lgHextraDensity
bool lgHextraDensity
Definition: hextra.h:47
t_rfield::lgComptonOn
bool lgComptonOn
Definition: rfield.h:295
rfield
t_rfield rfield
Definition: rfield.cpp:8
t_rfield::flux
realnum ** flux
Definition: rfield.h:86
ioQQQ
FILE * ioQQQ
Definition: cddefines.cpp:7
rfield.h
t_DoppVel::DispScale
realnum DispScale
Definition: doppvel.h:42
t_rfield::csigh
realnum * csigh
Definition: rfield.h:288
t_ionbal::CosRayHeatThermalElectrons
double CosRayHeatThermalElectrons
Definition: ionbal.h:131
t_ionbal::xNeutronHeatRate
double xNeutronHeatRate
Definition: ionbal.h:138
highen.h
trace.h
t_hextra::crtemp
realnum crtemp
Definition: hextra.h:16
t_opac::iopcom
long int iopcom
Definition: opacity.h:213
DoppVel
t_DoppVel DoppVel
Definition: doppvel.cpp:5
t_rfield::outlin
realnum ** outlin
Definition: rfield.h:199
t_hextra::turrad
realnum turrad
Definition: hextra.h:41
t_dense::gas_phase
realnum gas_phase[LIMELM]
Definition: dense.h:71
t_radius::depth
double depth
Definition: radius.h:38
t_opac::ippr
long int ippr
Definition: opacity.h:216
CR_EDEN_GAL_BACK_EV_CMM3
#define CR_EDEN_GAL_BACK_EV_CMM3
Definition: hextra.h:10
Heavy
t_Heavy Heavy
Definition: heavy.cpp:5
ASSERT
#define ASSERT(exp)
Definition: cddefines.h:578
t_trace::lgComBug
bool lgComBug
Definition: trace.h:37
ipHYDROGEN
const int ipHYDROGEN
Definition: cddefines.h:305
opac
t_opac opac
Definition: opacity.cpp:5
t_rfield::cinrat
double cinrat
Definition: rfield.h:294
highen
void highen(void)
Definition: highen.cpp:21
t_hextra::cryden
realnum cryden
Definition: hextra.h:14
t_rfield::comup
double * comup
Definition: rfield.h:255
radius
t_radius radius
Definition: radius.cpp:5
sexp
sys_float sexp(sys_float x)
Definition: service.cpp:914
dense.h
t_hextra::HextraScaleDensity
realnum HextraScaleDensity
Definition: hextra.h:50
t_magnetic::energydensity
double energydensity
Definition: magnetic.h:36
trace
t_trace trace
Definition: trace.cpp:5
t_DoppVel::TurbVel
realnum TurbVel
Definition: doppvel.h:12
t_Heavy::Valence_IP_Ryd
double Valence_IP_Ryd[LIMELM][LIMELM]
Definition: heavy.h:24
cddefines.h
hextra
t_hextra hextra
Definition: hextra.cpp:5
EN1EV
const UNUSED double EN1EV
Definition: physconst.h:192
t_rfield::cmcool
double cmcool
Definition: rfield.h:293
t_radius::Radius
double Radius
Definition: radius.h:25
thermal
t_thermal thermal
Definition: thermal.cpp:5
t_radius::rinner
double rinner
Definition: radius.h:22
t_pressure::PresGasCurr
double PresGasCurr
Definition: pressure.h:89
t_rfield::comdn
double * comdn
Definition: rfield.h:256
t_opac::OpacStack
double * OpacStack
Definition: opacity.h:151
GammaK
double GammaK(long int ipLoEnr, long int ipHiEnr, long int ipOpac, double yield1, t_phoHeat *photoHeat)
Definition: cont_gammas.cpp:359
t_thermal::heating
double heating[LIMELM][LIMELM]
Definition: thermal.h:158
radius.h
t_ionbal::CosRayHeatNeutralParticles
double CosRayHeatNeutralParticles
Definition: ionbal.h:127
t_hextra::HextraSSradius
realnum HextraSSradius
Definition: hextra.h:63
t_rfield::nflux
long int nflux
Definition: rfield.h:43
SPEEDLIGHT
const UNUSED double SPEEDLIGHT
Definition: physconst.h:100
heavy.h
t_hextra::lgNeutrnHeatOn
bool lgNeutrnHeatOn
Definition: hextra.h:71
ELECTRON_MASS
const UNUSED double ELECTRON_MASS
Definition: physconst.h:91
MAX2
#define MAX2
Definition: cddefines.h:782
t_rfield::SummedCon
double * SummedCon
Definition: rfield.h:171
ionbal
t_ionbal ionbal
Definition: ionbal.cpp:5
pressure.h
LIMELM
const int LIMELM
Definition: cddefines.h:258
t_rfield::cmheat
double cmheat
Definition: rfield.h:292
t_hextra::totneu
realnum totneu
Definition: hextra.h:69
t_hextra::TurbHeat
realnum TurbHeat
Definition: hextra.h:32
t_rfield::anu2
realnum * anu2
Definition: rfield.h:79
t_dense::xIonDense
double xIonDense[LIMELM][LIMELM+1]
Definition: dense.h:125
doppvel.h
t_thermal::htot
double htot
Definition: thermal.h:149
t_ionbal::ExtraHeatRate
double ExtraHeatRate
Definition: ionbal.h:134
t_hextra::CrsSecNeutron
double CrsSecNeutron
Definition: hextra.h:77
ionbal.h
magnetic.h
gammas.h
t_rfield::OccNumbIncidCont
realnum * OccNumbIncidCont
Definition: rfield.h:138
physconst.h
t_hextra::lgHextraSS
bool lgHextraSS
Definition: hextra.h:54
magnetic
t_magnetic magnetic
Definition: magnetic.cpp:17
t_rfield::ConInterOut
realnum * ConInterOut
Definition: rfield.h:164
t_hextra::HextraSS_M
double HextraSS_M
Definition: hextra.h:60
t_phoHeat
Definition: thermal.h:169
t_rfield::outlin_noplot
realnum * outlin_noplot
Definition: rfield.h:200
hextra.h
t_ionbal::CompRecoilIonRate
double ** CompRecoilIonRate
Definition: ionbal.h:158
pressure
t_pressure pressure
Definition: pressure.cpp:5
t_ionbal::nCompRecoilElec
long int nCompRecoilElec[LIMELM]
Definition: ionbal.h:188
t_ionbal::ipCompRecoil
long int ** ipCompRecoil
Definition: ionbal.h:155
t_hextra::crpowr
realnum crpowr
Definition: hextra.h:15
t_hextra::cr_energydensity
double cr_energydensity
Definition: hextra.h:22
t_hextra::lgHextraDepth
bool lgHextraDepth
Definition: hextra.h:39
t_rfield::csigc
realnum * csigc
Definition: rfield.h:289
t_hextra::lg_CR_B_equipartition
bool lg_CR_B_equipartition
Definition: hextra.h:19
t_phoHeat::HeatHiEnr
double HeatHiEnr
Definition: thermal.h:176
opacity.h
t_hextra::HextraSSalpha
realnum HextraSSalpha
Definition: hextra.h:57
GRAV_CONST
const UNUSED double GRAV_CONST
Definition: physconst.h:109
t_opac::ioppr
long int ioppr
Definition: opacity.h:217
t_ionbal::CosRayIonRate
double CosRayIonRate
Definition: ionbal.h:123
EN1RYD
const UNUSED double EN1RYD
Definition: physconst.h:179
DEBUG_ENTRY
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:684
t_trace::lgTrace
bool lgTrace
Definition: trace.h:12
t_ionbal::CompRecoilHeatRate
double ** CompRecoilHeatRate
Definition: ionbal.h:164