cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rt_tau_reset.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 /*RT_tau_reset after first iteration, updates the optical depths, mirroring this
4  * routine but with the previous iteration's variables */
5 #include "cddefines.h"
6 #include "taulines.h"
7 #include "trace.h"
8 #include "iso.h"
9 #include "rfield.h"
10 #include "opacity.h"
11 #include "h2.h"
12 #include "mole.h"
13 #include "geometry.h"
14 #include "dense.h"
15 #include "atomfeii.h"
16 #include "colden.h"
17 #include "rt.h"
18 
19 /* ====================================================================== */
20 /*RT_tau_reset update total optical depth scale,
21  * called by cloudy after iteration is complete */
22 void RT_tau_reset(void)
23 {
24  long int i,
25  ipHi,
26  ipISO,
27  nelem,
28  ipLo;
29 
30  DEBUG_ENTRY( "RT_tau_reset()" );
31 
32  if( trace.lgTrace )
33  {
34  fprintf( ioQQQ, " UPDATE estimating new optical depths\n" );
36  {
37  fprintf( ioQQQ, " New Hydrogen outward optical depths:\n" );
38  for( ipHi=1; ipHi < iso_sp[ipH_LIKE][ trace.ipIsoTrace[ipH_LIKE] ].numLevels_max; ipHi++ )
39  {
40  fprintf( ioQQQ, "%3ld", ipHi );
41  for( ipLo=0; ipLo < ipHi; ipLo++ )
42  {
43  if( iso_sp[ipH_LIKE][trace.ipIsoTrace[ipH_LIKE]].trans(ipHi,ipLo).ipCont() <= 0 )
44  fprintf( ioQQQ, "%10.2e", 1e-30 );
45  else
46  fprintf( ioQQQ, "%10.2e",
47  iso_sp[ipH_LIKE][trace.ipIsoTrace[ipH_LIKE]].trans(ipHi,ipLo).Emis().TauIn() );
48  }
49  fprintf( ioQQQ, "\n" );
50  }
51  }
52  }
53 
54  /* save column densities of H species */
55  for( i=0; i<NCOLD; ++i )
56  {
58  }
59  for( i=0; i < mole_global.num_calc; i++ )
60  {
61  mole.species[i].column_old = mole.species[i].column;
62  }
63 
66 
67  /* all iso sequences */
68  for(ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
69  {
70  for( nelem=ipISO; nelem < LIMELM; nelem++ )
71  {
72  if( dense.lgElmtOn[nelem] )
73  {
74  if( iso_ctrl.lgDielRecom[ipISO] )
75  {
76  for( ipHi=0; ipHi < iso_sp[ipISO][nelem].numLevels_max; ipHi++ )
77  {
78  RT_line_one_tau_reset(SatelliteLines[ipISO][nelem][ipSatelliteLines[ipISO][nelem][ipHi]]);
79  }
80  }
81 
82  for( ipHi=1; ipHi < iso_sp[ipISO][nelem].numLevels_max; ipHi++ )
83  {
84  /* the bound-bound transitions within the model atoms */
85  for( ipLo=0; ipLo < ipHi; ipLo++ )
86  {
87  enum {DEBUG_LOC=false};
88  if( DEBUG_LOC )
89  {
90  if( ipISO==1 && nelem==1 && ipHi==iso_ctrl.nLyaLevel[ipISO] && ipLo==0 )
91  fprintf(ioQQQ,"DEBUG rt before loop %li %li %li %li tot %.3e in %.3e\n",
92  ipISO, nelem, ipHi , ipLo ,
93  iso_sp[ipISO][nelem].trans(iso_ctrl.nLyaLevel[ipISO],0).Emis().TauTot() ,
94  iso_sp[ipISO][nelem].trans(iso_ctrl.nLyaLevel[ipISO],0).Emis().TauIn());
95  }
96  /*RT_line_one_tau_reset computes average of old and new optical depths
97  * for new scale at end of iter */
98  RT_line_one_tau_reset(iso_sp[ipISO][nelem].trans(ipHi,ipLo));
99  if( DEBUG_LOC )
100  {
101  if( ipISO==1 && nelem==1 && ipHi==iso_ctrl.nLyaLevel[ipISO] && ipLo==0 )
102  fprintf(ioQQQ,"DEBUG rt after loop %li %li %li %li tot %.3e in %.3e\n",
103  ipISO, nelem, ipHi , ipLo ,
104  iso_sp[ipISO][nelem].trans(iso_ctrl.nLyaLevel[ipISO],0).Emis().TauTot() ,
105  iso_sp[ipISO][nelem].trans(iso_ctrl.nLyaLevel[ipISO],0).Emis().TauIn());
106  }
107  }
108  }
109  /* the extra Lyman lines */
110  for( ipHi=iso_sp[ipISO][nelem].st[iso_sp[ipISO][nelem].numLevels_local-1].n()+1; ipHi < iso_ctrl.nLyman[ipISO]; ipHi++ )
111  {
112  /* fully transfer all of the extra lines even though
113  * have not solved for their upper level populations */
114  RT_line_one_tau_reset(ExtraLymanLines[ipISO][nelem][ipExtraLymanLines[ipISO][nelem][ipHi]]);
115  }
116  }
117  }
118  }
119 
120  /* >>>chng 99 nov 11 did not have case b for hydrogenic species on second and
121  * higher iterations */
122  /* option to clobber these taus for Lyman lines, if case b is set */
123  if( opac.lgCaseB )
124  {
125  for( nelem=0; nelem < LIMELM; nelem++ )
126  {
127  if( dense.lgElmtOn[nelem] )
128  {
129  realnum f;
130  /* La may be case B, tlamin set to 1e9 by default with case b command */
132  /* >>>chng 99 nov 22, did not reset TauCon */
134  iso_sp[ipH_LIKE][nelem].trans(ipH2p,ipH1s).Emis().TauTot() =
135  2.f*iso_sp[ipH_LIKE][nelem].trans(ipH2p,ipH1s).Emis().TauIn();
137 
138  for( ipHi=3; ipHi < iso_sp[ipH_LIKE][nelem].numLevels_max; ipHi++ )
139  {
140  if( iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).ipCont() <= 0 )
141  continue;
142 
143  iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).Emis().TauIn() =
144  f*iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).Emis().opacity();
145  /* reset line optical depth to continuum source */
146  iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).Emis().TauCon() = iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).Emis().TauIn();
147  iso_sp[ipH_LIKE][nelem].trans(ipHi,ipH1s).Emis().TauTot() =
148  2.f*iso_sp[ipH_LIKE][nelem].trans(ipH2p,ipH1s).Emis().TauIn();
149  }
150  }
151  }
152 
153  /* now do helium like sequence - different since collapsed levels
154  * all go to ground */
155  for( nelem=1; nelem < LIMELM; nelem++ )
156  {
157  if( dense.lgElmtOn[nelem] )
158  {
159  double Aprev;
160  realnum ratio;
161  /* La may be case B, tlamin set to 1e9 by default with case b command */
163 
165 
167  2.f*iso_sp[ipHE_LIKE][nelem].trans(ipHe2p1P,ipHe1s1S).Emis().TauIn();
168 
170 
171  /* this will be the trans prob of the previous lyman line, will use this to
172  * find the next one up in the series */
173  Aprev = iso_sp[ipHE_LIKE][nelem].trans(ipHe2p1P,ipHe1s1S).Emis().Aul();
174 
175  i = ipHe2p1P+1;
176  /* >>chng 02 jan 05, remove explicit list of lyman lines, use As to guess
177  * which are which - this will work for any number of levels */
178  for( i = ipHe2p1P+1; i < iso_sp[ipHE_LIKE][nelem].numLevels_max; i++ )
179  {
180  if( iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).ipCont() <= 0 )
181  continue;
182 
183  /* >>chng 02 mar 19 use proper test for resonance collapsed lines */
184  if( iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().Aul()> Aprev/10. ||
185  iso_sp[ipHE_LIKE][nelem].st[i].S() < 0 )
186  {
187  Aprev = iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().Aul();
188  iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().TauIn() =
189  ratio*iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().opacity();
190  /* reset line optical depth to continuum source */
191  iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().TauCon() =
192  iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().TauIn();
193  iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().TauTot() =
194  2.f*iso_sp[ipHE_LIKE][nelem].trans(i,ipHe1s1S).Emis().TauIn();
195  }
196  }
197  }
198  }
199  }
200 
201  /* all heavy element lines */
202  for( i=1; i <= nLevel1; i++ )
203  {
205  /* >>chng 96 jul 06 following sanity check added */
206  ASSERT( fabs(TauLines[i].Emis().TauIn()) <= fabs(TauLines[i].Emis().TauTot()) );
207  }
208 
209  /* zero out fine opacity fine grid fine mesh array */
210  memset(rfield.fine_opt_depth , 0 , (unsigned long)rfield.nfine*sizeof(realnum) );
211 
212  /* all level 2 heavy element lines */
213  for( i=0; i < nWindLine; i++ )
214  {
215  if( (*TauLine2[i].Hi()).IonStg() < (*TauLine2[i].Hi()).nelem()+1-NISO )
216  {
218  }
219  }
220 
221  /* all hyperfine structure lines */
222  for( i=0; i < nHFLines; i++ )
223  {
225  }
226 
227  /* external database lines */
228  for (int ipSpecies=0; ipSpecies < nSpecies; ++ipSpecies)
229  {
230  for( EmissionList::iterator em=dBaseTrans[ipSpecies].Emis().begin();
231  em != dBaseTrans[ipSpecies].Emis().end(); ++em)
232  {
233  RT_line_one_tau_reset((*em).Tran());
234  }
235  }
236 
237  /* inner shell lines */
238  for( i=0; i < nUTA; i++ )
239  {
240  /* these are line optical depth arrays
241  * inward optical depth */
242  /* heat is special for this array - it is heat per pump */
243  double hsave = UTALines[i].Coll().heat();
245  UTALines[i].Coll().heat() = hsave;
246  }
247 
248  /* the large H2 molecule */
249  for( diatom_iter diatom = diatoms.begin(); diatom != diatoms.end(); ++diatom )
250  (*diatom)->H2_RT_tau_reset();
251 
252  /* large FeII atom */
254 
255  if( opac.lgCaseB )
256  {
257  for( i=0; i < rfield.nupper; i++ )
258  {
259  /* DEPABS and SCT are abs and sct optical depth for depth only
260  * we will not change total optical depths, just reset inner to half
261  * TauAbsGeo(i,2) = 2.*TauAbsFace(i) */
262  opac.TauAbsGeo[0][i] = opac.TauAbsGeo[1][i]/2.f;
263  /* TauScatGeo(i,2) = 2.*TauScatFace(i) */
264  opac.TauScatGeo[0][i] = opac.TauScatGeo[1][i]/2.f;
265  }
266  }
267  else if( geometry.lgSphere )
268  {
269  /* closed or spherical case */
270  for( i=0; i < rfield.nupper; i++ )
271  {
272  /* [1] is total optical depth from previous iteration,
273  * [0] is optical depth at current position */
274  opac.TauAbsGeo[1][i] = 2.f*opac.TauAbsFace[i];
275  opac.TauAbsGeo[0][i] = opac.TauAbsFace[i];
276  opac.TauScatGeo[1][i] = 2.f*opac.TauScatFace[i];
277  opac.TauScatGeo[0][i] = opac.TauScatFace[i];
278  opac.TauTotalGeo[1][i] = opac.TauScatGeo[1][i] + opac.TauAbsGeo[1][i];
279  opac.TauTotalGeo[0][i] = opac.TauScatGeo[0][i] + opac.TauAbsGeo[0][i];
280  }
281  }
282  else
283  {
284  /* open geometry */
285  for( i=0; i < rfield.nupper; i++ )
286  {
287  opac.TauTotalGeo[1][i] = opac.TauTotalGeo[0][i];
288  opac.TauTotalGeo[0][i] = opac.taumin;
289  opac.TauAbsGeo[1][i] = opac.TauAbsGeo[0][i];
290  opac.TauAbsGeo[0][i] = opac.taumin;
291  opac.TauScatGeo[1][i] = opac.TauScatGeo[0][i];
292  opac.TauScatGeo[0][i] = opac.taumin;
293  }
294  }
295 
296  /* same for open and closed geometries */
297  for( i=0; i < rfield.nupper; i++ )
298  {
299  /* total optical depth across computed shell */
301  /* e2( tau across shell), optical depth from ill face to shielded face of cloud
302  * not that opac.TauAbsFace is reset to small number just after this */
304  /* TauAbsFace and TauScatFace are abs and sct optical depth to ill face */
306  opac.TauAbsFace[i] = opac.taumin;
307  }
308 
309  /* this is optical depth at x-ray point defining effective optical depth */
310  rt.tauxry = opac.TauAbsGeo[0][rt.ipxry-1];
311  return;
312 }
t_mole_global mole_global
Definition: mole.cpp:6
realnum * fine_opt_depth
Definition: rfield.h:410
realnum & opacity() const
Definition: emission.h:593
t_colden colden
Definition: colden.cpp:5
TransitionList UTALines("UTALines",&AnonStates)
const int ipHE_LIKE
Definition: iso.h:63
t_opac opac
Definition: opacity.cpp:5
multi_arr< int, 3 > ipSatelliteLines
Definition: taulines.cpp:37
int num_calc
Definition: mole.h:314
long int nLevel1
Definition: taulines.cpp:28
t_isoCTRL iso_ctrl
Definition: iso.cpp:6
void FeII_RT_tau_reset(void)
Definition: atom_feii.cpp:1425
const int NISO
Definition: cddefines.h:265
bool lgIsoTraceFull[NISO]
Definition: trace.h:88
realnum & TauTot() const
Definition: emission.h:433
TransitionList HFLines("HFLines",&AnonStates)
t_dense dense
Definition: dense.cpp:24
const int ipHe2p1P
Definition: iso.h:49
realnum colden_old[NCOLD]
Definition: colden.h:38
long int ipIsoTrace[NISO]
Definition: trace.h:91
FILE * ioQQQ
Definition: cddefines.cpp:7
realnum * E2TauAbsTotal
Definition: opacity.h:126
realnum * TauScatFace
Definition: opacity.h:91
const int ipHe1s1S
Definition: iso.h:41
TransitionList TauLine2("TauLine2",&AnonStates)
long int nSpecies
Definition: taulines.cpp:21
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:8
long int nupper
Definition: rfield.h:46
realnum tauxry
Definition: rt.h:253
bool lgSphere
Definition: geometry.h:24
t_trace trace
Definition: trace.cpp:5
void RT_tau_reset(void)
t_geometry geometry
Definition: geometry.cpp:5
long int nLyman[NISO]
Definition: iso.h:334
const int ipH1s
Definition: iso.h:27
bool lgTrace
Definition: trace.h:12
EmissionList::reference Emis() const
Definition: transition.h:408
realnum ** TauScatGeo
Definition: opacity.h:83
multi_arr< int, 3 > ipExtraLymanLines
Definition: taulines.cpp:24
#define NCOLD
Definition: colden.h:9
t_mole_local mole
Definition: mole.cpp:7
t_rfield rfield
Definition: rfield.cpp:8
long & ipCont() const
Definition: transition.h:450
bool lgCaseB
Definition: opacity.h:161
bool lgDielRecom[NISO]
Definition: iso.h:365
float realnum
Definition: cddefines.h:107
valarray< class molezone > species
Definition: mole.h:355
realnum thmin
Definition: opacity.h:175
vector< diatomics * > diatoms
Definition: h2.cpp:8
realnum telec
Definition: opacity.h:175
bool lgElmtOn[LIMELM]
Definition: dense.h:146
realnum * TauAbsFace
Definition: opacity.h:91
vector< vector< TransitionList > > SatelliteLines
Definition: taulines.cpp:38
long nWindLine
Definition: cdinit.cpp:19
realnum * TauAbsTotal
Definition: opacity.h:129
TransitionProxy trans(const long ipHi, const long ipLo)
Definition: iso.h:444
int nLyaLevel[NISO]
Definition: iso.h:377
realnum tlamin
Definition: opacity.h:158
const int ipH2p
Definition: iso.h:29
realnum ** TauTotalGeo
Definition: opacity.h:87
#define ASSERT(exp)
Definition: cddefines.h:582
realnum & TauCon() const
Definition: emission.h:453
TransitionList TauLines("TauLines",&AnonStates)
bool lgHBug
Definition: trace.h:85
const int ipH_LIKE
Definition: iso.h:62
vector< vector< TransitionList > > ExtraLymanLines
Definition: taulines.cpp:25
const int LIMELM
Definition: cddefines.h:262
long nfine
Definition: rfield.h:402
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
realnum ** TauAbsGeo
Definition: opacity.h:82
long int nHFLines
Definition: taulines.cpp:31
#define S(I_, J_)
long int numLevels_max
Definition: iso.h:493
long int nUTA
Definition: taulines.cpp:26
long int ipxry
Definition: rt.h:250
vector< TransitionList > dBaseTrans
Definition: taulines.cpp:17
double e2(double t)
Definition: service.cpp:299
realnum & Aul() const
Definition: emission.h:613
realnum colden[NCOLD]
Definition: colden.h:38
void RT_line_one_tau_reset(const TransitionProxy &t)
realnum & TauIn() const
Definition: emission.h:423
realnum taumin
Definition: opacity.h:154
vector< diatomics * >::iterator diatom_iter
Definition: h2.h:13
t_rt rt
Definition: rt.cpp:5