cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
save_average.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 /*save_average routine to read in list of species to output as averages */
4 #include "cddefines.h"
5 #include "cddrive.h"
6 #include "elementnames.h"
7 #include "save.h"
8 #include "parser.h"
9 
10 /* return value is number of lines, -1 if file could not be opened */
12  /* the file we will write to */
13  long int ipPun,
14  ostringstream& chHeader)
15 {
16  DEBUG_ENTRY( "parse_save_average()" );
17 
18  /* ensure the memory from any previous call is freed */
19  save.SaveAverageFree(ipPun);
20 
21  /* use this to count number of species, and will assert equal to
22  * total malloced above */
23  size_t nLine = 0;
24  /* keep reading until we hit END */
25  while( 1 )
26  {
27  p.getline();
28  if( p.m_lgEOF )
29  {
30  fprintf( ioQQQ,
31  " Save average hit EOF while reading list; use END to end list.\n" );
33  }
34  if (p.hasCommand("END" ))
35  break;
36  /* count number of species we will save */
37  ++nLine;
38  if( p.nMatch("TEMP" ))
39  {
40  /* temperature */
41  save.chAverageType[ipPun].push_back("TEMP");
42  }
43  else if( p.nMatch("COLU" ))
44  {
45  /* column density */
46  save.chAverageType[ipPun].push_back("COLU");
47  }
48  else if( p.nMatch("IONI" ))
49  {
50  /* ionization fraction */
51  save.chAverageType[ipPun].push_back("IONI");
52  }
53  else
54  {
55  fprintf(ioQQQ,"PROBLEM one of the jobs TEMPerature, COLUmn density, or IONIzation, must appear.\n");
57  }
58 
59  /* get element name, a string we shall pass on to the routine
60  * that computes final quantities */
61  int i = p.GetElem( );
62  if( i < 0 )
63  {
64  /* no name found */
65  fprintf(ioQQQ, "save average did not see an element on this line, sorry\n");
66  p.PrintLine(ioQQQ);
68  }
70 
71  /* now get ionization stage */
72  save.nAverageIonList[ipPun].push_back((int) p.FFmtRead());
73  if( p.lgEOL() )
74  {
75  /* error - needed that ionization stage */
76  p.NoNumb("ionization stage" );
77  }
78 
79  /* look for volume keyword, otherwise will be radius
80  * only used for some options */
81  if( p.nMatch( "VOLU" ) )
82  {
83  /* volume */
84  save.nAverage2ndPar[ipPun].push_back(1);
85  }
86  else
87  {
88  /* radius */
89  save.nAverage2ndPar[ipPun].push_back(0);
90  }
91  }
92 
93  ASSERT(nLine == save.chAverageType[ipPun].size());
94  ASSERT(nLine == save.chSaveSpecies[ipPun].size());
95  ASSERT(nLine == save.nAverageIonList[ipPun].size());
96  ASSERT(nLine == save.nAverage2ndPar[ipPun].size());
98 /*# define PADEBUG*/
99 # ifdef PADEBUG
100  fprintf(ioQQQ , "DEBUG save_average %li species read in.\n",
101  save.nAverageList[ipPun] );
102 # endif
103 
104 # ifdef PADEBUG
105  for( i=0; i<nLine ; ++i )
106  {
107  fprintf(ioQQQ, "PDDEBUG %s %s %i %i\n",
108  save.chAverageType[ipPun][i].c_str(),
109  save.chSaveSpecies[ipPun][i].c_str() ,
111  save.nAverage2ndPar[ipPun][i] );
112  }
113 # endif
114 
115  /* save headers */
116  sncatf(chHeader, "#averages");
117  for( size_t i=0; i<nLine ; ++i )
118  {
119  sncatf(chHeader, "\t %s %s %i %i",
120  save.chAverageType[ipPun][i].c_str(),
121  save.chSaveSpecies[ipPun][i].c_str() ,
123  save.nAverage2ndPar[ipPun][i] );
124  }
125  sncatf(chHeader, "\n");
126 }
127 
129  /* the file we will write to */
130  long int ipPun)
131 {
132  DEBUG_ENTRY( "save_average()" );
133 
134  /* do the output */
135  for( long i=0; i<save.nAverageList[ipPun] ; ++i )
136  {
137  double result;
138  char chWeight[7];
139  if( save.nAverage2ndPar[ipPun][i] == 0 )
140  strcpy( chWeight , "RADIUS");
141  else
142  strcpy( chWeight , "VOLUME");
143 
144  if( save.chAverageType[ipPun][i] == "TEMP" )
145  {
146  /* temperature */
147  if( cdTemp(
148  save.chSaveSpecies[ipPun][i].c_str() ,
150  &result ,
151  chWeight ) )
152  {
153  fprintf( ioQQQ, " save average temperature could not identify the species.\n" );
155  }
156  }
157  else if( save.chAverageType[ipPun][i] == "IONI" )
158  {
159  /* ionization fraction
160  * H2 is a special case, HYDRO 0 requests
161  * the H2 fraction, n(H2)/n(H) */
162  if( "HYDR" == save.chSaveSpecies[ipPun][i] &&
163  save.nAverageIonList[ipPun][i]== 0 )
164  save.chSaveSpecies[ipPun][i] = "H2 ";
165  if( cdIonFrac(
166  save.chSaveSpecies[ipPun][i].c_str() ,
168  &result ,
169  chWeight ,
170  false
171  ) )
172  {
173  fprintf( ioQQQ, " save average ionization fraction could not identify the species.\n" );
175  }
176  }
177  else if( save.chAverageType[ipPun][i] == "COLU" )
178  {
179  /* column density */
180  if( cdColm(
181  save.chSaveSpecies[ipPun][i].c_str() ,
183  &result ) )
184  {
185  fprintf( ioQQQ, " save average column density fraction could not identify the species.\n" );
187  }
188  }
189  else
190  TotalInsanity();
191 
192  // <=C13 gave log quantities, now do linear but accept log key for backwards compatibility
193  fprintf(save.params[ipPun].ipPnunit, "\t %e", PrtLogLin( result ) );
194  }
195  fprintf(save.params[ipPun].ipPnunit, "\n");
196 }
bool nMatch(const char *chKey) const
Definition: parser.h:150
void parse_save_average(Parser &p, long int ipPun, ostringstream &chHeader)
vector< string > chAverageType[LIMPUN]
Definition: save.h:271
vector< int > nAverageIonList[LIMPUN]
Definition: save.h:273
bool hasCommand(const char *s2)
Definition: parser.cpp:746
STATIC long int ipPun
Definition: save_do.cpp:367
double FFmtRead(void)
Definition: parser.cpp:472
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
size_t sncatf(char *buf, size_t bufSize, const char *fmt,...)
Definition: service.cpp:716
int cdIonFrac(const char *chLabel, long int IonStage, double *fracin, const char *chWeight, bool lgDensity)
Definition: cddrive.cpp:909
int cdTemp(const char *chLabel, long int IonStage, double *TeMean, const char *chWeight)
Definition: cddrive.cpp:1311
FILE * ioQQQ
Definition: cddefines.cpp:7
FILE * ipPnunit
Definition: save.h:195
Definition: parser.h:43
t_elementnames elementnames
Definition: elementnames.cpp:5
static long int nLine
Definition: save_line.cpp:271
void SaveAverageFree(long i)
Definition: save.h:246
#define EXIT_FAILURE
Definition: cddefines.h:168
vector< int > nAverage2ndPar[LIMPUN]
Definition: save.h:275
#define cdEXIT(FAIL)
Definition: cddefines.h:482
NORETURN void NoNumb(const char *chDesc) const
Definition: parser.cpp:345
long int GetElem(void) const
Definition: parser.cpp:321
char chElementNameShort[LIMELM][CHARS_ELEMENT_NAME_SHORT]
Definition: elementnames.h:21
double PrtLogLin(double value)
Definition: save_do.cpp:370
SaveParams params[LIMPUN]
Definition: save.h:278
#define ASSERT(exp)
Definition: cddefines.h:613
bool getline()
Definition: parser.cpp:273
int cdColm(const char *chLabel, long int ion, double *theocl)
Definition: cddrive.cpp:592
long nAverageList[LIMPUN]
Definition: save.h:269
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
bool lgEOL(void) const
Definition: parser.h:113
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
vector< string > chSaveSpecies[LIMPUN]
Definition: save.h:385
void save_average(long int ipPun)
int PrintLine(FILE *fp) const
Definition: parser.h:206
bool m_lgEOF
Definition: parser.h:55
t_save save
Definition: save.cpp:5