cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parse_blackbody.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 /*ParseBlackbody parse parameters off black body command */
4 #include "cddefines.h"
5 #include "physconst.h"
6 #include "optimize.h"
7 #include "input.h"
8 #include "rfield.h"
9 #include "radius.h"
10 #include "parse.h"
11 #include "parser.h"
12 
14  /* input command line, already changed to caps */
15  Parser &p)
16 {
17  bool
18  lgIntensitySet=false;
19  double a,
20  dil,
21  rlogl;
22 
23  char chParamType[20] = "";
24  int nParam = 0;
25 
26  DEBUG_ENTRY( "ParseBlackbody()" );
27 
28  set_NaN( rlogl );
29 
30  /* type is blackbody */
31  strcpy( rfield.chSpType[rfield.nShape], "BLACK" );
32  strcpy( rfield.chSpNorm[p.m_nqh], "LUMI" );
33 
34  /* these two are not used for this continuum shape */
35  rfield.cutoff[rfield.nShape][0] = 0.;
36  rfield.cutoff[rfield.nShape][1] = 0.;
37 
38  /* get the blackbody temperature */
40  if( p.lgEOL() )
41  p.NoNumb("blackbody temperature");
42 
43  /* this is the temperature - make sure its linear in the end
44  * there are two keys, LINEAR and LOG, that could be here,
45  * else choose which is here by which side of 10 */
46  if( (rfield.slope[rfield.nShape] <= 10. && !p.nMatch("LINE")) ||
47  p.nMatch(" LOG") )
48  {
49  /* log option */
51  }
52 
53  /* check that temp is not too low - could happen if log misused */
54  if( rfield.slope[rfield.nShape] < 1e4 )
55  {
56  fprintf( ioQQQ, " Is T(star)=%10.2e correct???\n",
58  }
59 
60  /* now check that temp not too low - would peak below low
61  * energy limit of the code
62  * factor is temperature of 1 Ryd, egamry is high-energy limit of code */
64  {
65  fprintf( ioQQQ, " This temperature is very low - the blackbody will have significant flux low the low energy limit of the code, presently %10.2e Ryd.\n",
66  rfield.emm );
67  fprintf( ioQQQ, " Was this intended?\n" );
68  }
69 
70  /* now check that temp not too high - would extend beyond high
71  * energy limit of the code
72  * factor is temperature of 1 Ryd, egamry is high-energy limit of code */
74  {
75  fprintf( ioQQQ, " This temperature is very high - the blackbody will have significant flux above the high-energy limit of the code,%10.2e Ryd.\n",
76  rfield.egamry );
77  fprintf( ioQQQ, " Was this intended?\n" );
78  }
79 
80  /* also possible to input log(total luminosity)=real log(l) */
81  a = p.FFmtRead();
82 
83  /* there was not a second number on the line; check if LTE or STE */
84  if( p.nMatch(" LTE") || p.nMatch("LTE ") ||
85  p.nMatch(" STE") || p.nMatch("STE ") )
86  {
87  /* set energy density to the STE - strict thermodynamic equilibrium - value */
88  strcpy( chParamType , "STE" );
89  nParam = 1;
90 
91  if( !p.lgEOL() )
92  {
93  fprintf(ioQQQ,"PROBLEM the luminosity was specified on "
94  "the BLACKBODY K STE command.\n");
95  fprintf(ioQQQ,"Do not specify the luminosity since STE does this.\n");
96  fprintf( ioQQQ, " Sorry.\n" );
98  }
99 
100  /* use blackbody relations to get intensity from temperature */
101  rlogl = log10(4.*STEFAN_BOLTZ) + 4.*log10(rfield.slope[rfield.nShape]);
102 
103  /* set radius to very large value if not already set */
104  if( !radius.lgRadiusKnown )
105  {
106  radius.Radius = pow(10.,radius.rdfalt);
107  }
108 
109  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
110  lgIntensitySet = true;
111  }
112 
113  /* a second number was entered, what was it? */
114  else if( p.nMatch("LUMI") )
115  {
116  strcpy( chParamType , "LUMINOSITY" );
117  nParam = 2;
118  rlogl = a;
119  strcpy( rfield.chRSpec[p.m_nqh], "4 PI" );
120  if( p.lgEOL() )
121  p.NoNumb("luminosity" );
122  lgIntensitySet = true;
123  }
124 
125  else if( p.nMatch("RADI") )
126  {
127  strcpy( chParamType , "RADIUS" );
128  nParam = 2;
129  /* radius was entered, convert to total luminosity */
130  rlogl = -3.147238 + 2.*a + 4.*log10(rfield.slope[rfield.nShape]);
131  strcpy( rfield.chRSpec[p.m_nqh], "4 PI" );
132  if( p.lgEOL() )
133  p.NoNumb("radius" );
134  lgIntensitySet = true;
135  }
136 
137  else if( p.nMatch("DENS") )
138  {
139  strcpy( chParamType , "ENERGY DENSITY" );
140  nParam = 2;
141  /* number was temperature to deduce energy density
142  * number is linear if greater than 10, or if LINEAR appears on line
143  * want number to be log of temperature at end of this */
144  if( !p.nMatch(" LOG") && (p.nMatch("LINE") || a > 10.) )
145  {
146  a = log10(a);
147  }
148  rlogl = log10(4.*STEFAN_BOLTZ) + 4.*a;
149  /* set radius to very large value if not already set */
150  if( !radius.lgRadiusKnown )
151  {
152  radius.Radius = pow(10.,radius.rdfalt);
153  }
154  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
155  if( p.lgEOL() )
156  p.NoNumb("energy density");
157  lgIntensitySet = true;
158  }
159 
160  else if( p.nMatch("DILU") )
161  {
162  strcpy( chParamType , "DILUTION FACTOR" );
163  nParam = 2;
164  /* number is dilution factor, if negative then its log */
165  if( a <= 0. )
166  dil = a;
167  else
168  dil = log10(a);
169 
170  if( dil > 0. )
171  fprintf( ioQQQ, "PROBLEM Is the dilution factor > 1 on this "
172  "blackbody command physical?\n" );
173 
174  /* intensity from black body relations and temperature */
175  rlogl = log10(4.*STEFAN_BOLTZ) + 4.*log10(rfield.slope[rfield.nShape]);
176 
177  /* add on dilution factor */
178  rlogl += dil;
179 
180  /* set radius to very large value if not already set */
181  if( !radius.lgRadiusKnown )
182  {
183  radius.Radius = pow(10.,radius.rdfalt);
184  }
185  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
186  if( p.lgEOL() )
187  p.NoNumb("dilution factor" );
188  lgIntensitySet = true;
189  }
190 
191  else if( p.nMatch("DISK") )
192  {
193  if( p.lgEOL() )
194  p.NoNumb("disk Te" );
195 
196  strcpy( chParamType , "DISK" );
197  nParam = 2;
198 
199  rfield.cutoff[rfield.nShape][0] = a;
200  /* this is the temperature - make sure its linear in the end
201  * there are two keys, LINEAR and LOG, that could be here,
202  * else choose which is here by which side of 10 */
203  if( (rfield.cutoff[rfield.nShape][0] <= 10. && !p.nMatch("LINE")) ||
204  p.nMatch(" LOG") )
205  {
206  /* log option */
207  rfield.cutoff[rfield.nShape][0] = pow(10.,rfield.cutoff[rfield.nShape][0]);
208  }
209  a = log10( rfield.cutoff[rfield.nShape][0] );
210 
211  strcpy( rfield.chSpType[rfield.nShape], "DISKB" );
212  lgIntensitySet = false;
213  }
214 
215  if( lgIntensitySet )
216  {
217  /* a luminosity option was specified
218  * check that stack of shape and luminosity specifications
219  * is parallel, stop if not - this happens is background comes
220  * BETWEEN another set of shape and luminosity commands */
221  if( rfield.nShape != p.m_nqh )
222  {
223  fprintf( ioQQQ, " This command has come between a previous ordered pair of continuum shape and luminosity commands.\n Reorder the commands to complete each continuum specification before starting another.\n" );
224  fprintf( ioQQQ, " Sorry.\n" );
226  }
227 
228  rfield.range[p.m_nqh][0] = rfield.emm;
229  rfield.range[p.m_nqh][1] = rfield.egamry;
230  rfield.totpow[p.m_nqh] = rlogl;
231  ++p.m_nqh;
232  }
233  /* vary option */
234  if( optimize.lgVarOn )
235  {
236  /* this test no option on blackbody command */
237  if( strcmp(chParamType,"") == 0 )
238  {
239  /* no luminosity options on vary */
241  strcpy( optimize.chVarFmt[optimize.nparm], "BLACKbody= %f LOG" );
242  }
243  else
244  {
245  char chHold[100];
246  /* there was an option - honor it */
247  if( nParam==1 )
248  {
250  strcpy( chHold , "BLACKbody= %f LOG ");
251  strcat( chHold , chParamType );
252  }
253  else if( nParam==2 )
254  {
257  strcpy( chHold , "BLACKbody= %f LOG %f ");
258  strcat( chHold , chParamType );
259  }
260  else
261  TotalInsanity();
262  strcpy( optimize.chVarFmt[optimize.nparm], chHold );
263  }
264 
265  /* pointer to where to write */
267  /* log of temp stored here */
269  /* the increment in the first steps away from the original value */
270  optimize.vincr[optimize.nparm] = 0.5f;
271  ++optimize.nparm;
272  }
273 
274  /* increment SED indices */
275  ++rfield.nShape;
276  if( rfield.nShape >= LIMSPC )
277  {
278  fprintf( ioQQQ, " Too many continua entered; increase LIMSPC\n" );
280  }
281 
282  return;
283 }
bool nMatch(const char *chKey) const
Definition: parser.h:135
double Radius
Definition: radius.h:22
double FFmtRead(void)
Definition: parser.cpp:353
NORETURN void TotalInsanity(void)
Definition: service.cpp:886
t_input input
Definition: input.cpp:12
void ParseBlackbody(Parser &p)
void set_NaN(sys_float &x)
Definition: cpu.cpp:673
long int nvfpnt[LIMPAR]
Definition: optimize.h:194
long int m_nqh
Definition: parser.h:41
double totpow[LIMSPC]
Definition: rfield.h:300
char chRSpec[LIMSPC][5]
Definition: rfield.h:351
realnum emm
Definition: rfield.h:49
long int nRead
Definition: input.h:46
char chVarFmt[LIMPAR][FILENAME_PATH_LENGTH_2]
Definition: optimize.h:263
FILE * ioQQQ
Definition: cddefines.cpp:7
realnum vparm[LIMEXT][LIMPAR]
Definition: optimize.h:188
Definition: parser.h:31
double cutoff[LIMSPC][3]
Definition: rfield.h:300
bool lgVarOn
Definition: optimize.h:203
double range[LIMSPC][2]
Definition: rfield.h:347
const int LIMSPC
Definition: rfield.h:18
realnum egamry
Definition: rfield.h:52
double slope[LIMSPC]
Definition: rfield.h:300
const double STEFAN_BOLTZ
Definition: physconst.h:210
long int nparm
Definition: optimize.h:200
t_rfield rfield
Definition: rfield.cpp:8
float realnum
Definition: cddefines.h:107
#define EXIT_FAILURE
Definition: cddefines.h:144
#define cdEXIT(FAIL)
Definition: cddefines.h:438
NORETURN void NoNumb(const char *chDesc) const
Definition: parser.cpp:233
bool lgRadiusKnown
Definition: radius.h:116
t_optimize optimize
Definition: optimize.cpp:5
char chSpNorm[LIMSPC][5]
Definition: rfield.h:351
t_radius radius
Definition: radius.cpp:5
realnum vincr[LIMPAR]
Definition: optimize.h:191
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:688
bool lgEOL(void) const
Definition: parser.h:98
long int nShape
Definition: rfield.h:322
double rdfalt
Definition: radius.h:124
long int nvarxt[LIMPAR]
Definition: optimize.h:194
char chSpType[LIMSPC][6]
Definition: rfield.h:351
const double TE1RYD
Definition: physconst.h:183