CoolProp 6.8.1dev
An open-source fluid property and humid air property database
CubicsLibrary.cpp
Go to the documentation of this file.
1#include <string>
2#include <map>
3#include "CubicsLibrary.h"
4#include "all_cubics_JSON.h" // Makes a std::string variable called all_cubics_JSON
5#include "cubic_fluids_schema_JSON.h" // Makes a std::string variable called cubic_fluids_schema_JSON
6#include "rapidjson_include.h"
7#include "CPstrings.h"
8#include "CoolProp.h"
9#include "Configuration.h"
11
12namespace CoolProp {
13namespace CubicLibrary {
14
16{
17 private:
18 std::map<std::string, CubicsValues> fluid_map;
19 std::map<std::string, std::string> aliases_map;
21 std::map<std::string, std::string> JSONstring_map;
22 bool empty; // Is empty
23 public:
24 CubicsLibraryClass() : empty(true) {
25 // This JSON formatted string comes from the all_cubics_JSON.h header which is a C++-escaped version of the JSON file
27 };
28 bool is_empty() {
29 return empty;
30 };
31 int add_many(rapidjson::Value& listing) {
32 int counter = 0;
33 for (rapidjson::Value::ValueIterator itr = listing.Begin(); itr != listing.End(); ++itr) {
34 CubicsValues val;
35 val.Tc = cpjson::get_double(*itr, "Tc");
36 val.pc = cpjson::get_double(*itr, "pc");
37 val.acentric = cpjson::get_double(*itr, "acentric");
38 val.molemass = cpjson::get_double(*itr, "molemass");
39 val.name = cpjson::get_string(*itr, "name");
40 val.aliases = cpjson::get_string_array(*itr, "aliases");
41 val.CAS = cpjson::get_string(*itr, "CAS");
42 if (itr->HasMember("rhomolarc") && (*itr)["rhomolarc"].IsNumber()) {
43 val.rhomolarc = cpjson::get_double(*itr, "rhomolarc");
44 }
45 if (itr->HasMember("alpha") && (*itr)["alpha"].IsObject()) {
46 rapidjson::Value& alpha = (*itr)["alpha"];
47 val.alpha_type = cpjson::get_string(alpha, "type");
48 val.alpha_coeffs = cpjson::get_double_array(alpha, "c");
49 } else {
50 val.alpha_type = "default";
51 }
52 if (itr->HasMember("alpha0") && (*itr)["alpha0"].IsArray()) {
53 val.alpha0 = JSONFluidLibrary::parse_alpha0((*itr)["alpha0"]);
54 }
55 std::pair<std::map<std::string, CubicsValues>::iterator, bool> ret;
56 ret = fluid_map.insert(std::pair<std::string, CubicsValues>(upper(val.name), val));
57 if (ret.second == false && get_config_bool(OVERWRITE_FLUIDS)) {
58 // Already there, see http://www.cplusplus.com/reference/map/map/insert/
59 fluid_map.erase(ret.first);
60 ret = fluid_map.insert(std::pair<std::string, CubicsValues>(upper(val.name), val));
61 if (get_debug_level() > 0) {
62 std::cout << "added the cubic fluid: " + val.name << std::endl;
63 }
64 assert(ret.second == true);
65 }
66
67 for (std::vector<std::string>::const_iterator it = val.aliases.begin(); it != val.aliases.end(); ++it) {
68 if (aliases_map.find(*it) == aliases_map.end()) {
69 // It's not already in aliases map
70 aliases_map.insert(std::pair<std::string, std::string>(*it, upper(val.name)));
71 }
72 }
73
74 // Add/Replace name->JSONstring mapping to easily pull out if the user wants it
75 // Convert fuid_json to a string and store it in the map.
76 std::pair<std::map<std::string, std::string>::iterator, bool> addJson;
77 addJson = JSONstring_map.insert(std::pair<std::string, std::string>(upper(val.name),cpjson::json2string(*itr)));
78 if (addJson.second == false && get_config_bool(OVERWRITE_FLUIDS)) {
79 // Already there, see http://www.cplusplus.com/reference/map/map/insert/
80 JSONstring_map.erase(addJson.first);
81 addJson = JSONstring_map.insert(std::pair<std::string, std::string>(upper(val.name),cpjson::json2string(*itr)));
82 if (get_debug_level() > 0) {
83 std::cout << "added the cubic fluid: " + val.name << std::endl;
84 }
85 assert(addJson.second == true);
86 }
87
88 counter++;
89 }
90 return counter;
91 };
92
93 std::string get_JSONstring(const std::string& key) {
94 std::string uppercase_identifier = upper(key);
95 // Try to find it
96 std::map<std::string, std::string>::iterator it = JSONstring_map.find(uppercase_identifier);
97 // If it is found
98 if (it == JSONstring_map.end()) {
99 std::map<std::string, std::string>::iterator italias = aliases_map.find(uppercase_identifier);
100 if (italias != aliases_map.end()) {
101 // Alias was found, use it to get the fluid name, and then the cubic values
102 it = JSONstring_map.find(italias->second);
103 } else {
104 throw ValueError(format("Fluid identifier [%s] was not found in CubicsLibrary", uppercase_identifier.c_str()));
105 }
106 }
107 // Then, load the fluids we would like to add
108 rapidjson::Document doc;
109 cpjson::JSON_string_to_rapidjson(it->second, doc);
110 rapidjson::Document doc2;
111 doc2.SetArray();
112 doc2.PushBack(doc, doc.GetAllocator());
113 return cpjson::json2string(doc2);
114 }
115
116 CubicsValues get(const std::string& identifier) {
117 std::string uppercase_identifier = upper(identifier);
118 // Try to find it
119 std::map<std::string, CubicsValues>::iterator it = fluid_map.find(uppercase_identifier);
120 // If it is found
121 if (it != fluid_map.end()) {
122 return it->second;
123 } else {
124 std::map<std::string, std::string>::iterator italias = aliases_map.find(uppercase_identifier);
125 if (italias != aliases_map.end()) {
126 // Alias was found, use it to get the fluid name, and then the cubic values
127 return fluid_map.find(italias->second)->second;
128 } else {
129 throw ValueError(format("Fluid identifier [%s] was not found in CubicsLibrary", uppercase_identifier.c_str()));
130 }
131 }
132 };
133 std::string get_fluids_list() {
134 std::vector<std::string> out;
135 for (std::map<std::string, CubicsValues>::const_iterator it = fluid_map.begin(); it != fluid_map.end(); ++it) {
136 out.push_back(it->first);
137 }
138 return strjoin(out, ",");
139 }
140};
141static CubicsLibraryClass library;
142
143void add_fluids_as_JSON(const std::string& JSON) {
144 // First we validate the json string against the schema;
145 std::string errstr;
147 // Then we check the validation code
148 if (val_code == cpjson::SCHEMA_VALIDATION_OK) {
149 rapidjson::Document dd;
150
151 dd.Parse<0>(JSON.c_str());
152 if (dd.HasParseError()) {
153 throw ValueError("Cubics JSON is not valid JSON");
154 } else {
155 try {
156 library.add_many(dd);
157 } catch (std::exception& /* e */) {
158 throw ValueError(format("Unable to load cubics library with error: %s", errstr.c_str()));
159 }
160 }
161 } else {
162 throw ValueError(format("Unable to validate cubics library against schema with error: %s", errstr.c_str()));
163 }
164}
165std::string get_fluid_as_JSONstring(const std::string& identifier) {
166 return library.get_JSONstring(identifier);
167}
168
169CubicLibrary::CubicsValues get_cubic_values(const std::string& identifier) {
170 return library.get(identifier);
171}
174}
176 return library.get_fluids_list();
177}
178
179} // namespace CubicLibrary
180} // namespace CoolProp