CoolProp 6.8.0
An open-source fluid property and humid air property database
DataStructures.cpp
Go to the documentation of this file.
1
2
3#include "DataStructures.h"
4#include "Exceptions.h"
5#include "CoolPropTools.h"
6#include "CoolProp.h"
7#include <memory>
8
9namespace CoolProp {
10
12{
13 int key;
14 const char *short_desc, *IO, *units, *description;
15 bool trivial;
16};
17
20 {iT, "T", "IO", "K", "Temperature", false},
21 {iP, "P", "IO", "Pa", "Pressure", false},
22 {iDmolar, "Dmolar", "IO", "mol/m^3", "Molar density", false},
23 {iHmolar, "Hmolar", "IO", "J/mol", "Molar specific enthalpy", false},
24 {iSmolar, "Smolar", "IO", "J/mol/K", "Molar specific entropy", false},
25 {iUmolar, "Umolar", "IO", "J/mol", "Molar specific internal energy", false},
26 {iGmolar, "Gmolar", "O", "J/mol", "Molar specific Gibbs energy", false},
27 {iHelmholtzmolar, "Helmholtzmolar", "O", "J/mol", "Molar specific Helmholtz energy", false},
28 {iDmass, "Dmass", "IO", "kg/m^3", "Mass density", false},
29 {iHmass, "Hmass", "IO", "J/kg", "Mass specific enthalpy", false},
30 {iSmass, "Smass", "IO", "J/kg/K", "Mass specific entropy", false},
31 {iUmass, "Umass", "IO", "J/kg", "Mass specific internal energy", false},
32 {iGmass, "Gmass", "O", "J/kg", "Mass specific Gibbs energy", false},
33 {iHelmholtzmass, "Helmholtzmass", "O", "J/kg", "Mass specific Helmholtz energy", false},
34 {iQ, "Q", "IO", "mol/mol", "Molar vapor quality", false},
35 {iDelta, "Delta", "IO", "-", "Reduced density (rho/rhoc)", false},
36 {iTau, "Tau", "IO", "-", "Reciprocal reduced temperature (Tc/T)", false},
38 {iCpmolar, "Cpmolar", "O", "J/mol/K", "Molar specific constant pressure specific heat", false},
39 {iCpmass, "Cpmass", "O", "J/kg/K", "Mass specific constant pressure specific heat", false},
40 {iCvmolar, "Cvmolar", "O", "J/mol/K", "Molar specific constant volume specific heat", false},
41 {iCvmass, "Cvmass", "O", "J/kg/K", "Mass specific constant volume specific heat", false},
42 {iCp0molar, "Cp0molar", "O", "J/mol/K", "Ideal gas molar specific constant pressure specific heat", false},
43 {iCp0mass, "Cp0mass", "O", "J/kg/K", "Ideal gas mass specific constant pressure specific heat", false},
44 {iHmolar_residual, "Hmolar_residual", "O", "J/mol/K", "Residual molar enthalpy", false},
45 {iSmolar_residual, "Smolar_residual", "O", "J/mol/K", "Residual molar entropy (sr/R = s(T,rho) - s^0(T,rho))", false},
46 {iGmolar_residual, "Gmolar_residual", "O", "J/mol/K", "Residual molar Gibbs energy", false},
47 {iGWP20, "GWP20", "O", "-", "20-year global warming potential", true},
48 {iGWP100, "GWP100", "O", "-", "100-year global warming potential", true},
49 {iGWP500, "GWP500", "O", "-", "500-year global warming potential", true},
50 {iFH, "FH", "O", "-", "Flammability hazard", true},
51 {iHH, "HH", "O", "-", "Health hazard", true},
52 {iPH, "PH", "O", "-", "Physical hazard", true},
53 {iODP, "ODP", "O", "-", "Ozone depletion potential", true},
54 {iBvirial, "Bvirial", "O", "-", "Second virial coefficient", false},
55 {iCvirial, "Cvirial", "O", "-", "Third virial coefficient", false},
56 {idBvirial_dT, "dBvirial_dT", "O", "-", "Derivative of second virial coefficient with respect to T", false},
57 {idCvirial_dT, "dCvirial_dT", "O", "-", "Derivative of third virial coefficient with respect to T", false},
58 {igas_constant, "gas_constant", "O", "J/mol/K", "Molar gas constant", true},
59 {imolar_mass, "molar_mass", "O", "kg/mol", "Molar mass", true},
60 {iacentric_factor, "acentric", "O", "-", "Acentric factor", true},
61 {idipole_moment, "dipole_moment", "O", "C-m", "Dipole moment", true},
62 {irhomass_reducing, "rhomass_reducing", "O", "kg/m^3", "Mass density at reducing point", true},
63 {irhomolar_reducing, "rhomolar_reducing", "O", "mol/m^3", "Molar density at reducing point", true},
64 {irhomolar_critical, "rhomolar_critical", "O", "mol/m^3", "Molar density at critical point", true},
65 {irhomass_critical, "rhomass_critical", "O", "kg/m^3", "Mass density at critical point", true},
66 {iT_reducing, "T_reducing", "O", "K", "Temperature at the reducing point", true},
67 {iT_critical, "T_critical", "O", "K", "Temperature at the critical point", true},
68 {iT_triple, "T_triple", "O", "K", "Temperature at the triple point", true},
69 {iT_max, "T_max", "O", "K", "Maximum temperature limit", true},
70 {iT_min, "T_min", "O", "K", "Minimum temperature limit", true},
71 {iP_min, "P_min", "O", "Pa", "Minimum pressure limit", true},
72 {iP_max, "P_max", "O", "Pa", "Maximum pressure limit", true},
73 {iP_critical, "p_critical", "O", "Pa", "Pressure at the critical point", true},
74 {iP_reducing, "p_reducing", "O", "Pa", "Pressure at the reducing point", true},
75 {iP_triple, "p_triple", "O", "Pa", "Pressure at the triple point (pure only)", true},
76 {ifraction_min, "fraction_min", "O", "-", "Fraction (mole, mass, volume) minimum value for incompressible solutions", true},
77 {ifraction_max, "fraction_max", "O", "-", "Fraction (mole, mass, volume) maximum value for incompressible solutions", true},
78 {iT_freeze, "T_freeze", "O", "K", "Freezing temperature for incompressible solutions", true},
79
80 {ispeed_sound, "speed_of_sound", "O", "m/s", "Speed of sound", false},
81 {iviscosity, "viscosity", "O", "Pa-s", "Viscosity", false},
82 {iconductivity, "conductivity", "O", "W/m/K", "Thermal conductivity", false},
83 {isurface_tension, "surface_tension", "O", "N/m", "Surface tension", false},
84 {iPrandtl, "Prandtl", "O", "-", "Prandtl number", false},
85
86 {iisothermal_compressibility, "isothermal_compressibility", "O", "1/Pa", "Isothermal compressibility", false},
87 {iisobaric_expansion_coefficient, "isobaric_expansion_coefficient", "O", "1/K", "Isobaric expansion coefficient", false},
88 {iisentropic_expansion_coefficient, "isentropic_expansion_coefficient", "O", "-", "Isentropic expansion coefficient", false},
89 {iZ, "Z", "O", "-", "Compressibility factor", false},
90 {ifundamental_derivative_of_gas_dynamics, "fundamental_derivative_of_gas_dynamics", "O", "-", "Fundamental derivative of gas dynamics", false},
91 {iPIP, "PIP", "O", "-", "Phase identification parameter", false},
92
93 {ialphar, "alphar", "O", "-", "Residual Helmholtz energy", false},
94 {idalphar_dtau_constdelta, "dalphar_dtau_constdelta", "O", "-", "Derivative of residual Helmholtz energy with tau", false},
95 {idalphar_ddelta_consttau, "dalphar_ddelta_consttau", "O", "-", "Derivative of residual Helmholtz energy with delta", false},
96
97 {ialpha0, "alpha0", "O", "-", "Ideal Helmholtz energy", false},
98 {idalpha0_dtau_constdelta, "dalpha0_dtau_constdelta", "O", "-", "Derivative of ideal Helmholtz energy with tau", false},
99 {idalpha0_ddelta_consttau, "dalpha0_ddelta_consttau", "O", "-", "Derivative of ideal Helmholtz energy with delta", false},
100 {id2alpha0_ddelta2_consttau, "d2alpha0_ddelta2_consttau", "O", "-", "Second derivative of ideal Helmholtz energy with delta", false},
101 {id3alpha0_ddelta3_consttau, "d3alpha0_ddelta3_consttau", "O", "-", "Third derivative of ideal Helmholtz energy with delta", false},
102
103 {iPhase, "Phase", "O", "-", "Phase index as a float", false},
104
105};
106
108{
109 public:
110 std::map<int, bool> trivial_map;
111 std::map<int, std::string> short_desc_map, description_map, IO_map, units_map;
112 std::map<std::string, int> index_map;
114 const parameter_info* const end = parameter_info_list + sizeof(parameter_info_list) / sizeof(parameter_info_list[0]);
115 for (const parameter_info* el = parameter_info_list; el != end; ++el) {
116 short_desc_map.insert(std::pair<int, std::string>(el->key, el->short_desc));
117 IO_map.insert(std::pair<int, std::string>(el->key, el->IO));
118 units_map.insert(std::pair<int, std::string>(el->key, el->units));
119 description_map.insert(std::pair<int, std::string>(el->key, el->description));
120 index_map_insert(el->short_desc, el->key);
121 trivial_map.insert(std::pair<int, bool>(el->key, el->trivial));
122 }
123 // Backward compatibility aliases
124 index_map_insert("D", iDmass);
125 index_map_insert("H", iHmass);
126 index_map_insert("M", imolar_mass);
127 index_map_insert("S", iSmass);
128 index_map_insert("U", iUmass);
129 index_map_insert("C", iCpmass);
130 index_map_insert("O", iCvmass);
131 index_map_insert("G", iGmass);
132 index_map_insert("V", iviscosity);
133 index_map_insert("L", iconductivity);
134 index_map_insert("pcrit", iP_critical);
135 index_map_insert("Pcrit", iP_critical);
136 index_map_insert("Tcrit", iT_critical);
137 index_map_insert("Ttriple", iT_triple);
138 index_map_insert("ptriple", iP_triple);
139 index_map_insert("rhocrit", irhomass_critical);
140 index_map_insert("Tmin", iT_min);
141 index_map_insert("Tmax", iT_max);
142 index_map_insert("pmax", iP_max);
143 index_map_insert("pmin", iP_min);
144 index_map_insert("molemass", imolar_mass);
145 index_map_insert("molarmass", imolar_mass);
146 index_map_insert("A", ispeed_sound);
147 index_map_insert("I", isurface_tension);
148 }
149
150 private:
151 void index_map_insert(const std::string& desc, int key) {
152 index_map.insert(std::pair<std::string, int>(desc, key));
153 index_map.insert(std::pair<std::string, int>(upper(desc), key));
154 }
155};
156
157// std::unique_ptr<ParameterInformation> parameter_information_p;
161 //parameter_information_p = std::make_unique<ParameterInformation>();
163 }
165}
166
167bool is_trivial_parameter(int key) {
168 auto& parameter_information = get_parameter_information();
169 auto it = parameter_information.trivial_map.find(key);
170 if (it != parameter_information.trivial_map.end()) {
171 return it->second;
172 }
173 throw ValueError(format("Unable to match the key [%d: %s] in is_trivial_parameter", key, get_parameter_information(key, "short").c_str()));
174}
175
176std::string get_parameter_information(int key, const std::string& info) {
177 const std::map<int, std::string>* M;
178 auto& parameter_information = get_parameter_information();
179 // Hook up the right map (since they are all of the same type)
180 if (!info.compare("IO")) {
181 M = &(parameter_information.IO_map);
182 } else if (!info.compare("short")) {
183 M = &(parameter_information.short_desc_map);
184 } else if (!info.compare("long")) {
185 M = &(parameter_information.description_map);
186 } else if (!info.compare("units")) {
187 M = &(parameter_information.units_map);
188 } else {
189 throw ValueError(format("Bad info string [%s] to get_parameter_information", info.c_str()));
190 }
191
192 auto it = M->find(key);
193 if (it != M->end()) {
194 return it->second;
195 }
196 throw ValueError(format("Unable to match the key [%d] in get_parameter_information for info [%s]", key, info.c_str()));
197}
198
201 auto& parameter_information = get_parameter_information();
202 std::vector<std::string> strings;
203 for (std::map<std::string, int>::const_iterator it = parameter_information.index_map.begin(); it != parameter_information.index_map.end(); ++it) {
204 strings.push_back(it->first);
205 }
206 return strjoin(strings, ",");
207}
208bool is_valid_parameter(const std::string& param_name, parameters& iOutput) {
209 auto& parameter_information = get_parameter_information();
210 // Try to find it
211 std::map<std::string, int>::const_iterator it = parameter_information.index_map.find(param_name);
212 // If equal to end, not found
213 if (it != parameter_information.index_map.end()) {
214 // Found, return it
215 iOutput = static_cast<parameters>(it->second);
216 return true;
217 } else {
218 return false;
219 }
220}
221
222bool is_valid_first_derivative(const std::string& name, parameters& iOf, parameters& iWrt, parameters& iConstant) {
223 if (get_debug_level() > 5) {
224 std::cout << format("is_valid_first_derivative(%s)", name.c_str());
225 }
226 // There should be exactly one /
227 // There should be exactly one |
228
229 // Suppose we start with "d(P)/d(T)|Dmolar"
230 std::vector<std::string> split_at_bar = strsplit(name, '|'); // "d(P)/d(T)" and "Dmolar"
231 if (split_at_bar.size() != 2) {
232 return false;
233 }
234
235 std::vector<std::string> split_at_slash = strsplit(split_at_bar[0], '/'); // "d(P)" and "d(T)"
236 if (split_at_slash.size() != 2) {
237 return false;
238 }
239
240 std::size_t i0 = split_at_slash[0].find("(");
241 std::size_t i1 = split_at_slash[0].find(")", i0);
242 if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0 + 1)) && (i1 != std::string::npos))) {
243 return false;
244 }
245 std::string num = split_at_slash[0].substr(i0 + 1, i1 - i0 - 1);
246
247 i0 = split_at_slash[1].find("(");
248 i1 = split_at_slash[1].find(")", i0);
249 if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0 + 1)) && (i1 != std::string::npos))) {
250 return false;
251 }
252 std::string den = split_at_slash[1].substr(i0 + 1, i1 - i0 - 1);
253
254 parameters Of, Wrt, Constant;
255 if (is_valid_parameter(num, Of) && is_valid_parameter(den, Wrt) && is_valid_parameter(split_at_bar[1], Constant)) {
256 iOf = Of;
257 iWrt = Wrt;
258 iConstant = Constant;
259 return true;
260 } else {
261 return false;
262 }
263}
264
265bool is_valid_first_saturation_derivative(const std::string& name, parameters& iOf, parameters& iWrt) {
266 if (get_debug_level() > 5) {
267 std::cout << format("is_valid_first_saturation_derivative(%s)", name.c_str());
268 }
269 // There should be exactly one /
270 // There should be exactly one |
271
272 // Suppose we start with "d(P)/d(T)|sigma"
273 std::vector<std::string> split_at_bar = strsplit(name, '|'); // "d(P)/d(T)" and "sigma"
274 if (split_at_bar.size() != 2) {
275 return false;
276 }
277
278 std::vector<std::string> split_at_slash = strsplit(split_at_bar[0], '/'); // "d(P)" and "d(T)"
279 if (split_at_slash.size() != 2) {
280 return false;
281 }
282
283 std::size_t i0 = split_at_slash[0].find("(");
284 std::size_t i1 = split_at_slash[0].find(")", i0);
285 if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0 + 1)) && (i1 != std::string::npos))) {
286 return false;
287 }
288 std::string num = split_at_slash[0].substr(i0 + 1, i1 - i0 - 1);
289
290 i0 = split_at_slash[1].find("(");
291 i1 = split_at_slash[1].find(")", i0);
292 if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0 + 1)) && (i1 != std::string::npos))) {
293 return false;
294 }
295 std::string den = split_at_slash[1].substr(i0 + 1, i1 - i0 - 1);
296
297 parameters Of, Wrt;
298 if (is_valid_parameter(num, Of) && is_valid_parameter(den, Wrt) && upper(split_at_bar[1]) == "SIGMA") {
299 iOf = Of;
300 iWrt = Wrt;
301 return true;
302 } else {
303 return false;
304 }
305}
306
307bool is_valid_second_derivative(const std::string& name, parameters& iOf1, parameters& iWrt1, parameters& iConstant1, parameters& iWrt2,
308 parameters& iConstant2) {
309 if (get_debug_level() > 5) {
310 std::cout << format("is_valid_second_derivative(%s)", name.c_str());
311 }
312
313 // Suppose we start with "d(d(P)/d(Dmolar)|T)/d(Dmolar)|T"
314 std::size_t i = name.rfind('|');
315 if ((i == 0) || (i == std::string::npos)) {
316 return false;
317 }
318 std::string constant2 = name.substr(i + 1); // "T"
319 if (!is_valid_parameter(constant2, iConstant2)) {
320 return false;
321 };
322 std::string left_of_bar = name.substr(0, i); // "d(d(P)/d(Dmolar)|T)/d(Dmolar)"
323
324 i = left_of_bar.rfind('/');
325 if ((i == 0) || (i == std::string::npos)) {
326 return false;
327 }
328 std::string left_of_slash = left_of_bar.substr(0, i); // "d(d(P)/d(Dmolar)|T)"
329 std::string right_of_slash = left_of_bar.substr(i + 1); // "d(Dmolar)"
330
331 i = left_of_slash.find("(");
332 std::size_t i1 = left_of_slash.rfind(")");
333 if (!((i > 0) && (i != std::string::npos) && (i1 > (i + 1)) && (i1 != std::string::npos))) {
334 return false;
335 }
336 std::string num = left_of_slash.substr(i + 1, i1 - i - 1); // "d(P)/d(Dmolar)|T"
337 if (!is_valid_first_derivative(num, iOf1, iWrt1, iConstant1)) {
338 return false;
339 }
340
341 i = right_of_slash.find("(");
342 i1 = right_of_slash.rfind(")");
343 if (!((i > 0) && (i != std::string::npos) && (i1 > (i + 1)) && (i1 != std::string::npos))) {
344 return false;
345 }
346 std::string den = right_of_slash.substr(i + 1, i1 - i - 1); // "Dmolar"
347 if (!is_valid_parameter(den, iWrt2)) {
348 return false;
349 }
350
351 // If we haven't quit yet, all is well
352 return true;
353}
354
356{
358 const char *short_desc, *long_desc;
359};
360
362 {iphase_liquid, "phase_liquid", ""},
363 {iphase_gas, "phase_gas", ""},
364 {iphase_twophase, "phase_twophase", ""},
365 {iphase_supercritical, "phase_supercritical", ""},
366 {iphase_supercritical_gas, "phase_supercritical_gas", "p < pc, T > Tc"},
367 {iphase_supercritical_liquid, "phase_supercritical_liquid", "p > pc, T < Tc"},
368 {iphase_critical_point, "phase_critical_point", "p = pc, T = Tc"},
369 {iphase_unknown, "phase_unknown", ""},
370 {iphase_not_imposed, "phase_not_imposed", ""},
371};
372
374{
375 public:
376 std::map<phases, std::string> short_desc_map, long_desc_map;
377 std::map<std::string, phases> index_map;
379 const phase_info* const end = phase_info_list + sizeof(phase_info_list) / sizeof(phase_info_list[0]);
380 for (const phase_info* el = phase_info_list; el != end; ++el) {
381 short_desc_map.insert(std::pair<phases, std::string>(el->key, el->short_desc));
382 long_desc_map.insert(std::pair<phases, std::string>(el->key, el->long_desc));
383 index_map.insert(std::pair<std::string, phases>(el->short_desc, el->key));
384 }
385 }
386};
387
388//std::unique_ptr<PhaseInformation> phase_information_p;
391 if (!phase_information_p) {
392 //phase_information_p = std::make_unique<PhaseInformation>();
394 }
395 return *phase_information_p;
396}
397
398const std::string& get_phase_short_desc(phases phase) {
399 auto& coolprop_information = get_phase_information();
400 auto iter = coolprop_information.short_desc_map.find(phase);
401 if (iter != coolprop_information.short_desc_map.end()) {
402 return iter->second;
403 }
404 throw ValueError("Cannot find the short phase description.");
405}
406bool is_valid_phase(const std::string& phase_name, phases& iOutput) {
407 auto& phase_information = get_phase_information();
408 // Try to find it
409 std::map<std::string, phases>::const_iterator it = phase_information.index_map.find(phase_name);
410 // If equal to end, not found
411 if (it != phase_information.index_map.end()) {
412 // Found, return it
413 iOutput = static_cast<phases>(it->second);
414 return true;
415 } else {
416 return false;
417 }
418}
419
420phases get_phase_index(const std::string& param_name) {
422 if (is_valid_phase(param_name, iPhase)) {
423 return iPhase;
424 } else {
425 throw ValueError(format("Your input name [%s] is not valid in get_phase_index (names are case sensitive)", param_name.c_str()));
426 }
427}
428
430{
432 std::string short_desc;
433};
434
436 { i1, "1"},
437 { i2a, "2A"},
438 { i2b, "2B"},
439 { i3a, "3A"},
440 { i3b, "3B"},
441 { i4a, "4A"},
442 { i4b, "4B"},
443 { i4c, "4C"},
444};
445
447public:
448 std::map<schemes, std::string> short_desc_map;
449 std::map<std::string, schemes> index_map;
451 {
452 const scheme_info* const end = scheme_info_list + sizeof(scheme_info_list) / sizeof(scheme_info_list[0]);
453 for (const scheme_info* el = scheme_info_list; el != end; ++el)
454 {
455 short_desc_map.insert(std::pair<schemes, std::string>(el->key, el->short_desc));
456 index_map.insert(std::pair<std::string, schemes>(el->short_desc, el->key));
457 }
458 }
459};
460
461//std::unique_ptr<SchemeInformation> scheme_information_p;
465 //scheme_information_p = std::make_unique<SchemeInformation>();
467 }
468 return *scheme_information_p;
469}
470
471const std::string& get_scheme_short_desc(schemes scheme) {
472 auto& coolprop_information = get_scheme_information();
473 auto it = coolprop_information.short_desc_map.find(scheme);
474 if (it != coolprop_information.short_desc_map.end()) {
475 return it->second;
476 }
477 throw ValueError("Cannot find the short scheme description.");
478}
479
480bool is_valid_scheme(const std::string &scheme_name, schemes &iOutput) {
481 auto& scheme_information = get_scheme_information();
482 auto it = scheme_information.index_map.find(scheme_name);
483 // If equal to end, not found
484 if (it != scheme_information.index_map.end()){
485 // Found, return it
486 iOutput = static_cast<schemes>(it->second);
487 return true;
488 }
489 else{
490 return false;
491 }
492}
493
494schemes get_scheme_index(const std::string &param_name) {
495 schemes iScheme;
496 if (is_valid_scheme(param_name, iScheme)){
497 return iScheme;
498 }
499 else{
500 throw ValueError(format("Your input name [%s] is not valid in get_scheme_index (names are case sensitive)",param_name.c_str()));
501 }
502}
503
504parameters get_parameter_index(const std::string& param_name) {
505 parameters iOutput;
506 if (is_valid_parameter(param_name, iOutput)) {
507 return iOutput;
508 } else {
509 throw ValueError(format("Your input name [%s] is not valid in get_parameter_index (names are case sensitive)", param_name.c_str()));
510 }
511}
512
514{
516 const char *short_desc, *long_desc;
517};
518
520 {QT_INPUTS, "QT_INPUTS", "Molar quality, Temperature in K"},
521 {QSmolar_INPUTS, "QS_INPUTS", "Molar quality, Entropy in J/mol/K"},
522 {QSmass_INPUTS, "QS_INPUTS", "Molar quality, Entropy in J/kg/K"},
523 {HmolarQ_INPUTS, "HQ_INPUTS", "Enthalpy in J/mol, Molar quality"},
524 {HmassQ_INPUTS, "HQ_INPUTS", "Enthalpy in J/kg, Molar quality"},
525 {DmassQ_INPUTS, "DmassQ_INPUTS", "Molar density kg/m^3, Molar quality"},
526 {DmolarQ_INPUTS, "DmolarQ_INPUTS", "Molar density in mol/m^3, Molar quality"},
527
528 {PQ_INPUTS, "PQ_INPUTS", "Pressure in Pa, Molar quality"},
529
530 {PT_INPUTS, "PT_INPUTS", "Pressure in Pa, Temperature in K"},
531
532 {DmassT_INPUTS, "DmassT_INPUTS", "Mass density in kg/m^3, Temperature in K"},
533 {DmolarT_INPUTS, "DmolarT_INPUTS", "Molar density in mol/m^3, Temperature in K"},
534 {HmassT_INPUTS, "HmassT_INPUTS", "Enthalpy in J/kg, Temperature in K"},
535 {HmolarT_INPUTS, "HmolarT_INPUTS", "Enthalpy in J/mol, Temperature in K"},
536 {SmassT_INPUTS, "SmassT_INPUTS", "Entropy in J/kg/K, Temperature in K"},
537 {SmolarT_INPUTS, "SmolarT_INPUTS", "Entropy in J/mol/K, Temperature in K"},
538 {TUmass_INPUTS, "TUmass_INPUTS", "Temperature in K, Internal energy in J/kg"},
539 {TUmolar_INPUTS, "TUmolar_INPUTS", "Temperature in K, Internal energy in J/mol"},
540
541 {DmassP_INPUTS, "DmassP_INPUTS", "Mass density in kg/m^3, Pressure in Pa"},
542 {DmolarP_INPUTS, "DmolarP_INPUTS", "Molar density in mol/m^3, Pressure in Pa"},
543 {HmassP_INPUTS, "HmassP_INPUTS", "Enthalpy in J/kg, Pressure in Pa"},
544 {HmolarP_INPUTS, "HmolarP_INPUTS", "Enthalpy in J/mol, Pressure in Pa"},
545 {PSmass_INPUTS, "PSmass_INPUTS", "Pressure in Pa, Entropy in J/kg/K"},
546 {PSmolar_INPUTS, "PSmolar_INPUTS", "Pressure in Pa, Entropy in J/mol/K "},
547 {PUmass_INPUTS, "PUmass_INPUTS", "Pressure in Pa, Internal energy in J/kg"},
548 {PUmolar_INPUTS, "PUmolar_INPUTS", "Pressure in Pa, Internal energy in J/mol"},
549
550 {DmassHmass_INPUTS, "DmassHmass_INPUTS", "Mass density in kg/m^3, Enthalpy in J/kg"},
551 {DmolarHmolar_INPUTS, "DmolarHmolar_INPUTS", "Molar density in mol/m^3, Enthalpy in J/mol"},
552 {DmassSmass_INPUTS, "DmassSmass_INPUTS", "Mass density in kg/m^3, Entropy in J/kg/K"},
553 {DmolarSmolar_INPUTS, "DmolarSmolar_INPUTS", "Molar density in mol/m^3, Entropy in J/mol/K"},
554 {DmassUmass_INPUTS, "DmassUmass_INPUTS", "Mass density in kg/m^3, Internal energy in J/kg"},
555 {DmolarUmolar_INPUTS, "DmolarUmolar_INPUTS", "Molar density in mol/m^3, Internal energy in J/mol"},
556
557 {HmassSmass_INPUTS, "HmassSmass_INPUTS", "Enthalpy in J/kg, Entropy in J/kg/K"},
558 {HmolarSmolar_INPUTS, "HmolarSmolar_INPUTS", "Enthalpy in J/mol, Entropy in J/mol/K"},
559 {SmassUmass_INPUTS, "SmassUmass_INPUTS", "Entropy in J/kg/K, Internal energy in J/kg"},
560 {SmolarUmolar_INPUTS, "SmolarUmolar_INPUTS", "Entropy in J/mol/K, Internal energy in J/mol"},
561};
562
564{
565 public:
566 std::map<input_pairs, std::string> short_desc_map, long_desc_map;
567 std::map<std::string, input_pairs> index_map;
569 const input_pair_info* const end = input_pair_list + sizeof(input_pair_list) / sizeof(input_pair_list[0]);
570 for (const input_pair_info* el = input_pair_list; el != end; ++el) {
571 short_desc_map.insert(std::pair<input_pairs, std::string>(el->key, el->short_desc));
572 long_desc_map.insert(std::pair<input_pairs, std::string>(el->key, el->long_desc));
573 index_map.insert(std::pair<std::string, input_pairs>(el->short_desc, el->key));
574 }
575 }
576};
577
578//std::unique_ptr<InputPairInformation> input_pair_information_p;
582 //input_pair_information_p = std::make_unique<InputPairInformation>();
584 }
586}
587
588input_pairs get_input_pair_index(const std::string& input_pair_name) {
589 auto& coolprop_information = get_input_pair_information();
590 auto it = coolprop_information.index_map.find(input_pair_name);
591 if (it != coolprop_information.index_map.end()) {
592 return it->second;
593 }
594 throw ValueError(format("Your input name [%s] is not valid in get_input_pair_index (names are case sensitive)", input_pair_name.c_str()));
595}
596
597const std::string& get_input_pair_short_desc(input_pairs pair) {
598 auto& coolprop_information = get_input_pair_information();
599 auto it = coolprop_information.short_desc_map.find(pair);
600 if (it != coolprop_information.short_desc_map.end()) {
601 return it->second;
602 }
603 throw ValueError("Cannot find the short input pair description.");
604}
605const std::string& get_input_pair_long_desc(input_pairs pair) {
606 auto& coolprop_information = get_input_pair_information();
607 auto it = coolprop_information.long_desc_map.find(pair);
608 if (it != coolprop_information.long_desc_map.end()) {
609 return it->second;
610 }
611 throw ValueError("Cannot find the long input pair description.");
612}
614 switch (pair) {
615 case QT_INPUTS:
616 p1 = iQ;
617 p2 = iT;
618 break;
619 case QSmolar_INPUTS:
620 p1 = iQ;
621 p2 = iSmolar;
622 break;
623 case QSmass_INPUTS:
624 p1 = iQ;
625 p2 = iSmass;
626 break;
627 case HmolarQ_INPUTS:
628 p1 = iHmolar;
629 p2 = iQ;
630 break;
631 case HmassQ_INPUTS:
632 p1 = iHmass;
633 p2 = iQ;
634 break;
635 case PQ_INPUTS:
636 p1 = iP;
637 p2 = iQ;
638 break;
639 case PT_INPUTS:
640 p1 = iP;
641 p2 = iT;
642 break;
643 case DmassT_INPUTS:
644 p1 = iDmass;
645 p2 = iT;
646 break;
647 case DmolarT_INPUTS:
648 p1 = iDmolar;
649 p2 = iT;
650 break;
651 case HmassT_INPUTS:
652 p1 = iHmass;
653 p2 = iT;
654 break;
655 case HmolarT_INPUTS:
656 p1 = iHmolar;
657 p2 = iT;
658 break;
659 case SmassT_INPUTS:
660 p1 = iSmass;
661 p2 = iT;
662 break;
663 case SmolarT_INPUTS:
664 p1 = iSmolar;
665 p2 = iT;
666 break;
667 case TUmass_INPUTS:
668 p1 = iT;
669 p2 = iUmass;
670 break;
671 case TUmolar_INPUTS:
672 p1 = iT;
673 p2 = iUmolar;
674 break;
675 case DmassP_INPUTS:
676 p1 = iDmass;
677 p2 = iP;
678 break;
679 case DmolarP_INPUTS:
680 p1 = iDmolar;
681 p2 = iP;
682 break;
683 case DmassQ_INPUTS:
684 p1 = iDmass;
685 p2 = iQ;
686 break;
687 case DmolarQ_INPUTS:
688 p1 = iDmolar;
689 p2 = iQ;
690 break;
691 case HmassP_INPUTS:
692 p1 = iHmass;
693 p2 = iP;
694 break;
695 case HmolarP_INPUTS:
696 p1 = iHmolar;
697 p2 = iP;
698 break;
699 case PSmass_INPUTS:
700 p1 = iP;
701 p2 = iSmass;
702 break;
703 case PSmolar_INPUTS:
704 p1 = iP;
705 p2 = iSmolar;
706 break;
707 case PUmass_INPUTS:
708 p1 = iP;
709 p2 = iUmass;
710 break;
711 case PUmolar_INPUTS:
712 p1 = iP;
713 p2 = iUmolar;
714 break;
716 p1 = iDmass;
717 p2 = iHmass;
718 break;
720 p1 = iDmolar;
721 p2 = iHmolar;
722 break;
724 p1 = iDmass;
725 p2 = iSmass;
726 break;
728 p1 = iDmolar;
729 p2 = iSmolar;
730 break;
732 p1 = iDmass;
733 p2 = iUmass;
734 break;
736 p1 = iDmolar;
737 p2 = iUmolar;
738 break;
740 p1 = iHmass;
741 p2 = iSmass;
742 break;
744 p1 = iHmolar;
745 p2 = iSmolar;
746 break;
748 p1 = iSmass;
749 p2 = iUmass;
750 break;
752 p1 = iSmolar;
753 p2 = iUmolar;
754 break;
755 default:
756 throw ValueError(format("Invalid input pair"));
757 }
758}
759
761{
763 const char* name;
764};
765
767{
769 const char* name;
771};
772
774 {HEOS_BACKEND_FAMILY, "HEOS"}, {REFPROP_BACKEND_FAMILY, "REFPROP"}, {INCOMP_BACKEND_FAMILY, "INCOMP"}, {IF97_BACKEND_FAMILY, "IF97"},
775 {TREND_BACKEND_FAMILY, "TREND"}, {TTSE_BACKEND_FAMILY, "TTSE"}, {BICUBIC_BACKEND_FAMILY, "BICUBIC"}, {SRK_BACKEND_FAMILY, "SRK"},
776 {PR_BACKEND_FAMILY, "PR"}, {VTPR_BACKEND_FAMILY, "VTPR"}, {PCSAFT_BACKEND_FAMILY, "PCSAFT"}};
777
779 {HEOS_BACKEND_MIX, "HelmholtzEOSMixtureBackend", HEOS_BACKEND_FAMILY},
780 {REFPROP_BACKEND_PURE, "REFPROPBackend", REFPROP_BACKEND_FAMILY},
781 {REFPROP_BACKEND_MIX, "REFPROPMixtureBackend", REFPROP_BACKEND_FAMILY},
782 {INCOMP_BACKEND, "IncompressibleBackend", INCOMP_BACKEND_FAMILY},
783 {IF97_BACKEND, "IF97Backend", IF97_BACKEND_FAMILY},
784 {TREND_BACKEND, "TRENDBackend", TREND_BACKEND_FAMILY},
785 {TTSE_BACKEND, "TTSEBackend", TTSE_BACKEND_FAMILY},
786 {BICUBIC_BACKEND, "BicubicBackend", BICUBIC_BACKEND_FAMILY},
787 {SRK_BACKEND, "SRKBackend", SRK_BACKEND_FAMILY},
788 {PR_BACKEND, "PengRobinsonBackend", PR_BACKEND_FAMILY},
789 {VTPR_BACKEND, "VTPRBackend", VTPR_BACKEND_FAMILY},
790 {PCSAFT_BACKEND, "PCSAFTBackend", PCSAFT_BACKEND_FAMILY}};
791
793{
794 public:
795 std::map<backend_families, std::string> family_name_map;
796 std::map<backends, backend_families> backend_family_map;
797 std::map<backends, std::string> backend_name_map;
798
799 std::map<std::string, backend_families> family_name_map_r;
800 std::map<std::string, backends> backend_name_map_r;
801
803 const backend_family_info* const family_end = backend_family_list + sizeof(backend_family_list) / sizeof(backend_family_list[0]);
804 for (const backend_family_info* el = backend_family_list; el != family_end; ++el) {
805 family_name_map.insert(std::pair<backend_families, std::string>(el->family, el->name));
806 family_name_map_r.insert(std::pair<std::string, backend_families>(el->name, el->family));
807 }
808 const backend_info* const backend_end = backend_list + sizeof(backend_list) / sizeof(backend_list[0]);
809 for (const backend_info* el = backend_list; el != backend_end; ++el) {
810 backend_family_map.insert(std::pair<backends, backend_families>(el->backend, el->family));
811 backend_name_map.insert(std::pair<backends, std::string>(el->backend, el->name));
812 backend_name_map_r.insert(std::pair<std::string, backends>(el->name, el->backend));
813 family_name_map_r.insert(std::pair<std::string, backend_families>(el->name, el->family));
814 }
815 }
816};
817
818//std::unique_ptr<BackendInformation> backend_information_p;
822 //backend_information_p = std::make_unique<BackendInformation>();
824 }
825 return *backend_information_p;
826}
827
829void extract_backend_families(std::string backend_string, backend_families& f1, backend_families& f2) {
830 auto& backend_information = get_backend_information();
833 std::size_t i = backend_string.find("&");
834 std::map<std::string, backend_families>::const_iterator it;
835 if (i != std::string::npos) {
836 it = backend_information.family_name_map_r.find(backend_string.substr(0, i)); // Before "&"
837 if (it != backend_information.family_name_map_r.end()) f1 = it->second;
838 it = backend_information.family_name_map_r.find(backend_string.substr(i + 1)); // After "&"
839 if (it != backend_information.family_name_map_r.end()) f2 = it->second;
840 } else {
841 it = backend_information.family_name_map_r.find(backend_string);
842 if (it != backend_information.family_name_map_r.end()) f1 = it->second;
843 }
844}
845
846void extract_backend_families_string(std::string backend_string, backend_families& f1, std::string& f2) {
847 auto& backend_information = get_backend_information();
848 backend_families f2_enum;
849 extract_backend_families(backend_string, f1, f2_enum);
850 std::map<backend_families, std::string>::const_iterator it;
851 it = backend_information.family_name_map.find(f2_enum);
852 if (it != backend_information.family_name_map.end())
853 f2 = it->second;
854 else
855 f2.clear();
856}
857
858std::string get_backend_string(backends backend) {
859 auto& backend_information = get_backend_information();
860 std::map<backends, std::string>::const_iterator it;
861 it = backend_information.backend_name_map.find(backend);
862 if (it != backend_information.backend_name_map.end())
863 return it->second;
864 else
865 return std::string("");
866}
867
868} /* namespace CoolProp */
869
870#ifdef ENABLE_CATCH
871# include <catch2/catch_all.hpp>
872# include <sstream>
873
874TEST_CASE("Check that all parameters are described", "") {
875 for (int i = 1; i < CoolProp::iundefined_parameter; ++i) {
876 std::ostringstream ss;
877 ss << "Parameter index," << i << "last index:" << CoolProp::iundefined_parameter;
878 SECTION(ss.str(), "") {
879 std::string prior;
880 if (i > 1) {
881 CHECK_NOTHROW(prior = CoolProp::get_parameter_information(i - 1, "short"));
882 CAPTURE(prior);
883 }
884 CHECK_NOTHROW(CoolProp::get_parameter_information(i, "short"));
885 }
886 }
887}
888
889TEST_CASE("Check that all phases are described", "[phase_index]") {
890 for (int i = 0; i < CoolProp::iphase_not_imposed; ++i) {
891 std::ostringstream ss;
892 ss << "Parameter index," << i << "last index:" << CoolProp::iundefined_parameter;
893 SECTION(ss.str(), "") {
894 std::string stringrepr;
895 int key;
896 CHECK_NOTHROW(stringrepr = CoolProp::get_phase_short_desc(static_cast<CoolProp::phases>(i)));
897 CAPTURE(stringrepr);
898 CHECK_NOTHROW(key = CoolProp::get_phase_index(stringrepr));
899 CAPTURE(key);
900 CHECK(key == i);
901 }
902 }
903}
904
905#endif