9#if defined(COOLPROP_NO_INCBIN)
22INCBIN(all_fluids_CBOR,
"all_fluids.cbor");
28static JSONFluidLibrary library;
40static std::once_flag library_load_flag;
42static void ensure_library_loaded() {
43 std::call_once(library_load_flag, &
load);
47 if (getenv(
"COOLPROP_DISABLE_SUPERANCILLARIES_ENTIRELY")) {
48 std::cout <<
"CoolProp: superancillaries have been disabled because the COOLPROP_DISABLE_SUPERANCILLARIES_ENTIRELY environment variable has "
59 }
catch (std::exception& e) {
60 std::cout << e.what() <<
'\n';
66 auto it = string_to_index_map.find(fluid);
67 if (it != string_to_index_map.end()) {
68 auto it2 = fluid_map.find(it->second);
70 if (it2 != fluid_map.end()) {
72 throw ValueError(
format(
"Not possible to set reference state for fluid %s because offset values are NAN", fluid.c_str()));
74 it2->second.EOS().alpha0.EnthalpyEntropyOffset.set(delta_a1, delta_a2, ref);
84 shared_ptr<CoolProp::HelmholtzEOSBackend> HEOS = std::make_shared<CoolProp::HelmholtzEOSBackend>(it2->second);
87 HEOS->update(
DmolarT_INPUTS, it2->second.EOS().hs_anchor.rhomolar, it2->second.EOS().hs_anchor.T);
88 it2->second.EOS().hs_anchor.hmolar = HEOS->hmolar();
89 it2->second.EOS().hs_anchor.smolar = HEOS->smolar();
91 double f = (HEOS->name() ==
"Water" || HEOS->name() ==
"CarbonDioxide") ? 1.00001 : 1.0;
94 HEOS->update(
DmolarT_INPUTS, it2->second.EOS().reduce.rhomolar * f, it2->second.EOS().reduce.T * f);
95 it2->second.EOS().reduce.hmolar = HEOS->hmolar();
96 it2->second.EOS().reduce.smolar = HEOS->smolar();
99 HEOS->update(
DmolarT_INPUTS, it2->second.crit.rhomolar * f, it2->second.crit.T * f);
100 it2->second.crit.hmolar = HEOS->hmolar();
101 it2->second.crit.smolar = HEOS->smolar();
104 HEOS->update(
DmolarT_INPUTS, it2->second.triple_liquid.rhomolar, it2->second.triple_liquid.T);
105 it2->second.triple_liquid.hmolar = HEOS->hmolar();
106 it2->second.triple_liquid.smolar = HEOS->smolar();
109 HEOS->update(
DmolarT_INPUTS, it2->second.triple_vapor.rhomolar, it2->second.triple_vapor.T);
110 it2->second.triple_vapor.hmolar = HEOS->hmolar();
111 it2->second.triple_vapor.smolar = HEOS->smolar();
113 if (!HEOS->is_pure()) {
115 HEOS->update(
DmolarT_INPUTS, it2->second.EOS().max_sat_T.rhomolar, it2->second.EOS().max_sat_T.T);
116 it2->second.EOS().max_sat_T.hmolar = HEOS->hmolar();
117 it2->second.EOS().max_sat_T.smolar = HEOS->smolar();
119 HEOS->update(
DmolarT_INPUTS, it2->second.EOS().max_sat_p.rhomolar, it2->second.EOS().max_sat_p.T);
120 it2->second.EOS().max_sat_p.hmolar = HEOS->hmolar();
121 it2->second.EOS().max_sat_p.smolar = HEOS->smolar();
124 throw ValueError(
format(
"fluid [%s] was not found in JSONFluidLibrary", fluid.c_str()));
133 ensure_library_loaded();
141 if (!listing.is_array()) {
145 for (
const auto& fluid_json : listing) {
156 std::size_t index = fluid_map.size();
163 fluid.
name = fluid_json.at(
"INFO").at(
"NAME").get<std::string>();
167 name_vector.push_back(fluid.
name);
171 if (!fluid_json.at(
"INFO").contains(
"CAS")) {
174 fluid.
CAS = fluid_json.at(
"INFO").at(
"CAS").get<std::string>();
177 if (!fluid_json.at(
"INFO").contains(
"REFPROP_NAME")) {
178 throw ValueError(
format(
"fluid [%s] does not have \"REFPROP_NAME\" member", fluid.
name.c_str()));
180 fluid.
REFPROPname = fluid_json.at(
"INFO").at(
"REFPROP_NAME").get<std::string>();
183 if (fluid_json.at(
"INFO").contains(
"FORMULA")) {
190 if (fluid_json.at(
"INFO").contains(
"INCHI_STRING")) {
196 if (fluid_json.at(
"INFO").contains(
"INCHI_KEY")) {
202 if (fluid_json.at(
"INFO").contains(
"SMILES")) {
208 if (fluid_json.at(
"INFO").contains(
"CHEMSPIDER_ID")) {
214 if (fluid_json.at(
"INFO").contains(
"2DPNG_URL")) {
221 if (!(fluid_json.at(
"INFO").contains(
"ENVIRONMENTAL"))) {
223 std::cout <<
format(
"Environmental data are missing for fluid [%s]\n", fluid.
name.c_str());
233 if (!fluid_json.contains(
"STATES")) {
239 std::cout <<
format(
"Loading fluid %s with CAS %s; %d fluids loaded\n", fluid.
name.c_str(), fluid.
CAS.c_str(), index);
249 if (!fluid_json.contains(
"ANCILLARIES")) {
255 if (!(fluid_json.at(
"ANCILLARIES").contains(
"surface_tension"))) {
257 std::cout <<
format(
"Surface tension curves are missing for fluid [%s]\n", fluid.
name.c_str());
264 if (!(fluid_json.at(
"ANCILLARIES").contains(
"melting_line"))) {
266 std::cout <<
format(
"Melting line curves are missing for fluid [%s]\n", fluid.
name.c_str());
273 if (!(fluid_json.contains(
"TRANSPORT"))) {
287 if (string_to_index_map.find(fluid.
CAS) != string_to_index_map.end()) {
288 index = string_to_index_map.find(fluid.
CAS)->second;
289 }
else if (string_to_index_map.find(fluid.
name) != string_to_index_map.end()) {
290 index = string_to_index_map.find(fluid.
name)->second;
291 }
else if (string_to_index_map.find(
upper(fluid.
name)) != string_to_index_map.end()) {
292 index = string_to_index_map.find(
upper(fluid.
name))->second;
295 for (
const auto& alias : fluid.
aliases) {
296 if (string_to_index_map.find(alias) != string_to_index_map.end()) {
297 index = string_to_index_map.find(alias)->second;
300 if (string_to_index_map.find(
upper(alias)) != string_to_index_map.end()) {
301 index = string_to_index_map.find(
upper(alias))->second;
307 bool fluid_exists =
false;
309 if (index != fluid_map.size()) {
311 name_vector.pop_back();
313 throw ValueError(
format(
"Cannot load fluid [%s:%s] because it is already in library; index = [%i] of [%i]; Consider enabling the "
314 "config boolean variable OVERWRITE_FLUIDS",
315 fluid.
name.c_str(), fluid.
CAS.c_str(), index, fluid_map.size()));
327 if (fluid_exists) fluid_map.erase(fluid_map.find(index));
329 fluid_map[index] = fluid;
336 if (fluid_exists) JSONstring_map.erase(JSONstring_map.find(index));
338 JSONstring_map[index] = fluid_json.dump();
344 string_to_index_map[fluid.
CAS] = index;
349 string_to_index_map[fluid.
name] = index;
354 for (
const auto& alias : fluid.
aliases) {
355 string_to_index_map[alias] = index;
358 string_to_index_map[
upper(alias)] = index;
363 std::cout <<
format(
"Loaded fluid: %s - Number of fluids = %d\n", fluid.
name, fluid_map.size());
366 }
catch (
const std::exception& e) {
367 throw ValueError(
format(
"Unable to load fluid [%s] due to error: %s", fluid.
name.c_str(), e.what()));
372 ensure_library_loaded();
377 ensure_library_loaded();
378 return library.
get(fluid_string);
382 ensure_library_loaded();
387 ensure_library_loaded();
392 ensure_library_loaded();