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) {
53static 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 return m_binary_pair_map;
96 rapidjson::Document doc;
97 doc.Parse<0>(str.c_str());
98 if (doc.HasParseError()) {
99 std::cout << str << std::endl;
100 throw ValueError(
"Unable to parse binary interaction function string");
106 if (m_binary_pair_map.size() == 0) {
124 for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) {
129 std::vector<std::string> CAS;
136 std::sort(CAS.begin(), CAS.end());
142 std::swap(name1, name2);
154 if (itr->HasMember(
"xi") && itr->HasMember(
"zeta")) {
159 }
else if (itr->HasMember(
"gammaT") && itr->HasMember(
"gammaV") && itr->HasMember(
"betaT") && itr->HasMember(
"betaV")) {
174 std::cout <<
"Loading error: binary pair of " << name1 <<
" & " << name2
175 <<
"does not provide either a) xi and zeta b) gammaT, gammaV, betaT, and betaV" << std::endl;
179 std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator it = m_binary_pair_map.find(CAS);
180 if (it == m_binary_pair_map.end()) {
182 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
186 m_binary_pair_map.erase(it);
187 std::pair<std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator,
bool> ret;
189 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
190 assert(ret.second ==
true);
194 format(
"CAS pair(%s,%s) already in binary interaction map; considering enabling configuration key OVERWRITE_BINARY_INTERACTION",
195 CAS[0].c_str(), CAS[1].c_str()));
206 std::string CAS1, CAS2, name1 = identifier1, name2 = identifier2;
207 shared_ptr<CoolProp::HelmholtzEOSMixtureBackend> HEOS1, HEOS2;
209 std::vector<std::string> id1split =
strsplit(identifier1,
'-');
210 if (id1split.size() == 3) {
213 std::vector<std::string> names1(1, identifier1);
215 CAS1 = HEOS1->fluid_param_string(
"CAS");
218 std::vector<std::string> id2split =
strsplit(identifier2,
'-');
219 if (id2split.size() == 3) {
222 std::vector<std::string> names2(1, identifier2);
224 CAS2 = HEOS2->fluid_param_string(
"CAS");
228 std::vector<std::string> CAS;
233 std::sort(CAS.begin(), CAS.end());
236 if (CAS[0] != CAS1) {
237 std::swap(name1, name2);
247 if (rule ==
"linear") {
252 dict.
add_number(
"gammaT", 0.5 * (HEOS1->T_critical() + HEOS2->T_critical()) / sqrt(HEOS1->T_critical() * HEOS2->T_critical()));
253 double rhoc1 = HEOS1->rhomolar_critical(), rhoc2 = HEOS2->rhomolar_critical();
254 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));
257 }
else if (rule ==
"Lorentz-Berthelot") {
265 throw ValueError(
format(
"Your simple mixing rule [%s] was not understood", rule.c_str()));
268 std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator it = m_binary_pair_map.find(CAS);
269 if (it == m_binary_pair_map.end()) {
271 m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
275 m_binary_pair_map.erase(it);
276 std::pair<std::map<std::vector<std::string>, std::vector<Dictionary>>::iterator,
bool> ret;
277 ret = m_binary_pair_map.insert(std::pair<std::vector<std::string>, std::vector<Dictionary>>(CAS, std::vector<Dictionary>(1, dict)));
278 assert(ret.second ==
true);
282 format(
"CAS pair(%s,%s) already in binary interaction map; considering enabling configuration key OVERWRITE_BINARY_INTERACTION",
283 CAS[0].c_str(), CAS[1].c_str()));
289static MixtureBinaryPairLibrary mixturebinarypairlibrary;
299 std::vector<std::string> out;
300 for (std::map<std::vector<std::string>, std::vector<Dictionary>>::const_iterator it = mixturebinarypairlibrary.
binary_pair_map().begin();
302 out.push_back(
strjoin(it->first,
"&"));
309 std::vector<std::string> CAS;
314 std::vector<Dictionary>& v = mixturebinarypairlibrary.
binary_pair_map()[CAS];
316 if (key ==
"name1") {
317 return v[0].get_string(
"name1");
318 }
else if (key ==
"name2") {
319 return v[0].get_string(
"name2");
320 }
else if (key ==
"BibTeX") {
321 return v[0].get_string(
"BibTeX");
322 }
else if (key ==
"function") {
323 return v[0].get_string(
"function");
324 }
else if (key ==
"type") {
325 return v[0].get_string(
"type");
326 }
else if (key ==
"F") {
328 }
else if (key ==
"xi") {
330 }
else if (key ==
"zeta") {
332 }
else if (key ==
"gammaT") {
334 }
else if (key ==
"gammaV") {
336 }
else if (key ==
"betaT") {
338 }
else if (key ==
"betaV") {
344 throw ValueError(
format(
"Could not match the parameter [%s] for the binary pair [%s,%s] - for now this is an error.", key.c_str(),
345 CAS1.c_str(), CAS2.c_str()));
348 std::sort(CAS.begin(), CAS.end());
350 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - order of CAS numbers is backwards; found the swapped CAS numbers.",
351 CAS1.c_str(), CAS2.c_str()));
353 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
360 std::vector<std::string> CAS;
365 std::vector<Dictionary>& v = mixturebinarypairlibrary.
binary_pair_map()[CAS];
366 if (v[0].has_number(key)) {
367 v[0].add_number(key, value);
369 throw ValueError(
format(
"Could not set the parameter [%s] for the binary pair [%s,%s] - for now this is an error", key.c_str(),
370 CAS1.c_str(), CAS2.c_str()));
374 std::sort(CAS.begin(), CAS.end());
376 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - order of CAS numbers is backwards; found the swapped CAS numbers.",
377 CAS1.c_str(), CAS2.c_str()));
379 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
386 std::vector<std::string> CAS;
391 std::sort(CAS.begin(), CAS.end());
394 return mixturebinarypairlibrary.
binary_pair_map()[CAS][0].get_string(
"function");
396 throw ValueError(
format(
"Could not match the binary pair [%s,%s] - for now this is an error.", CAS1.c_str(), CAS2.c_str()));
411 std::map<std::string, Dictionary> m_departure_function_map;
416 return m_departure_function_map;
420 rapidjson::Document doc;
421 doc.Parse<0>(str.c_str());
422 if (doc.HasParseError()) {
423 std::cout << str << std::endl;
424 throw ValueError(
"Unable to parse departure function string");
430 for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) {
448 if (!type.compare(
"GERG-2008")) {
456 }
else if (type ==
"Gaussian+Exponential") {
466 }
else if (!type.compare(
"Exponential")) {
469 throw ValueError(
format(
"It was not possible to parse departure function with type [%s]", type.c_str()));
475 for (std::vector<std::string>::const_iterator it = aliases.begin(); it != aliases.end(); ++it) {
484 std::map<std::string, Dictionary>::iterator it = m_departure_function_map.find(name);
485 if (it == m_departure_function_map.end()) {
487 m_departure_function_map.insert(std::pair<std::string, Dictionary>(name, dict));
491 m_departure_function_map.erase(it);
492 std::pair<std::map<std::string, Dictionary>::iterator,
bool> ret;
493 ret = m_departure_function_map.insert(std::pair<std::string, Dictionary>(name, dict));
494 assert(ret.second ==
true);
499 std::vector<std::string> names;
500 for (std::map<std::string, Dictionary>::const_iterator it = m_departure_function_map.begin(); it != m_departure_function_map.end();
502 names.push_back(it->first);
504 throw ValueError(
format(
"Name of departure function [%s] is already loaded. Current departure function names are: %s", name.c_str(),
510 if (m_departure_function_map.size() == 0) {
520static MixtureDepartureFunctionsLibrary mixturedeparturefunctionslibrary;
527 throw ValueError(
format(
"Departure function name [%s] seems to be invalid", Name.c_str()));
535 std::string type_dep = dict_dep.
get_string(
"type");
537 if (!type_dep.compare(
"GERG-2008")) {
539 int Npower =
static_cast<int>(dict_dep.
get_number(
"Npower"));
546 }
else if (!type_dep.compare(
"Exponential")) {
550 }
else if (!type_dep.compare(
"Gaussian+Exponential")) {
552 int Npower =
static_cast<int>(dict_dep.
get_number(
"Npower"));
569 std::size_t N = components.size();
571 STLMatrix beta_v, gamma_v, beta_T, gamma_T;
572 beta_v.resize(N, std::vector<CoolPropDbl>(N, 0));
573 gamma_v.resize(N, std::vector<CoolPropDbl>(N, 0));
574 beta_T.resize(N, std::vector<CoolPropDbl>(N, 0));
575 gamma_T.resize(N, std::vector<CoolPropDbl>(N, 0));
579 for (std::size_t i = 0; i < N; ++i) {
580 for (std::size_t j = 0; j < N; ++j) {
585 std::string CAS1 = components[i].CAS;
586 std::vector<std::string> CAS(2,
"");
587 CAS[0] = components[i].CAS;
588 CAS[1] = components[j].CAS;
589 std::sort(CAS.begin(), CAS.end());
592 bool swapped = (CAS1.compare(CAS[0]) != 0);
599 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()));
606 std::string type_red = dict_red.
get_string(
"type");
608 if (!type_red.compare(
"GERG-2008")) {
610 beta_v[i][j] = 1 / dict_red.
get_number(
"betaV");
611 beta_T[i][j] = 1 / dict_red.
get_number(
"betaT");
616 gamma_v[i][j] = dict_red.
get_number(
"gammaV");
617 gamma_T[i][j] = dict_red.
get_number(
"gammaT");
618 }
else if (!type_red.compare(
"Lemmon-xi-zeta")) {
621 throw ValueError(
format(
"type [%s] for reducing function for pair [%s, %s] is invalid", type_red.c_str(),
640 std::vector<double> n(1, 0), d(1, 1), t(1, 1), l(1, 0);
655void parse_HMX_BNC(
const std::string& s, std::vector<REFPROP_binary_element>& BIP, std::vector<REFPROP_departure_function>& functions) {
657 bool block_started =
false;
658 std::size_t i_started = 0, i_ended = 0, i = 0;
659 std::vector<std::string> lines =
strsplit(s,
'\n');
660 for (std::vector<std::string>::iterator it = lines.begin(); it != lines.end(); ++it) {
662 block_started =
true;
665 if (block_started &&
strstrip(*it).empty()) {
672 for (i = i_started; i < i_ended; ++i) {
679 std::vector<std::pair<std::size_t, std::size_t>> bounds;
680 std::size_t last_excalamation = i_started;
681 for (i = i_started; i <= i_ended; ++i) {
683 bounds.push_back(std::make_pair<std::size_t, std::size_t>(last_excalamation + 1, i - 1));
684 last_excalamation = i;
688 std::vector<REFPROP_binary_element> chunks;
689 for (std::vector<std::pair<std::size_t, std::size_t>>::iterator it = bounds.begin(); it != bounds.end(); ++it) {
691 for (std::size_t i = it->first; i <= it->second; ++i) {
698 if (lines[i].find(
"/") > 0) {
702 for (std::size_t j = bits.size() - 1; j > 0; --j) {
703 if (bits[j].empty()) {
704 bits.erase(bits.begin() + j);
708 if (bits[0].find(
"/") > 0 && bits[1].size() == 3) {
709 std::vector<std::string> theCAS =
strsplit(bits[0],
'/');
710 bnc.
CAS1 = theCAS[0];
711 bnc.
CAS2 = theCAS[1];
719 }
else if (
strstrip(bits[0]) ==
"CAS#") {
726 if (!bnc.
CAS1.empty()) {
734 for (std::size_t i = i_ended + 1; i < lines.size(); ++i) {
737 for (j_end = i + 1; j_end < lines.size(); ++j_end) {
738 if (
strstrip(lines[j_end]).empty()) {
747 dep.
model = std::string(lines[i + 1].begin(), lines[i + 1].begin() + 3);
748 dep.
comments.push_back(lines[i + 1]);
749 for (std::size_t j = i + 2; j <= j_end; ++j) {
758 std::vector<std::string> bits =
strsplit(lines[j],
' ');
760 for (std::size_t k = bits.size() - 1; k > 0; --k) {
761 if (bits[k].empty()) {
762 bits.erase(bits.begin() + k);
768 dep.
Npower =
static_cast<short>(strtol(bits[0].c_str(), NULL, 10));
769 dep.
Nterms_power =
static_cast<short>(strtol(bits[1].c_str(), NULL, 10));
770 dep.
Nspecial =
static_cast<short>(strtol(bits[3].c_str(), NULL, 10));
771 dep.
Nterms_special =
static_cast<short>(strtol(bits[4].c_str(), NULL, 10));
781 if (dep.
a.size() - 1 <
static_cast<size_t>(dep.
Npower)) {
782 dep.
eta.push_back(0);
784 dep.
beta.push_back(0);
785 dep.
gamma.push_back(0);
796 functions.push_back(dep);
802 if (string_data.find(
"#MXM") != std::string::npos) {
804 std::vector<REFPROP_binary_element> BIP;
805 std::vector<REFPROP_departure_function> functions;
809 rapidjson::Document doc;
811 for (std::vector<REFPROP_binary_element>::const_iterator it = BIP.begin(); it < BIP.end(); ++it) {
814 el.AddMember(
"CAS1", rapidjson::Value(it->CAS1.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
815 el.AddMember(
"CAS2", rapidjson::Value(it->CAS2.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
816 el.AddMember(
"Name1",
"??", doc.GetAllocator());
817 el.AddMember(
"Name2",
"??", doc.GetAllocator());
818 el.AddMember(
"betaT", it->betaT, doc.GetAllocator());
819 el.AddMember(
"gammaT", it->gammaT, doc.GetAllocator());
820 el.AddMember(
"betaV", it->betaV, doc.GetAllocator());
821 el.AddMember(
"gammaV", it->gammaV, doc.GetAllocator());
822 el.AddMember(
"F", it->Fij, doc.GetAllocator());
823 el.AddMember(
"function", rapidjson::Value(it->model.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
824 std::string tex_string =
"(from HMX.BNC format)::" +
strjoin(it->comments,
"\n");
825 el.AddMember(
"BibTeX", rapidjson::Value(tex_string.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
826 doc.PushBack(el, doc.GetAllocator());
831 rapidjson::Document doc;
833 for (std::vector<REFPROP_departure_function>::const_iterator it = functions.begin(); it < functions.end(); ++it) {
836 el.AddMember(
"Name", rapidjson::Value(it->model.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
837 std::vector<std::string> aliases;
842 if (it->Nterms_special > 0 || it->Nterms_power == 3) {
843 el.AddMember(
"type",
"GERG-2008", doc.GetAllocator());
844 el.AddMember(
"Npower", it->Npower, doc.GetAllocator());
845 if (it->Nterms_power == 3 && it->Nspecial == 0) {
846 std::vector<double> zeros(it->a.size(), 0);
858 el.AddMember(
"type",
"Exponential", doc.GetAllocator());
862 std::string tex_string =
"(from HMX.BNC format)::" +
strjoin(it->comments,
"\n");
863 el.AddMember(
"BibTeX", rapidjson::Value(tex_string.c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
864 doc.PushBack(el, doc.GetAllocator());