cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
save_line.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 /*save_line parse save lines command, or actually do the save lines output */
4 /*Save_Line_RT parse the save line rt command - read in a set of lines */
5 #include "cddefines.h"
6 #include "cddrive.h"
7 #include "radius.h"
8 #include "opacity.h"
9 #include "phycon.h"
10 #include "dense.h"
11 #include "lines.h"
12 #include "h2.h"
13 #include "prt.h"
14 #include "iso.h"
15 #include "parser.h"
16 #include "count_ptr.h"
17 #include "save.h"
18 /* this is the limit to the number of emission lines we can store */
19 #define NPUNLM 200L
20 
21 /* implement the save line xxx command. cumulative, structure, and
22  * emissivity all use same code base and variables, so only one can be used
23  * at present */
24 
26 {
27 public:
28  string chPLab[NPUNLM];
29  long int nLinesEntered;
31  long int ipLine[NPUNLM];
34  lgMustPrintFirstTime(true) {}
35 };
36 
38 
40  /* true, return rel intensity, false, log of luminosity or intensity I */
41  bool lgLog3,
42  ostringstream& chHeader,
43  long ipPun)
44 {
45  char chTemp[INPUT_LINE_LENGTH];
46 
47  // save return value of cdLine, 0 for success, -number of lines for fail
48  long int i;
49 
50  DEBUG_ENTRY( "parse_save_line()" );
51 
52  /* very first time this routine is called, chDo is "READ" and we read
53  * in lines from the input stream. The line labels and wavelengths
54  * are store locally, and output in later calls to this routine
55  * following is flag saying whether to do relative intensity or
56  * absolute emissivity */
58 
59  linelist[ipPun]->lgRelativeIntensity = lgLog3;
60 
61  /* number of lines we will save */
62  linelist[ipPun]->nLinesEntered = 0;
63 
64  /* get the next line, and check for eof */
65  p.getline();
66  if( p.m_lgEOF )
67  {
68  fprintf( ioQQQ,
69  " Hit EOF while reading line list; use END to end list.\n" );
71  }
72 
73  while( !p.hasCommand("END") )
74  {
75  if( linelist[ipPun]->nLinesEntered >= NPUNLM )
76  {
77  fprintf( ioQQQ,
78  " Too many lines have been entered; the limit is %ld. Increase variable NPUNLM in routine save_line.\n",
79  linelist[ipPun]->nLinesEntered );
81  }
82 
83  LineID line = p.getLineID();
84  linelist[ipPun]->chPLab[linelist[ipPun]->nLinesEntered] = line.chLabel;
85  linelist[ipPun]->wavelength[linelist[ipPun]->nLinesEntered] = line.wave;
86 
87  /* this is total number stored so far */
88  ++linelist[ipPun]->nLinesEntered;
89 
90  /* get next line and check for eof */
91  p.getline();
92  if( p.m_lgEOF )
93  {
94  fprintf( ioQQQ, " Hit EOF while reading line list; use END to end list.\n" );
96  }
97 
98  }
99 
100  sncatf( chHeader, "#depth" );
101  for( i=0; i < linelist[ipPun]->nLinesEntered; i++ )
102  {
103  sprt_wl( chTemp, linelist[ipPun]->wavelength[i] );
104  sncatf( chHeader,
105  "\t%s %s", linelist[ipPun]->chPLab[i].c_str(), chTemp );
106  }
107  sncatf( chHeader, "\n" );
108 }
109 
110 void save_line(FILE * ioPUN, /* the file we will write to */
111  const char *chDo,
112  // intrinsic or emergent line emission?
113  bool lgEmergent,
114  long ipPun
115  )
116 {
117  long int i;
118  double a[NPUNLM],
119  absint,
120  relint;
121 
122  DEBUG_ENTRY( "save_line()" );
123 
124  /* it is possible that we will get here after an initial temperature
125  * too high abort, and the line arrays will not have been defined.
126  * do no lines in this case. must still do save so that there
127  * is not a missing line in the grid save output */
128  long nLinesNow = LineSave.nsum >0 ? linelist[ipPun]->nLinesEntered : 0;
129 
130  bool lgBadLine = false;
131  if( nzone <= 1 && linelist[ipPun]->lgMustGetLines )
132  {
133  for( i=0; i < nLinesNow; i++ )
134  {
135  linelist[ipPun]->ipLine[i] =
136  LineSave.findline(linelist[ipPun]->chPLab[i].c_str(), linelist[ipPun]->wavelength[i]);
137  if( linelist[ipPun]->ipLine[i] <= 0 )
138  {
139  // missed line - ignore if H2 line since large model may be off
140  if( !h2.lgEnabled && strncmp( linelist[ipPun]->chPLab[i].c_str() , "H2 " , 4 )==0 )
141  {
142  if( linelist[ipPun]->lgMustPrintFirstTime )
143  {
144  /* it's an H2 line and H2 is not being done - ignore it */
145  fprintf( ioQQQ,"\nPROBLEM Did not find an H2 line, the large model is not "
146  "included, so I will ignore it. Log intensity set to -30.\n" );
147  fprintf( ioQQQ,"I will totally ignore any future missed H2 lines\n\n");
148  linelist[ipPun]->lgMustPrintFirstTime = false;
149  }
150  /* flag saying to ignore this line */
151  linelist[ipPun]->ipLine[i] = -2;
152  }
153  else
154  {
155  fprintf( ioQQQ, " save_line could not find line ");
156  prt_line_err( ioQQQ, linelist[ipPun]->chPLab[i].c_str(), linelist[ipPun]->wavelength[i] );
157  linelist[ipPun]->ipLine[i] = -1;
158  lgBadLine = true;
159  }
160  }
161  }
162  linelist[ipPun]->lgMustGetLines = false;
163  if( lgBadLine )
164  {
166  }
167  }
168 
169  if( strcmp(chDo,"PUNS") == 0 )
170  {
171  /* save lines emissivity command */
172  /* save lines structure command */
173 
174  for( i=0; i < nLinesNow; i++ )
175  {
176  /* this version of cdEmis uses index, does not search, do not call if line could not be found */
177  /* test on case where we abort before first zone is done
178  * this happens in grid when temperature bounds of code
179  * are exceeded. In this case return small float */
180  if( lgAbort && nzone <=1 )
181  a[i] = SMALLFLOAT;
182  else if( linelist[ipPun]->ipLine[i]>0 )
183  cdEmis_ip(linelist[ipPun]->ipLine[i],&a[i],lgEmergent);
184  else
185  a[i] = 1e-30f;
186  }
187  }
188 
189  else if( strcmp(chDo,"PUNC") == 0 )
190  {
191  /* save lines cumulative command */
192  for( i=0; i < nLinesNow; i++ )
193  {
194  if ( (lgAbort && nzone <=1) || linelist[ipPun]->ipLine[i]<=0 )
195  {
196  a[i] = 0.;
197  }
198  else
199  {
200  cdLine_ip(linelist[ipPun]->ipLine[i],&relint,&absint,lgEmergent);
201  if( linelist[ipPun]->lgRelativeIntensity )
202  /* relative intensity case */
203  a[i] = relint;
204  else
205  /* emissivity or luminosity case */
206  a[i] = absint;
207  }
208  }
209  }
210  else if( strcmp(chDo,"PUNO") == 0 )
211  {
212  /* save lines optical depth some command */
213  for( i=0; i < nLinesNow; i++ )
214  {
215  if ( (lgAbort && nzone <=1) || linelist[ipPun]->ipLine[i]<=0 )
216  {
217  a[i] = 0.;
218  }
219  else
220  {
221  TransitionProxy tr = LineSave.lines[linelist[ipPun]->ipLine[i]].getTransition();
222  if (tr.associated())
223  a[i] = tr.Emis().TauIn();
224  else
225  a[i] = 0.;
226  }
227  }
228  }
229  else
230  {
231  fprintf( ioQQQ,
232  " unrecognized key for save_line=%4.4s\n",
233  chDo );
235  }
236 
237  fprintf( ioPUN, "%.5e", radius.depth_mid_zone );
238 
239  for( i=0; i < nLinesNow; i++ )
240  {
241  fprintf( ioPUN, "\t%.4e", a[i] );
242  }
243  fprintf( ioPUN, "\n" );
244 
245  return;
246 }
247 
248 #define LIMLINE 10
249 static long int line_RT_type[LIMLINE] =
250  {LONG_MIN , LONG_MIN ,LONG_MIN , LONG_MIN ,LONG_MIN ,
251  LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN },
253  {LONG_MIN , LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,
254  LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN },
256  {LONG_MIN , LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,
257  LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN },
259  {LONG_MIN , LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,
260  LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN },
262  {LONG_MIN , LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,
263  LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN ,LONG_MIN };
264 static bool lgMustPrintHeader=true;
265 static long int nLine=-1;
266 
267 /*Save_Line_RT parse the save line rt command - read in a set of lines */
269 {
270  /* save line rt parameters */
271  DEBUG_ENTRY( "Parse_Save_Line_RT()" );
272 
273  /* very first time this routine is called, chDo is "READ" and we read
274  * in lines from the input stream. The line labels and wavelengths
275  * are store locally, and output in later calls to this routine */
276 
277  /* say that we must print the header */
278  lgMustPrintHeader = true;
279 
280  /* get the next line, and check for eof */
281  nLine = 0;
282  p.getline();
283  if( p.m_lgEOF )
284  {
285  fprintf( ioQQQ,
286  " Hit EOF while reading line list; use END to end list.\n" );
288  }
289 
290  do
291  {
292  if(nLine>=LIMLINE )
293  {
294  fprintf(ioQQQ," PUNCH RT has too many lines - increase LIMLINE in save_line.cpp\n");
296  }
297 
298  /* right now it just does lines in the iso sequences */
299  line_RT_type[nLine] = (long int)p.FFmtRead();
300  line_RT_ipISO[nLine] = (long int)p.FFmtRead();
301  line_RT_nelem[nLine] = (long int)p.FFmtRead();
302  line_RT_ipHi[nLine] = (long int)p.FFmtRead();
303  line_RT_ipLo[nLine] = (long int)p.FFmtRead();
304 
305  if( p.lgEOL() )
306  {
307  fprintf( ioQQQ,
308  " there must be five numbers on this line\n");
309  p.PrintLine(ioQQQ);
311  }
312 
313  /* now increment number of lines */
314  ++nLine;
315 
316  /* now get next line until we hit eof or the word END */
317  p.getline();
318  } while( !p.m_lgEOF && !p.nMatch( "END") );
319  if( p.m_lgEOF )
320  {
321  fprintf( ioQQQ,
322  " Save_Line_RT hit end of file looking for END of RT lines\n");
323  p.PrintLine(ioQQQ);
325  }
326 }
327 
329  FILE * ioPUN )
330 {
331  /* save line rt parameters */
332 
333  DEBUG_ENTRY( "Save_Line_RT()" );
334 
335 
336  static char chLabel[LIMLINE][30];
337  long int n;
338  if( lgMustPrintHeader )
339  {
340  fprintf( ioPUN , "Line\tP(con,inc)\tAul\tgl\tgu\n");
341  for( n=0; n<nLine; ++n )
342  {
344  /* print info for header of file, line id and pump rate */
345  sprintf( chLabel[n] , "%s ",
346  chLineLbl(tr).c_str() );
347  fprintf( ioPUN , "%s ", chLabel[n] );
348  fprintf( ioPUN , "%.4e ",
349  tr.Emis().pump());
350  fprintf( ioPUN , "%.4e ",
351  tr.Emis().Aul());
352  fprintf( ioPUN , "%.0f ",
353  (*tr.Lo()).g());
354  fprintf( ioPUN , "%.0f ",
355  (*tr.Hi()).g());
356  fprintf( ioPUN , "\n");
357 
358  if( line_RT_type[n]!=0. )
359  {
360  /* for now code only exists for H He like iso - assert this */
361  fprintf( ioQQQ,
362  " Save_Line_RT only H, He like allowed for now\n");
364  }
365  }
366  fprintf( ioPUN , "Line\tTauIn\tPopLo\tPopHi\tCul\tk(line)\tk(con,abs)\tk(con,scat)\n");
367  lgMustPrintHeader = false;
368  }
369 
370  fprintf(ioPUN, "RADIUS\t%e\tDEPTH\t%e\tTe\t%e\tNe\t%e\n",
373  phycon.te ,
374  dense.eden );
375  for( n=0; n<nLine; ++n )
376  {
378 
379  /* index for line within continuum array */
380  long int ipCont = tr.ipCont();
381  fprintf( ioPUN , "%s ", chLabel[n] );
382  fprintf( ioPUN , "\t%e\t%e\t%e",
383  tr.Emis().TauIn() ,
384  (*tr.Lo()).Pop(),
385  (*tr.Hi()).Pop()
386  );
387  fprintf( ioPUN , "\t%e",
389  );
390 
391  fprintf( ioPUN , "\t%e\t%e\t%e\n",
392  tr.Emis().PopOpc(),
393  opac.opacity_abs[ipCont-1] ,
394  opac.opacity_sct[ipCont-1]
395  );
396  }
397 }
398 
399 # undef LIMELM
400 
#define LIMLINE
Definition: save_line.cpp:248
void Parse_Save_Line_RT(Parser &p)
Definition: save_line.cpp:268
bool nMatch(const char *chKey) const
Definition: parser.h:140
void cdLine_ip(long int ipLine, double *relint, double *absint)
Definition: cddrive.cpp:1112
bool hasCommand(const char *s2)
Definition: parser.cpp:705
double * opacity_abs
Definition: opacity.h:103
STATIC long int ipPun
Definition: save_do.cpp:721
realnum wave
Definition: lines.h:18
double FFmtRead(void)
Definition: parser.cpp:438
string chLineLbl(const TransitionProxy &t)
Definition: transition.h:599
double EdenHCorr
Definition: dense.h:227
t_opac opac
Definition: opacity.cpp:5
long findline(const char *chLabel, realnum wavelength)
Definition: lines.cpp:293
const realnum SMALLFLOAT
Definition: cpu.h:246
size_t sncatf(char *buf, size_t bufSize, const char *fmt,...)
Definition: service.cpp:812
void save_line(FILE *ip, const char *chDo, bool lgEmergent, long ipPun)
Definition: save_line.cpp:110
t_phycon phycon
Definition: phycon.cpp:6
t_LineSave LineSave
Definition: lines.cpp:9
Definition: lines.h:14
FILE * ioQQQ
Definition: cddefines.cpp:7
void parse_save_line(Parser &p, bool lgLog3, ostringstream &chHeader, long int ipPun)
double * opacity_sct
Definition: opacity.h:106
string chLabel
Definition: lines.h:17
long int nzone
Definition: cddefines.cpp:14
Definition: parser.h:42
static long int line_RT_ipISO[LIMLINE]
Definition: save_line.cpp:252
vector< LinSv > lines
Definition: lines.h:132
static long int line_RT_nelem[LIMLINE]
Definition: save_line.cpp:255
t_dense dense
Definition: global.cpp:15
void cdEmis_ip(long int ipLine, double *emiss, bool lgEmergent)
Definition: cddrive.cpp:573
static long int line_RT_type[LIMLINE]
Definition: save_line.cpp:249
bool associated() const
Definition: transition.h:54
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:11
void prt_line_err(FILE *ioOUT, const char *label, realnum wvlng)
Definition: prt.cpp:161
static long int nLine
Definition: save_line.cpp:265
LineID getLineID()
Definition: parser.cpp:535
static long int line_RT_ipLo[LIMLINE]
Definition: save_line.cpp:261
ColliderList colliders(dense)
static const long LIMPUN
Definition: save.h:13
bool lgMustPrintFirstTime
Definition: save_line.cpp:32
#define NPUNLM
Definition: save_line.cpp:19
static count_ptr< SaveLineList > linelist[LIMPUN]
Definition: save_line.cpp:37
bool lgEnabled
Definition: h2_priv.h:352
EmissionList::reference Emis() const
Definition: transition.h:447
void Save_Line_RT(FILE *ip)
Definition: save_line.cpp:328
long int ipLine[NPUNLM]
Definition: save_line.cpp:31
bool lgRelativeIntensity
Definition: save_line.cpp:32
long & ipCont() const
Definition: transition.h:489
float realnum
Definition: cddefines.h:124
static long int line_RT_ipHi[LIMLINE]
Definition: save_line.cpp:258
#define EXIT_FAILURE
Definition: cddefines.h:168
const int INPUT_LINE_LENGTH
Definition: cddefines.h:301
qList::iterator Hi() const
Definition: transition.h:435
#define cdEXIT(FAIL)
Definition: cddefines.h:484
diatomics h2("h2", 4100.,&hmi.H2_total, Yan_H2_CS)
double depth_mid_zone
Definition: radius.h:31
static bool lgMustPrintHeader
Definition: save_line.cpp:264
t_radius radius
Definition: radius.cpp:5
realnum wavelength[NPUNLM]
Definition: save_line.cpp:30
TransitionProxy trans(const long ipHi, const long ipLo)
Definition: iso.h:473
double Radius_mid_zone
Definition: radius.h:31
void sprt_wl(char *chString, realnum wl)
Definition: prt.cpp:56
qList::iterator Lo() const
Definition: transition.h:431
long int nLinesEntered
Definition: save_line.cpp:29
bool getline()
Definition: parser.cpp:249
CollisionProxy Coll() const
Definition: transition.h:463
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
double & PopOpc() const
Definition: emission.h:658
static vector< realnum > wavelength
double eden
Definition: dense.h:201
bool lgEOL(void) const
Definition: parser.h:103
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
int PrintLine(FILE *fp) const
Definition: parser.h:200
long int nsum
Definition: lines.h:87
string chPLab[NPUNLM]
Definition: save_line.cpp:28
bool m_lgEOF
Definition: parser.h:53
double te
Definition: phycon.h:21
realnum & Aul() const
Definition: emission.h:668
bool lgMustGetLines
Definition: save_line.cpp:32
static long int * ipLine
Definition: prt_linesum.cpp:14
double ColUL(const ColliderList &colls) const
Definition: collision.h:106
realnum & TauIn() const
Definition: emission.h:458
bool lgAbort
Definition: cddefines.cpp:10
double & pump() const
Definition: emission.h:518