Cloudy
Spectral Synthesis Code for Astrophysics
Loading...
Searching...
No Matches
cddefines.h
Go to the documentation of this file.
1/* This file is part of Cloudy and is copyright (C)1978-2025 by Gary J. Ferland and
2 * others. For conditions of distribution and use see copyright notice in license.txt */
3
4#ifndef CDDEFINES_H_
5#define CDDEFINES_H_
6
7#include "cdstd.h"
8
9#ifdef _MSC_VER
10/* we are not using MS foundation class */
11# ifndef WIN32_LEAN_AND_MEAN
12# define WIN32_LEAN_AND_MEAN
13# endif
14#endif
15
16#ifdef __clang__
17// this would generate lots of warnings about mismatched tags in the STL valarray definition
18#pragma clang diagnostic ignored "-Wmismatched-tags"
19#endif
20
21/* these headers are needed by all files */
22/*lint -e129 these resolve several issues pclint has with my system headers */
23/*lint -e78 */
24/*lint -e830 */
25/*lint -e38 */
26/*lint -e148 */
27/*lint -e114 */
28/*lint -e18 */
29/*lint -e49 */
30// C++ versions of C headers
31#include <cstdio>
32#include <cstdlib>
33#include <cctype>
34#ifdef _MSC_VER
35// MSVC needs this before cmath in order provide numeric constants
36// (M_PI etc.) defined by C99 but not C++ standards to date.
37#define _USE_MATH_DEFINES
38#endif
39#include <cmath>
40#include <cassert>
41#include <cstring>
42#include <cstdint>
43#include <cfloat>
44#include <climits>
45#include <ctime>
46#if defined(__sun) && defined(__SUNPRO_CC)
47// with Solaris Studio 12.2 under Sparc Solaris, csignal doesn't define sigaction...
48#include <signal.h>
49#else
50#include <csignal>
51#endif
52// C++ headers
53#include <limits>
54#include <string>
55#include <sstream>
56#include <iomanip>
57#include <array>
58#include <vector>
59#include <valarray>
60#include <complex>
61#include <map>
62#include <tuple>
63#include <regex>
64#include <memory>
65#include <stdexcept>
66#include <algorithm>
67#include <fstream>
68#include <bitset>
69#include <unordered_map>
70#include <numeric>
71
72// Workaround for Windows...
73#if defined(_MSC_VER) && !defined(SYS_CONFIG)
74#define SYS_CONFIG "cloudyconfig_vs.h"
75#endif
76
77// platform specific configuration; generated by configure.sh
78#ifdef SYS_CONFIG
79#include SYS_CONFIG
80#else
81#include "cloudyconfig.h"
82#endif
83
84// prevent problems on platforms with broken support (such as Mac homebrew g++)
85#ifndef HAVE_AVX_INTRIN
86#undef __AVX__
87#endif
88
89#ifndef HAVE_FMA_INTRIN
90#undef __FMA__
91#endif
92
93#ifndef HAVE_AVX2_INTRIN
94#undef __AVX2__
95#endif
96
97#ifndef HAVE_AVX512F_INTRIN
98#undef __AVX512F__
99#endif
100
101#ifdef __AVX__
102#include <immintrin.h>
103#endif
104
105/*lint +e18 */
106/*lint +e49 */
107/*lint +e38 */
108/*lint +e148 */
109/*lint +e830 */
110/*lint +e78 */
111/*lint -e129 */
112
113using namespace std;
114
115#undef NULL
116#define NULL nullptr
117
118#undef STATIC
119#ifdef USE_GPROF
120#define STATIC
121#else
122#define STATIC static
123#endif
124
125#ifdef FLT_IS_DBL
126typedef double realnum;
127#else
128typedef float realnum;
129#endif
130
131typedef float sys_float;
132// prevent explicit float's from creeping back into the code
133#define float PLEASE_USE_REALNUM_NOT_FLOAT
134
135// define realnum literals, use as 12_r or 12.4_r
148inline realnum operator ""_r( unsigned long long l )
149{
150 return realnum(l);
151}
152
153inline realnum operator ""_r( long double l )
154{
155 return realnum(l);
156}
157
158inline FILE *sys_fopen(const char *path, const char *mode)
159{
160 return fopen( path, mode );
161}
162#define fopen PLEASE_USE_open_data_NOT_fopen
163
164typedef enum {
165 ES_SUCCESS=0, // everything went fine...
166 ES_FAILURE=1, // general failure exit
167 ES_WARNINGS, // warnings were present
168 ES_BOTCHES, // botched monitors were present
169 ES_CLOUDY_ABORT, // Cloudy aborted
170 ES_BAD_ASSERT, // an assert in the code failed
171 ES_BAD_ALLOC, // a memory allocation failed
172 ES_OUT_OF_RANGE, // an out-of-range exception was thrown
173 ES_DOMAIN_ERROR, // a vectorized math routine threw a domain error
174 ES_ILLEGAL_INSTRUCTION, // the CPU encountered an illegal instruction
175 ES_FP_EXCEPTION, // a floating point exception was caught
176 ES_SEGFAULT, // a segmentation fault occurred
177 ES_BUS_ERROR, // a bus error occurred
178 ES_UNKNOWN_SIGNAL, // an unknown signal was caught
179 ES_UNKNOWN_EXCEPTION, // an unknown exception was caught
180 ES_TOP // NB NB -- this should always be the last entry
181} exit_type;
182
183// make sure the system definitions are on par with ours
184// especially EXIT_FAILURE does not have a guaranteed value!
185#undef EXIT_SUCCESS
186#define EXIT_SUCCESS ES_SUCCESS
187#undef EXIT_FAILURE
188#define EXIT_FAILURE ES_FAILURE
189
190#ifdef BOUNDS_CHECK
191#define lgBOUNDSCHECKVAL true
192#else
193#define lgBOUNDSCHECKVAL false
194#endif
195
196/* make sure this is globally visible as well! */
197/* This must be done at the start of every file, to ensure that policy
198 for FPE handling, etc., is guaranteed to be set up before the
199 construction of file-statics and globals. */
200#include "cpu.h"
201
202//*************************************************************************
203//
221//
222// This implementation has been obtained from Wikipedia
223//
224//*************************************************************************
225
226template<typename T> class Singleton
227{
228public:
229 static T& Inst()
230 {
231 static T instance; // assumes T has a protected default constructor
232 return instance;
233 }
234};
235
236/**************************************************************************
237 *
238 * these are variables and pointers for output from the code, used everywhere
239 * declared extern here, and definition is in cddefines.cpp
240 *
241 **************************************************************************/
242
246
248{
249public:
250 FILE *m_fp;
251 // Implicit conversion
252 Output(FILE* fp) : m_fp(fp) {}
253 FILE *fptr() const
254 {
255 return m_fp;
256 }
257};
258
259extern FILE *ioQQQ;
260
261extern FILE *ioStdin;
262
263extern FILE *ioMAP;
264
267extern FILE* ioPrnErr;
268
271extern bool lgTestCodeCalled;
272
275extern bool lgTestCodeEnabled;
276
279extern bool lgPrnErr;
280
283extern long int nzone;
284
286extern double fnzone;
287
290extern long int iteration;
291
298extern const double ZeroNum;
299
304extern const void* ZeroPtr;
305
306/**************************************************************************
307 *
308 * these are constants used to dimension several vectors and index arrays
309 *
310 **************************************************************************/
311
316const int FILENAME_PATH_LENGTH = 200;
317
320
324const int INPUT_LINE_LENGTH = 2000;
325
327const int NCHLAB = 20;
328
331const int LIMELM = 30;
332
334const int NISO = 2;
335
339const int NHYDRO_MAX_LEVEL = 401;
340
342const double MAX_DENSITY = 1.e24;
343
345const double DEPTH_OFFSET = 1.e-30;
346
349
350/* indices within recombination coefficient array */
351/* ipRecEsc is state specific escape probability*/
352const int ipRecEsc = 2;
353/* the net escaping, including destruction by background and optical deepth*/
354const int ipRecNetEsc = 1;
355/* ipRecRad is state specific radiative recombination rate*/
356const int ipRecRad = 0;
360
361/* these specify the form of the line redistribution function */
362/* partial redistribution with wings */
363const int ipPRD = 1;
364/* complete redistribution, core only, no wings, Hummer's K2 function */
365const int ipCRD = -1;
366/* complete redistribution with wings */
367const int ipCRDW = 2;
368/* redistribution function for Lya, calls Hummer routine for H-like series only */
369const int ipLY_A = -2;
370
372const int ipHYDROGEN = 0;
373const int ipHELIUM = 1;
374const int ipLITHIUM = 2;
375const int ipBERYLLIUM = 3;
376const int ipBORON = 4;
377const int ipCARBON = 5;
378const int ipNITROGEN = 6;
379const int ipOXYGEN = 7;
380const int ipFLUORINE = 8;
381const int ipNEON = 9;
382const int ipSODIUM = 10;
383const int ipMAGNESIUM = 11;
384const int ipALUMINIUM = 12;
385const int ipSILICON = 13;
386const int ipPHOSPHORUS = 14;
387const int ipSULPHUR = 15;
388const int ipCHLORINE = 16;
389const int ipARGON = 17;
390const int ipPOTASSIUM = 18;
391const int ipCALCIUM = 19;
392const int ipSCANDIUM = 20;
393const int ipTITANIUM = 21;
394const int ipVANADIUM = 22;
395const int ipCHROMIUM = 23;
396const int ipMANGANESE = 24;
397const int ipIRON = 25;
398const int ipCOBALT = 26;
399const int ipNICKEL = 27;
400const int ipCOPPER = 28;
401const int ipZINC = 29;
402const int ipKRYPTON = 35;
403
404/***************************************************************************
405 * the following are prototypes for some routines that are part of the
406 * debugging process - they come and go in any particular sub.
407 * it is not necessary to declare them when used since they are defined here
408 **************************************************************************/
409
418double fudge(long int ipnt);
419
423void broken(void);
424
427void fixit_base(const char* func, const char* file, int line,
428 const char *reason);
429
430class Fixit
431{
432public:
433 Fixit(const char* func, const char* file, int line,
434 const char *reason)
435 {
436 fixit_base(func,file,line,reason);
437 }
438};
439
440#define fixit(a) \
441 do { \
442 static Fixit fixit_s(__func__,__FILE__,__LINE__, (a)); \
443 } while (0)
444
446void CodeReview(void);
447
449void TestCode(void);
450
455void MyAssert(const char *file, int line, const char *comment);
456
459
461{
462 const char* p_routine;
463 const char* p_file;
464 long p_line;
466public:
467 cloudy_exit(const char* routine, const char* file, long line, exit_type exit_code)
468 {
470 p_file = file;
471 p_line = line;
472 p_exit = exit_code;
473 }
474 const char* routine() const throw()
475 {
476 return p_routine;
477 }
478 const char* file() const throw()
479 {
480 return p_file;
481 }
482 long line() const
483 {
484 return p_line;
485 }
487 {
488 return p_exit;
489 }
490};
491
492// workarounds for __func__ are defined in cpu.h
493#define cdEXIT( FAIL ) throw cloudy_exit( __func__, __FILE__, __LINE__, FAIL )
494
495// calls like puts( "[Stop in MyRoutine]" ) have been integrated in cdEXIT above
496#define puts( STR ) Using_puts_before_cdEXIT_is_no_longer_needed
497
499void ShowMe(void);
500
502NORETURN void TotalInsanity(void);
503
504/* TotalInsanityAsStub always calls TotalInsanity(), but in such a way that
505 * it can be used as a stub for another routine without generating warnings
506 * about unreachable code after the stub. Hence this should NOT be NORETURN */
507template<class T>
509{
510 // this is always true...
511 if( ZeroNum == 0. )
513 else
514 return T();
515}
516
518NORETURN void BadRead(void);
519
523int dbg_printf(int debug, const char *fmt, ...);
524
526int dprintf(FILE *fp, const char *format, ...);
527
529inline void cdBacktrace()
530{
531 cpu.i().GenerateBacktrace(NULL);
532 cpu.i().PrintBacktrace("DEBUG ", false);
533}
534
536int fprintf (const Output& stream, const char *format, ...);
537
538int dprintf(const Output & stream, const char *format, ...);
539
545bool read_whole_line( string& chLine, FILE *ioIN );
546
547#ifdef HAVE_LIBCPP_BUG
548
549#include "service.h"
550
551// workaround for the bug described in https://bugs.llvm.org/show_bug.cgi?id=17782
552inline istringstream& operator>> ( istringstream& s, double& x )
553{
554 FPRead(s, s.str(), x);
555 return s;
556}
557
558inline istringstream& operator>> ( istringstream& s, sys_float& x )
559{
560 double y;
561 FPRead(s, s.str(), y);
562 x = sys_float(y);
563 return s;
564}
565
566#endif
567
568/**************************************************************************
569 *
570 * various macros used by the code
571 *
572 **************************************************************************/
573
577#ifndef NDEBUG
578# define DEBUG
579#else
580# undef DEBUG
581#endif
582
584{
585 int p_sig;
586public:
587 bad_signal(int sig, void* ptr);
588 bad_signal(const bad_signal&) = default;
589 bad_signal& operator= (const bad_signal&) = default;
590 virtual ~bad_signal() throw() {}
591 int sig() const throw()
592 {
593 return p_sig;
594 }
595};
596
598{
599 const char* p_file;
600 long p_line;
601 const char* p_comment;
602public:
603 bad_assert(const char* file, long line, const char* comment);
604 bad_assert(const bad_assert&) = default;
605 bad_assert& operator= (const bad_assert&) = default;
606 virtual ~bad_assert() throw() {}
607 void print(void) const
608 {
609 fprintf(ioQQQ,"DISASTER Assertion failure at %s:%ld\n%s\n",
611 }
612 const char* file() const throw()
613 {
614 return p_file;
615 }
616 long line() const throw()
617 {
618 return p_line;
619 }
620 const char *comment() const throw()
621 {
622 return p_comment;
623 }
624};
625
627{
628 const char* p_comment;
629public:
630 explicit cloudy_abort(const char* comment);
631 cloudy_abort(const cloudy_abort&) = default;
633 virtual ~cloudy_abort() throw() {}
634 const char *comment() const throw()
635 {
636 return p_comment;
637 }
638};
639
640/* the do { ... } while ( 0 ) construct prevents bugs in code like this:
641 * if( test )
642 * ASSERT( n == 10 );
643 * else
644 * do something else...
645 */
646#undef ASSERT
647#if NDEBUG
648# define ASSERT(exp) ((void)0)
649#else
650# define ASSERT(exp) \
651 do { \
652 if (UNLIKELY(!(exp))) \
653 throw bad_assert(__FILE__,__LINE__,"Failed: " #exp); \
654 } while( 0 )
655#endif
656
657#define MESSAGE_ASSERT(msg, exp) ASSERT( (msg) ? (exp) : false )
658
659inline NORETURN void OUT_OF_RANGE(const char* str)
660{
661 cpu.i().GenerateBacktrace(NULL);
662 throw out_of_range( str );
663}
664
665inline NORETURN void DOMAIN_ERROR(const string& str)
666{
667 cpu.i().GenerateBacktrace(NULL);
668 throw domain_error( str );
669}
670
671#ifdef __SUNPRO_CC
672#pragma does_not_return(OUT_OF_RANGE)
673#endif
674
675/* Windows does not define isnan */
676/* use our version on all platforms since the isnanf
677 * function does not exist under Solaris 9 either */
678#undef isnan
679#define isnan MyIsnan
680
683class t_debug : public Singleton<t_debug>
684{
685 friend class Singleton<t_debug>;
686 FILE *p_fp;
688protected:
689 t_debug() : p_fp(stderr)
690 {
691 p_callLevel = 0;
692 }
693public:
694 void enter(const char *name)
695 {
696 ++p_callLevel;
697 fprintf(p_fp,"%*c%s\n",p_callLevel,'>',name);
698 }
699 void leave(const char *name)
700 {
701 fprintf(p_fp,"%*c%s\n",p_callLevel,'<',name);
702 --p_callLevel;
703 }
704};
705
708class t_nodebug : public Singleton<t_nodebug>
709{
710 friend class Singleton<t_nodebug>;
711protected:
713public:
714 void enter(const char *) const {}
715 void leave(const char *) const {}
716};
717
718template<class Trace>
720{
721 const char *p_name;
722public:
723 explicit debugtrace(const char *funcname)
724 {
725 p_name = funcname;
726 Trace::Inst().enter(p_name);
727 }
728 debugtrace(const debugtrace&) = default;
729 debugtrace& operator= (const debugtrace&) = default;
731 {
732 Trace::Inst().leave(p_name);
733 }
734 const char* name() const
735 {
736 return p_name;
737 }
738};
739
740#ifdef DEBUG_FUN
741#define DEBUG_ENTRY( funcname ) debugtrace<t_debug> DEBUG_ENTRY( funcname )
742#else
743#define DEBUG_ENTRY( funcname ) ((void)0)
744#endif
745
746// overload the character manipulation routines
747inline char tolower(char c)
748{
749 return static_cast<char>( tolower( static_cast<int>(c) ) );
750}
751inline unsigned char tolower(unsigned char c)
752{
753 return static_cast<unsigned char>( tolower( static_cast<int>(c) ) );
754}
755
756inline char toupper(char c)
757{
758 return static_cast<char>( toupper( static_cast<int>(c) ) );
759}
760inline unsigned char toupper(unsigned char c)
761{
762 return static_cast<unsigned char>( toupper( static_cast<int>(c) ) );
763}
764
765/* TorF(l) returns a 'T' or 'F' depending on the 'logical' expr 'l' */
766inline char TorF( bool l ) { return l ? 'T' : 'F'; }
767/* */
768
770inline bool is_odd( int j ) { return (j&1) == 1; }
771inline bool is_odd( long j ) { return (j&1L) == 1L; }
772/* */
773
775inline long nint( double x ) { return static_cast<long>( (x < 0.) ? x-0.5 : x+0.5 ); }
776/* */
777
778/* define min for mixed arguments, the rest already exists */
779inline long min( int a, long b ) { long c = a; return ( (c < b) ? c : b ); }
780inline long min( long a, int b ) { long c = b; return ( (a < c) ? a : c ); }
781inline double min( sys_float a, double b ) { double c = a; return ( (c < b) ? c : b ); }
782inline double min( double a, sys_float b ) { double c = b; return ( (a < c) ? a : c ); }
783
784/* want to define this only if no native os support exists */
785#ifndef HAVE_POWI
787double powi( double , long int );
788#endif
789
791double powpq(double x, int p, int q);
792
793/* avoid ambiguous overloads */
794#ifndef HAVE_POW_DOUBLE_INT
795inline double pow( double x, int i ) { return powi( x, long(i) ); }
796#endif
797
798#ifndef HAVE_POW_DOUBLE_LONG
799inline double pow( double x, long i ) { return powi( x, i ); }
800#endif
801
802#ifndef HAVE_POW_FLOAT_INT
803inline sys_float pow( sys_float x, int i ) { return sys_float( powi( double(x), long(i) ) ); }
804#endif
805
806#ifndef HAVE_POW_FLOAT_LONG
807inline sys_float pow( sys_float x, long i ) { return sys_float( powi( double(x), i ) ); }
808#endif
809
810#ifndef HAVE_POW_FLOAT_DOUBLE
811inline double pow( sys_float x, double y ) { return pow( double(x), y ); }
812#endif
813
814#ifndef HAVE_POW_DOUBLE_FLOAT
815inline double pow( double x, sys_float y ) { return pow( x, double(y) ); }
816#endif
817
818#undef MIN2
820#define MIN2(a,b) min(a,b)
821/* */
822
823#undef MIN3
825#define MIN3(a,b,c) (min(min(a,b),c))
826/* */
827
828#undef MIN4
830#define MIN4(a,b,c,d) (min(min(a,b),min(c,d)))
831/* */
832
833/* define max for mixed arguments, the rest already exists */
834inline long max( int a, long b ) { long c = a; return ( (c > b) ? c : b ); }
835inline long max( long a, int b ) { long c = b; return ( (a > c) ? a : c ); }
836inline double max( sys_float a, double b ) { double c = a; return ( (c > b) ? c : b ); }
837inline double max( double a, sys_float b ) { double c = b; return ( (a > c) ? a : c ); }
838
839#undef MAX2
841#define MAX2(a,b) max(a,b)
842/* */
843
844#undef MAX3
846#define MAX3(a,b,c) (max(max(a,b),c))
847/* */
848
849#undef MAX4
851#define MAX4(a,b,c,d) (max(max(a,b),max(c,d)))
852/* */
853
854template<class T>
855inline void vzero(vector<T>& vec)
856{
857 memset(vec.data(), 0, vec.size()*sizeof(T));
858}
859
864template<class T>
865inline T sign( T x, T y )
866{
867 return ( y < T() ) ? -abs(x) : abs(x);
868}
869/* */
870
872template<class T>
873inline int sign3( T x ) { return ( x < T() ) ? -1 : ( ( x > T() ) ? 1 : 0 ); }
874/* */
875
877inline bool fp_equal( sys_float x, sys_float y, int n=3 )
878{
879 ASSERT( n >= 1 );
880 // mimic IEEE behavior
881 if( isnan(x) || isnan(y) )
882 return false;
883 int sx = sign3(x);
884 int sy = sign3(y);
885 // treat zero cases first to avoid division by zero below
886 if( sx == 0 && sy == 0 )
887 return true;
888 // either x or y is zero (but not both), or x and y have different sign
889 if( sx*sy != 1 )
890 return false;
891 x = abs(x);
892 y = abs(y);
893 // adjust epsilon value for denormalized numbers
894 int exp;
895 (void)frexp(max(x,y), &exp);
896 sys_float epsilon = ldexp(FLT_EPSILON, max(0,FLT_MIN_EXP-exp));
897 return ( 1.f - min(x,y)/max(x,y) < ((sys_float)n+0.1f)*epsilon );
898}
899
900inline bool fp_equal( double x, double y, int n=3 )
901{
902 ASSERT( n >= 1 );
903 // mimic IEEE behavior
904 if( isnan(x) || isnan(y) )
905 return false;
906 int sx = sign3(x);
907 int sy = sign3(y);
908 // treat zero cases first to avoid division by zero below
909 if( sx == 0 && sy == 0 )
910 return true;
911 // either x or y is zero (but not both), or x and y have different sign
912 if( sx*sy != 1 )
913 return false;
914 x = abs(x);
915 y = abs(y);
916 // adjust epsilon value for denormalized numbers
917 int exp;
918 (void)frexp(max(x,y), &exp);
919 double epsilon = ldexp(DBL_EPSILON, max(0,DBL_MIN_EXP-exp));
920 return ( 1. - min(x,y)/max(x,y) < ((double)n+0.1)*epsilon );
921}
922
924{
925 ASSERT( tol > 0.f );
926 // mimic IEEE behavior
927 if( isnan(x) || isnan(y) )
928 return false;
929 // make sure the tolerance is not too stringent
930 ASSERT( tol >= FLT_EPSILON*max(abs(x),abs(y)) );
931 return ( abs( x-y ) <= tol );
932}
933
934inline bool fp_equal_tol( double x, double y, double tol )
935{
936 ASSERT( tol > 0. );
937 // mimic IEEE behavior
938 if( isnan(x) || isnan(y) )
939 return false;
940 // make sure the tolerance is not too stringent
941 ASSERT( tol >= DBL_EPSILON*max(abs(x),abs(y)) );
942 return ( abs( x-y ) <= tol );
943}
944
946inline bool fp_bound( sys_float lo, sys_float x, sys_float hi, int n=3 )
947{
948 ASSERT( n >= 1 );
949 // mimic IEEE behavior
950 if( isnan(x) || isnan(lo) || isnan(hi) )
951 return false;
952 if( fp_equal(lo,hi,n) )
953 return fp_equal(0.5f*(lo+hi),x,n);
954 if( ((hi-x)/(hi-lo))*((x-lo)/(hi-lo)) < -((sys_float)n+0.1f)*FLT_EPSILON )
955 return false;
956 return true;
957}
958inline bool fp_bound( double lo, double x, double hi, int n=3 )
959{
960 ASSERT( n >= 1 );
961 // mimic IEEE behavior
962 if( isnan(x) || isnan(lo) || isnan(hi) )
963 return false;
964 if( fp_equal(lo,hi,n) )
965 return fp_equal(0.5*(lo+hi),x,n);
966 if( ((hi-x)/(hi-lo))*((x-lo)/(hi-lo)) < -((double)n+0.1)*DBL_EPSILON )
967 return false;
968 return true;
969}
971{
972 ASSERT( tol > 0.f );
973 // mimic IEEE behavior
974 if( isnan(x) || isnan(lo) || isnan(hi) )
975 return false;
976 if( fp_equal_tol(lo,hi,tol) )
977 return fp_equal_tol(0.5f*(lo+hi),x,tol);
978 if( ((hi-x)/(hi-lo))*((x-lo)/(hi-lo)) < -tol )
979 return false;
980 return true;
981}
982inline bool fp_bound_tol( double lo, double x, double hi, double tol )
983{
984 ASSERT( tol > 0. );
985 // mimic IEEE behavior
986 if( isnan(x) || isnan(lo) || isnan(hi) )
987 return false;
988 if( fp_equal_tol(lo,hi,tol) )
989 return fp_equal_tol(0.5*(lo+hi),x,tol);
990 if( ((hi-x)/(hi-lo))*((x-lo)/(hi-lo)) < -tol )
991 return false;
992 return true;
993}
994
995
996#undef POW2
998#define POW2 pow2
999template<class T>
1000inline T pow2(T a) { return a*a; }
1001/* */
1002
1003#undef POW3
1005#define POW3 pow3
1006template<class T>
1007inline T pow3(T a) { return a*a*a; }
1008/* */
1009
1010#undef POW4
1012#define POW4 pow4
1013template<class T>
1014inline T pow4(T a) { T b = a*a; return b*b; }
1015/* */
1016
1017#undef SDIV
1021inline sys_float SDIV( sys_float x ) { return ( fabs((double)x) < (double)SMALLFLOAT ) ? (sys_float)SMALLFLOAT : x; }
1022/* \todo should we use SMALLDOUBLE here ? it produces overflows now... PvH */
1023inline double SDIV( double x ) { return ( fabs(x) < (double)SMALLFLOAT ) ? (double)SMALLFLOAT : x; }
1024// inline double SDIV( double x ) { return ( fabs(x) < SMALLDOUBLE ) ? SMALLDOUBLE : x; }
1025/* */
1026
1031{
1032 // this should crash...
1033 if( isnan(x) || isnan(y) )
1034 return x/y;
1035 int sx = sign3(x);
1036 int sy = sign3(y);
1037 // 0/0 -> NaN, this should crash as well...
1038 if( sx == 0 && sy == 0 )
1039 {
1040 if( isnan(res_0by0) )
1041 return x/y;
1042 else
1043 return res_0by0;
1044 }
1045 if( sx == 0 )
1046 return 0.;
1047 if( sy == 0 )
1048 return ( sx < 0 ) ? -FLT_MAX : FLT_MAX;
1049 // at this stage x != 0. and y != 0.
1050 sys_float ay = abs(y);
1051 if( ay >= 1.f )
1052 return x/y;
1053 else
1054 {
1055 // multiplication is safe since ay < 1.
1056 if( abs(x) < ay*FLT_MAX )
1057 return x/y;
1058 else
1059 return ( sx*sy < 0 ) ? -FLT_MAX : FLT_MAX;
1060 }
1061}
1062
1064{
1065 return safe_div( x, y, numeric_limits<sys_float>::quiet_NaN() );
1066}
1067
1071inline double safe_div(double x, double y, double res_0by0)
1072{
1073 // this should crash...
1074 if( isnan(x) || isnan(y) )
1075 return x/y;
1076 int sx = sign3(x);
1077 int sy = sign3(y);
1078 // 0/0 -> NaN, this should crash as well...
1079 if( sx == 0 && sy == 0 )
1080 {
1081 if( isnan(res_0by0) )
1082 return x/y;
1083 else
1084 return res_0by0;
1085 }
1086 if( sx == 0 )
1087 return 0.;
1088 if( sy == 0 )
1089 return ( sx < 0 ) ? -DBL_MAX : DBL_MAX;
1090 // at this stage x != 0. and y != 0.
1091 double ay = abs(y);
1092 if( ay >= 1. )
1093 return x/y;
1094 else
1095 {
1096 // multiplication is safe since ay < 1.
1097 if( abs(x) < ay*DBL_MAX )
1098 return x/y;
1099 else
1100 return ( sx*sy < 0 ) ? -DBL_MAX : DBL_MAX;
1101 }
1102}
1103
1104inline double safe_div(double x, double y)
1105{
1106 return safe_div( x, y, numeric_limits<double>::quiet_NaN() );
1107}
1108
1109template<class T>
1110inline void invalidate_array(T* p, size_t size)
1111{
1112 if( size > 0 )
1113 memset( p, -1, size );
1114}
1115
1116inline void invalidate_array(double* p, size_t size)
1117{
1118 set_NaN( p, (long)(size/sizeof(double)) );
1119}
1120
1121inline void invalidate_array(sys_float* p, size_t size)
1122{
1123 set_NaN( p, (long)(size/sizeof(sys_float)) );
1124}
1125
1128template<class T> inline T* get_ptr(T *v)
1129{
1130 return v;
1131}
1132template<class T> inline T* get_ptr(valarray<T> &v)
1133{
1134 return &v[0];
1135}
1136template<class T, class U> inline T* get_ptr(vector<T,U> &v)
1137{
1138 return &v[0];
1139}
1140template<class T> inline const T* get_ptr(const valarray<T> &v)
1141{
1142 return const_cast<const T*>(&const_cast<valarray<T>&>(v)[0]);
1143}
1144template<class T, class U> inline const T* get_ptr(const vector<T,U> &v)
1145{
1146 return const_cast<const T*>(&const_cast<vector<T,U>&>(v)[0]);
1147}
1148
1154double csphot(long int inu, long int ithr, long int iofset);
1155
1157double AnuUnit(realnum energy);
1158
1163void cap4(char *chCAP , const char *chLab);
1164
1167void uncaps(char *chCard);
1168void uncaps(string& chCard);
1169
1172void caps(char *chCard);
1173void caps(string& chCard);
1174
1181double FFmtRead(const char *chCard,
1182 long int *ipnt,
1183 long int last,
1184 bool *lgEOL);
1185
1191long nMatch(const char *chKey,
1192 const char *chCard);
1193
1194// these are safe versions of strstr, strchr, etc to work around a deficiency in glibc
1195inline const char *strstr_s(const char *haystack, const char *needle)
1196{
1197 return const_cast<const char *>(strstr(haystack, needle));
1198}
1199
1200inline char *strstr_s(char *haystack, const char *needle)
1201{
1202 return const_cast<char *>(strstr(haystack, needle));
1203}
1204
1205inline const char *strchr_s(const char *s, int c)
1206{
1207 return const_cast<const char *>(strchr(s, c));
1208}
1209
1210inline char *strchr_s(char *s, int c)
1211{
1212 return const_cast<char *>(strchr(s, c));
1213}
1214
1217long int ipow( long, long );
1218
1219// this routine is fully equivalent to snprintf() apart from the fact that it
1220// concatenates the output to an existing string rather than replacing it.
1221size_t sncatf( char* buf, size_t bufSize, const char* fmt, ... );
1222
1223size_t sncatf( ostringstream& buf, const char* fmt, ... );
1224
1227void PrintE82( FILE*, double );
1228
1230void PrintE71( FILE*, double );
1231
1233void PrintE93( FILE*, double );
1234
1240// prevent compiler warnings on non-MS systems
1241#ifdef _MSC_VER
1242char *PrintEfmt(const char *fmt, double val );
1243#else
1244#define PrintEfmt( F, V ) F, V
1245#endif
1246
1248const double SEXP_LIMIT = 84.;
1250const double DSEXP_LIMIT = 680.;
1251
1254double sexp(double x);
1255
1259
1260double dsexp(double x);
1261
1263inline double exp10(double x)
1264{
1265 if( x < -330. )
1266 return 0.;
1267 else if( x > 310. )
1268 return pow2(BIGDOUBLE); // +Inf
1269 else
1270 {
1271 double y = trunc(x/3.);
1272 double z = 3.*y;
1273 x -= z;
1274 x *= 2.302585092994045684; // constant is ln(10)
1275 x -= 7.90550887243868070612e-3*z; // constant is ln(10)-10/3*ln(2)
1276 return ldexp(exp(x),10*int(y));
1277 }
1278}
1279
1282{
1283 if( x < -50.f )
1284 return 0.f;
1285 else if( x > 40.f )
1286 return pow2(BIGFLOAT); // +Inf
1287 else
1288 {
1289 sys_float y = truncf(x/3.f);
1290 sys_float z = 3.f*y;
1291 x -= z;
1292 x *= 2.302585093f; // constant is ln(10)
1293 x -= 7.9055088724e-3f*z; // constant is ln(10)-10/3*ln(2)
1294 return ldexpf(expf(x),10*int(y));
1295 }
1296}
1297
1299{
1300 return exp10f(x);
1301}
1302
1309
1312class t_wavl {
1318 realnum p_convertWvl() const;
1320 realnum p_wlAirVac() const;
1324 double p_RefIndex(double EnergyWN) const;
1325public:
1329 t_wavl operator- () const { return t_wavl(-p_wavl, p_type); }
1331 realnum wavlVac() const { return p_convertWvl(); }
1334 string sprt_wl(const char* format=NULL) const;
1336 void prt_wl(FILE *io, const char* format=NULL) const;
1337};
1338
1355inline t_wavl operator ""_vac(unsigned long long wavl) { return t_wavl(wavl, WL_VACUUM); }
1356inline t_wavl operator ""_vac(long double wavl) { return t_wavl(wavl, WL_VACUUM); }
1357inline t_wavl operator ""_air(unsigned long long wavl) { return t_wavl(wavl, WL_AIR); }
1358inline t_wavl operator ""_air(long double wavl) { return t_wavl(wavl, WL_AIR); }
1359
1360// shorthand for turning variables into wavelengths
1361inline t_wavl t_vac(realnum w) { return t_wavl(w, WL_VACUUM); }
1362inline t_wavl t_air(realnum w) { return t_wavl(w, WL_AIR); }
1363
1367
1368double plankf(long int ip);
1369
1370// safe version of getline() that correctly handles all types of EOL lf, crlf and cr...
1371istream& SafeGetline(istream& is, string& t);
1372
1382void spsort( realnum x[], long int n, long int iperm[], int kflag, int *ier);
1383
1384/**************************************************************************
1385 *
1386 * disable some bogus errors in the ms c compiler
1387 *
1388 **************************************************************************/
1389
1390/* */
1391#ifdef _MSC_VER
1392 /* disable strcat warning */
1393# pragma warning( disable : 4996 )
1394 /* disable bogus underflow warning in MS VS*/
1395# pragma warning( disable : 4056 )
1396 /* disable "inline function removed since not used", MS VS*/
1397# pragma warning( disable : 4514 )
1398 /* disable "assignment operator could not be generated", cddefines.h
1399 * line 126 */
1400# pragma warning( disable : 4512 )
1401#endif
1402#ifdef __INTEL_COMPILER
1403# pragma warning( disable : 1572 )
1404#endif
1405/* */
1406
1407/*lint +e129 these resolve several issues pclint has with my system headers */
1408/*lint +e78 */
1409/*lint +e830 */
1410/*lint +e38 */
1411/*lint +e148 */
1412/*lint +e114 */
1413/*lint +e18 */
1414/*lint +e49 */
1415
1416#endif /* CDDEFINES_H_ */
1417
long int nzone
Definition cddefines.cpp:15
FILE * ioPrnErr
Definition cddefines.cpp:11
bool lgTestCodeCalled
Definition cddefines.cpp:12
FILE * ioQQQ
Definition cddefines.cpp:9
bool lgTestCodeEnabled
Definition cddefines.cpp:13
FILE * ioStdin
Definition cddefines.cpp:10
bool lgPrnErr
Definition cddefines.cpp:14
long int iteration
Definition cddefines.cpp:17
double fnzone
Definition cddefines.cpp:16
float sys_float
Definition cddefines.h:131
double csphot(long int inu, long int ithr, long int iofset)
Definition service.cpp:1771
double plankf(long int ip)
Definition service.cpp:1789
#define fopen
Definition cddefines.h:162
const int FILENAME_PATH_LENGTH_2
Definition cddefines.h:319
const int FILENAME_PATH_LENGTH
Definition cddefines.h:316
#define NULL
Definition cddefines.h:116
#define isnan
Definition cddefines.h:679
#define ASSERT(exp)
Definition cddefines.h:650
sys_float sexp(sys_float x)
Definition service.cpp:1206
bool is_odd(int j)
Definition cddefines.h:770
const int ipSILICON
Definition cddefines.h:385
#define PrintEfmt(F, V)
Definition cddefines.h:1244
const int ipRecEsc
Definition cddefines.h:352
const int ipBERYLLIUM
Definition cddefines.h:375
const double MAX_DENSITY
Definition cddefines.h:342
const double DSEXP_LIMIT
Definition cddefines.h:1250
const int ipCHROMIUM
Definition cddefines.h:395
const double SEXP_LIMIT
Definition cddefines.h:1248
long nMatch(const char *chKey, const char *chCard)
Definition service.cpp:731
char tolower(char c)
Definition cddefines.h:747
const int ipNITROGEN
Definition cddefines.h:378
const int ipZINC
Definition cddefines.h:401
wl_type
Definition cddefines.h:1308
@ WL_VACUUM
Definition cddefines.h:1308
@ WL_AIR
Definition cddefines.h:1308
@ WL_NATIVE
Definition cddefines.h:1308
const int NCHLAB
Definition cddefines.h:327
const int ipIRON
Definition cddefines.h:397
exit_type
Definition cddefines.h:164
@ ES_DOMAIN_ERROR
Definition cddefines.h:173
@ ES_FAILURE
Definition cddefines.h:166
@ ES_BOTCHES
Definition cddefines.h:168
@ ES_SEGFAULT
Definition cddefines.h:176
@ ES_TOP
Definition cddefines.h:180
@ ES_WARNINGS
Definition cddefines.h:167
@ ES_BUS_ERROR
Definition cddefines.h:177
@ ES_BAD_ASSERT
Definition cddefines.h:170
@ ES_UNKNOWN_SIGNAL
Definition cddefines.h:178
@ ES_SUCCESS
Definition cddefines.h:165
@ ES_UNKNOWN_EXCEPTION
Definition cddefines.h:179
@ ES_OUT_OF_RANGE
Definition cddefines.h:172
@ ES_BAD_ALLOC
Definition cddefines.h:171
@ ES_ILLEGAL_INSTRUCTION
Definition cddefines.h:174
@ ES_FP_EXCEPTION
Definition cddefines.h:175
@ ES_CLOUDY_ABORT
Definition cddefines.h:169
void cdBacktrace()
Definition cddefines.h:529
const int ipCARBON
Definition cddefines.h:377
const int ipSCANDIUM
Definition cddefines.h:392
const int ipALUMINIUM
Definition cddefines.h:384
sys_float exp10f(sys_float x)
Definition cddefines.h:1281
const int ipOXYGEN
Definition cddefines.h:379
const int NHYDRO_MAX_LEVEL
Definition cddefines.h:339
@ CHARS_SPECIES
Definition cddefines.h:347
istringstream & operator>>(istringstream &s, double &x)
Definition cddefines.h:552
void PrintE93(FILE *, double)
Definition service.cpp:1129
void broken(void)
Definition service.cpp:1274
FILE * ioMAP
Definition cdinit.cpp:9
const double DEPTH_OFFSET
Definition cddefines.h:345
int sign3(T x)
Definition cddefines.h:873
NORETURN void BadRead(void)
Definition service.cpp:1193
void TestCode(void)
Definition service.cpp:1264
@ CHARS_ISOTOPE_SYM
Definition cddefines.h:348
const int ipCOPPER
Definition cddefines.h:400
void CodeReview(void)
Definition service.cpp:1300
void PrintE82(FILE *, double)
Definition service.cpp:1030
double fudge(long int ipnt)
Definition service.cpp:761
const int LIMELM
Definition cddefines.h:331
const int ipPHOSPHORUS
Definition cddefines.h:386
const int INPUT_LINE_LENGTH
Definition cddefines.h:324
T sign(T x, T y)
Definition cddefines.h:865
const int ipLITHIUM
Definition cddefines.h:374
sys_float safe_div(sys_float x, sys_float y, sys_float res_0by0)
Definition cddefines.h:1030
int dbg_printf(int debug, const char *fmt,...)
Definition service.cpp:1360
int dprintf(FILE *fp, const char *format,...)
Definition service.cpp:1309
const double ZeroNum
Definition cdinit.cpp:13
const int ipMAGNESIUM
Definition cddefines.h:383
const void * ZeroPtr
Definition cdinit.cpp:15
const int ipVANADIUM
Definition cddefines.h:394
t_wavl t_vac(realnum w)
Definition cddefines.h:1361
const int ipBORON
Definition cddefines.h:376
const int ipSODIUM
Definition cddefines.h:382
NORETURN void OUT_OF_RANGE(const char *str)
Definition cddefines.h:659
void cap4(char *chCAP, const char *chLab)
Definition service.cpp:260
void MyAssert(const char *file, int line, const char *comment)
Definition service.cpp:175
const int ipTITANIUM
Definition cddefines.h:393
char toupper(char c)
Definition cddefines.h:756
char TorF(bool l)
Definition cddefines.h:766
const int ipCOBALT
Definition cddefines.h:398
void vzero(vector< T > &vec)
Definition cddefines.h:855
void PrintE71(FILE *, double)
Definition service.cpp:1079
double AnuUnit(realnum energy)
Definition service.cpp:192
T TotalInsanityAsStub()
Definition cddefines.h:508
NORETURN void DOMAIN_ERROR(const string &str)
Definition cddefines.h:665
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition service.cpp:396
bool fp_bound_tol(sys_float lo, sys_float x, sys_float hi, sys_float tol)
Definition cddefines.h:970
const int NISO
Definition cddefines.h:334
FILE * ioQQQ
Definition cddefines.cpp:9
const char * strstr_s(const char *haystack, const char *needle)
Definition cddefines.h:1195
const int ipHELIUM
Definition cddefines.h:373
const int ipRecNetEsc
Definition cddefines.h:354
float realnum
Definition cddefines.h:128
const int ipFLUORINE
Definition cddefines.h:380
long int ipow(long, long)
Definition service.cpp:864
const int ipNICKEL
Definition cddefines.h:399
int fprintf(const Output &stream, const char *format,...)
Definition service.cpp:1328
const char * strchr_s(const char *s, int c)
Definition cddefines.h:1205
bool fp_bound(sys_float lo, sys_float x, sys_float hi, int n=3)
Definition cddefines.h:946
T * get_ptr(T *v)
Definition cddefines.h:1128
const int ipSULPHUR
Definition cddefines.h:387
long nint(double x)
Definition cddefines.h:775
const int ipCALCIUM
Definition cddefines.h:391
long max(int a, long b)
Definition cddefines.h:834
bool fp_equal(sys_float x, sys_float y, int n=3)
Definition cddefines.h:877
void caps(char *chCard)
Definition service.cpp:302
double powpq(double x, int p, int q)
Definition service.cpp:836
const int ipCRDW
Definition cddefines.h:367
const int ipPOTASSIUM
Definition cddefines.h:390
void spsort(realnum x[], long int n, long int iperm[], int kflag, int *ier)
Definition service.cpp:1429
NORETURN void TotalInsanity(void)
Definition service.cpp:1177
t_wavl t_air(realnum w)
Definition cddefines.h:1362
void fixit_base(const char *func, const char *file, int line, const char *reason)
Definition service.cpp:1283
sys_float SDIV(sys_float x)
Definition cddefines.h:1021
const int ipHYDROGEN
Definition cddefines.h:372
FILE * sys_fopen(const char *path, const char *mode)
Definition cddefines.h:158
double dsexp(double x)
Definition service.cpp:1245
const int ipRecRad
Definition cddefines.h:356
T pow4(T a)
Definition cddefines.h:1014
const int ipNEON
Definition cddefines.h:381
size_t sncatf(char *buf, size_t bufSize, const char *fmt,...)
Definition service.cpp:922
const int ipCRD
Definition cddefines.h:365
const int ipCHLORINE
Definition cddefines.h:388
long min(int a, long b)
Definition cddefines.h:779
bool read_whole_line(string &chLine, FILE *ioIN)
Definition service.cpp:71
const int ipKRYPTON
Definition cddefines.h:402
void cdPrepareExit(exit_type)
Definition cdinit.cpp:131
double exp10(double x)
Definition cddefines.h:1263
const int ipMANGANESE
Definition cddefines.h:396
void uncaps(char *chCard)
Definition service.cpp:280
void invalidate_array(T *p, size_t size)
Definition cddefines.h:1110
const int ipARGON
Definition cddefines.h:389
const int ipLY_A
Definition cddefines.h:369
bool fp_equal_tol(sys_float x, sys_float y, sys_float tol)
Definition cddefines.h:923
void ShowMe(void)
Definition service.cpp:200
double powi(double, long int)
Definition service.cpp:800
istream & SafeGetline(istream &is, string &t)
Definition service.cpp:1852
const int ipPRD
Definition cddefines.h:363
Fixit(const char *func, const char *file, int line, const char *reason)
Definition cddefines.h:433
Definition cddefines.h:248
Output(FILE *fp)
Definition cddefines.h:252
FILE * m_fp
Definition cddefines.h:250
FILE * fptr() const
Definition cddefines.h:253
Definition cddefines.h:227
static T & Inst()
Definition cddefines.h:229
void print(void) const
Definition cddefines.h:607
const char * comment() const
Definition cddefines.h:620
bad_assert(const bad_assert &)=default
const char * file() const
Definition cddefines.h:612
long p_line
Definition cddefines.h:600
const char * p_file
Definition cddefines.h:599
bad_assert & operator=(const bad_assert &)=default
const char * p_comment
Definition cddefines.h:601
long line() const
Definition cddefines.h:616
virtual ~bad_assert()
Definition cddefines.h:606
bad_assert(const char *file, long line, const char *comment)
Definition cddefines.cpp:24
int sig() const
Definition cddefines.h:591
virtual ~bad_signal()
Definition cddefines.h:590
bad_signal(const bad_signal &)=default
bad_signal(int sig, void *ptr)
Definition cddefines.cpp:19
bad_signal & operator=(const bad_signal &)=default
int p_sig
Definition cddefines.h:585
cloudy_abort & operator=(const cloudy_abort &)=default
const char * p_comment
Definition cddefines.h:628
const char * comment() const
Definition cddefines.h:634
virtual ~cloudy_abort()
Definition cddefines.h:633
cloudy_abort(const cloudy_abort &)=default
cloudy_abort(const char *comment)
Definition cddefines.cpp:30
const char * file() const
Definition cddefines.h:478
long line() const
Definition cddefines.h:482
const char * p_file
Definition cddefines.h:463
long p_line
Definition cddefines.h:464
const char * p_routine
Definition cddefines.h:462
exit_type p_exit
Definition cddefines.h:465
exit_type exit_status() const
Definition cddefines.h:486
const char * routine() const
Definition cddefines.h:474
cloudy_exit(const char *routine, const char *file, long line, exit_type exit_code)
Definition cddefines.h:467
const char * p_name
Definition cddefines.h:721
debugtrace(const debugtrace &)=default
debugtrace & operator=(const debugtrace &)=default
~debugtrace()
Definition cddefines.h:730
const char * name() const
Definition cddefines.h:734
debugtrace(const char *funcname)
Definition cddefines.h:723
void leave(const char *name)
Definition cddefines.h:699
FILE * p_fp
Definition cddefines.h:686
int p_callLevel
Definition cddefines.h:687
t_debug()
Definition cddefines.h:689
void enter(const char *name)
Definition cddefines.h:694
void leave(const char *) const
Definition cddefines.h:715
void enter(const char *) const
Definition cddefines.h:714
t_nodebug()
Definition cddefines.h:712
Definition cddefines.h:1312
t_wavl()
Definition cddefines.h:1326
realnum wavlVac() const
Definition cddefines.h:1331
string sprt_wl(const char *format=NULL) const
Definition cddefines.cpp:90
realnum p_wavl
Definition cddefines.h:1314
t_wavl(realnum w, wl_type t)
Definition cddefines.h:1327
wl_type p_type
Definition cddefines.h:1316
t_wavl operator-() const
Definition cddefines.h:1329
void prt_wl(FILE *io, const char *format=NULL) const
Definition cddefines.cpp:157
realnum p_convertWvl() const
Definition cddefines.cpp:35
double p_RefIndex(double EnergyWN) const
Definition cddefines.cpp:67
realnum p_wlAirVac() const
Definition cddefines.cpp:44
void set_NaN(sys_float &x)
Definition cpu.cpp:960
static t_cpu cpu
Definition cpu.h:436
const realnum BIGFLOAT
Definition cpu.h:233
const double BIGDOUBLE
Definition cpu.h:238
#define NORETURN
Definition cpu.h:475
const realnum SMALLFLOAT
Definition cpu.h:235
double energy(const genericState &gs)
Definition generic_state.cpp:51
#define pow2(a)
Definition physconst_template.h:28
#define pow3(a)
Definition physconst_template.h:29
void FPRead(istringstream &iss, const string &s, double &value)
Definition service.cpp:551