cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
service.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 /*
4 * a set of routines that are widely used across the code for various
5 * housekeeping chores. These do not do any physics and are unlikely to
6 * change over time. The prototypes are in cddefines.h and so are
7 * automatically picked up by all routines
8 */
9 /*FFmtRead scan input line for free format number */
10 /*caps convert input command line (through eol) to ALL CAPS */
11 /*ShowMe produce request to send information to GJF after a crash */
12 /*AnuUnit produce continuum energy in arbitrary units */
13 /*cap4 convert first 4 char of input line chLab into chCAP all in caps, null termination */
14 /*insane set flag saying that insanity has occurred */
15 /*nMatch determine whether match to a keyword occurs on command line,
16  * return value is 0 if no match, and position of match within string if hit */
17 /*fudge enter fudge factors, or some arbitrary number, with fudge command*/
18 /*qip compute pow(x,n) for positive integer n through repeated squares */
19 /*dsexp safe exponential function for doubles */
20 /*sexp safe exponential function */
21 /*TestCode set flag saying that test code is in place */
22 /*CodeReview - placed next to code that needs to be checked */
23 /*fixit - say that code needs to be fixed */
24 /*broken set flag saying that the code is broken, */
25 /*dbg_printf is a debug print routine that was provided by Peter Teuben,
26  * as a component from his NEMO package. It offers run-time specification
27  * of the level of debugging */
28 /*qg32 32 point Gaussian quadrature, original Fortran given to Gary F by Jim Lattimer */
29 /*TotalInsanity general error handler for something that cannot happen */
30 /*BadRead general error handler for trying to read data, but failing */
31 /*MyMalloc wrapper for malloc(). Returns a good pointer or dies. */
32 /*spsort netlib routine to sort array returning sorted indices */
33 /*chLineLbl use information in line transfer arrays to generate a line label *
34  * this label is null terminated */
35 /*chIonLbl use information in line array to generate a null terminated ion label in "Fe 2" */
36 /*csphot returns photoionization cross section from opacity stage using std pointers */
37 /*MyAssert a version of assert that fails gracefully */
38 /*RandGauss normal random variate generator */
39 /*MyGaussRand a wrapper for RandGauss, see below */
40 
41 #include "cdstd.h"
42 #include <cstdarg> /* ANSI variable arg macros */
43 #include "cddefines.h"
44 #include "service.h"
45 #include "cddrive.h"
46 #include "called.h"
47 #include "opacity.h"
48 #include "rfield.h"
49 #include "hextra.h"
50 #include "struc.h"
51 #include "fudgec.h"
52 #include "broke.h"
53 #include "trace.h"
54 #include "input.h"
55 #include "save.h"
56 #include "version.h"
57 #include "warnings.h"
58 #include "conv.h"
59 #include "atmdat.h"
60 #include "mole.h"
61 #include "prt.h"
62 #include "integrate.h"
63 
64 #ifdef __CYGWIN__
65 extern "C" { int vsnprintf(char*, size_t, const char*, va_list); }
66 #endif
67 
68 /*read_whole_line - safe version of fgets - read a line,
69  * return null if cannot read line or if input line is too long */
70 char *read_whole_line( char *chLine , int nChar , FILE *ioIN )
71 {
72  char *chRet;
73 
74  DEBUG_ENTRY( "read_whole_line()" );
75 
76  /* wipe the buffer to prevent the code from accidentally picking up on previous input */
77  memset( chLine, 0, (size_t)nChar );
78 
79  /* this always writes a '\0' character, even if line does not fit in buffer
80  * the terminating newline is copied only if the line does fit in the buffer */
81  if( (chRet = fgets( chLine, nChar, ioIN )) == NULL )
82  return NULL;
83 
84  long lineLength = strlen( chRet );
85  //fprintf(ioQQQ , "DEBUG reading:%s\n" , chLine);
86  //fprintf(ioQQQ , "DEBUG length is %li nChar is %i \n", lineLength , nChar);
87 
88  /* return null if input string is longer than nChar-1 (including terminating newline),
89  * the longest we can read. Print and return null but chLine still has as much of
90  * the line as could be placed in the buffer */
91  if( lineLength>=nChar-1 )
92  {
93  if( called.lgTalk )
94  fprintf( ioQQQ, "DISASTER PROBLEM read_whole_line found input"
95  " with a line too long to be read, limit is %i char. "
96  "Start of line follows:\n%s\n",
97  nChar , chLine );
98 
99  lgAbort = true;
100  return NULL;
101  }
102  return chRet;
103 }
104 
106 void Split(const string& str, // input string
107  const string& sep, // separator, may be multiple characters
108  vector<string>& lst, // the separated items will be appended here
109  split_mode mode) // SPM_RELAX, SPM_KEEP_EMPTY, or SPM_STRICT; see cddefines.h
110 {
111  DEBUG_ENTRY( "Split()" );
112 
113  bool lgStrict = ( mode == SPM_STRICT );
114  bool lgKeep = ( mode == SPM_KEEP_EMPTY );
115  bool lgFail = false;
116  string::size_type ptr1 = 0;
117  string::size_type ptr2 = str.find( sep );
118  string sstr = str.substr( ptr1, ptr2-ptr1 );
119  if( sstr.length() > 0 )
120  lst.push_back( sstr );
121  else {
122  if( lgStrict ) lgFail = true;
123  if( lgKeep ) lst.push_back( sstr );
124  }
125  while( ptr2 != string::npos ) {
126  // the separator is skipped
127  ptr1 = ptr2 + sep.length();
128  if( ptr1 < str.length() ) {
129  ptr2 = str.find( sep, ptr1 );
130  sstr = str.substr( ptr1, ptr2-ptr1 );
131  if( sstr.length() > 0 )
132  lst.push_back( sstr );
133  else {
134  if( lgStrict ) lgFail = true;
135  if( lgKeep ) lst.push_back( sstr );
136  }
137  }
138  else {
139  ptr2 = string::npos;
140  if( lgStrict ) lgFail = true;
141  if( lgKeep ) lst.push_back( "" );
142  }
143  }
144  if( lgFail )
145  {
146  fprintf( ioQQQ, " A syntax error occurred while splitting the string: \"%s\"\n", str.c_str() );
147  fprintf( ioQQQ, " The separator is \"%s\". Empty substrings are not allowed.\n", sep.c_str() );
149  }
150 }
151 
152 // remove whitespace from the end of a string
153 void trimTrailingWhiteSpace( string &str )
154 {
155  size_t pos = str.find_last_not_of(" \t");
156  // If this fails, everything is whitespace.
157  if ( pos != string::npos )
158  str.erase( pos+1 );
159  else
160  str.clear();
161  return;
162 }
163 
164 // remove whitespace from the end of a string
165 void trimTrailingWhiteSpace( char *str )
166 {
167  int pos = strlen( str );
168  while( pos > 0 && (str[pos-1]==' ' || str[pos-1]=='\t' ))
169  --pos;
170  str[pos] = '\0';
171  // If this fails, everything is whitespace.
172  // ASSERT( pos != 0 );
173  return;
174 }
175 
176 /* a version of assert that fails gracefully */
177 void MyAssert(const char *file, int line, const char *comment)
178 {
179  DEBUG_ENTRY( "MyAssert()" );
180 
181  fprintf(ioQQQ,"\n\n\n PROBLEM DISASTER\n An assert has been thrown, this is bad.\n");
182  fprintf(ioQQQ," %s\n",comment);
183  fprintf(ioQQQ," It happened in the file %s at line number %i\n", file, line );
184  fprintf(ioQQQ," This is iteration %li, nzone %li, fzone %.2f, lgSearch=%c.\n",
185  iteration ,
186  nzone ,
187  fnzone ,
188  TorF(conv.lgSearch) );
189 
190  ShowMe();
191 # ifdef OLD_ASSERT
193 # endif
194 }
195 
196 /*AnuUnit produce continuum energy in arbitrary units, as determined by ChkUnits() */
197 double AnuUnit(realnum energy_ryd)
198 {
199  DEBUG_ENTRY( "AnuUnit()" );
200 
201  return Energy((double)energy_ryd).get(save.chConSavEnr[save.ipConPun]);
202 }
203 
204 /*ShowMe produce request to send information to GJF after a crash */
205 void ShowMe(void)
206 {
207  DEBUG_ENTRY( "ShowMe()" );
208 
209  /* print info if output unit is defined */
210  if( ioQQQ != NULL )
211  {
212  /* >>chng 06 mar 02 - check if molecular but cosmic rays are ignored */
213  molezone* h2 = findspecieslocal("H2");
214  // molecular species may not be set up yet, so check for NULL pointer...
215  if( (hextra.cryden == 0.) && h2 != NULL && h2->xFracLim > 0.1 )
216  {
217  fprintf( ioQQQ, " >>> \n >>> \n >>> Cosmic rays are not included and the gas is molecular. "
218  "THIS IS KNOWN TO BE UNSTABLE. Add cosmic rays and try again.\n >>> \n >>>\n\n");
219  }
220  else
221  {
222  fprintf( ioQQQ, "\n\n\n" );
223  fprintf( ioQQQ, " vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv \n" );
224  fprintf( ioQQQ, " > PROBLEM DISASTER PROBLEM DISASTER. <\n" );
225  fprintf( ioQQQ, " > Sorry, something bad has happened. <\n" );
226  fprintf( ioQQQ, " > Please post this on the Cloudy web site <\n" );
227  fprintf( ioQQQ, " > discussion board at www.nublado.org <\n" );
228  fprintf( ioQQQ, " > Please send all following information: <\n" );
229  fprintf( ioQQQ, " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n" );
230  fprintf( ioQQQ, "\n\n" );
231 
232 
233  fprintf( ioQQQ, " Cloudy version number is %s\n",
234  t_version::Inst().chVersion );
235  fprintf( ioQQQ, " %s\n\n", t_version::Inst().chInfo );
236 
237  fprintf( ioQQQ, "%5ld warnings,%3ld cautions,%3ld temperature failures. Messages follow.\n",
239 
240  /* print the warnings first */
241  cdWarnings(ioQQQ);
242 
243  /* now print the cautions */
244  cdCautions(ioQQQ);
245 
246  /* now output the commands */
248 
249  if( input.lgInitPresent )
250  {
251  fprintf(ioQQQ," This input stream included one or more init files.\n");
252  fprintf(ioQQQ," If these files are not part of the standard Cloudy distribution\n");
253  fprintf(ioQQQ," then I will need a copy of them too.\n");
254  }
255  }
256  }
257  return;
258 }
259 
260 /*cap4 convert first 4 char of input line chLab into chCAP all in caps, null termination */
261 void cap4(char *chCAP , /* output string, cap'd first 4 char of chLab, with null terminating */
262  const char *chLab) /* input string ending with null byte */
263 {
264  DEBUG_ENTRY( "cap4()" );
265 
266  /* convert 4 character string in chLab to ALL CAPS in chCAP */
267  for( long i=0; i < 4; i++ )
268  {
269  /* toupper is function in ctype that converts to upper case */
270  chCAP[i] = toupper( chLab[i] );
271  if( chLab[i] == '\0' )
272  break;
273  }
274 
275  /* now end string with null byte */
276  chCAP[4] = '\0';
277  return;
278 }
279 
280 /*uncaps convert input command line (through eol) to all lowercase */
281 void uncaps(char *chCard )
282 {
283  DEBUG_ENTRY( "uncaps()" );
284 
285  long i = 0;
286  while( chCard[i] != '\0' )
287  {
288  chCard[i] = tolower( chCard[i] );
289  ++i;
290  }
291  return;
292 }
293 
294 /*caps convert input command line (through eol) to all uppercase */
295 void caps(char *chCard )
296 {
297  DEBUG_ENTRY( "caps()" );
298 
299  long i = 0;
300  while( chCard[i] != '\0' )
301  {
302  chCard[i] = toupper( chCard[i] );
303  ++i;
304  }
305  return;
306 }
307 
308 static const double pos_pow10[] = {
309  1.e+000, 1.e+001, 1.e+002, 1.e+003, 1.e+004, 1.e+005, 1.e+006, 1.e+007, 1.e+008, 1.e+009,
310  1.e+010, 1.e+011, 1.e+012, 1.e+013, 1.e+014, 1.e+015, 1.e+016, 1.e+017, 1.e+018, 1.e+019,
311  1.e+020, 1.e+021, 1.e+022, 1.e+023, 1.e+024, 1.e+025, 1.e+026, 1.e+027, 1.e+028, 1.e+029,
312  1.e+030, 1.e+031, 1.e+032, 1.e+033, 1.e+034, 1.e+035, 1.e+036, 1.e+037, 1.e+038, 1.e+039,
313  1.e+040, 1.e+041, 1.e+042, 1.e+043, 1.e+044, 1.e+045, 1.e+046, 1.e+047, 1.e+048, 1.e+049,
314  1.e+050, 1.e+051, 1.e+052, 1.e+053, 1.e+054, 1.e+055, 1.e+056, 1.e+057, 1.e+058, 1.e+059,
315  1.e+060, 1.e+061, 1.e+062, 1.e+063, 1.e+064, 1.e+065, 1.e+066, 1.e+067, 1.e+068, 1.e+069,
316  1.e+070, 1.e+071, 1.e+072, 1.e+073, 1.e+074, 1.e+075, 1.e+076, 1.e+077, 1.e+078, 1.e+079,
317  1.e+080, 1.e+081, 1.e+082, 1.e+083, 1.e+084, 1.e+085, 1.e+086, 1.e+087, 1.e+088, 1.e+089,
318  1.e+090, 1.e+091, 1.e+092, 1.e+093, 1.e+094, 1.e+095, 1.e+096, 1.e+097, 1.e+098, 1.e+099,
319  1.e+100, 1.e+101, 1.e+102, 1.e+103, 1.e+104, 1.e+105, 1.e+106, 1.e+107, 1.e+108, 1.e+109,
320  1.e+110, 1.e+111, 1.e+112, 1.e+113, 1.e+114, 1.e+115, 1.e+116, 1.e+117, 1.e+118, 1.e+119,
321  1.e+120, 1.e+121, 1.e+122, 1.e+123, 1.e+124, 1.e+125, 1.e+126, 1.e+127, 1.e+128, 1.e+129,
322  1.e+130, 1.e+131, 1.e+132, 1.e+133, 1.e+134, 1.e+135, 1.e+136, 1.e+137, 1.e+138, 1.e+139,
323  1.e+140, 1.e+141, 1.e+142, 1.e+143, 1.e+144, 1.e+145, 1.e+146, 1.e+147, 1.e+148, 1.e+149,
324  1.e+150, 1.e+151, 1.e+152, 1.e+153, 1.e+154, 1.e+155, 1.e+156, 1.e+157, 1.e+158, 1.e+159,
325  1.e+160, 1.e+161, 1.e+162, 1.e+163, 1.e+164, 1.e+165, 1.e+166, 1.e+167, 1.e+168, 1.e+169,
326  1.e+170, 1.e+171, 1.e+172, 1.e+173, 1.e+174, 1.e+175, 1.e+176, 1.e+177, 1.e+178, 1.e+179,
327  1.e+180, 1.e+181, 1.e+182, 1.e+183, 1.e+184, 1.e+185, 1.e+186, 1.e+187, 1.e+188, 1.e+189,
328  1.e+190, 1.e+191, 1.e+192, 1.e+193, 1.e+194, 1.e+195, 1.e+196, 1.e+197, 1.e+198, 1.e+199,
329  1.e+200, 1.e+201, 1.e+202, 1.e+203, 1.e+204, 1.e+205, 1.e+206, 1.e+207, 1.e+208, 1.e+209,
330  1.e+210, 1.e+211, 1.e+212, 1.e+213, 1.e+214, 1.e+215, 1.e+216, 1.e+217, 1.e+218, 1.e+219,
331  1.e+220, 1.e+221, 1.e+222, 1.e+223, 1.e+224, 1.e+225, 1.e+226, 1.e+227, 1.e+228, 1.e+229,
332  1.e+230, 1.e+231, 1.e+232, 1.e+233, 1.e+234, 1.e+235, 1.e+236, 1.e+237, 1.e+238, 1.e+239,
333  1.e+240, 1.e+241, 1.e+242, 1.e+243, 1.e+244, 1.e+245, 1.e+246, 1.e+247, 1.e+248, 1.e+249,
334  1.e+250, 1.e+251, 1.e+252, 1.e+253, 1.e+254, 1.e+255, 1.e+256, 1.e+257, 1.e+258, 1.e+259,
335  1.e+260, 1.e+261, 1.e+262, 1.e+263, 1.e+264, 1.e+265, 1.e+266, 1.e+267, 1.e+268, 1.e+269,
336  1.e+270, 1.e+271, 1.e+272, 1.e+273, 1.e+274, 1.e+275, 1.e+276, 1.e+277, 1.e+278, 1.e+279,
337  1.e+280, 1.e+281, 1.e+282, 1.e+283, 1.e+284, 1.e+285, 1.e+286, 1.e+287, 1.e+288, 1.e+289,
338  1.e+290, 1.e+291, 1.e+292, 1.e+293, 1.e+294, 1.e+295, 1.e+296, 1.e+297, 1.e+298, 1.e+299,
339  1.e+300, 1.e+301, 1.e+302, 1.e+303, 1.e+304, 1.e+305, 1.e+306, 1.e+307, 1.e+308
340 };
341 
342 static const int max_pow10 = int(sizeof(pos_pow10)/sizeof(pos_pow10[0]) - 1);
343 
344 static const double neg_pow10[] = {
345  1.e-000, 1.e-001, 1.e-002, 1.e-003, 1.e-004, 1.e-005, 1.e-006, 1.e-007, 1.e-008, 1.e-009,
346  1.e-010, 1.e-011, 1.e-012, 1.e-013, 1.e-014, 1.e-015, 1.e-016, 1.e-017, 1.e-018, 1.e-019,
347  1.e-020, 1.e-021, 1.e-022, 1.e-023, 1.e-024, 1.e-025, 1.e-026, 1.e-027, 1.e-028, 1.e-029,
348  1.e-030, 1.e-031, 1.e-032, 1.e-033, 1.e-034, 1.e-035, 1.e-036, 1.e-037, 1.e-038, 1.e-039,
349  1.e-040, 1.e-041, 1.e-042, 1.e-043, 1.e-044, 1.e-045, 1.e-046, 1.e-047, 1.e-048, 1.e-049,
350  1.e-050, 1.e-051, 1.e-052, 1.e-053, 1.e-054, 1.e-055, 1.e-056, 1.e-057, 1.e-058, 1.e-059,
351  1.e-060, 1.e-061, 1.e-062, 1.e-063, 1.e-064, 1.e-065, 1.e-066, 1.e-067, 1.e-068, 1.e-069,
352  1.e-070, 1.e-071, 1.e-072, 1.e-073, 1.e-074, 1.e-075, 1.e-076, 1.e-077, 1.e-078, 1.e-079,
353  1.e-080, 1.e-081, 1.e-082, 1.e-083, 1.e-084, 1.e-085, 1.e-086, 1.e-087, 1.e-088, 1.e-089,
354  1.e-090, 1.e-091, 1.e-092, 1.e-093, 1.e-094, 1.e-095, 1.e-096, 1.e-097, 1.e-098, 1.e-099,
355  1.e-100, 1.e-101, 1.e-102, 1.e-103, 1.e-104, 1.e-105, 1.e-106, 1.e-107, 1.e-108, 1.e-109,
356  1.e-110, 1.e-111, 1.e-112, 1.e-113, 1.e-114, 1.e-115, 1.e-116, 1.e-117, 1.e-118, 1.e-119,
357  1.e-120, 1.e-121, 1.e-122, 1.e-123, 1.e-124, 1.e-125, 1.e-126, 1.e-127, 1.e-128, 1.e-129,
358  1.e-130, 1.e-131, 1.e-132, 1.e-133, 1.e-134, 1.e-135, 1.e-136, 1.e-137, 1.e-138, 1.e-139,
359  1.e-140, 1.e-141, 1.e-142, 1.e-143, 1.e-144, 1.e-145, 1.e-146, 1.e-147, 1.e-148, 1.e-149,
360  1.e-150, 1.e-151, 1.e-152, 1.e-153, 1.e-154, 1.e-155, 1.e-156, 1.e-157, 1.e-158, 1.e-159,
361  1.e-160, 1.e-161, 1.e-162, 1.e-163, 1.e-164, 1.e-165, 1.e-166, 1.e-167, 1.e-168, 1.e-169,
362  1.e-170, 1.e-171, 1.e-172, 1.e-173, 1.e-174, 1.e-175, 1.e-176, 1.e-177, 1.e-178, 1.e-179,
363  1.e-180, 1.e-181, 1.e-182, 1.e-183, 1.e-184, 1.e-185, 1.e-186, 1.e-187, 1.e-188, 1.e-189,
364  1.e-190, 1.e-191, 1.e-192, 1.e-193, 1.e-194, 1.e-195, 1.e-196, 1.e-197, 1.e-198, 1.e-199,
365  1.e-200, 1.e-201, 1.e-202, 1.e-203, 1.e-204, 1.e-205, 1.e-206, 1.e-207, 1.e-208, 1.e-209,
366  1.e-210, 1.e-211, 1.e-212, 1.e-213, 1.e-214, 1.e-215, 1.e-216, 1.e-217, 1.e-218, 1.e-219,
367  1.e-220, 1.e-221, 1.e-222, 1.e-223, 1.e-224, 1.e-225, 1.e-226, 1.e-227, 1.e-228, 1.e-229,
368  1.e-230, 1.e-231, 1.e-232, 1.e-233, 1.e-234, 1.e-235, 1.e-236, 1.e-237, 1.e-238, 1.e-239,
369  1.e-240, 1.e-241, 1.e-242, 1.e-243, 1.e-244, 1.e-245, 1.e-246, 1.e-247, 1.e-248, 1.e-249,
370  1.e-250, 1.e-251, 1.e-252, 1.e-253, 1.e-254, 1.e-255, 1.e-256, 1.e-257, 1.e-258, 1.e-259,
371  1.e-260, 1.e-261, 1.e-262, 1.e-263, 1.e-264, 1.e-265, 1.e-266, 1.e-267, 1.e-268, 1.e-269,
372  1.e-270, 1.e-271, 1.e-272, 1.e-273, 1.e-274, 1.e-275, 1.e-276, 1.e-277, 1.e-278, 1.e-279,
373  1.e-280, 1.e-281, 1.e-282, 1.e-283, 1.e-284, 1.e-285, 1.e-286, 1.e-287, 1.e-288, 1.e-289,
374  1.e-290, 1.e-291, 1.e-292, 1.e-293, 1.e-294, 1.e-295, 1.e-296, 1.e-297, 1.e-298, 1.e-299,
375  1.e-300, 1.e-301, 1.e-302, 1.e-303, 1.e-304, 1.e-305, 1.e-306, 1.e-307
376 };
377 
378 static const int min_pow10 = -int(sizeof(neg_pow10)/sizeof(neg_pow10[0]) - 1);
379 
380 /*FFmtRead scan input line for free format number */
381 double FFmtRead(const char *chCard,
382  long int *ipnt,
383  long int length,
384  bool *lgEOL)
385 {
386  DEBUG_ENTRY( "FFmtRead()" );
387 
388  char chr = '\0';
389  const char *eol_ptr = &chCard[length]; // eol_ptr points one beyond end of buffer
390  const char *ptr = min(&chCard[*ipnt-1],eol_ptr); // ipnt is on fortran scale!
391 
392  if( *ipnt <= 0 )
393  {
394  fprintf(ioQQQ, "PROBLEM FFmtRead called with index <= 0, ipnt is %li\n",*ipnt);
395  fprintf(ioQQQ, "Line image: %s\n", chCard);
396  TotalInsanity();
397  }
398  else if( *ipnt > length )
399  {
400  fprintf(ioQQQ, "PROBLEM FFmtRead called with index > length, ipnt is %li length is %li\n",
401  *ipnt, length);
402  fprintf(ioQQQ, "Line image: %s\n", chCard);
403  TotalInsanity();
404  }
405 
406  while( true )
407  {
408  if( ptr >= eol_ptr || ( chr = *ptr++ ) == '\0' )
409  {
410  *ipnt = length+1;
411  *lgEOL = true;
412  return 0.;
413  }
414  const char *lptr = ptr;
415  char lchr = chr;
416  if( ( lchr == '-' || lchr == '+' ) && lptr < eol_ptr )
417  lchr = *lptr++;
418  if( lchr == '.' && lptr < eol_ptr )
419  lchr = *lptr;
420  if( isdigit(lchr) )
421  break;
422  }
423 
424  //double atofval = atof(ptr-1);
425 
426  double number = 0.0;
427  int exponent=0, sign=1, expsign=1, scale=0;
428  bool lgCommaFound = false, lgLastComma = false, foundpoint = false, foundexp = false;
429  do
430  {
431  lgCommaFound = lgLastComma;
432  if( chr == ',' )
433  {
434  /* don't complain about comma if it appears after number,
435  as determined by exiting loop before this sets lgCommaFound */
436  lgLastComma = true;
437  }
438  else if (isdigit(chr))
439  {
440  int digit = (chr - '0');
441  if (foundexp)
442  {
443  exponent = 10*exponent+digit;
444  }
445  else
446  {
447  number = 10.0*number+digit;
448  if (foundpoint)
449  ++scale;
450  }
451  }
452  else if (chr == '-')
453  {
454  if (foundexp)
455  {
456  if (exponent != 0 || expsign != 1)
457  break;
458  expsign = -1;
459  }
460  else
461  {
462  if (number != 0 || sign != 1)
463  break;
464  sign = -1;
465  }
466  }
467  else if (tolower(chr) == 'e')
468  {
469  if (foundexp)
470  break;
471  foundexp = true;
472  }
473  else if (chr == '.')
474  {
475  if (foundpoint)
476  break;
477  foundpoint = true;
478  }
479  if( ptr == eol_ptr )
480  break;
481  chr = *ptr++;
482  }
483  while( isdigit(chr) || chr == '.' || chr == '-' || chr == '+' || chr == ',' || chr == 'e' || chr == 'E' );
484 
485  if( lgCommaFound )
486  {
487  fprintf( ioQQQ, " PROBLEM - a comma was found embedded in a number, this is deprecated.\n" );
488  fprintf(ioQQQ, "== %-80s ==\n",chCard);
489  }
490 
491  int expo = expsign*exponent-scale;
492  double value = sign*number;
493  // numbers produced by FFmtRead() should ideally be accurate to 1 ULP, but certainly
494  // better than 3 ULP (the rest of the code relies on this).
495  // To achieve this we use a lookup table of powers of 10, which is also fast...
496  if( expo >= 0 )
497  {
498  while( expo > max_pow10 )
499  {
500  value *= pos_pow10[max_pow10];
501  expo -= max_pow10;
502  }
503  value *= pos_pow10[expo];
504  }
505  else
506  {
507  while( expo < min_pow10 )
508  {
509  value *= neg_pow10[-min_pow10];
510  expo -= min_pow10;
511  }
512  value *= neg_pow10[-expo];
513  }
514 
515  //ASSERT(fp_equal(value,atofval,2));
516  //fprintf(ioQQQ,"%g %g %g\n",value == 0 ? atofval : atofval/value-1.,value,atofval);
517 
518  *ipnt = (long)(ptr - chCard); // ptr already points 1 beyond where next read should start
519  *lgEOL = false;
520  return value;
521 }
522 
523 /*nMatch determine whether match to a keyword occurs on command line,
524  * return value is 0 if no match, and position of match within string if hit */
525 long nMatch(const char *chKey,
526  const char *chCard)
527 {
528  const char *ptr;
529  long Match_v;
530 
531  DEBUG_ENTRY( "nMatch()" );
532 
533  ASSERT( strlen(chKey) > 0 );
534 
535  if( ( ptr = strstr_s( chCard, chKey ) ) == NULL )
536  {
537  /* did not find match, return 0 */
538  Match_v = 0L;
539  }
540  else
541  {
542  /* return position within chCard (fortran scale) */
543  Match_v = (long)(ptr-chCard+1);
544  }
545  return Match_v;
546 }
547 
548 /* fudge enter fudge factors, or some arbitrary number, with fudge command
549  * other sections of the code access these numbers by calling fudge
550  * fudge(0) returns the first number that was entered
551  * prototype for this function is in cddefines.h so that it can be used without
552  * declarations
553  * fudge(-1) queries the routine for the number of fudge parameters that were entered,
554  * zero returned if none */
555 double fudge(long int ipnt)
556 {
557  double fudge_v;
558 
559  DEBUG_ENTRY( "fudge()" );
560 
561  if( ipnt < 0 )
562  {
563  /* this is special case, return number of arguments */
564  fudge_v = fudgec.nfudge;
565  fudgec.lgFudgeUsed = true;
566  }
567  else if( ipnt >= fudgec.nfudge )
568  {
569  fprintf( ioQQQ, " FUDGE factor not entered for array number %3ld\n",
570  ipnt );
572  }
573  else
574  {
575  fudge_v = fudgec.fudgea[ipnt];
576  fudgec.lgFudgeUsed = true;
577  }
578  return fudge_v;
579 }
580 
581 /* want to define this only if no native os support exists */
582 #ifndef HAVE_POWI
583 
584 /* powi.c - calc x^n, where n is an integer! */
585 
586 /* Very slightly modified version of power() from Computer Language, Sept. 86,
587  pg 87, by Jon Snader (who extracted the binary algorithm from Donald Knuth,
588  "The Art of Computer Programming", vol 2, 1969).
589  powi() will only be called when an exponentiation with an integer
590  exponent is performed, thus tests & code for fractional exponents were
591  removed.
592  */
593 
594 double powi( double x, long int n ) /* returns: x^n */
595 /* x; base */
596 /* n; exponent */
597 {
598  double p; /* holds partial product */
599 
600  DEBUG_ENTRY( "powi()" );
601 
602  if( x == 0 )
603  return 0.;
604 
605  /* test for negative exponent */
606  if( n < 0 )
607  {
608  n = -n;
609  x = 1/x;
610  }
611 
612  p = is_odd(n) ? x : 1; /* test & set zero power */
613 
614  /*lint -e704 shift right of signed quantity */
615  /*lint -e720 Boolean test of assignment */
616  while( n >>= 1 )
617  { /* now do the other powers */
618  x *= x; /* sq previous power of x */
619  if( is_odd(n) ) /* if low order bit set */
620  p *= x; /* then, multiply partial product by latest power of x */
621  }
622  /*lint +e704 shift right of signed quantity */
623  /*lint +e720 Boolean test of assignment */
624  return p;
625 }
626 
627 #endif /* HAVE_POWI */
628 
629 /* efficiently calculate x^(p/q) */
630 double powpq(double x, int p, int q)
631 {
632  DEBUG_ENTRY( "powpq()" );
633 
634  if( q < 0 )
635  {
636  p = -p;
637  q = -q;
638  }
639 
640  if( q == 1 )
641  return powi(x,p);
642  else if( q == 2 )
643  return powi(sqrt(x),p);
644  else if( q == 3 )
645  return powi(cbrt(x),p);
646  else if( q == 4 )
647  return powi(sqrt(sqrt(x)),p);
648  else if( q == 6 )
649  return powi(sqrt(cbrt(x)),p);
650  else if( q == 8 )
651  return powi(sqrt(sqrt(sqrt(x))),p);
652  else if( q == 9 )
653  return powi(cbrt(cbrt(x)),p);
654  else
655  return pow(x,double(p)/double(q));
656 }
657 
658 long ipow( long m, long n ) /* returns: m^n */
659 /* m; base */
660 /* n; exponent */
661 {
662  long p; /* holds partial product */
663 
664  DEBUG_ENTRY( "ipow()" );
665 
666  if( m == 0 || (n < 0 && m > 1) )
667  return 0L;
668  /* NOTE: negative exponent always results in 0 for integers!
669  * (except for the case when m==1 or -1) */
670 
671  if( n < 0 )
672  { /* test for negative exponent */
673  n = -n;
674  m = 1/m;
675  }
676 
677  p = is_odd(n) ? m : 1; /* test & set zero power */
678 
679  /*lint -e704 shift right of signed quantity */
680  /*lint -e720 Boolean test of assignment */
681  while( n >>= 1 )
682  { /* now do the other powers */
683  m *= m; /* sq previous power of m */
684  if( is_odd(n) ) /* if low order bit set */
685  p *= m; /* then, multiply partial product by latest power of m */
686  }
687  /*lint +e704 shift right of signed quantity */
688  /*lint +e720 Boolean test of assignment */
689  return p;
690 }
691 
692 #ifndef HAVE_STRNLEN
693 
694 // this routine cannot clash with library version since it has C++ linkage
695 size_t strnlen(const char *s, size_t maxlen)
696 {
697  for( size_t i=0; i < maxlen; ++i )
698  if( s[i] == '\0' )
699  return i;
700  return maxlen;
701 }
702 
703 #endif
704 
705 //
706 // sncatf() is fully equivalent to snprintf() apart from the fact that it
707 // concatenates the output to an existing string rather than replacing it.
708 //
709 // this routine was taken from
710 // http://stackoverflow.com/questions/2674312/how-to-append-strings-using-sprintf
711 //
712 // the return value is the length the string in buf[] would have had _if_ buf[]
713 // would have been large enough to hold it. Hence this value can be used to test
714 // for truncation: if ret_val >= bufSize then the string in buf[] was truncated.
715 //
716 size_t sncatf( char* buf, size_t bufSize, const char* fmt, ... )
717 {
718  size_t result;
719  va_list args;
720  size_t len = strnlen( buf, bufSize );
721 
722  va_start( args, fmt );
723  result = vsnprintf( buf + len, bufSize - len, fmt, args );
724  va_end( args );
725 
726  return result + len;
727 }
728 
729 size_t sncatf( ostringstream& str, const char* fmt, ... )
730 {
731  DEBUG_ENTRY( "sncatf()" );
732  size_t result;
733  size_t len = str.tellp();
734  va_list args;
735  char tmp[64];
736  char *tmp1=tmp;
737 
738  va_start( args, fmt );
739  result = vsnprintf( tmp, sizeof(tmp), fmt, args );
740  va_end( args );
741 
742  if (result >= sizeof(tmp))
743  {
744  tmp1 = new char[result+1];
745  va_start( args, fmt );
746  result = vsnprintf( tmp1, result+1, fmt, args );
747  va_end( args );
748  }
749 
750  str << tmp1;
751 
752  if (tmp1 != tmp)
753  delete [] tmp1;
754 
755  return result+len;
756 }
757 
758 /*PrintE82 - series of routines to mimic 1p, e8.2 fortran output */
759 /***********************************************************
760  * contains the following sets of routines to get around *
761  * the MS C++ compilers unusual exponential output. *
762  * PrintEfmt <= much faster, no overhead with unix *
763  * PrintE93 *
764  * PrintE82 *
765  * PrintE71 *
766  **********************************************************/
767 
768 #ifdef _MSC_VER
769 /**********************************************************/
770 /*
771  * Instead of printf'ing with %e or %.5e or whatever, call
772  * efmt("%e", val) and print the result with %s. This lets
773  * us work around bugs in VS C 6.0.
774  */
775 char *PrintEfmt(const char *fmt, double val /* , char *buf */)
776 {
777  static char buf[30]; /* or pass it in */
778 
779  DEBUG_ENTRY( "PrintEfmt()" );
780 
781  /* create the string */
782  sprintf(buf, fmt, val);
783 
784  /* code to fix incorrect ms v e format. works only for case where there is
785  * a leading space in the format - for formats like 7.1, 8.2, 9.3, 10.4, etc
786  * result will have 1 too many characters */
787  char *ep , buf2[30];
788 
789  /* msvc behaves badly in different ways for positive vs negative sign vals,
790  * if val is positive must create a leading space */
791  if( val >= 0.)
792  {
793  strcpy(buf2 , " " );
794  strcat(buf2 , buf);
795  strcpy( buf , buf2);
796  }
797 
798  /* allow for both e and E formats */
799  if((ep = strchr_s(buf, 'e')) == NULL)
800  {
801  ep = strchr_s(buf, 'E');
802  }
803 
804  /* ep can still be NULL if val is Inf or NaN */
805  if(ep != NULL)
806  {
807  /* move pointer two char past the e, to pick up the e and sign */
808  ep += 2;
809 
810  /* terminate buf where the e is, *ep points to this location */
811  *ep = '\0';
812 
813  /* skip next char, */
814  ++ep;
815 
816  /* copy resulting string to return string */
817  strcat( buf, ep );
818  }
819  return buf;
820 }
821 #endif
822 
823 /**********************************************************/
824 void PrintE82( FILE* ioOUT, double value )
825 {
826  double frac , xlog , xfloor , tvalue;
827  int iExp;
828 
829  DEBUG_ENTRY( "PrintE82()" );
830 
831  if( value < 0 )
832  {
833  fprintf(ioOUT,"********");
834  }
835  else if( value <= DBL_MIN )
836  {
837  fprintf(ioOUT,"0.00E+00");
838  }
839  else
840  {
841  /* round number off for 8.2 format (not needed since can't be negative) */
842  tvalue = value;
843  xlog = log10( tvalue );
844  xfloor = floor(xlog);
845  /* this is now the fractional part */
846  if (xfloor < 0.)
847  frac = tvalue*exp10(-xfloor);
848  else
849  frac = (10.*tvalue)*exp10(-(xfloor+1.));
850  /*this is the possibly signed exponential part */
851  iExp = (int)xfloor;
852  if( frac>9.9945 )
853  {
854  frac /= 10.;
855  iExp += 1;
856  }
857  /* print the fractional part*/
858  fprintf(ioOUT,"%.2f",frac);
859  /* E for exponent */
860  fprintf(ioOUT,"E");
861  /* if positive throw a + sign*/
862  if(iExp>=0 )
863  {
864  fprintf(ioOUT,"+");
865  }
866  fprintf(ioOUT,"%.2d",iExp);
867  }
868  return;
869 }
870 /*
871  *==============================================================================
872  */
873 void PrintE71( FILE* ioOUT, double value )
874 {
875  double frac , xlog , xfloor , tvalue;
876  int iExp;
877 
878  DEBUG_ENTRY( "PrintE71()" );
879 
880  if( value < 0 )
881  {
882  fprintf(ioOUT,"*******");
883  }
884  else if( value <= DBL_MIN )
885  {
886  fprintf(ioOUT,"0.0E+00");
887  }
888  else
889  {
890  /* round number off for 8.2 format (not needed since can't be negative) */
891  tvalue = value;
892  xlog = log10( tvalue );
893  xfloor = floor(xlog);
894  /* this is now the fractional part */
895  if (xfloor < 0.)
896  frac = tvalue*exp10(-xfloor);
897  else
898  frac = (10.*tvalue)*exp10(-(xfloor+1.));
899  /*this is the possibly signed exponential part */
900  iExp = (int)xfloor;
901  if( frac>9.9945 )
902  {
903  frac /= 10.;
904  iExp += 1;
905  }
906  /* print the fractional part*/
907  fprintf(ioOUT,"%.1f",frac);
908  /* E for exponent */
909  fprintf(ioOUT,"E");
910  /* if positive throw a + sign*/
911  if(iExp>=0 )
912  {
913  fprintf(ioOUT,"+");
914  }
915  fprintf(ioOUT,"%.2d",iExp);
916  }
917  return;
918 }
919 
920 /*
921  *==============================================================================
922  */
923 void PrintE93( FILE* ioOUT, double value )
924 {
925  double frac , xlog , xfloor, tvalue;
926  int iExp;
927 
928  DEBUG_ENTRY( "PrintE93()" );
929 
930  if( value < 0 )
931  {
932  fprintf(ioOUT,"*********");
933  }
934  else if( value <= DBL_MIN )
935  {
936  fprintf(ioOUT,"0.000E+00");
937  }
938  else
939  {
940  /* round number off for 9.3 format, neg numb not possible */
941  tvalue = value;
942  xlog = log10( tvalue );
943  xfloor = floor(xlog);
944  /* this is now the fractional part */
945  if (xfloor < 0.)
946  frac = tvalue*exp10(-xfloor);
947  else
948  frac = (10.*tvalue)*exp10(-(xfloor+1.));
949  /*this is the possibly signed exponential part */
950  iExp = (int)xfloor;
951  if( frac>9.99949 )
952  {
953  frac /= 10.;
954  iExp += 1;
955  }
956  /* print the fractional part*/
957  fprintf(ioOUT,"%5.3f",frac);
958  /* E for exponent */
959  fprintf(ioOUT,"E");
960  /* if positive throw a + sign*/
961  if(iExp>=0 )
962  {
963  fprintf(ioOUT,"+");
964  }
965  fprintf(ioOUT,"%.2d",iExp);
966  }
967  return;
968 }
969 
970 /*TotalInsanity general error handler for something that cannot happen */
972 {
973  DEBUG_ENTRY( "TotalInsanity()" );
974 
975  /* something that cannot happen, happened,
976  * if this message is triggered, simply place a breakpoint here
977  * and debug the error */
978  fprintf( ioQQQ, " Something that cannot happen, has happened.\n" );
979  fprintf( ioQQQ, " This is TotalInsanity, I live in %s.\n", __FILE__ );
980  ShowMe();
981 
983 }
984 
985 /*BadRead general error handler for trying to read data, but failing */
986 NORETURN void BadRead(void)
987 {
988  DEBUG_ENTRY( "BadRead()" );
989 
990  /* read failed */
991  fprintf( ioQQQ, " A read of internal input data has failed.\n" );
992  fprintf( ioQQQ, " This is BadRead, I live in %s.\n", __FILE__ );
993  ShowMe();
994 
996 }
997 
998 /*sexp safe exponential function */
1000 {
1001  sys_float sexp_v;
1002 
1003  DEBUG_ENTRY( "sexp()" );
1004 
1005  /* SEXP_LIMIT is 84 in cddefines.h */
1006  if( x < SEXP_LIMIT )
1007  {
1008  sexp_v = exp(-x);
1009  }
1010  else
1011  {
1012  sexp_v = 0.f;
1013  }
1014  return sexp_v;
1015 }
1016 
1017 /*sexp safe exponential function */
1018 double sexp(double x)
1019 {
1020  double sexp_v;
1021 
1022  DEBUG_ENTRY( "sexp()" );
1023 
1024  /* SEXP_LIMIT is 84 in cddefines.h */
1025  if( x < SEXP_LIMIT )
1026  {
1027  sexp_v = exp(-x);
1028  }
1029  else
1030  {
1031  sexp_v = 0.;
1032  }
1033  return sexp_v;
1034 }
1035 
1036 
1037 /*dsexp safe exponential function for doubles */
1038 double dsexp(double x)
1039 {
1040  double dsexp_v;
1041 
1042  DEBUG_ENTRY( "dsexp()" );
1043 
1044  if( x < DSEXP_LIMIT )
1045  {
1046  dsexp_v = exp(-x);
1047  }
1048  else
1049  {
1050  dsexp_v = 0.;
1051  }
1052  return dsexp_v;
1053 }
1054 
1055 /*TestCode set flag saying that test code is in place
1056  * prototype in cddefines.h */
1057 void TestCode(void)
1058 {
1059  DEBUG_ENTRY( "TestCode()" );
1060 
1061  /* called if test code is in place */
1062  lgTestCodeCalled = true;
1063  return;
1064 }
1065 
1066 /*broken set flag saying that the code is broken, */
1067 void broken(void)
1068 {
1069  DEBUG_ENTRY( "broken()" );
1070 
1071  broke.lgBroke = true;
1072  return;
1073 }
1074 
1075 /*fixit say that code needs to be fixed */
1076 void fixit_base(const char* func,
1077  const char* file,
1078  int line,
1079  const char* reason
1080  )
1081 {
1082  DEBUG_ENTRY( "fixit_base()" );
1083 
1084  broke.lgFixit = true;
1085  ostringstream oss;
1086  oss << "-- At " << file << ":"<< line << " in " << func <<"()\n";
1087  oss << reason;
1088  FixitList::Inst().list.push_back(oss.str());
1089  return;
1090 }
1091 
1092 /*CodeReview placed next to code that needs to be checked */
1093 void CodeReview(void)
1094 {
1095  DEBUG_ENTRY( "CodeReview()" );
1096 
1097  broke.lgCheckit = true;
1098  return;
1099 }
1100 
1102 int dprintf(FILE *fp, const char *format, ...)
1103 {
1104  va_list ap;
1105  int i1, i2;
1106 
1107  DEBUG_ENTRY( "dprintf()" );
1108  va_start(ap,format);
1109  i1 = fprintf(fp,"DEBUG ");
1110  if (i1 >= 0)
1111  i2 = vfprintf(fp,format,ap);
1112  else
1113  i2 = 0;
1114  if (i2 < 0)
1115  i1 = 0;
1116  va_end(ap);
1117 
1118  return i1+i2;
1119 }
1120 
1121 int fprintf (const Output& stream, const char *format, ...)
1122 {
1123  va_list ap;
1124  va_start(ap,format);
1125  int i = vfprintf(stream.fptr(), format, ap);
1126  va_end(ap);
1127  return i;
1128 }
1129 
1130 int dprintf(const Output& stream, const char *format, ...)
1131 {
1132  DEBUG_ENTRY( "dprintf()" );
1133  va_list ap;
1134  va_start(ap,format);
1135  int i1 = fprintf(stream.fptr(),"DEBUG ");
1136  int i2;
1137  if (i1 >= 0)
1138  i2 = vfprintf(stream.fptr(),format,ap);
1139  else
1140  i2 = 0;
1141  if (i2 < 0)
1142  i1 = 0;
1143  va_end(ap);
1144 
1145  return i1+i2;
1146 }
1147 
1148 
1149 
1150 /* dbg_printf is a debug print routine that was provided by Peter Teuben,
1151  * as a component from his NEMO package. It offers run-time specification
1152  * of the level of debugging */
1153 int dbg_printf(int debug, const char *fmt, ...)
1154 {
1155  va_list ap;
1156  int i=0;
1157 
1158  DEBUG_ENTRY( "dbg_printf()" );
1159 
1160  /* print this debug message? (debug_level not currently used)*/
1161  if(debug <= trace.debug_level)
1162  {
1163  va_start(ap, fmt);
1164 
1165  i = vfprintf(ioQQQ, fmt, ap);
1166  /* drain ioQQQ */
1167  fflush(ioQQQ);
1168  va_end(ap);
1169  }
1170  return i;
1171 }
1172 
1173 
1174 /*qg32 32 point Gaussian quadrature, originally given to Gary F by Jim Lattimer */
1175 double qg32(
1176  double xl, /*lower limit to integration range*/
1177  double xu, /*upper limit to integration range*/
1178  /*following is the pointer to the function that will be evaluated*/
1179  double (*fct)(double) )
1180 {
1181  double a = 0.5*(xu+xl),
1182  b = xu-xl,
1183  y = 0.;
1184 
1185  DEBUG_ENTRY( "qg32()" );
1186 
1187  /********************************************************************************
1188  * *
1189  * 32-point Gaussian quadrature *
1190  * xl : the lower limit of integration *
1191  * xu : the upper limit *
1192  * fct : the (external) function *
1193  * returns the value of the integral *
1194  * *
1195  * simple call to integrate sine from 0 to pi *
1196  * double agn = qg32( 0., 3.141592654 , sin ); *
1197  * *
1198  *******************************************************************************/
1199 
1200  double weights[16] = {
1201  .35093050047350483e-2, .81371973654528350e-2, .12696032654631030e-1, .17136931456510717e-1,
1202  .21417949011113340e-1, .25499029631188088e-1, .29342046739267774e-1, .32911111388180923e-1,
1203  .36172897054424253e-1, .39096947893535153e-1, .41655962113473378e-1, .43826046502201906e-1,
1204  .45586939347881942e-1, .46922199540402283e-1, .47819360039637430e-1, .48270044257363900e-1};
1205 
1206  double c[16] = {
1207  .498631930924740780, .49280575577263417, .4823811277937532200, .46745303796886984000,
1208  .448160577883026060, .42468380686628499, .3972418979839712000, .36609105937014484000,
1209  .331522133465107600, .29385787862038116, .2534499544661147000, .21067563806531767000,
1210  .165934301141063820, .11964368112606854, .7223598079139825e-1, .24153832843869158e-1};
1211 
1212  for( int i=0; i<16; i++)
1213  {
1214  y += b * weights[i] * ((*fct)(a+b*c[i]) + (*fct)(a-b*c[i]));
1215  }
1216 
1217  /* the answer */
1218  return y;
1219 }
1220 
1221 /*spsort netlib routine to sort array returning sorted indices */
1222 void spsort(
1223  /* input array to be sorted */
1224  realnum x[],
1225  /* number of values in x */
1226  long int n,
1227  /* permutation output array */
1228  long int iperm[],
1229  /* flag saying what to do - 1 sorts into increasing order, not changing
1230  * the original vector, -1 sorts into decreasing order. 2, -2 change vector */
1231  int kflag,
1232  /* error condition, should be 0 */
1233  int *ier)
1234 {
1235  /*
1236  ****BEGIN PROLOGUE SPSORT
1237  ****PURPOSE Return the permutation vector generated by sorting a given
1238  * array and, optionally, rearrange the elements of the array.
1239  * The array may be sorted in increasing or decreasing order.
1240  * A slightly modified quicksort algorithm is used.
1241  ****LIBRARY SLATEC
1242  ****CATEGORY N6A1B, N6A2B
1243  ****TYPE SINGLE PRECISION (SPSORT-S, DPSORT-D, IPSORT-I, HPSORT-H)
1244  ****KEY WORDS NUMBER SORTING, PASSIVE SORTING, SINGLETON QUICKSORT, SORT
1245  ****AUTHOR Jones, R. E., (SNLA)
1246  * Rhoads, G. S., (NBS)
1247  * Wisniewski, J. A., (SNLA)
1248  ****DESCRIPTION
1249  *
1250  * SPSORT returns the permutation vector IPERM generated by sorting
1251  * the array X and, optionally, rearranges the values in X. X may
1252  * be sorted in increasing or decreasing order. A slightly modified
1253  * quicksort algorithm is used.
1254  *
1255  * IPERM is such that X(IPERM(I)) is the Ith value in the rearrangement
1256  * of X. IPERM may be applied to another array by calling IPPERM,
1257  * SPPERM, DPPERM or HPPERM.
1258  *
1259  * The main difference between SPSORT and its active sorting equivalent
1260  * SSORT is that the data are referenced indirectly rather than
1261  * directly. Therefore, SPSORT should require approximately twice as
1262  * long to execute as SSORT. However, SPSORT is more general.
1263  *
1264  * Description of Parameters
1265  * X - input/output -- real array of values to be sorted.
1266  * If ABS(KFLAG) = 2, then the values in X will be
1267  * rearranged on output; otherwise, they are unchanged.
1268  * N - input -- number of values in array X to be sorted.
1269  * IPERM - output -- permutation array such that IPERM(I) is the
1270  * index of the value in the original order of the
1271  * X array that is in the Ith location in the sorted
1272  * order.
1273  * KFLAG - input -- control parameter:
1274  * = 2 means return the permutation vector resulting from
1275  * sorting X in increasing order and sort X also.
1276  * = 1 means return the permutation vector resulting from
1277  * sorting X in increasing order and do not sort X.
1278  * = -1 means return the permutation vector resulting from
1279  * sorting X in decreasing order and do not sort X.
1280  * = -2 means return the permutation vector resulting from
1281  * sorting X in decreasing order and sort X also.
1282  * IER - output -- error indicator:
1283  * = 0 if no error,
1284  * = 1 if N is zero or negative,
1285  * = 2 if KFLAG is not 2, 1, -1, or -2.
1286  ****REFERENCES R. C. Singleton, Algorithm 347, An efficient algorithm
1287  * for sorting with minimal storage, Communications of
1288  * the ACM, 12, 3 (1969), pp. 185-187.
1289  ****ROUTINES CALLED XERMSG
1290  ****REVISION HISTORY (YYMMDD)
1291  * 761101 DATE WRITTEN
1292  * 761118 Modified by John A. Wisniewski to use the Singleton
1293  * quicksort algorithm.
1294  * 870423 Modified by Gregory S. Rhoads for passive sorting with the
1295  * option for the rearrangement of the original data.
1296  * 890620 Algorithm for rearranging the data vector corrected by R.
1297  * Boisvert.
1298  * 890622 Prologue upgraded to Version 4.0 style by D. Lozier.
1299  * 891128 Error when KFLAG.LT.0 and N=1 corrected by R. Boisvert.
1300  * 920507 Modified by M. McClain to revise prologue text.
1301  * 920818 Declarations section rebuilt and code restructured to use
1302  * IF-THEN-ELSE-ENDIF. (SMR, WRB)
1303  ****END PROLOGUE SPSORT
1304  * .. Scalar Arguments ..
1305  */
1306  long int i,
1307  ij,
1308  il[21],
1309  indx,
1310  indx0,
1311  istrt,
1312  istrt_,
1313  iu[21],
1314  j,
1315  k,
1316  kk,
1317  l,
1318  lm,
1319  lmt,
1320  m,
1321  nn;
1322  realnum r,
1323  ttemp;
1324 
1325  DEBUG_ENTRY( "spsort()" );
1326 
1327  /* .. Array Arguments .. */
1328  /* .. Local Scalars .. */
1329  /* .. Local Arrays .. */
1330  /* .. External Subroutines .. */
1331  /* .. Intrinsic Functions .. */
1332  /****FIRST EXECUTABLE STATEMENT SPSORT */
1333  *ier = 0;
1334  nn = n;
1335  if( nn < 1 )
1336  {
1337  *ier = 1;
1338  return;
1339  }
1340  else
1341  {
1342  kk = labs(kflag);
1343  if( kk != 1 && kk != 2 )
1344  {
1345  *ier = 2;
1346  return;
1347  }
1348  else
1349  {
1350 
1351  /* Initialize permutation vector to index on f scale
1352  * */
1353  for( i=0; i < nn; i++ )
1354  {
1355  iperm[i] = i+1;
1356  }
1357 
1358  /* Return if only one value is to be sorted */
1359  if( nn == 1 )
1360  {
1361  --iperm[0];
1362  return;
1363  }
1364 
1365  /* Alter array X to get decreasing order if needed */
1366  if( kflag <= -1 )
1367  {
1368  for( i=0; i < nn; i++ )
1369  {
1370  x[i] = -x[i];
1371  }
1372  }
1373 
1374  /* Sort X only */
1375  m = 1;
1376  i = 1;
1377  j = nn;
1378  r = .375e0;
1379  }
1380  }
1381 
1382  while( true )
1383  {
1384  if( i == j )
1385  goto L_80;
1386  if( r <= 0.5898437e0 )
1387  {
1388  r += 3.90625e-2;
1389  }
1390  else
1391  {
1392  r -= 0.21875e0;
1393  }
1394 
1395 L_40:
1396  k = i;
1397 
1398  /* Select a central element of the array and save it in location L
1399  * */
1400  ij = i + (long)((j-i)*r);
1401  lm = iperm[ij-1];
1402 
1403  /* If first element of array is greater than LM, interchange with LM
1404  * */
1405  if( x[iperm[i-1]-1] > x[lm-1] )
1406  {
1407  iperm[ij-1] = iperm[i-1];
1408  iperm[i-1] = lm;
1409  lm = iperm[ij-1];
1410  }
1411  l = j;
1412 
1413  /* If last element of array is less than LM, interchange with LM
1414  * */
1415  if( x[iperm[j-1]-1] < x[lm-1] )
1416  {
1417  iperm[ij-1] = iperm[j-1];
1418  iperm[j-1] = lm;
1419  lm = iperm[ij-1];
1420 
1421  /* If first element of array is greater than LM, interchange
1422  * with LM
1423  * */
1424  if( x[iperm[i-1]-1] > x[lm-1] )
1425  {
1426  iperm[ij-1] = iperm[i-1];
1427  iperm[i-1] = lm;
1428  lm = iperm[ij-1];
1429  }
1430  }
1431 
1432  /* Find an element in the second half of the array which is smaller
1433  * than LM */
1434  while( true )
1435  {
1436  l -= 1;
1437  if( x[iperm[l-1]-1] <= x[lm-1] )
1438  {
1439 
1440  /* Find an element in the first half of the array which is greater
1441  * than LM */
1442  while( true )
1443  {
1444  k += 1;
1445  if( x[iperm[k-1]-1] >= x[lm-1] )
1446  break;
1447  }
1448 
1449  /* Interchange these elements */
1450  if( k > l )
1451  break;
1452  lmt = iperm[l-1];
1453  iperm[l-1] = iperm[k-1];
1454  iperm[k-1] = lmt;
1455  }
1456  }
1457 
1458  /* Save upper and lower subscripts of the array yet to be sorted */
1459  if( l - i > j - k )
1460  {
1461  il[m-1] = i;
1462  iu[m-1] = l;
1463  i = k;
1464  m += 1;
1465  }
1466  else
1467  {
1468  il[m-1] = k;
1469  iu[m-1] = j;
1470  j = l;
1471  m += 1;
1472  }
1473 
1474 L_90:
1475  if( j - i >= 1 )
1476  goto L_40;
1477  if( i == 1 )
1478  continue;
1479  i -= 1;
1480 
1481  while( true )
1482  {
1483  i += 1;
1484  if( i == j )
1485  break;
1486  lm = iperm[i];
1487  if( x[iperm[i-1]-1] > x[lm-1] )
1488  {
1489  k = i;
1490 
1491  while( true )
1492  {
1493  iperm[k] = iperm[k-1];
1494  k -= 1;
1495 
1496  if( x[lm-1] >= x[iperm[k-1]-1] )
1497  break;
1498  }
1499  iperm[k] = lm;
1500  }
1501  }
1502 
1503  /* Begin again on another portion of the unsorted array */
1504 L_80:
1505  m -= 1;
1506  if( m == 0 )
1507  break;
1508  /*lint -e644 not explicitly initialized */
1509  i = il[m-1];
1510  j = iu[m-1];
1511  /*lint +e644 not explicitly initialized */
1512  goto L_90;
1513  }
1514 
1515  /* Clean up */
1516  if( kflag <= -1 )
1517  {
1518  for( i=0; i < nn; i++ )
1519  {
1520  x[i] = -x[i];
1521  }
1522  }
1523 
1524  /* Rearrange the values of X if desired */
1525  if( kk == 2 )
1526  {
1527 
1528  /* Use the IPERM vector as a flag.
1529  * If IPERM(I) < 0, then the I-th value is in correct location */
1530  for( istrt=1; istrt <= nn; istrt++ )
1531  {
1532  istrt_ = istrt - 1;
1533  if( iperm[istrt_] >= 0 )
1534  {
1535  indx = istrt;
1536  indx0 = indx;
1537  ttemp = x[istrt_];
1538  while( iperm[indx-1] > 0 )
1539  {
1540  x[indx-1] = x[iperm[indx-1]-1];
1541  indx0 = indx;
1542  iperm[indx-1] = -iperm[indx-1];
1543  indx = labs(iperm[indx-1]);
1544  }
1545  x[indx0-1] = ttemp;
1546  }
1547  }
1548 
1549  /* Revert the signs of the IPERM values */
1550  for( i=0; i < nn; i++ )
1551  {
1552  iperm[i] = -iperm[i];
1553  }
1554  }
1555 
1556  for( i=0; i < nn; i++ )
1557  {
1558  --iperm[i];
1559  }
1560  return;
1561 }
1562 
1563 /*MyMalloc wrapper for malloc(). Returns a good pointer or dies.
1564  * memory is filled with NaN
1565  * >>chng 05 dec 14, do not set to NaN since tricks debugger
1566  * routines within code do not call this or malloc, but rather MALLOC
1567  * which is resolved into MyMalloc or malloc depending on whether
1568  * NDEBUG is set by the compiler to indicate "not debugging",
1569  * in typical negative C style */
1570 STATIC void MyMalloc_base(void* ptr,
1571  size_t size, /*use same type as library function MALLOC*/
1572  const char *chFile,
1573  int line)
1574 {
1575  DEBUG_ENTRY( "MyMalloc_base()" );
1576 
1577  /* debug branch for printing malloc args */
1578  {
1579  enum{DEBUG_LOC=false};
1580  if( DEBUG_LOC)
1581  {
1582  static long int kount=0, nTot=0;
1583  nTot += (long)size;
1584  fprintf(ioQQQ,"%li\t%li\t%li\n",
1585  kount ,
1586  (long)size ,
1587  nTot );
1588  ++kount;
1589  }
1590  }
1591 
1592  if( ptr == NULL )
1593  {
1594  fprintf(ioQQQ,"DISASTER MyMalloc could not allocate %lu bytes. Exit in MyMalloc.",
1595  (unsigned long)size );
1596  fprintf(ioQQQ,"MyMalloc called from file %s at line %i.\n",
1597  chFile , line );
1598 
1599  if( struc.nzlim>2000 )
1600  fprintf(ioQQQ,"This may have been caused by the large number of zones."
1601  " %li zones were requested. Is this many zones really necessary?\n",
1602  struc.nzlim );
1603 
1605  }
1606 
1607  /* flag -DNOINIT will turn off this initialization which can fool valgrind/purify */
1608 # if !defined(NDEBUG) && !defined(NOINIT)
1609 
1610  size_t nFloat = size/4;
1611  size_t nDouble = size/8;
1612  sys_float *fptr = static_cast<sys_float*>(ptr);
1613  double *dptr = static_cast<double*>(ptr);
1614 
1615  /* >>chng 04 feb 03, fill memory with invalid numbers, PvH */
1616  /* on IA32/AMD64 processors this will generate NaN's for both float and double;
1617  * on most other (modern) architectures it is likely to do the same... */
1618  /* >>chng 05 dec 14, change code to generate signaling NaN's for most cases (but not all!) */
1619  if( size == nDouble*8 )
1620  {
1621  /* this could be an array of doubles as well as floats -> we will hedge our bets
1622  * we will fill the array with a pattern that is interpreted as all signaling
1623  * NaN's for doubles, and alternating signaling and quiet NaN's for floats:
1624  * byte offset: 0 4 8 12 16
1625  * double | SNaN | SNan |
1626  * float | SNaN | QNaN | SNan | QNaN | (little-endian, e.g. Intel, AMD, alpha)
1627  * float | QNaN | SNaN | QNan | SNaN | (big-endian, e.g. Sparc, PowerPC, MIPS) */
1628  set_NaN( dptr, (long)nDouble );
1629  }
1630  else if( size == nFloat*4 )
1631  {
1632  /* this could be an arrays of floats, but not doubles -> init to all float SNaN */
1633  set_NaN( fptr, (long)nFloat );
1634  }
1635  else
1636  {
1637  memset( ptr, 0xff, size );
1638  }
1639 
1640 # endif /* !defined(NDEBUG) && !defined(NOINIT) */
1641 }
1642 
1643 void *MyMalloc(size_t size,
1644  const char *chFile,
1645  int line)
1646 {
1647  ASSERT( size > 0 );
1648 
1649  void *ptr = malloc(size);
1650  MyMalloc_base(ptr, size, chFile, line);
1651  return ptr;
1652 }
1653 
1654 /* function to facilitate addressing opacity array */
1655 double csphot(
1656  /* INU is array index pointing to frequency where opacity is to be evaluated
1657  * on f not c scale */
1658  long int inu,
1659  /* ITHR is pointer to threshold*/
1660  long int ithr,
1661  /* IOFSET is offset as defined in opac0*/
1662  long int iofset)
1663 {
1664  double csphot_v;
1665 
1666  DEBUG_ENTRY( "csphot()" );
1667 
1668  csphot_v = opac.OpacStack[inu-ithr+iofset-1];
1669  return csphot_v;
1670 }
1671 
1672 /*RandGauss normal Gaussian random number generator
1673  * the user must call srand to set the seed before using this routine.
1674 
1675  * the random numbers will have a mean of xMean and a standard deviation of s
1676 
1677  * The convention is for srand to be called when the command setting
1678  * the noise is parsed
1679 
1680  * for very small dispersion there are no issues, but when the dispersion becomes
1681  * large the routine will find negative values - so most often used in this case
1682  * to find dispersion in log space
1683  * this routine will return a normal Gaussian - must be careful in how this is
1684  * used when adding noise to physical quantity */
1685 /*
1686 NB - following from Ryan Porter:
1687 I discovered that I unintentionally created an antisymmetric skew in my
1688 Monte Carlo. RandGauss is symmetric in log space, which means it is not
1689 symmetric in linear space. But to get the right standard deviation you
1690 have to take 10^x, where x is the return from RandGauss. The problem is
1691 10^x will happen less frequently than 10^-x, so without realizing it, the
1692 average "tweak" to every piece of atomic data in my Monte Carlo run was
1693 not 1.0 but something greater than 1.0, causing every single line to have
1694 an average Monte Carlo emissivity greater than the regular value. Any place
1695 that takes 10^RandGauss() needs to be adjusted if what is intended is +/- x. */
1696 double RandGauss(
1697  /* mean value */
1698  double xMean,
1699  /*standard deviation s */
1700  double s )
1701 {
1702  double x1, x2, w, yy1;
1703  static double yy2=-BIGDOUBLE;
1704  static int use_last = false;
1705 
1706  DEBUG_ENTRY( "RandGauss()" );
1707 
1708  if( use_last )
1709  {
1710  yy1 = yy2;
1711  use_last = false;
1712  }
1713  else
1714  {
1715  do {
1716  x1 = 2.*genrand_real3() - 1.;
1717  x2 = 2.*genrand_real3() - 1.;
1718  w = x1 * x1 + x2 * x2;
1719  } while ( w >= 1.0 );
1720 
1721  w = sqrt((-2.0*log(w))/w);
1722  yy1 = x1 * w;
1723  yy2 = x2 * w;
1724  use_last = true;
1725  }
1726  return xMean + yy1 * s;
1727 }
1728 
1729 /* MyGaussRand takes as input a percent uncertainty less than 50%
1730  * (expressed as 0.5). The routine then assumes this input variable represents one
1731  * standard deviation about a mean of unity, and returns a random number within
1732  * that range. A hard cutoff is imposed at two standard deviations, which
1733  * eliminates roughly 5% of the normal distribution. In other words, the routine
1734  * returns a number in a normal distribution with standard deviation equal to
1735  * the input. The number will be between 1-3*stdev and 1+3*stdev. */
1736 double MyGaussRand( double PctUncertainty )
1737 {
1738  double StdDev;
1739  double result;
1740 
1741  DEBUG_ENTRY( "MyGaussRand()" );
1742 
1743  ASSERT( PctUncertainty < 0.5 );
1744  /* We want this "percent uncertainty" to represent one standard deviation */
1745  StdDev = PctUncertainty;
1746 
1747  do
1748  {
1749  /*result = exp10( RandGauss( 0., logStdDev ) );*/
1750  result = 1.+RandGauss( 0., StdDev );
1751  }
1752  /* only allow values that are within 3 standard deviations */
1753  while( (result < 1.-3.*PctUncertainty) || (result > 1.+3.*PctUncertainty) );
1754 
1755  ASSERT( result>0. && result<2. );
1756  return result;
1757 }
1758 
1759 /*plankf evaluate Planck function for any cell at current electron temperature */
1760 double plankf(long int ip)
1761 {
1762  double plankf_v;
1763 
1764  DEBUG_ENTRY( "plankf()" );
1765 
1766  /* evaluate Planck function
1767  * argument is pointer to cell energy in ANU
1768  * return photon flux for cell IP */
1769  if( rfield.ContBoltz[ip] <= 0. )
1770  {
1771  plankf_v = 1e-35;
1772  }
1773  else
1774  {
1775  plankf_v = 6.991e-21*POW2(FR1RYD*rfield.anu(ip))/
1776  (1./rfield.ContBoltz[ip] - 1.)*FR1RYD*4.;
1777  }
1778  return plankf_v;
1779 }
1780 
1782 {
1783  fstream io;
1784  string line;
1785  open_data( io, "citation_cloudy.txt", mode_r );
1786  while( SafeGetline( io, line ) )
1787  {
1788  if( line[0] == '#' )
1789  continue;
1790  // replace XXXX with actual version number
1791  size_t p = line.find( "XXXX" );
1792  if( p != string::npos )
1793  line.replace( p, 4, t_version::Inst().chVersion );
1794  fprintf( ioQQQ, "%s\n", line.c_str() );
1795  }
1796 }
1797 
1799 {
1800  fstream io;
1801  string line;
1802  open_data( io, "citation_data.txt", mode_r );
1803  while( SafeGetline( io, line ) )
1804  {
1805  if( line[0] == '#' )
1806  continue;
1807  // replace XXXX with actual version number
1808  size_t p = line.find( "XXXX" );
1809  if( p != string::npos )
1810  line.replace( p, 4, atmdat.chVersion );
1811  fprintf( ioQQQ, "%s\n", line.c_str() );
1812  }
1813 }
1814 
1815 // this routine was taken from
1816 // http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf
1817 // it is copyrighted by a creative commons license
1818 // http://creativecommons.org/licenses/by-sa/3.0/
1819 //
1820 // safe version of getline() that correctly handles all types of EOL lf, crlf and cr...
1821 // it has been modified such that it does not produce a spurious empty line at the end of a file
1822 // this way it is compatible with the standard getline() (at least with g++/linux).
1823 istream& SafeGetline(istream& is, string& t)
1824 {
1825  t.clear();
1826 
1827  // The characters in the stream are read one-by-one using a streambuf.
1828  // That is faster than reading them one-by-one using the istream.
1829  // Code that uses streambuf this way must be guarded by a sentry object.
1830  // The sentry object performs various tasks,
1831  // such as thread synchronization and updating the stream state.
1832 
1833  istream::sentry se(is, true);
1834  streambuf* sb = is.rdbuf();
1835 
1836  while( true )
1837  {
1838  int c = sb->sbumpc();
1839  switch (c)
1840  {
1841  case '\n':
1842  if( sb->sgetc() == EOF )
1843  is.setstate(ios::eofbit);
1844  return is;
1845  case '\r':
1846  if( sb->sgetc() == '\n' )
1847  sb->sbumpc();
1848  if( sb->sgetc() == EOF )
1849  is.setstate(ios::eofbit);
1850  return is;
1851  case EOF:
1852  // Also handle the case when the last line has no line ending
1853  is.setstate(ios::eofbit);
1854  return is;
1855  default:
1856  t += (char)c;
1857  }
1858  }
1859 }
long int nTeFail
Definition: conv.h:201
t_fudgec fudgec
Definition: fudgec.cpp:5
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:765
vector< double, allocator_avx< double > > ContBoltz
Definition: rfield.h:124
t_atmdat atmdat
Definition: atmdat.cpp:6
void cdPrintCommands(FILE *ioOUT)
Definition: cddrive.cpp:527
void PrintE93(FILE *, double)
Definition: service.cpp:923
static double x2[63]
bool is_odd(int j)
Definition: cddefines.h:753
double * OpacStack
Definition: opacity.h:164
double exp10(double x)
Definition: cddefines.h:1368
#define NORETURN
Definition: cpu.h:455
istream & SafeGetline(istream &is, string &t)
Definition: service.cpp:1823
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
t_input input
Definition: input.cpp:12
const double BIGDOUBLE
Definition: cpu.h:249
static const double neg_pow10[]
Definition: service.cpp:344
t_opac opac
Definition: opacity.cpp:5
static double x1[83]
t_struc struc
Definition: struc.cpp:6
split_mode
Definition: service.h:21
void set_NaN(sys_float &x)
Definition: cpu.cpp:906
static const double pos_pow10[]
Definition: service.cpp:308
size_t sncatf(char *buf, size_t bufSize, const char *fmt,...)
Definition: service.cpp:716
bool lgInitPresent
Definition: input.h:108
bool lgFudgeUsed
Definition: fudgec.h:19
void cdCautions(FILE *ioOUT)
Definition: cddrive.cpp:219
char TorF(bool l)
Definition: cddefines.h:749
#define PrintEfmt(F, V)
Definition: cddefines.h:1349
bool lgBroke
Definition: broke.h:30
t_warnings warnings
Definition: warnings.cpp:11
void cdWarnings(FILE *ioPNT)
Definition: cddrive.cpp:192
long nMatch(const char *chKey, const char *chCard)
Definition: service.cpp:525
t_conv conv
Definition: conv.cpp:5
T sign(T x, T y)
Definition: cddefines.h:842
t_hextra hextra
Definition: hextra.cpp:5
static const int max_pow10
Definition: service.cpp:342
const char * strstr_s(const char *haystack, const char *needle)
Definition: cddefines.h:1300
void * MyMalloc(size_t size, const char *file, int line)
Definition: service.cpp:1643
sys_float sexp(sys_float x)
Definition: service.cpp:999
int dbg_printf(int debug, const char *fmt,...)
Definition: service.cpp:1153
double fudge(long int ipnt)
Definition: service.cpp:555
FILE * ioQQQ
Definition: cddefines.cpp:7
long int ncaun
Definition: warnings.h:28
molezone * findspecieslocal(const char buf[])
long int nzone
Definition: cddefines.cpp:14
bool lgTalk
Definition: called.h:12
Definition: mole.h:378
void CloudyPrintReference()
Definition: service.cpp:1781
void cap4(char *chCAP, const char *chLab)
Definition: service.cpp:261
double anu(size_t i) const
Definition: mesh.h:120
double dsexp(double x)
Definition: service.cpp:1038
void CodeReview(void)
Definition: service.cpp:1093
void trimTrailingWhiteSpace(string &str)
Definition: service.cpp:153
void fixit_base(const char *func, const char *file, int line, const char *reason)
Definition: service.cpp:1076
char chVersion[iVersionLength]
Definition: atmdat.h:448
static t_version & Inst()
Definition: cddefines.h:209
realnum xFracLim
Definition: mole.h:424
void uncaps(char *chCard)
Definition: service.cpp:281
char toupper(char c)
Definition: cddefines.h:739
long int iteration
Definition: cddefines.cpp:16
const double DSEXP_LIMIT
Definition: cddefines.h:1355
bool lgSearch
Definition: conv.h:168
t_trace trace
Definition: trace.cpp:5
void broken(void)
Definition: service.cpp:1067
int dprintf(FILE *fp, const char *format,...)
Definition: service.cpp:1102
void PrintE71(FILE *, double)
Definition: service.cpp:873
char tolower(char c)
Definition: cddefines.h:730
const ios_base::openmode mode_r
Definition: cpu.h:267
#define POW2
Definition: cddefines.h:979
#define STATIC
Definition: cddefines.h:118
t_rfield rfield
Definition: rfield.cpp:9
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
float sys_float
Definition: cddefines.h:127
bool lgFixit
Definition: broke.h:33
#define cdEXIT(FAIL)
Definition: cddefines.h:482
t_broke broke
Definition: broke.cpp:10
double powi(double, long int)
Definition: service.cpp:594
long min(int a, long b)
Definition: cddefines.h:762
const char * strchr_s(const char *s, int c)
Definition: cddefines.h:1310
diatomics h2("h2", 4100.,&hmi.H2_total, Yan_H2_CS)
double RandGauss(double xMean, double s)
Definition: service.cpp:1696
realnum cryden
Definition: hextra.h:24
double AnuUnit(realnum energy)
Definition: service.cpp:197
void MyAssert(const char *file, int line, const char *comment)
Definition: service.cpp:177
long int nfudge
Definition: fudgec.h:17
long int nzlim
Definition: struc.h:19
long int ipow(long, long)
Definition: service.cpp:658
static const int min_pow10
Definition: service.cpp:378
#define ASSERT(exp)
Definition: cddefines.h:613
FILE * fptr() const
Definition: cddefines.h:233
double qg32(double, double, double(*)(double))
Definition: service.cpp:1175
double csphot(long int inu, long int ithr, long int iofset)
Definition: service.cpp:1655
Definition: energy.h:9
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
double powpq(double x, int p, int q)
Definition: service.cpp:630
STATIC void MyMalloc_base(void *ptr, size_t size, const char *chFile, int line)
Definition: service.cpp:1570
void DatabasePrintReference()
Definition: service.cpp:1798
bool lgTestCodeCalled
Definition: cddefines.cpp:11
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
const char * chConSavEnr[LIMPUN]
Definition: save.h:405
void Split(const string &str, const string &sep, vector< string > &lst, split_mode mode)
Definition: service.cpp:106
vector< string > list
Definition: broke.h:17
char * read_whole_line(char *chLine, int nChar, FILE *ioIN)
Definition: service.cpp:70
double MyGaussRand(double PctUncertainty)
Definition: service.cpp:1736
long int nwarn
Definition: warnings.h:28
int debug_level
Definition: trace.h:118
void caps(char *chCard)
Definition: service.cpp:295
double fnzone
Definition: cddefines.cpp:15
void ShowMe(void)
Definition: service.cpp:205
void PrintE82(FILE *, double)
Definition: service.cpp:824
t_save save
Definition: save.cpp:5
double genrand_real3()
double frac(double d)
const double SEXP_LIMIT
Definition: cddefines.h:1353
double plankf(long int ip)
Definition: service.cpp:1760
long int ipConPun
Definition: save.h:408
void TestCode(void)
Definition: service.cpp:1057
double get(const char *unit) const
Definition: energy.cpp:138
t_called called
Definition: called.cpp:4
NORETURN void BadRead(void)
Definition: service.cpp:986
bool lgAbort
Definition: cddefines.cpp:10
void spsort(realnum x[], long int n, long int iperm[], int kflag, int *ier)
Definition: service.cpp:1222
bool lgCheckit
Definition: broke.h:37
realnum fudgea[NFUDGC]
Definition: fudgec.h:15
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition: service.cpp:381