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-2022 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  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
108  lgIntensitySet = true;
109 
110  if (p.nMatch(" STE") || p.nMatch("STE "))
112  }
113 
114  /* a second number was entered, what was it? */
115  else if( p.nMatch("LUMI") )
116  {
117  strcpy( chParamType , "LUMINOSITY" );
118  nParam = 2;
119  rlogl = a;
120  strcpy( rfield.chRSpec[p.m_nqh], "4 PI" );
121  if( p.lgEOL() )
122  p.NoNumb("luminosity" );
123  lgIntensitySet = true;
124  }
125 
126  else if( p.nMatch("RADI") )
127  {
128  strcpy( chParamType , "RADIUS" );
129  nParam = 2;
130  /* radius was entered, convert to total luminosity */
131  rlogl = -3.147238 + 2.*a + 4.*log10(rfield.slope[rfield.nShape]);
132  strcpy( rfield.chRSpec[p.m_nqh], "4 PI" );
133  if( p.lgEOL() )
134  p.NoNumb("radius" );
135  lgIntensitySet = true;
136  }
137 
138  else if( p.nMatch("DENS") )
139  {
140  strcpy( chParamType , "ENERGY DENSITY" );
141  nParam = 2;
142  /* number was temperature to deduce energy density
143  * number is linear if greater than 10, or if LINEAR appears on line
144  * want number to be log of temperature at end of this */
145  if( !p.nMatch(" LOG") && (p.nMatch("LINE") || a > 10.) )
146  {
147  a = log10(a);
148  }
149  rlogl = log10(4.*STEFAN_BOLTZ) + 4.*a;
150  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
151  if( p.lgEOL() )
152  p.NoNumb("energy density");
153  lgIntensitySet = true;
154  }
155 
156  else if( p.nMatch("DILU") )
157  {
158  strcpy( chParamType , "DILUTION FACTOR" );
159  nParam = 2;
160  /* number is dilution factor, if negative then its log */
161  if( a <= 0. )
162  dil = a;
163  else
164  dil = log10(a);
165 
166  if( dil > 0. )
167  fprintf( ioQQQ, "PROBLEM Is the dilution factor > 1 on this "
168  "blackbody command physical?\n" );
169 
170  /* intensity from black body relations and temperature */
171  rlogl = log10(4.*STEFAN_BOLTZ) + 4.*log10(rfield.slope[rfield.nShape]);
172 
173  /* add on dilution factor */
174  rlogl += dil;
175 
176  strcpy( rfield.chRSpec[p.m_nqh], "SQCM" );
177  if( p.lgEOL() )
178  p.NoNumb("dilution factor" );
179  lgIntensitySet = true;
180  }
181 
182  else if( p.nMatch("DISK") )
183  {
184  if( p.lgEOL() )
185  p.NoNumb("disk Te" );
186 
187  strcpy( chParamType , "DISK" );
188  nParam = 2;
189 
190  rfield.cutoff[rfield.nShape][0] = a;
191  /* this is the temperature - make sure its linear in the end
192  * there are two keys, LINEAR and LOG, that could be here,
193  * else choose which is here by which side of 10 */
194  if( (rfield.cutoff[rfield.nShape][0] <= 10. && !p.nMatch("LINE")) ||
195  p.nMatch(" LOG") )
196  {
197  /* log option */
199  }
200  a = log10( rfield.cutoff[rfield.nShape][0] );
201 
202  strcpy( rfield.chSpType[rfield.nShape], "DISKB" );
203  lgIntensitySet = false;
204  }
205 
206  if( lgIntensitySet )
207  {
208  /* a luminosity option was specified
209  * check that stack of shape and luminosity specifications
210  * is parallel, stop if not - this happens is background comes
211  * BETWEEN another set of shape and luminosity commands */
212  if( rfield.nShape != p.m_nqh )
213  {
214  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" );
215  fprintf( ioQQQ, " Sorry.\n" );
217  }
218 
219  rfield.range[p.m_nqh][0] = rfield.emm();
220  rfield.range[p.m_nqh][1] = rfield.egamry();
221  rfield.totpow[p.m_nqh] = rlogl;
222  ++p.m_nqh;
223  }
224  /* vary option */
225  if( optimize.lgVarOn )
226  {
227  /* this test no option on blackbody command */
228  if( strcmp(chParamType,"") == 0 )
229  {
230  /* no luminosity options on vary */
232  strcpy( optimize.chVarFmt[optimize.nparm], "BLACKbody= %f LOG" );
233  }
234  else
235  {
236  char chHold[100];
237  /* there was an option - honor it */
238  if( nParam==1 )
239  {
241  strcpy( chHold , "BLACKbody= %f LOG ");
242  strcat( chHold , chParamType );
243  }
244  else if( nParam==2 )
245  {
248  strcpy( chHold , "BLACKbody= %f LOG %f ");
249  strcat( chHold , chParamType );
250  }
251  else
252  TotalInsanity();
253  strcpy( optimize.chVarFmt[optimize.nparm], chHold );
254  }
255 
256  /* pointer to where to write */
258  /* log of temp stored here */
260  /* the increment in the first steps away from the original value */
261  optimize.vincr[optimize.nparm] = 0.5f;
262  ++optimize.nparm;
263  }
264 
265  /* increment SED indices */
266  ++rfield.nShape;
267  if( rfield.nShape >= LIMSPC )
268  {
269  fprintf( ioQQQ, " Too many continua entered; increase LIMSPC\n" );
271  }
272 
273  return;
274 }
double emm() const
Definition: mesh.h:93
bool nMatch(const char *chKey) const
Definition: parser.h:150
double FFmtRead(void)
Definition: parser.cpp:472
double exp10(double x)
Definition: cddefines.h:1368
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
t_input input
Definition: input.cpp:12
void ParseBlackbody(Parser &p)
void set_NaN(sys_float &x)
Definition: cpu.cpp:906
long int nvfpnt[LIMPAR]
Definition: optimize.h:198
long int m_nqh
Definition: parser.h:54
double totpow[LIMSPC]
Definition: rfield.h:284
char chRSpec[LIMSPC][5]
Definition: rfield.h:335
long int nRead
Definition: input.h:105
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:43
double cutoff[LIMSPC][3]
Definition: rfield.h:284
bool lgVarOn
Definition: optimize.h:207
double range[LIMSPC][2]
Definition: rfield.h:331
const int LIMSPC
Definition: rfield.h:21
double slope[LIMSPC]
Definition: rfield.h:284
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:300
#define cdEXIT(FAIL)
Definition: cddefines.h:482
NORETURN void NoNumb(const char *chDesc) const
Definition: parser.cpp:345
t_optimize optimize
Definition: optimize.cpp:6
char chSpNorm[LIMSPC][5]
Definition: rfield.h:335
realnum vincr[LIMPAR]
Definition: optimize.h:195
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
double egamry() const
Definition: mesh.h:97
bool lgEOL(void) const
Definition: parser.h:113
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
long int nShape
Definition: rfield.h:306
long int nvarxt[LIMPAR]
Definition: optimize.h:198
char chSpType[LIMSPC][6]
Definition: rfield.h:335