cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cdspec.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2017 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*cdSPEC returns the spectrum needed for Keith Arnaud's XSPEC */
4 #include "cddefines.h"
5 #include "cddrive.h"
6 #include "geometry.h"
7 #include "radius.h"
8 #include "rfield.h"
9 #include "opacity.h"
10 #include "grid.h"
11 
12 /*
13  * this routine returns the spectrum needed for Keith Arnaud's XSPEC
14  * X-Ray analysis code. It should be called after cdDrive has successfully
15  * computed a model. the calling routine must ensure that the vectors
16  * have enough space to store the resulting spectrum,
17  * given the bounds and energy resolution
18  */
19 
20 void cdSPEC(
21  /* option - the type of spectrum to be returned
22  * 1 the incident continuum 4\pi nuJ_nu, , erg cm-2 s-1
23  *
24  * 2 the attenuated incident continuum, same units
25  * 3 the reflected continuum, same units
26  *
27  * 4 diffuse continuous emission outward direction
28  * 5 diffuse continuous emission, reflected
29  *
30  * 6 collisional+recombination lines, outward
31  * 7 collisional+recombination lines, reflected
32  *
33  * 8 pumped lines, outward <= not implemented
34  * 9 pumped lines, reflected <= not implemented
35  *
36  * all lines and continuum emitted by the cloud assume full coverage of
37  * continuum source */
38  int nOption ,
39 
40  /* the number of cells + 1*/
41  long int nEnergy ,
42 
43  /* the returned spectrum, same size is two energy spectra (see option), returns nEnergy -1 pts */
44  double ReturnedSpectrum[] )
45 
46 {
47  /* this pointer will bet set to one of the cloudy continuum arrays */
48  realnum *cont ,
49  refac;
50  long int ncell , j;
51  vector<realnum> cont_local;
52 
53  DEBUG_ENTRY( "cdSPEC()" );
54 
55  ASSERT( nEnergy <= rfield.nflux );
56 
57  if( nOption == 1 )
58  {
59  /* this is the incident continuum, col 2 of save continuum command */
60  cont = rfield.flux_total_incident[0];
61  }
62  else if( nOption == 2 )
63  {
64  /* the attenuated transmitted continuum, no diffuse emission,
65  * col 3 of save continuum command */
66  cont = rfield.flux[0];
67  }
68  else if( nOption == 3 )
69  {
70  /* reflected incident continuum, col 6 of save continuum command */
71  cont = rfield.ConRefIncid[0];
72  }
73  else if( nOption == 4 )
74  {
75  /* diffuse continuous emission outward direction */
76  cont_local.resize(rfield.nflux_with_check);
77  cont = &cont_local[0];
78 
79  /* need to free the vector once done */
81  for( j=0; j<rfield.nflux; ++j)
82  {
83  cont[j] = rfield.ConEmitOut[0][j]*refac;
84  }
85  }
86  else if( nOption == 5 )
87  {
88  cont_local.resize(rfield.nflux_with_check);
89  /* reflected diffuse continuous emission */
90  cont = &cont_local[0];
91  /* need to free the vector once done */
93  for( j=0; j<rfield.nflux; ++j)
94  {
95  cont[j] = rfield.ConEmitReflec[0][j]*refac;
96  }
97  }
98  else if( nOption == 6 )
99  {
100  cont_local.resize(rfield.nflux_with_check);
101  /* all outward lines, */
102  cont = &cont_local[0];
103  /* correct back to inner radius */
105  for( j=0; j<rfield.nflux; ++j)
106  {
107  /* units of lines here are to cancel out with tricks applied to continuum cells
108  * when finally extracted below */
109  cont[j] = rfield.outlin[0][j] *rfield.widflx(j)/rfield.anu(j)*refac;
110  }
111  }
112  else if( nOption == 7 )
113  {
114  /* all reflected lines */
115  if( geometry.lgSphere )
116  {
117  refac = 0.;
118  }
119  else
120  {
121  refac = 1.;
122  }
123 
124  cont_local.resize(rfield.nflux_with_check);
125  cont = &cont_local[0];
126  /* need to free the vector once done */
127  for( j=0; j<rfield.nflux; ++j)
128  {
129  /* units of lines here are to cancel out with tricks applied to continuum cells
130  * when finally extracted below */
131  cont[j] = rfield.reflin[0][j] *rfield.widflx(j)/rfield.anu(j)*refac;
132  }
133  }
134  else
135  {
136  fprintf(ioQQQ," cdSPEC called with impossible nOption (%i)\n", nOption);
138  }
139 
140  /* now generate the continua */
141  for( ncell = 0; ncell < nEnergy-1; ++ncell )
142  {
143  ReturnedSpectrum[ncell] = cont[ncell] * EN1RYD * rfield.anu2(ncell) / rfield.widflx(ncell);
144  }
145 
146  return;
147 }
148 
149 
150 /* returns in units photons/cm^2/s/bin */
151 void cdSPEC2(
152  /* option - the type of spectrum to be returned
153  * 1 the incident continuum 4\pi nuJ_nu, , erg cm-2 s-1
154  *
155  * 2 the attenuated incident continuum, same units
156  * 3 the reflected continuum, same units
157  *
158  * 4 diffuse emission, lines + continuum, outward
159  * 5 diffuse emission, lines + continuum, reflected
160  *
161  * 6 diffuse continuous emission outward direction
162  * 7 diffuse continuous emission, reflected
163  *
164  * 8 total transmitted, lines and continuum
165  * 9 total reflected, lines and continuum
166  *
167  *10 exp(-tau) to the illuminated face
168  *
169  * all lines and continuum emitted by the cloud assume full coverage of
170  * continuum source */
171  int nOption ,
172 
173  /* the number of cells */
174  long int nEnergy,
175 
176  /* the index of the lowest and highest energy bounds to use. */
177  long ipLoEnergy,
178  long ipHiEnergy,
179 
180  /* the returned spectrum, same size is two energy spectra (see option), returns nEnergy -1 pts */
181  realnum ReturnedSpectrum[] )
182 
183 {
184  realnum refac;
185 
186  DEBUG_ENTRY( "cdSPEC2()" );
187 
188  if( ! ( ipLoEnergy >= 0 && ipLoEnergy < ipHiEnergy && ipHiEnergy < rfield.nflux_with_check &&
189  nEnergy == (ipHiEnergy-ipLoEnergy+1) && nEnergy >= 2 && nOption <= NUM_OUTPUT_TYPES ) )
190  {
191  fprintf( ioQQQ, "invalid parameter for cdSPEC2\n" );
193  }
194 
195  const realnum *trans_coef_total = rfield.getCoarseTransCoef();
196 
197  for( long i = 0; i < nEnergy; i++ )
198  {
199  long j = ipLoEnergy + i;
200 
201  if( j >= rfield.nflux )
202  {
203  ReturnedSpectrum[i] = SMALLFLOAT;
204  continue;
205  }
206 
207  if( nOption == 0 )
208  {
209  /* the attenuated incident continuum */
210  realnum flxatt = rfield.flux[0][j]*
211  (realnum)radius.r1r0sq * trans_coef_total[j];
212 
213  /* the outward emitted continuum */
214  realnum conem = (rfield.ConEmitOut[0][j] + rfield.outlin[0][j])*
216 
217  /* the reflected continuum */
218  realnum flxref = rfield.ConRefIncid[0][j] + rfield.ConEmitReflec[0][j] +
219  rfield.reflin[0][j];
220 
221  ReturnedSpectrum[i] = flxatt + conem + flxref;
222  }
223  else if( nOption == 1 )
224  {
225  /* this is the incident continuum, col 2 of save continuum command */
226  ReturnedSpectrum[i] = rfield.flux_total_incident[0][j];
227  }
228  else if( nOption == 2 )
229  {
230  /* the attenuated transmitted continuum, no diffuse emission,
231  * col 3 of save continuum command */
232  ReturnedSpectrum[i] = rfield.flux[0][j]*
233  (realnum)radius.r1r0sq * trans_coef_total[j];
234  }
235  else if( nOption == 3 )
236  {
237  /* reflected incident continuum, col 6 of save continuum command */
238  ReturnedSpectrum[i] = rfield.ConRefIncid[0][j];
239  }
240  else if( nOption == 4 )
241  {
242  /* all outward diffuse emission */
243  /* correct back to inner radius */
245  ReturnedSpectrum[i] = (rfield.outlin[0][j]+rfield.ConEmitOut[0][j])*refac;
246  }
247  else if( nOption == 5 )
248  {
249  /* all reflected diffuse emission */
250  if( geometry.lgSphere )
251  {
252  refac = 0.;
253  }
254  else
255  {
256  refac = 1.;
257  }
258 
259  ReturnedSpectrum[i] = (rfield.reflin[0][j]+rfield.ConEmitReflec[0][j])*refac;
260  }
261  else if( nOption == 6 )
262  {
263  /* all outward line emission */
264  /* correct back to inner radius */
266  ReturnedSpectrum[i] = rfield.outlin[0][j]*refac;
267  }
268  else if( nOption == 7 )
269  {
270  /* all reflected line emission */
271  if( geometry.lgSphere )
272  {
273  refac = 0.;
274  }
275  else
276  {
277  refac = 1.;
278  }
279 
280  ReturnedSpectrum[i] = rfield.reflin[0][j]*refac;
281  }
282  else if( nOption == 8 )
283  {
284  /* total transmitted continuum */
285  /* correct back to inner radius */
287  ReturnedSpectrum[i] = (rfield.ConEmitOut[0][j]+ rfield.outlin[0][j])*refac
288  + rfield.flux[0][j]*(realnum)radius.r1r0sq*trans_coef_total[j];
289  }
290  else if( nOption == 9 )
291  {
292  /* total reflected continuum */
293  ReturnedSpectrum[i] = rfield.ConRefIncid[0][j] + rfield.ConEmitReflec[0][j] +
294  rfield.reflin[0][j];
295  }
296  else if( nOption == 10 )
297  {
298  /* this is exp(-tau) */
299  /* This is the TOTAL attenuation in both the continuum and lines.
300  * Jon Miller discovered that the line attenuation was missing in 07.02 */
301  ReturnedSpectrum[i] = opac.ExpmTau[j]*trans_coef_total[j];
302  }
303  else
304  {
305  fprintf(ioQQQ," cdSPEC called with impossible nOption (%i)\n", nOption);
307  }
308 
309  ASSERT( ReturnedSpectrum[i] >=0.f );
310  }
311 
312  return;
313 }
double widflx(size_t i) const
Definition: mesh.h:147
t_opac opac
Definition: opacity.cpp:5
realnum ** flux
Definition: rfield.h:70
const realnum SMALLFLOAT
Definition: cpu.h:246
realnum ** flux_total_incident
Definition: rfield.h:201
realnum covgeo
Definition: geometry.h:45
realnum ** outlin
Definition: rfield.h:191
FILE * ioQQQ
Definition: cddefines.cpp:7
void cdSPEC2(int Option, long int nEnergy, long int ipLoEnergy, long int ipHiEnergy, realnum ReturnedSpectrum[])
double anu(size_t i) const
Definition: mesh.h:111
long int nflux_with_check
Definition: rfield.h:51
const realnum * getCoarseTransCoef()
Definition: rfield.cpp:56
bool lgSphere
Definition: geometry.h:34
t_geometry geometry
Definition: geometry.cpp:5
t_rfield rfield
Definition: rfield.cpp:9
float realnum
Definition: cddefines.h:124
const int NUM_OUTPUT_TYPES
Definition: grid.h:22
#define EXIT_FAILURE
Definition: cddefines.h:168
void cdSPEC(int Option, long int nEnergy, double ReturnedSpectrum[])
Definition: cdspec.cpp:20
#define cdEXIT(FAIL)
Definition: cddefines.h:484
double anu2(size_t i) const
Definition: mesh.h:115
t_radius radius
Definition: radius.cpp:5
realnum ** reflin
Definition: rfield.h:198
realnum ** ConEmitOut
Definition: rfield.h:153
#define ASSERT(exp)
Definition: cddefines.h:617
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
realnum * ExpmTau
Definition: opacity.h:144
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
realnum ** ConEmitReflec
Definition: rfield.h:147
double r1r0sq
Definition: radius.h:31
long int nflux
Definition: rfield.h:48
realnum ** ConRefIncid
Definition: rfield.h:159