CoolProp
Configuration.h
1 #ifndef COOLPROP_CONFIGURATION
2 #define COOLPROP_CONFIGURATION
3 
4 #include "Exceptions.h"
5 #include "CoolPropTools.h"
6 
7 #if !defined(SWIG) // Hide this for swig - Swig gets confused
8 #include "rapidjson_include.h"
9 #endif
10 
11 /* See http://stackoverflow.com/a/148610
12  * See http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511
13  * This will be used to generate an enum like:
14  * enum configuration_keys {NORMALIZE_GAS_CONSTANTS, CRITICAL_SPLINES_ENABLED};
15  *
16  * The values in this list are given by:
17  * enum, string representation of enum, default value, description
18  *
19  * The type of the default value specifies the only type that will be accepted for this parameter
20  */
21 #define CONFIGURATION_KEYS_ENUM \
22  X(NORMALIZE_GAS_CONSTANTS, "NORMALIZE_GAS_CONSTANTS", true, "If true, for mixtures, the molar gas constant (R) will be set to the CODATA value") \
23  X(CRITICAL_WITHIN_1UK, "CRITICAL_WITHIN_1UK", true, "If true, any temperature within 1 uK of the critical temperature will be considered to be AT the critical point") \
24  X(CRITICAL_SPLINES_ENABLED, "CRITICAL_SPLINES_ENABLED", true, "If true, the critical splines will be used in the near-vicinity of the critical point") \
25  X(SAVE_RAW_TABLES, "SAVE_RAW_TABLES", false, "If true, the raw, uncompressed tables will also be written to file") \
26  X(ALTERNATIVE_TABLES_DIRECTORY, "ALTERNATIVE_TABLES_DIRECTORY", "", "If provided, this path will be the root directory for the tabular data. Otherwise, ${HOME}/.CoolProp/Tables is used") \
27  X(ALTERNATIVE_REFPROP_PATH, "ALTERNATIVE_REFPROP_PATH", "", "An alternative path to be provided to the directory that contains REFPROP's fluids and mixtures directories. If provided, the SETPATH function will be called with this directory prior to calling any REFPROP functions.") \
28  X(ALTERNATIVE_REFPROP_HMX_BNC_PATH, "ALTERNATIVE_REFPROP_HMX_BNC_PATH", "", "An alternative path to the HMX.BNC file. If provided, it will be passed into REFPROP's SETUP or SETMIX routines") \
29  X(ALTERNATIVE_REFPROP_LIBRARY_PATH, "ALTERNATIVE_REFPROP_LIBRARY_PATH", "", "An alternative path to the shared library file. If provided, it will be used to load REFPROP") \
30  X(REFPROP_DONT_ESTIMATE_INTERACTION_PARAMETERS, "REFPROP_DONT_ESTIMATE_INTERACTION_PARAMETERS", false, "If true, if the binary interaction parameters in REFPROP are estimated, throw an error rather than silently continuing") \
31  X(REFPROP_IGNORE_ERROR_ESTIMATED_INTERACTION_PARAMETERS, "REFPROP_IGNORE_ERROR_ESTIMATED_INTERACTION_PARAMETERS", false, "If true, if the binary interaction parameters in REFPROP are unable to be estimated, silently continue rather than failing") \
32  X(REFPROP_USE_GERG, "REFPROP_USE_GERG", false, "If true, rather than using the highly-accurate pure fluid equations of state, use the pure-fluid EOS from GERG-2008") \
33  X(REFPROP_ERROR_THRESHOLD, "REFPROP_ERROR_THRESHOLD", static_cast<int>(0), "The highest acceptable error code without throwing an exception") \
34  X(REFPROP_USE_PENGROBINSON, "REFPROP_USE_PENGROBINSON", false, "If true, rather than using the highly-accurate pure fluid equations of state, use the Peng-Robinson EOS") \
35  X(MAXIMUM_TABLE_DIRECTORY_SIZE_IN_GB, "MAXIMUM_TABLE_DIRECTORY_SIZE_IN_GB", 1.0, "The maximum allowed size of the directory that is used to store tabular data") \
36  X(DONT_CHECK_PROPERTY_LIMITS, "DONT_CHECK_PROPERTY_LIMITS", false, "If true, when possible, CoolProp will skip checking whether values are inside the property limits") \
37  X(HENRYS_LAW_TO_GENERATE_VLE_GUESSES, "HENRYS_LAW_TO_GENERATE_VLE_GUESSES", false, "If true, when doing water-based mixture dewpoint calculations, use Henry's Law to generate guesses for liquid-phase composition") \
38  X(PHASE_ENVELOPE_STARTING_PRESSURE_PA, "PHASE_ENVELOPE_STARTING_PRESSURE_PA", 100.0, "Starting pressure [Pa] for phase envelope construction") \
39  X(R_U_CODATA, "R_U_CODATA", 8.3144598, "The value for the ideal gas constant in J/mol/K according to CODATA 2014. This value is used to harmonize all the ideal gas constants. This is especially important in the critical region.") \
40  X(VTPR_UNIFAC_PATH, "VTPR_UNIFAC_PATH", "", "The path to the directory containing the UNIFAC JSON files. Should be slash terminated") \
41  X(SPINODAL_MINIMUM_DELTA, "SPINODAL_MINIMUM_DELTA", 0.5, "The minimal delta to be used in tracing out the spinodal; make sure that the EOS has a spinodal at this value of delta=rho/rho_r") \
42  X(OVERWRITE_FLUIDS, "OVERWRITE_FLUIDS", false, "If true, and a fluid is added to the fluids library that is already there, rather than not adding the fluid (and probably throwing an exception), overwrite it") \
43  X(OVERWRITE_DEPARTURE_FUNCTION, "OVERWRITE_DEPARTURE_FUNCTION", false, "If true, and a departure function to be added is already there, rather than not adding the departure function (and probably throwing an exception), overwrite it") \
44  X(OVERWRITE_BINARY_INTERACTION, "OVERWRITE_BINARY_INTERACTION", false, "If true, and a pair of binary interaction pairs to be added is already there, rather than not adding the binary interaction pair (and probably throwing an exception), overwrite it") \
45  X(USE_GUESSES_IN_PROPSSI, "USE_GUESSES_IN_PROPSSI", false, "If true, calls to the vectorized versions of PropsSI use the previous state as guess value while looping over the input vectors, only makes sense when working with a single fluid and with points that are not too far from each other.") \
46  X(ASSUME_CRITICAL_POINT_STABLE, "ASSUME_CRITICAL_POINT_STABLE", false, "If true, evaluation of the stability of critical point will be skipped and point will be assumed to be stable") \
47  X(VTPR_ALWAYS_RELOAD_LIBRARY, "VTPR_ALWAYS_RELOAD_LIBRARY", false, "If true, the library will always be reloaded, no matter what is currently loaded") \
48  X(FLOAT_PUNCTUATION, "FLOAT_PUNCTUATION", ".", "The first character of this string will be used as the separator between the number fraction.") \
49  X(LIST_STRING_DELIMITER, "LIST_STRING_DELIMITER", ",", "The delimiter to be used when converting a list of strings to a string")
50 
51 
52  // Use preprocessor to create the Enum
53  enum configuration_keys{
54  #define X(Enum, String, Default, Desc) Enum,
55  CONFIGURATION_KEYS_ENUM
56  #undef X
57  };
58 
59 // Evidently SWIG+MATLAB cannot properly wrap enums within classes
60 enum ConfigurationDataTypes {
61  CONFIGURATION_NOT_DEFINED_TYPE = 0,
62  CONFIGURATION_BOOL_TYPE,
63  CONFIGURATION_DOUBLE_TYPE,
64  CONFIGURATION_INTEGER_TYPE,
65  CONFIGURATION_STRING_TYPE,
66  CONFIGURATION_ENDOFLIST_TYPE
67 };
68 
69 namespace CoolProp
70 {
71 
73 std::string config_key_to_string(configuration_keys keys);
74 
76 configuration_keys config_string_to_key(const std::string &s);
77 
79 std::string config_key_description(configuration_keys keys);
80 
82 std::string config_key_description(const std::string &key);
83 
87 {
88  public:
89 
91  operator bool() const { check_data_type(CONFIGURATION_BOOL_TYPE); return v_bool; };
93  operator double() const { check_data_type(CONFIGURATION_DOUBLE_TYPE); return v_double; };
95  operator std::string() const { check_data_type(CONFIGURATION_STRING_TYPE); return v_string; };
97  operator int() const { check_data_type(CONFIGURATION_INTEGER_TYPE); return v_integer; };
98  // Initializer for bool
99  ConfigurationItem(configuration_keys key, bool val){
100  this->key = key; type = CONFIGURATION_BOOL_TYPE; v_bool = val;
101  };
102  // Initializer for integer
103  ConfigurationItem(configuration_keys key, int val){
104  this->key = key; type = CONFIGURATION_INTEGER_TYPE; v_integer = val;
105  };
106  // Initializer for double
107  ConfigurationItem(configuration_keys key, double val){
108  this->key = key; type = CONFIGURATION_DOUBLE_TYPE; v_double = val;
109  };
110  // Initializer for const char *
111  ConfigurationItem(configuration_keys key, const char *val){
112  this->key = key; type = CONFIGURATION_STRING_TYPE; v_string = val;
113  };
114  // Initializer for string
115  ConfigurationItem(configuration_keys key, const std::string &val){
116  this->key = key; type = CONFIGURATION_STRING_TYPE; v_string = val;
117  };
118  void set_bool(bool val){
119  check_data_type(CONFIGURATION_BOOL_TYPE);
120  v_bool = val;
121  }
122  void set_integer(int val){
123  check_data_type(CONFIGURATION_INTEGER_TYPE);
124  v_integer = val;
125  }
126  void set_double(double val){
127  check_data_type(CONFIGURATION_DOUBLE_TYPE);
128  v_double = val;
129  }
130  void set_string(const std::string &val){
131  check_data_type(CONFIGURATION_STRING_TYPE);
132  v_string = val;
133  }
134 
135  configuration_keys get_key(void) const {
136  return this->key;
137  }
138  #if !defined(SWIG)
139  void add_to_json(rapidjson::Value &val, rapidjson::Document &d) const {
141  std::string name_string = config_key_to_string(key);
142  rapidjson::Value name(name_string.c_str(), d.GetAllocator());
143  switch (type){
144  case CONFIGURATION_BOOL_TYPE:
145  {
146  rapidjson::Value v(v_bool);
147  val.AddMember(name, v, d.GetAllocator()); break;
148  }
149  case CONFIGURATION_INTEGER_TYPE:
150  {
151  rapidjson::Value v(v_integer);
152  val.AddMember(name, v, d.GetAllocator()); break;
153  }
154  case CONFIGURATION_DOUBLE_TYPE:
155  {
156  rapidjson::Value v(v_double); // Try to upcast
157  val.AddMember(name, v, d.GetAllocator()); break;
158  }
159  case CONFIGURATION_STRING_TYPE:
160  {
161  rapidjson::Value v(v_string.c_str(), d.GetAllocator());
162  val.AddMember(name, v, d.GetAllocator()); break;
163  }
164  case CONFIGURATION_ENDOFLIST_TYPE:
165  case CONFIGURATION_NOT_DEFINED_TYPE:
166  throw ValueError();
167  }
168  }
169  void set_from_json(rapidjson::Value &val){
170  switch (type){
171  case CONFIGURATION_BOOL_TYPE: if (!val.IsBool()){throw ValueError(format("Input is not boolean"));}; v_bool = val.GetBool(); break;
172  case CONFIGURATION_INTEGER_TYPE: if (!val.IsInt()){throw ValueError(format("Input is not integer"));}; v_integer = val.GetInt(); break;
173  case CONFIGURATION_DOUBLE_TYPE: {
174  if (!val.IsDouble() && !val.IsInt()){throw ValueError(format("Input [%s] is not double (or something that can be cast to double)",cpjson::to_string(val).c_str()));};
175  if (val.IsDouble()){ v_double = val.GetDouble(); }
176  else{ v_double = static_cast<double>(val.GetInt()); }
177  break;
178  }
179  case CONFIGURATION_STRING_TYPE: if (!val.IsString()){throw ValueError(format("Input is not string"));}; v_string = val.GetString(); break;
180  case CONFIGURATION_ENDOFLIST_TYPE:
181  case CONFIGURATION_NOT_DEFINED_TYPE:
182  throw ValueError();
183  }
184  }
185  #endif // !defined(SWIG)
186 
187  private:
188  void check_data_type(ConfigurationDataTypes type) const {
189  if (type != this->type){
190  throw ValueError(format("type does not match"));
191  }
192  };
193  ConfigurationDataTypes type;
194  union {
195  double v_double;
196  bool v_bool;
197  int v_integer;
198 
199  };
200  std::string v_string;
201  configuration_keys key;
202 };
203 
205 {
206  protected:
207  std::map<configuration_keys,ConfigurationItem> items;
208 
209  public:
210  Configuration(){set_defaults();};
211  ~Configuration(){};
212 
214  ConfigurationItem &get_item(configuration_keys key){
215  // Try to find it
216  std::map<configuration_keys,ConfigurationItem>::iterator it = items.find(key);
217  // If equal to end, not found
218  if (it != items.end()){
219  // Found, return it
220  return it->second;
221  }
222  else{
223  throw ValueError(format("invalid item"));
224  }
225  }
228  {
229  std::pair<configuration_keys, ConfigurationItem> pair(item.get_key(), item);
230  items.insert(pair);
231  };
232 
234  std::map<configuration_keys, ConfigurationItem> & get_items(void){return items;};
235 
237  void set_defaults(void)
238  {
239  /* ***MAGIC WARNING**!!
240  * See http://stackoverflow.com/a/148610
241  * See http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511
242  */
243  #define X(Enum, String, Default, Desc) \
244  add_item(ConfigurationItem(Enum, Default));
245  CONFIGURATION_KEYS_ENUM
246  #undef X
247  };
248 };
249 
253 
255 bool get_config_bool(configuration_keys key);
257 int get_config_int(configuration_keys key);
259 double get_config_double(configuration_keys key);
261 std::string get_config_string(configuration_keys key);
262 #if !defined(SWIG) // Hide this for swig - Swig gets confused
263 void get_config_as_json(rapidjson::Document &doc);
264 #endif
265 std::string get_config_as_json_string();
267 
271 
273 void set_config_bool(configuration_keys key, bool val);
275 void set_config_int(configuration_keys key, int val);
277 void set_config_double(configuration_keys key, double val);
279 void set_config_string(configuration_keys key, const std::string &val);
281 #if !defined(SWIG) // Hide this for swig - Swig gets confused
282 void set_config_json(rapidjson::Document &doc);
283 #endif
284 void set_config_as_json_string(const std::string &s);
286 }
287 
288 #endif // COOLPROP_CONFIGURATION
ConfigurationItem & get_item(configuration_keys key)
Get an item from the configuration.
Definition: Configuration.h:214
void add_to_json(rapidjson::Value &val, rapidjson::Document &d) const
Cast to rapidjson::Value.
Definition: Configuration.h:140
double get_config_double(configuration_keys key)
Return the value of a double configuration key.
Definition: Configuration.cpp:92
std::string get_config_string(configuration_keys key)
Return the value of a string configuration key.
Definition: Configuration.cpp:95
Definition: Configuration.h:204
void set_defaults(void)
Set the default values in the configuration.
Definition: Configuration.h:237
std::string config_key_description(configuration_keys keys)
Return a string description of the configuration key.
Definition: Configuration.cpp:24
void set_config_int(configuration_keys key, int val)
Set the value of an integer configuration value.
Definition: Configuration.cpp:71
int get_config_int(configuration_keys key)
Return the value of an integer key from the configuration.
Definition: Configuration.cpp:89
void set_config_as_json_string(const std::string &s)
Set the entire configuration based on a json-formatted string.
Definition: Configuration.cpp:145
Definition: Exceptions.h:26
A class that contains one entry in configuration Can be cast to yield the output value.
Definition: Configuration.h:86
std::map< configuration_keys, ConfigurationItem > & get_items(void)
Return a reference to all of the items.
Definition: Configuration.h:234
void add_item(ConfigurationItem item)
Add an item to the configuration.
Definition: Configuration.h:227
std::string config_key_to_string(configuration_keys keys)
Convert the configuration key to a string in a 1-1 representation.
Definition: Configuration.cpp:7
void set_config_string(configuration_keys key, const std::string &val)
Set the value of a string configuration value.
Definition: Configuration.cpp:77
std::string get_config_as_json_string()
Get all the values in the configuration as a json-formatted string.
Definition: Configuration.cpp:105
void set_config_json(rapidjson::Document &doc)
Set values in the configuration based on a json file.
This file contains flash routines in which the state is unknown, and a solver of some kind must be us...
Definition: AbstractState.h:19
bool get_config_bool(configuration_keys key)
GETTERS
Definition: Configuration.cpp:86
void set_config_double(configuration_keys key, double val)
Set the value of a double configuration value.
Definition: Configuration.cpp:74
void set_config_bool(configuration_keys key, bool val)
SETTERS
Definition: Configuration.cpp:68
configuration_keys config_string_to_key(const std::string &s)
Convert a string description to a configuration key.
Definition: Configuration.cpp:52