23 rapidjson::Document doc;
24 doc.Parse<0>(str.c_str());
25 if (doc.HasParseError()) {
26 std::cout << str << std::endl;
27 throw ValueError(
"Unable to parse predefined mixture string");
33 if (!doc.IsArray() || !doc[0].IsObject()){
34 throw ValueError(
"You must provide an array of objects");
37 for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) {
53 static PredefinedMixturesLibrary predefined_mixtures_library;
56 std::vector<std::string> out;
57 for (std::map<std::string, Dictionary>::const_iterator it = predefined_mixtures_library.
predefined_mixture_map.begin();
59 out.push_back(it->first);
65 std::map<std::string, Dictionary>::const_iterator iter = predefined_mixtures_library.
predefined_mixture_map.find(name);
87 std::map<std::vector<std::string>, std::vector<Dictionary>> m_binary_pair_map;
92 if (m_binary_pair_map.size() == 0) {
95 return m_binary_pair_map;
99 rapidjson::Document doc;
100 doc.Parse<0>(str.c_str());
101 if (doc.HasParseError()) {
102 std::cout << str << std::endl;
103 throw ValueError(
"Unable to parse binary interaction function string");
121 for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) {
126 std::vector<std::string> CAS;
133 std::sort(CAS.begin(), CAS.end());
139 std::swap(name1, name2);
151 if (itr->HasMember(
"xi") && itr->HasMember(
"zeta")) {
156 }
else if (itr->HasMember(
"gammaT") && itr->HasMember(
"gammaV") && itr->HasMember(
"betaT") && itr->HasMember(
"betaV")) {
171 std::cout <<
"Loading error: binary pair of " << name1 <<
" & " << name2
172 <<
"does not provide either a) xi and zeta b) gammaT, gammaV, betaT, and betaV" << std::endl;
176 std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator it = m_binary_pair_map.find(CAS);
177 if (it == m_binary_pair_map.end()) {
179 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
183 m_binary_pair_map.erase(it);
184 std::pair<std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator,
bool> ret;
186 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
187 assert(ret.second ==
true);
191 format(
"CAS pair(%s,%s) already in binary interaction map; considering enabling configuration key OVERWRITE_BINARY_INTERACTION",
192 CAS[0].c_str(), CAS[1].c_str()));
203 std::string CAS1, CAS2, name1 = identifier1, name2 = identifier2;
204 shared_ptr<CoolProp::HelmholtzEOSMixtureBackend> HEOS1, HEOS2;
206 std::vector<std::string> id1split =
strsplit(identifier1,
'-');
207 if (id1split.size() == 3) {
210 std::vector<std::string> names1(1, identifier1);
212 CAS1 = HEOS1->fluid_param_string(
"CAS");
215 std::vector<std::string> id2split =
strsplit(identifier2,
'-');
216 if (id2split.size() == 3) {
219 std::vector<std::string> names2(1, identifier2);
221 CAS2 = HEOS2->fluid_param_string(
"CAS");
225 std::vector<std::string> CAS;
230 std::sort(CAS.begin(), CAS.end());
233 if (CAS[0] != CAS1) {
234 std::swap(name1, name2);
244 if (rule ==
"linear") {
249 dict.
add_number(
"gammaT", 0.5 * (HEOS1->T_critical() + HEOS2->T_critical()) / sqrt(HEOS1->T_critical() * HEOS2->T_critical()));
250 double rhoc1 = HEOS1->rhomolar_critical(), rhoc2 = HEOS2->rhomolar_critical();
251 dict.
add_number(
"gammaV", 4 * (1 / rhoc1 + 1 / rhoc2) / pow(1 / pow(rhoc1, 1.0 / 3.0) + 1 / pow(rhoc2, 1.0 / 3.0), 3));
254 }
else if (rule ==
"Lorentz-Berthelot") {
262 throw ValueError(
format(
"Your simple mixing rule [%s] was not understood", rule.c_str()));
265 std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator it = m_binary_pair_map.find(CAS);
266 if (it == m_binary_pair_map.end()) {
268 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
272 m_binary_pair_map.erase(it);
273 std::pair<std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator,
bool> ret;
274 ret = m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
275 assert(ret.second ==
true);
279 format(
"CAS pair(%s,%s) already in binary interaction map; considering enabling configuration key OVERWRITE_BINARY_INTERACTION",
280 CAS[0].c_str(), CAS[1].c_str()));
286 static MixtureBinaryPairLibrary mixturebinarypairlibrary;
288 static MixtureBinaryPairLibrary mixturebinarypairlibrary_default;
297 std::vector<std::string> out;
298 for (std::map<std::vector<std::string>, std::vector<Dictionary>>::const_iterator it = mixturebinarypairlibrary.
binary_pair_map().begin();
300 out.push_back(
strjoin(it->first,
"&"));
307 std::vector<std::string> CAS;
312 std::vector<Dictionary>& v = mixturebinarypairlibrary.
binary_pair_map()[CAS];
314 if (key ==
"name1") {
315 return v[0].get_string(
"name1");
316 }
else if (key ==
"name2") {
317 return v[0].get_string(
"name2");
318 }
else if (key ==
"BibTeX") {
319 return v[0].get_string(
"BibTeX");
320 }
else if (key ==
"function") {
321 return v[0].get_string(
"function");
322 }
else if (key ==
"type") {
323 return v[0].get_string(
"type");
324 }
else if (key ==
"F") {
326 }
else if (key ==
"xi") {
328 }
else if (key ==
"zeta") {
330 }
else if (key ==
"gammaT") {
332 }
else if (key ==
"gammaV") {
334 }
else if (key ==
"betaT") {
336 }
else if (key ==
"betaV") {
342 throw ValueError(
format(
"Could not match the parameter [%s] for the binary pair [%s,%s] - for now this is an error.", key.c_str(),
343 CAS1.c_str(), CAS2.c_str()));
346 std::sort(CAS.begin(), CAS.end());
348 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - order of CAS numbers is backwards; found the swapped CAS numbers.",
349 CAS1.c_str(), CAS2.c_str()));
351 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
358 std::vector<std::string> CAS;
363 std::vector<Dictionary>& v = mixturebinarypairlibrary.
binary_pair_map()[CAS];
364 if (v[0].has_number(key)) {
365 v[0].add_number(key, value);
367 throw ValueError(
format(
"Could not set the parameter [%s] for the binary pair [%s,%s] - for now this is an error", key.c_str(),
368 CAS1.c_str(), CAS2.c_str()));
372 std::sort(CAS.begin(), CAS.end());
374 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - order of CAS numbers is backwards; found the swapped CAS numbers.",
375 CAS1.c_str(), CAS2.c_str()));
377 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
384 std::vector<std::string> CAS;
389 std::sort(CAS.begin(), CAS.end());
392 return mixturebinarypairlibrary.
binary_pair_map()[CAS][0].get_string(
"function");
394 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
409 std::map<std::string, Dictionary> m_departure_function_map;
414 if (m_departure_function_map.size() == 0) {
417 return m_departure_function_map;
421 rapidjson::Document doc;
422 doc.Parse<0>(str.c_str());
423 if (doc.HasParseError()) {
424 std::cout << str << std::endl;
425 throw ValueError(
"Unable to parse departure function string");
431 for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) {
449 if (!type.compare(
"GERG-2008")) {
457 }
else if (type ==
"Gaussian+Exponential") {
467 }
else if (!type.compare(
"Exponential")) {
470 throw ValueError(
format(
"It was not possible to parse departure function with type [%s]", type.c_str()));
476 for (std::vector<std::string>::const_iterator it = aliases.begin(); it != aliases.end(); ++it) {
485 std::map<std::string, Dictionary>::iterator it = m_departure_function_map.find(name);
486 if (it == m_departure_function_map.end()) {
488 m_departure_function_map.insert(std::pair<std::string, Dictionary>(name, dict));
492 m_departure_function_map.erase(it);
493 std::pair<std::map<std::string, Dictionary>::iterator,
bool> ret;
494 ret = m_departure_function_map.insert(std::pair<std::string, Dictionary>(name, dict));
495 assert(ret.second ==
true);
500 std::vector<std::string> names;
501 for (std::map<std::string, Dictionary>::const_iterator it = m_departure_function_map.begin(); it != m_departure_function_map.end();
503 names.push_back(it->first);
505 throw ValueError(
format(
"Name of departure function [%s] is already loaded. Current departure function names are: %s", name.c_str(),
516 static MixtureDepartureFunctionsLibrary mixturedeparturefunctionslibrary;
523 throw ValueError(
format(
"Departure function name [%s] seems to be invalid", Name.c_str()));
531 std::string type_dep = dict_dep.
get_string(
"type");
533 if (!type_dep.compare(
"GERG-2008")) {
535 int Npower =
static_cast<int>(dict_dep.
get_number(
"Npower"));
542 }
else if (!type_dep.compare(
"Exponential")) {
546 }
else if (!type_dep.compare(
"Gaussian+Exponential")) {
548 int Npower =
static_cast<int>(dict_dep.
get_number(
"Npower"));
565 std::size_t N = components.size();
567 STLMatrix beta_v, gamma_v, beta_T, gamma_T;
568 beta_v.resize(N, std::vector<CoolPropDbl>(N, 0));
569 gamma_v.resize(N, std::vector<CoolPropDbl>(N, 0));
570 beta_T.resize(N, std::vector<CoolPropDbl>(N, 0));
571 gamma_T.resize(N, std::vector<CoolPropDbl>(N, 0));
575 for (std::size_t i = 0; i < N; ++i) {
576 for (std::size_t j = 0; j < N; ++j) {
581 std::string CAS1 = components[i].CAS;
582 std::vector<std::string> CAS(2,
"");
583 CAS[0] = components[i].CAS;
584 CAS[1] = components[j].CAS;
585 std::sort(CAS.begin(), CAS.end());
588 bool swapped = (CAS1.compare(CAS[0]) != 0);
595 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS[0].c_str(), CAS[1].c_str()));
602 std::string type_red = dict_red.
get_string(
"type");
604 if (!type_red.compare(
"GERG-2008")) {
606 beta_v[i][j] = 1 / dict_red.
get_number(
"betaV");
607 beta_T[i][j] = 1 / dict_red.
get_number(
"betaT");
612 gamma_v[i][j] = dict_red.
get_number(
"gammaV");
613 gamma_T[i][j] = dict_red.
get_number(
"gammaT");
614 }
else if (!type_red.compare(
"Lemmon-xi-zeta")) {
617 throw ValueError(
format(
"type [%s] for reducing function for pair [%s, %s] is invalid", type_red.c_str(),
636 std::vector<double> n(1, 0), d(1, 1), t(1, 1), l(1, 0);
651 void parse_HMX_BNC(
const std::string& s, std::vector<REFPROP_binary_element>& BIP, std::vector<REFPROP_departure_function>& functions) {
653 bool block_started =
false;
654 std::size_t i_started = 0, i_ended = 0, i = 0;
655 std::vector<std::string> lines =
strsplit(s,
'\n');
656 for (std::vector<std::string>::iterator it = lines.begin(); it != lines.end(); ++it) {
658 block_started =
true;
661 if (block_started &&
strstrip(*it).empty()) {
668 for (i = i_started; i < i_ended; ++i) {
675 std::vector<std::pair<std::size_t, std::size_t>> bounds;
676 std::size_t last_excalamation = i_started;
677 for (i = i_started; i <= i_ended; ++i) {
679 bounds.push_back(std::make_pair<std::size_t, std::size_t>(last_excalamation + 1, i - 1));
680 last_excalamation = i;
684 std::vector<REFPROP_binary_element> chunks;
685 for (std::vector<std::pair<std::size_t, std::size_t>>::iterator it = bounds.begin(); it != bounds.end(); ++it) {
687 for (std::size_t i = it->first; i <= it->second; ++i) {
694 if (lines[i].find(
"/") > 0) {
698 for (std::size_t j = bits.size() - 1; j > 0; --j) {
699 if (bits[j].empty()) {
700 bits.erase(bits.begin() + j);
704 if (bits[0].find(
"/") > 0 && bits[1].size() == 3) {
705 std::vector<std::string> theCAS =
strsplit(bits[0],
'/');
706 bnc.
CAS1 = theCAS[0];
707 bnc.
CAS2 = theCAS[1];
715 }
else if (
strstrip(bits[0]) ==
"CAS#") {
722 if (!bnc.
CAS1.empty()) {
730 for (std::size_t i = i_ended + 1; i < lines.size(); ++i) {
733 for (j_end = i + 1; j_end < lines.size(); ++j_end) {
734 if (
strstrip(lines[j_end]).empty()) {
743 dep.
model = std::string(lines[i + 1].begin(), lines[i + 1].begin() + 3);
744 dep.
comments.push_back(lines[i + 1]);
745 for (std::size_t j = i + 2; j <= j_end; ++j) {
754 std::vector<std::string> bits =
strsplit(lines[j],
' ');
756 for (std::size_t k = bits.size() - 1; k > 0; --k) {
757 if (bits[k].empty()) {
758 bits.erase(bits.begin() + k);
764 dep.
Npower =
static_cast<short>(strtol(bits[0].c_str(), NULL, 10));
765 dep.
Nterms_power =
static_cast<short>(strtol(bits[1].c_str(), NULL, 10));
766 dep.
Nspecial =
static_cast<short>(strtol(bits[3].c_str(), NULL, 10));
767 dep.
Nterms_special =
static_cast<short>(strtol(bits[4].c_str(), NULL, 10));
777 if (dep.
a.size() - 1 < dep.
Npower) {
778 dep.
eta.push_back(0);
780 dep.
beta.push_back(0);
781 dep.
gamma.push_back(0);
792 functions.push_back(dep);
798 if (string_data.find(
"#MXM") != std::string::npos) {
800 std::vector<REFPROP_binary_element> BIP;
801 std::vector<REFPROP_departure_function> functions;
805 rapidjson::Document doc;
807 for (std::vector<REFPROP_binary_element>::const_iterator it = BIP.begin(); it < BIP.end(); ++it) {
810 el.AddMember(
"CAS1", rapidjson::Value(it->CAS1.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
811 el.AddMember(
"CAS2", rapidjson::Value(it->CAS2.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
812 el.AddMember(
"Name1",
"??", doc.GetAllocator());
813 el.AddMember(
"Name2",
"??", doc.GetAllocator());
814 el.AddMember(
"betaT", it->betaT, doc.GetAllocator());
815 el.AddMember(
"gammaT", it->gammaT, doc.GetAllocator());
816 el.AddMember(
"betaV", it->betaV, doc.GetAllocator());
817 el.AddMember(
"gammaV", it->gammaV, doc.GetAllocator());
818 el.AddMember(
"F", it->Fij, doc.GetAllocator());
819 el.AddMember(
"function", rapidjson::Value(it->model.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
820 std::string tex_string =
"(from HMX.BNC format)::" +
strjoin(it->comments,
"\n");
821 el.AddMember(
"BibTeX", rapidjson::Value(tex_string.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
822 doc.PushBack(el, doc.GetAllocator());
827 rapidjson::Document doc;
829 for (std::vector<REFPROP_departure_function>::const_iterator it = functions.begin(); it < functions.end(); ++it) {
832 el.AddMember(
"Name", rapidjson::Value(it->model.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
833 std::vector<std::string> aliases;
838 if (it->Nterms_special > 0 || it->Nterms_power == 3) {
839 el.AddMember(
"type",
"GERG-2008", doc.GetAllocator());
840 el.AddMember(
"Npower", it->Npower, doc.GetAllocator());
841 if (it->Nterms_power == 3 && it->Nspecial == 0) {
842 std::vector<double> zeros(it->a.size(), 0);
854 el.AddMember(
"type",
"Exponential", doc.GetAllocator());
858 std::string tex_string =
"(from HMX.BNC format)::" +
strjoin(it->comments,
"\n");
859 el.AddMember(
"BibTeX", rapidjson::Value(tex_string.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
860 doc.PushBack(el, doc.GetAllocator());