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