CoolProp  6.6.0
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 
12 namespace CoolProp {
13 namespace 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 };
141 static CubicsLibraryClass library;
142 
143 void 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 }
165 std::string get_fluid_as_JSONstring(const std::string& identifier) {
166  return library.get_JSONstring(identifier);
167 }
168 
169 CubicLibrary::CubicsValues get_cubic_values(const std::string& identifier) {
170  return library.get(identifier);
171 }
172 std::string get_cubic_fluids_schema() {
174 }
175 std::string get_cubic_fluids_list() {
176  return library.get_fluids_list();
177 }
178 
179 } // namespace CubicLibrary
180 } // namespace CoolProp