30 std::map<std::size_t, CoolPropFluid> fluid_map;
32 std::map<std::size_t, std::string> JSONstring_map;
33 std::vector<std::string> name_vector;
34 std::map<std::string, std::size_t> string_to_index_map;
42 for (rapidjson::Value::ValueIterator itr = jsonalphar.Begin(); itr != jsonalphar.End(); ++itr) {
44 rapidjson::Value& contribution = *itr;
47 std::string type = contribution[
"type"].GetString();
49 if (!type.compare(
"ResidualHelmholtzPower")) {
54 assert(n.size() == d.size());
55 assert(n.size() == t.size());
56 assert(n.size() == l.size());
59 }
else if (!type.compare(
"ResidualHelmholtzGaussian")) {
67 assert(n.size() == d.size());
68 assert(n.size() == t.size());
69 assert(n.size() == eta.size());
70 assert(n.size() == epsilon.size());
71 assert(n.size() == beta.size());
72 assert(n.size() == gamma.size());
74 }
else if (!type.compare(
"ResidualHelmholtzGaoB")) {
83 assert(n.size() == t.size());
84 assert(n.size() == d.size());
85 assert(n.size() == eta.size());
86 assert(n.size() == epsilon.size());
87 assert(n.size() == beta.size());
88 assert(n.size() == gamma.size());
89 assert(n.size() == b.size());
91 }
else if (!type.compare(
"ResidualHelmholtzNonAnalytic")) {
103 assert(n.size() == a.size());
104 assert(n.size() == b.size());
105 assert(n.size() == beta.size());
106 assert(n.size() == A.size());
107 assert(n.size() == B.size());
108 assert(n.size() == C.size());
109 assert(n.size() == D.size());
111 }
else if (!type.compare(
"ResidualHelmholtzLemmon2005")) {
117 assert(n.size() == d.size());
118 assert(n.size() == t.size());
119 assert(n.size() == l.size());
120 assert(n.size() == m.size());
122 }
else if (!type.compare(
"ResidualHelmholtzDoubleExponential")) {
131 assert(n.size() == d.size());
132 assert(n.size() == t.size());
133 assert(n.size() == gt.size());
134 assert(n.size() == lt.size());
135 assert(n.size() == gd.size());
136 assert(n.size() == ld.size());
138 }
else if (!type.compare(
"ResidualHelmholtzExponential")) {
144 assert(n.size() == d.size());
145 assert(n.size() == t.size());
146 assert(n.size() == g.size());
147 assert(n.size() == l.size());
149 }
else if (!type.compare(
"ResidualHelmholtzAssociating")) {
160 throw ValueError(
format(
"Unsupported Residual helmholtz type: %s", type.c_str()));
172 if (!jsonalpha0.IsArray()) {
178 for (rapidjson::Value::ConstValueIterator itr = jsonalpha0.Begin(); itr != jsonalpha0.End(); ++itr) {
180 const rapidjson::Value& contribution = *itr;
183 std::string type = contribution[
"type"].GetString();
185 if (!type.compare(
"IdealGasHelmholtzLead")) {
193 }
else if (!type.compare(
"IdealGasHelmholtzPower")) {
201 }
else if (!type.compare(
"IdealGasHelmholtzLogTau")) {
208 }
else if (!type.compare(
"IdealGasHelmholtzPlanckEinsteinGeneralized")) {
221 }
else if (!type.compare(
"IdealGasHelmholtzPlanckEinstein")) {
226 for (std::size_t i = 0; i < t.size(); ++i) {
229 std::vector<CoolPropDbl> c(n.size(), 1);
230 std::vector<CoolPropDbl> d(c.size(), -1);
237 }
else if (!type.compare(
"IdealGasHelmholtzPlanckEinsteinFunctionT")) {
243 for (std::size_t i = 0; i < v.size(); ++i) {
244 theta[i] = -v[i] / Tc;
246 std::vector<CoolPropDbl> c(n.size(), 1);
247 std::vector<CoolPropDbl> d(c.size(), -1);
254 }
else if (!type.compare(
"IdealGasHelmholtzGERG2004Cosh")) {
264 }
else if (!type.compare(
"IdealGasHelmholtzGERG2004Sinh")) {
274 }
else if (!type.compare(
"IdealGasHelmholtzCP0Constant")) {
276 throw ValueError(
"Cannot add another IdealGasHelmholtzCP0Constant term; join them together");
282 }
else if (!type.compare(
"IdealGasHelmholtzCP0PolyT")) {
284 throw ValueError(
"Cannot add another CP0PolyT term; join them together");
291 }
else if (!type.compare(
"IdealGasHelmholtzCP0AlyLee")) {
298 if (std::abs(constants[0]) > 1e-14) {
299 std::vector<CoolPropDbl> c(1, constants[0]), t(1, 0);
306 std::vector<CoolPropDbl> n, c, d, t;
307 if (std::abs(constants[1]) > 1e-14) {
309 n.push_back(constants[1]);
310 t.push_back(-2 * constants[2] / Tc);
314 if (std::abs(constants[3]) > 1e-14) {
316 n.push_back(-constants[3]);
317 t.push_back(-2 * constants[4] / Tc);
326 }
else if (!type.compare(
"IdealGasHelmholtzEnthalpyEntropyOffset")) {
332 std::cout <<
format(
"Unsupported ideal-gas Helmholtz type: %s\n", type.c_str());
368 rapidjson::Value& reducing_state = EOS_json[
"STATES"][
"reducing"];
369 rapidjson::Value& satminL_state = EOS_json[
"STATES"][
"sat_min_liquid"];
370 rapidjson::Value& satminV_state = EOS_json[
"STATES"][
"sat_min_vapor"];
395 if (EOS_json.HasMember(
"SUPERANCILLARY")) {
396 if (getenv(
"COOLPROP_DISABLE_SUPERANCILLARIES_ENTIRELY")) {
408 if (EOS_json.HasMember(
"alpha0_prefactor")) {
411 if (EOS_json[
"STATES"].HasMember(
"hs_anchor")) {
412 rapidjson::Value& hs_anchor = EOS_json[
"STATES"][
"hs_anchor"];
420 if (EOS_json[
"STATES"].HasMember(
"pressure_max_sat")) {
421 rapidjson::Value& s = EOS_json[
"STATES"][
"pressure_max_sat"];
425 if (s.HasMember(
"hmolar")) {
431 if (EOS_json[
"STATES"].HasMember(
"temperature_max_sat")) {
432 rapidjson::Value& s = EOS_json[
"STATES"][
"temperature_max_sat"];
436 if (s.HasMember(
"hmolar")) {
442 if (EOS_json.HasMember(
"critical_region_splines")) {
443 rapidjson::Value& spline = EOS_json[
"critical_region_splines"];
459 for (rapidjson::Value::ValueIterator itr = EOS_array.Begin(); itr != EOS_array.End(); ++itr) {
466 if (dilute.HasMember(
"hardcoded")) {
468 if (!target.compare(
"Ethane")) {
471 }
else if (!target.compare(
"Cyclohexane")) {
474 }
else if (!target.compare(
"CarbonDioxideLaeseckeJPCRD2017")) {
478 throw ValueError(
format(
"hardcoded dilute viscosity [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
482 if (!type.compare(
"collision_integral")) {
494 }
else if (!type.compare(
"kinetic_theory")) {
496 }
else if (!type.compare(
"powers_of_T")) {
505 }
else if (!type.compare(
"powers_of_Tr")) {
513 }
else if (!type.compare(
"collision_integral_powers_of_Tstar")) {
525 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
532 if (!type.compare(
"Rainwater-Friend")) {
542 }
else if (!type.compare(
"empirical")) {
556 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
563 if (higher.HasMember(
"hardcoded")) {
565 if (!target.compare(
"Hydrogen")) {
568 }
else if (!target.compare(
"n-Hexane")) {
571 }
else if (!target.compare(
"n-Heptane")) {
574 }
else if (!target.compare(
"Toluene")) {
577 }
else if (!target.compare(
"Ethane")) {
580 }
else if (!target.compare(
"Benzene")) {
583 }
else if (!target.compare(
"CarbonDioxideLaeseckeJPCRD2017")) {
588 format(
"hardcoded higher order viscosity term [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
593 if (!type.compare(
"modified_Batschinski_Hildebrand")) {
608 assert(BH.
a.size() == BH.
t1.size());
609 assert(BH.
a.size() == BH.
d1.size());
610 assert(BH.
a.size() == BH.
gamma.size());
611 assert(BH.
a.size() == BH.
l.size());
615 assert(BH.
f.size() == BH.
t2.size());
616 assert(BH.
f.size() == BH.
d2.size());
619 assert(BH.
g.size() == BH.
h.size());
622 assert(BH.
p.size() == BH.
q.size());
623 }
else if (!type.compare(
"friction_theory")) {
642 assert(F.
Aa.size() == 3);
643 assert(F.
Aaa.size() == 3);
644 assert(F.
Ar.size() == 3);
648 if (higher.HasMember(
"Arr") && !higher.HasMember(
"Adrdr")) {
650 assert(F.
Arr.size() == 3);
651 }
else if (higher.HasMember(
"Adrdr") && !higher.HasMember(
"Arr")) {
653 assert(F.
Adrdr.size() == 3);
655 throw ValueError(
format(
"can only provide one of Arr or Adrdr for fluid %s", fluid.
name.c_str()));
657 if (higher.HasMember(
"Aii")) {
661 if (higher.HasMember(
"Aaaa") && higher.HasMember(
"Arrr")) {
669 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
720 if (viscosity.IsArray()) {
721 rapidjson::Value::ValueIterator itr = viscosity.Begin();
730 if (!viscosity.HasMember(
"sigma_eta") || !viscosity.HasMember(
"epsilon_over_k")) {
738 if (viscosity.HasMember(
"type") && !
cpjson::get_string(viscosity,
"type").compare(
"ECS")) {
744 if (viscosity.HasMember(
"type") && !
cpjson::get_string(viscosity,
"type").compare(
"rhosr-CS")) {
751 if (viscosity.HasMember(
"type") && !
cpjson::get_string(viscosity,
"type").compare(
"Chung")) {
756 if (viscosity.HasMember(
"hardcoded")) {
758 if (!target.compare(
"Water")) {
761 }
else if (!target.compare(
"HeavyWater")) {
764 }
else if (!target.compare(
"Helium")) {
767 }
else if (!target.compare(
"R23")) {
770 }
else if (!target.compare(
"Methanol")) {
773 }
else if (!target.compare(
"m-Xylene")) {
776 }
else if (!target.compare(
"o-Xylene")) {
779 }
else if (!target.compare(
"p-Xylene")) {
783 throw ValueError(
format(
"hardcoded viscosity [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
788 if (viscosity.HasMember(
"dilute")) {
792 if (viscosity.HasMember(
"initial_density")) {
796 if (viscosity.HasMember(
"higher_order")) {
803 if (dilute.HasMember(
"hardcoded")) {
805 if (!target.compare(
"CO2")) {
808 }
else if (!target.compare(
"CarbonDioxideHuberJPCRD2016")) {
811 }
else if (!target.compare(
"Ethane")) {
814 }
else if (!target.compare(
"none")) {
819 format(
"hardcoded dilute conductivity term [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
823 if (!type.compare(
"ratio_of_polynomials")) {
836 }
else if (!type.compare(
"eta0_and_poly")) {
847 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
853 if (dilute.HasMember(
"hardcoded")) {
855 if (!target.compare(
"CO2")) {
860 format(
"hardcoded residual conductivity term [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
864 if (!type.compare(
"polynomial")) {
877 }
else if (!type.compare(
"polynomial_and_exponential")) {
891 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
896 if (critical.HasMember(
"hardcoded")) {
898 if (!target.compare(
"R123")) {
901 }
else if (!target.compare(
"Ammonia")) {
904 }
else if (!target.compare(
"CarbonDioxideScalabrinJPCRD2006")) {
908 }
else if (!target.compare(
"None")) {
912 throw ValueError(
format(
"critical conductivity term [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
916 if (!type.compare(
"simplified_Olchowy_Sengers")) {
924 if (critical.HasMember(
"qD")) {
927 if (critical.HasMember(
"zeta0")) {
930 if (critical.HasMember(
"GAMMA")) {
933 if (critical.HasMember(
"gamma")) {
936 if (critical.HasMember(
"R0")) {
939 if (critical.HasMember(
"T_ref")) {
943 throw ValueError(
format(
"type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
953 if (conductivity.HasMember(
"type") && !
cpjson::get_string(conductivity,
"type").compare(
"ECS")) {
958 if (conductivity.HasMember(
"hardcoded")) {
960 if (!target.compare(
"Water")) {
963 }
else if (!target.compare(
"HeavyWater")) {
966 }
else if (!target.compare(
"Methane")) {
969 }
else if (!target.compare(
"R23")) {
972 }
else if (!target.compare(
"Helium")) {
977 format(
"hardcoded residual conductivity term [%s] is not understood for fluid %s", target.c_str(), fluid.
name.c_str()));
982 if (conductivity.HasMember(
"dilute")) {
986 if (conductivity.HasMember(
"residual")) {
990 if (conductivity.HasMember(
"critical")) {
999 if (transport.HasMember(
"viscosity")) {
1005 if (transport.HasMember(
"conductivity")) {
1025 if (melting_line.HasMember(
"type")) {
1027 if (!type.compare(
"Simon")) {
1028 rapidjson::Value& parts = melting_line[
"parts"];
1030 for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) {
1040 }
else if (!type.compare(
"polynomial_in_Tr")) {
1041 rapidjson::Value& parts = melting_line[
"parts"];
1043 for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) {
1053 }
else if (!type.compare(
"polynomial_in_Theta")) {
1054 rapidjson::Value& parts = melting_line[
"parts"];
1056 for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) {
1067 throw ValueError(
format(
"melting line type [%s] is not understood for fluid %s", type.c_str(), fluid.
name.c_str()));
1072 throw ValueError(
format(
"melting line does not have \"type\" for fluid %s", fluid.
name.c_str()));
1078 if (!states.HasMember(
"critical")) {
1079 throw ValueError(
format(
"fluid[\"STATES\"] [%s] does not have \"critical\" member", fluid.
name.c_str()));
1081 rapidjson::Value& crit = states[
"critical"];
1088 if (!states.HasMember(
"triple_liquid")) {
1089 throw ValueError(
format(
"fluid[\"STATES\"] [%s] does not have \"triple_liquid\" member", fluid.
name.c_str()));
1091 rapidjson::Value& triple_liquid = states[
"triple_liquid"];
1092 if (triple_liquid.ObjectEmpty()) {
1107 if (!states.HasMember(
"triple_vapor")) {
1108 throw ValueError(
format(
"fluid[\"STATES\"] [%s] does not have \"triple_vapor\" member", fluid.
name.c_str()));
1110 rapidjson::Value& triple_vapor = states[
"triple_vapor"];
1111 if (triple_vapor.ObjectEmpty()) {
1129 if (!ancillaries.HasMember(
"rhoL") || !ancillaries.HasMember(
"rhoV")) {
1130 throw ValueError(
"Ancillary curves for either rhoL or rhoV are missing");
1136 if (ancillaries.HasMember(
"pL") && ancillaries.HasMember(
"pV")) {
1141 else if (!ancillaries.HasMember(
"pL") && !ancillaries.HasMember(
"pV") && ancillaries.HasMember(
"pS")) {
1145 throw ValueError(
"Pressure ancillary curves are missing or invalid");
1148 if (ancillaries.HasMember(
"hL")) {
1152 std::cout <<
"Missing hL ancillary for fluid " << fluid.
name;
1155 if (ancillaries.HasMember(
"hLV")) {
1159 std::cout <<
"Missing hLV ancillary for fluid " << fluid.
name;
1163 if (ancillaries.HasMember(
"sL")) {
1167 std::cout <<
"Missing sL ancillary for fluid " << fluid.
name;
1170 if (ancillaries.HasMember(
"sLV")) {
1174 std::cout <<
"Missing sLV ancillary for fluid " << fluid.
name;
1178 std::cout <<
"Tmin invalid for sL for " << fluid.
name << std::endl;
1190 assert(fluid.
CAS.length() > 0);
1191 assert(fluid.
name.length() > 0);
1204 static void add_many(
const std::string& JSON_string);
1207 void add_many(rapidjson::Value& listing);
1209 void add_one(rapidjson::Value& fluid_json);
1213 std::map<std::string, std::size_t>::const_iterator it = string_to_index_map.find(key);
1214 if (it != string_to_index_map.end()) {
1216 std::map<std::size_t, std::string>::const_iterator it2 = JSONstring_map.find(it->second);
1217 if (it2 != JSONstring_map.end()) {
1219 rapidjson::Document doc;
1221 rapidjson::Document doc2;
1223 doc2.PushBack(doc, doc.GetAllocator());
1226 throw ValueError(
format(
"Unable to obtain JSON string for this identifier [%d]", it->second));
1229 throw ValueError(
format(
"Unable to obtain index for this identifier [%s]", key.c_str()));
1239 std::map<std::string, std::size_t>::const_iterator it = string_to_index_map.find(key);
1241 if (it != string_to_index_map.end()) {
1242 return get(it->second);
1245 std::vector<std::string>
endings;
1247 endings.push_back(
"-PengRobinson");
1248 for (std::vector<std::string>::const_iterator end =
endings.begin(); end !=
endings.end(); ++end) {
1250 std::string used_name = key.substr(0, key.size() - (*end).size());
1251 it = string_to_index_map.find(used_name);
1252 if (it != string_to_index_map.end()) {
1259 fluid.
EOSVector[0].alphar.empty_the_EOS();
1267 shared_ptr<AbstractCubic> ac;
1268 if (*end ==
"-SRK") {
1269 ac.reset(
new SRK(Tc, pc, acentric, R));
1270 }
else if (*end ==
"-PengRobinson") {
1276 ac->set_rhor(rhomolarc);
1283 shared_ptr<AbstractCubic> ac;
1284 if (*end ==
"-SRK") {
1286 }
else if (*end ==
"-PengRobinson") {
1291 ac->set_Tr(vals.
Tc);
1296 double v_c_Lmol = 2.14107171795 * (vals.
Tc / vals.
pc * 1000) + 0.00773144012514;
1297 ac->set_rhor(1 / (v_c_Lmol / 1000.0));
1301 ac->set_C_Twu(0, c[0], c[1], c[2]);
1323 throw ValueError(
format(
"key [%s] was not found in string_to_index_map in JSONFluidLibrary", key.c_str()));
1333 std::map<std::size_t, CoolPropFluid>::iterator it = fluid_map.find(key);
1335 if (it != fluid_map.end()) {
1338 throw ValueError(
format(
"key [%d] was not found in JSONFluidLibrary", key));
1355CoolPropFluid
get_fluid(
const std::string& fluid_string);