CoolProp  6.6.1dev
An open-source fluid property and humid air property database
Configuration.h
Go to the documentation of this file.
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, \
24  "If true, any temperature within 1 uK of the critical temperature will be considered to be AT the critical point") \
25  X(CRITICAL_SPLINES_ENABLED, "CRITICAL_SPLINES_ENABLED", true, \
26  "If true, the critical splines will be used in the near-vicinity of the critical point") \
27  X(SAVE_RAW_TABLES, "SAVE_RAW_TABLES", false, "If true, the raw, uncompressed tables will also be written to file") \
28  X(ALTERNATIVE_TABLES_DIRECTORY, "ALTERNATIVE_TABLES_DIRECTORY", "", \
29  "If provided, this path will be the root directory for the tabular data. Otherwise, ${HOME}/.CoolProp/Tables is used") \
30  X(ALTERNATIVE_REFPROP_PATH, "ALTERNATIVE_REFPROP_PATH", "", \
31  "An alternative path to be provided to the directory that contains REFPROP's fluids and mixtures directories. If provided, the SETPATH " \
32  "function will be called with this directory prior to calling any REFPROP functions.") \
33  X(ALTERNATIVE_REFPROP_HMX_BNC_PATH, "ALTERNATIVE_REFPROP_HMX_BNC_PATH", "", \
34  "An alternative path to the HMX.BNC file. If provided, it will be passed into REFPROP's SETUP or SETMIX routines") \
35  X(ALTERNATIVE_REFPROP_LIBRARY_PATH, "ALTERNATIVE_REFPROP_LIBRARY_PATH", "", \
36  "An alternative path to the shared library file. If provided, it will be used to load REFPROP") \
37  X(REFPROP_DONT_ESTIMATE_INTERACTION_PARAMETERS, "REFPROP_DONT_ESTIMATE_INTERACTION_PARAMETERS", false, \
38  "If true, if the binary interaction parameters in REFPROP are estimated, throw an error rather than silently continuing") \
39  X(REFPROP_IGNORE_ERROR_ESTIMATED_INTERACTION_PARAMETERS, "REFPROP_IGNORE_ERROR_ESTIMATED_INTERACTION_PARAMETERS", false, \
40  "If true, if the binary interaction parameters in REFPROP are unable to be estimated, silently continue rather than failing") \
41  X(REFPROP_USE_GERG, "REFPROP_USE_GERG", false, \
42  "If true, rather than using the highly-accurate pure fluid equations of state, use the pure-fluid EOS from GERG-2008") \
43  X(REFPROP_ERROR_THRESHOLD, "REFPROP_ERROR_THRESHOLD", static_cast<int>(0), "The highest acceptable error code without throwing an exception") \
44  X(REFPROP_USE_PENGROBINSON, "REFPROP_USE_PENGROBINSON", false, \
45  "If true, rather than using the highly-accurate pure fluid equations of state, use the Peng-Robinson EOS") \
46  X(MAXIMUM_TABLE_DIRECTORY_SIZE_IN_GB, "MAXIMUM_TABLE_DIRECTORY_SIZE_IN_GB", 1.0, \
47  "The maximum allowed size of the directory that is used to store tabular data") \
48  X(DONT_CHECK_PROPERTY_LIMITS, "DONT_CHECK_PROPERTY_LIMITS", false, \
49  "If true, when possible, CoolProp will skip checking whether values are inside the property limits") \
50  X(HENRYS_LAW_TO_GENERATE_VLE_GUESSES, "HENRYS_LAW_TO_GENERATE_VLE_GUESSES", false, \
51  "If true, when doing water-based mixture dewpoint calculations, use Henry's Law to generate guesses for liquid-phase composition") \
52  X(PHASE_ENVELOPE_STARTING_PRESSURE_PA, "PHASE_ENVELOPE_STARTING_PRESSURE_PA", 100.0, "Starting pressure [Pa] for phase envelope construction") \
53  X(R_U_CODATA, "R_U_CODATA", 8.3144598, \
54  "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. " \
55  "This is especially important in the critical region.") \
56  X(VTPR_UNIFAC_PATH, "VTPR_UNIFAC_PATH", "", "The path to the directory containing the UNIFAC JSON files. Should be slash terminated") \
57  X(SPINODAL_MINIMUM_DELTA, "SPINODAL_MINIMUM_DELTA", 0.5, \
58  "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") \
59  X(OVERWRITE_FLUIDS, "OVERWRITE_FLUIDS", false, \
60  "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 " \
61  "exception), overwrite it") \
62  X(OVERWRITE_DEPARTURE_FUNCTION, "OVERWRITE_DEPARTURE_FUNCTION", false, \
63  "If true, and a departure function to be added is already there, rather than not adding the departure function (and probably throwing an " \
64  "exception), overwrite it") \
65  X(OVERWRITE_BINARY_INTERACTION, "OVERWRITE_BINARY_INTERACTION", false, \
66  "If true, and a pair of binary interaction pairs to be added is already there, rather than not adding the binary interaction pair (and " \
67  "probably throwing an exception), overwrite it") \
68  X(USE_GUESSES_IN_PROPSSI, "USE_GUESSES_IN_PROPSSI", false, \
69  "If true, calls to the vectorized versions of PropsSI use the previous state as guess value while looping over the input vectors, only makes " \
70  "sense when working with a single fluid and with points that are not too far from each other.") \
71  X(ASSUME_CRITICAL_POINT_STABLE, "ASSUME_CRITICAL_POINT_STABLE", false, \
72  "If true, evaluation of the stability of critical point will be skipped and point will be assumed to be stable") \
73  X(VTPR_ALWAYS_RELOAD_LIBRARY, "VTPR_ALWAYS_RELOAD_LIBRARY", false, \
74  "If true, the library will always be reloaded, no matter what is currently loaded") \
75  X(FLOAT_PUNCTUATION, "FLOAT_PUNCTUATION", ".", "The first character of this string will be used as the separator between the number fraction.") \
76  X(LIST_STRING_DELIMITER, "LIST_STRING_DELIMITER", ",", "The delimiter to be used when converting a list of strings to a string")
77 
78 // Use preprocessor to create the Enum
80 {
81 #define X(Enum, String, Default, Desc) Enum,
83 #undef X
84 };
85 
86 // Evidently SWIG+MATLAB cannot properly wrap enums within classes
88 {
95 };
96 
97 namespace CoolProp {
98 
100 std::string config_key_to_string(configuration_keys keys);
101 
103 configuration_keys config_string_to_key(const std::string& s);
104 
107 
109 std::string config_key_description(const std::string& key);
110 
114 {
115  public:
117  operator bool() const {
118  check_data_type(CONFIGURATION_BOOL_TYPE);
119  return v_bool;
120  };
122  operator double() const {
123  check_data_type(CONFIGURATION_DOUBLE_TYPE);
124  return v_double;
125  };
127  operator std::string() const {
128  check_data_type(CONFIGURATION_STRING_TYPE);
129  return v_string;
130  };
132  operator int() const {
133  check_data_type(CONFIGURATION_INTEGER_TYPE);
134  return v_integer;
135  };
136  // Initializer for bool
138  this->key = key;
140  v_bool = val;
141  };
142  // Initializer for integer
144  this->key = key;
146  v_integer = val;
147  };
148  // Initializer for double
150  this->key = key;
152  v_double = val;
153  };
154  // Initializer for const char *
155  ConfigurationItem(configuration_keys key, const char* val) {
156  this->key = key;
158  v_string = val;
159  };
160  // Initializer for string
161  ConfigurationItem(configuration_keys key, const std::string& val) {
162  this->key = key;
164  v_string = val;
165  };
166  void set_bool(bool val) {
167  check_data_type(CONFIGURATION_BOOL_TYPE);
168  v_bool = val;
169  }
170  void set_integer(int val) {
171  check_data_type(CONFIGURATION_INTEGER_TYPE);
172  v_integer = val;
173  }
174  void set_double(double val) {
175  check_data_type(CONFIGURATION_DOUBLE_TYPE);
176  v_double = val;
177  }
178  void set_string(const std::string& val) {
179  check_data_type(CONFIGURATION_STRING_TYPE);
180  v_string = val;
181  }
182 
184  return this->key;
185  }
186 #if !defined(SWIG)
188  void add_to_json(rapidjson::Value& val, rapidjson::Document& d) const {
189  std::string name_string = config_key_to_string(key);
190  rapidjson::Value name(name_string.c_str(), d.GetAllocator());
191  switch (type) {
193  rapidjson::Value v(v_bool);
194  val.AddMember(name, v, d.GetAllocator());
195  break;
196  }
198  rapidjson::Value v(v_integer);
199  val.AddMember(name, v, d.GetAllocator());
200  break;
201  }
203  rapidjson::Value v(v_double); // Try to upcast
204  val.AddMember(name, v, d.GetAllocator());
205  break;
206  }
208  rapidjson::Value v(v_string.c_str(), d.GetAllocator());
209  val.AddMember(name, v, d.GetAllocator());
210  break;
211  }
214  throw ValueError();
215  }
216  }
217  void set_from_json(rapidjson::Value& val) {
218  switch (type) {
220  if (!val.IsBool()) {
221  throw ValueError(format("Input is not boolean"));
222  };
223  v_bool = val.GetBool();
224  break;
226  if (!val.IsInt()) {
227  throw ValueError(format("Input is not integer"));
228  };
229  v_integer = val.GetInt();
230  break;
232  if (!val.IsDouble() && !val.IsInt()) {
233  throw ValueError(format("Input [%s] is not double (or something that can be cast to double)", cpjson::to_string(val).c_str()));
234  };
235  if (val.IsDouble()) {
236  v_double = val.GetDouble();
237  } else {
238  v_double = static_cast<double>(val.GetInt());
239  }
240  break;
241  }
243  if (!val.IsString()) {
244  throw ValueError(format("Input is not string"));
245  };
246  v_string = val.GetString();
247  break;
250  throw ValueError();
251  }
252  }
253 #endif // !defined(SWIG)
254 
255  private:
256  void check_data_type(ConfigurationDataTypes type) const {
257  if (type != this->type) {
258  throw ValueError(format("type does not match"));
259  }
260  };
262  union
263  {
264  double v_double;
265  bool v_bool;
267  };
268  std::string v_string;
269  configuration_keys key;
270 };
271 
273 {
274  protected:
275  std::map<configuration_keys, ConfigurationItem> items;
276 
277  public:
279  set_defaults();
280  };
282 
285  // Try to find it
286  std::map<configuration_keys, ConfigurationItem>::iterator it = items.find(key);
287  // If equal to end, not found
288  if (it != items.end()) {
289  // Found, return it
290  return it->second;
291  } else {
292  throw ValueError(format("invalid item"));
293  }
294  }
297  std::pair<configuration_keys, ConfigurationItem> pair(item.get_key(), item);
298  items.insert(pair);
299  };
300 
302  std::map<configuration_keys, ConfigurationItem>& get_items(void) {
303  return items;
304  };
305 
307  void set_defaults(void) {
308 /* ***MAGIC WARNING**!!
309  * See http://stackoverflow.com/a/148610
310  * See http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511
311  */
312 #define X(Enum, String, Default, Desc) add_item(ConfigurationItem(Enum, Default));
314 #undef X
315  };
316 };
317 
321 
329 std::string get_config_string(configuration_keys key);
330 #if !defined(SWIG) // Hide this for swig - Swig gets confused
331 void get_config_as_json(rapidjson::Document& doc);
332 #endif
334 std::string get_config_as_json_string();
335 
339 
341 void set_config_bool(configuration_keys key, bool val);
343 void set_config_int(configuration_keys key, int val);
345 void set_config_double(configuration_keys key, double val);
347 void set_config_string(configuration_keys key, const std::string& val);
349 #if !defined(SWIG) // Hide this for swig - Swig gets confused
350 void set_config_json(rapidjson::Document& doc);
351 #endif
353 void set_config_as_json_string(const std::string& s);
354 } // namespace CoolProp
355 
356 #endif // COOLPROP_CONFIGURATION