CoolProp  6.6.1dev
An open-source fluid property and humid air property database
CoolPropLib.cpp
Go to the documentation of this file.
1 #if defined(_MSC_VER)
2 # define _CRTDBG_MAP_ALLOC
3 # define _CRT_SECURE_NO_WARNINGS
4 # include <crtdbg.h>
5 #else
6 # include <fenv.h>
7 #endif
8 
9 #include "CoolPropLib.h"
10 #include "CoolProp.h"
11 #include "HumidAirProp.h"
12 #include "DataStructures.h"
13 #include "Exceptions.h"
14 #include "float.h"
16 #include "AbstractState.h"
17 #include "Exceptions.h"
18 #include "Configuration.h"
20 
21 #include <string.h>
22 #include <mutex>
23 
24 void str2buf(const std::string& str, char* buf, int n) {
25  if (str.size() < static_cast<unsigned int>(n))
26  strcpy(buf, str.c_str());
27  else
28  throw CoolProp::ValueError("Buffer size is too small");
29 }
30 void HandleException(long* errcode, char* message_buffer, const long buffer_length) {
31  try {
32  throw; // Rethrow the error, and here we handle the error
33  } catch (CoolProp::HandleError& e) {
34  std::string errmsg = std::string("HandleError: ") + e.what();
35  if (errmsg.size() < static_cast<std::size_t>(buffer_length)) {
36  *errcode = 1;
37  strcpy(message_buffer, errmsg.c_str());
38  } else {
39  *errcode = 2;
40  }
41  } catch (CoolProp::CoolPropBaseError& e) {
42  std::string errmsg = std::string("Error: ") + e.what();
43  if (errmsg.size() < static_cast<std::size_t>(buffer_length)) {
44  *errcode = 1;
45  strcpy(message_buffer, errmsg.c_str());
46  } else {
47  *errcode = 2;
48  }
49  } catch (...) {
50  *errcode = 3;
51  }
52 }
53 
54 // In Microsoft Excel, they seem to check the FPU exception bits and error out because of it.
55 // By calling the _clearfp(), we can reset these bits, and not get the error
56 // See also http://stackoverflow.com/questions/11685441/floating-point-error-when-calling-dll-function-from-vba/27336496#27336496
57 // See also http://stackoverflow.com/questions/16849009/in-linux-do-there-exist-functions-similar-to-clearfp-and-statusfp for linux and OSX
59 {
61 #if defined(_MSC_VER)
62  _clearfp(); // For MSVC, clear the floating point error flags
63 #elif defined(FE_ALL_EXCEPT)
64  feclearexcept(FE_ALL_EXCEPT);
65 #endif
66  }
67 };
68 double convert_from_kSI_to_SI(long iInput, double value) {
69  if (get_debug_level() > 8) {
70  std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n", __FILE__, __LINE__, iInput, value).c_str();
71  }
72 
73  switch (iInput) {
74  case CoolProp::iP:
75  case CoolProp::iCpmass:
76  case CoolProp::iCp0mass:
77  case CoolProp::iSmass:
78  case CoolProp::iGmass:
79  case CoolProp::iCvmass:
80  case CoolProp::iHmass:
81  case CoolProp::iUmass:
83  return value * 1000.0;
84  case CoolProp::iDmass:
86  case CoolProp::iQ:
88  case CoolProp::iT:
89  case CoolProp::iPrandtl:
91  return value;
92  default:
93  throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI", iInput).c_str());
94  }
95 }
96 
97 double convert_from_SI_to_kSI(long iInput, double value) {
98  if (get_debug_level() > 8) {
99  std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n", __FILE__, __LINE__, iInput, value).c_str();
100  }
101 
102  switch (iInput) {
103  case CoolProp::iP:
104  case CoolProp::iCpmass:
105  case CoolProp::iCp0mass:
106  case CoolProp::iSmass:
107  case CoolProp::iGmass:
108  case CoolProp::iCvmass:
109  case CoolProp::iHmass:
110  case CoolProp::iUmass:
112  return value / 1000.0;
113  case CoolProp::iDmass:
114  case CoolProp::iQ:
117  case CoolProp::iT:
119  return value;
120  default:
121  throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str());
122  }
123 }
124 
125 EXPORT_CODE long CONVENTION redirect_stdout(const char* file) {
126  FILE* fp = freopen(file, "a+", stdout);
127  return (fp) ? 1 : 0; // 0 = failure if redirection could not be done; original stdout is already closed
128 }
129 EXPORT_CODE int CONVENTION set_reference_stateS(const char* Ref, const char* reference_state) {
130  fpu_reset_guard guard;
131  try {
132  CoolProp::set_reference_stateS(std::string(Ref), std::string(reference_state));
133  return true;
134  } catch (std::exception& e) {
135  CoolProp::set_error_string(e.what());
136  } catch (...) {
137  CoolProp::set_error_string("Undefined error");
138  }
139  return false;
140 }
141 EXPORT_CODE int CONVENTION set_reference_stateD(const char* Ref, double T, double rhomolar, double hmolar0, double smolar0) {
142  fpu_reset_guard guard;
143  try {
144  CoolProp::set_reference_stateD(std::string(Ref), T, rhomolar, hmolar0, smolar0);
145  return true;
146  } catch (std::exception& e) {
147  CoolProp::set_error_string(e.what());
148  } catch (...) {
149  CoolProp::set_error_string("Undefined error");
150  }
151  return false;
152 }
153 
154 // All the function interfaces that point to the single-input Props function
155 EXPORT_CODE double CONVENTION Props1(const char* FluidName, const char* Output) {
156  fpu_reset_guard guard;
157  double val = Props1SI(Output, FluidName);
158  if (!ValidNumber(val))
159  // Error code was already set in Props1SI
160  return val;
161  // val is valid; so, Output is already checked in Props1SI -> get_parameter_index won't throw
163  return convert_from_SI_to_kSI(iOutput, val);
164 }
165 EXPORT_CODE double CONVENTION PropsS(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Ref) {
166  return Props(Output, Name1[0], Prop1, Name2[0], Prop2, Ref);
167 }
168 EXPORT_CODE double CONVENTION Props(const char* Output, const char Name1, double Prop1, const char Name2, double Prop2, const char* Ref) {
169  fpu_reset_guard guard;
170  try {
171  // Get parameter indices
172  std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
174  if (!CoolProp::is_trivial_parameter(iOutput)) {
177 
178  // Convert inputs to SI
179  Prop1 = convert_from_kSI_to_SI(iName1, Prop1);
180  Prop2 = convert_from_kSI_to_SI(iName2, Prop2);
181  }
182 
183  // Call the SI function
184  double val = PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);
185 
186  // Convert back to unit system
187  return convert_from_SI_to_kSI(iOutput, val);
188  } catch (std::exception& e) {
189  CoolProp::set_error_string(e.what());
190  } catch (...) {
191  CoolProp::set_error_string("Undefined error");
192  }
193  return _HUGE;
194 }
195 EXPORT_CODE double CONVENTION saturation_ancillary(const char* fluid_name, const char* output, int Q, const char* input, double value) {
196  fpu_reset_guard guard;
197  try {
198  return CoolProp::saturation_ancillary(fluid_name, std::string(output), Q, std::string(input), value);
199  } catch (std::exception& e) {
200  CoolProp::set_error_string(e.what());
201  } catch (...) {
202  CoolProp::set_error_string("Undefined error");
203  }
204  return _HUGE;
205 }
206 EXPORT_CODE double CONVENTION Props1SI(const char* FluidName, const char* Output) {
207  fpu_reset_guard guard;
208  return CoolProp::Props1SI(std::string(FluidName), std::string(Output));
209 }
210 EXPORT_CODE void CONVENTION Props1SImulti(const char* Outputs, char* backend, const char* FluidNames, const double* fractions,
211  const long length_fractions, double* result, long* resdim1) {
212  fpu_reset_guard guard;
213  try {
214  // Outputs is a delimited string separated by LIST_STRING_DELIMITER
215  std::string delim = CoolProp::get_config_string(LIST_STRING_DELIMITER);
216  // strsplit only support char delimiter
217  if (delim.length() > 1)
218  throw CoolProp::ValueError(format("Length of string delimiter [%d] is bigger than 1 [%d]", delim.length(), delim.size()));
219  std::vector<std::string> _outputs = strsplit(Outputs, delim[0]);
220  // FluidNames is a delimited string separated by LIST_STRING_DELIMITER
221  std::vector<std::string> _fluidNames = strsplit(FluidNames, delim[0]);
222  if (_fluidNames.size() != length_fractions)
223  throw CoolProp::ValueError(
224  format("Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
225  std::vector<double> _fractions(fractions, fractions + length_fractions);
226  std::vector<std::vector<double>> _result = CoolProp::Props1SImulti(_outputs, backend, _fluidNames, _fractions);
227  // if CoolProp::Props1SImulti fails it will return an empty vector -> set result dimensions to 0
228  if (_result.size() == 0) {
229  *resdim1 = 0;
230  } else {
231  if (_result.size() > *resdim1)
232  throw CoolProp::ValueError(format("Result vector [%d] is bigger than allocated memory [%d]", _result[0].size(), *resdim1));
233  *resdim1 = _result[0].size();
234  for (int i = 0; i < _result[0].size(); i++) {
235  result[i] = _result[0][i];
236  }
237  }
238  } catch (std::exception& e) {
239  CoolProp::set_error_string(e.what());
240  } catch (...) {
241  CoolProp::set_error_string("Undefined error");
242  }
243 }
244 EXPORT_CODE double CONVENTION PropsSI(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* FluidName) {
245  fpu_reset_guard guard;
246  return CoolProp::PropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
247 }
248 EXPORT_CODE void CONVENTION PropsSImulti(const char* Outputs, const char* Name1, double* Prop1, const long size_Prop1, const char* Name2,
249  double* Prop2, const long size_Prop2, char* backend, const char* FluidNames, const double* fractions,
250  const long length_fractions, double* result, long* resdim1, long* resdim2) {
251  fpu_reset_guard guard;
252  try {
253  // Outputs is a delimited string separated by LIST_STRING_DELIMITER
254  std::string delim = CoolProp::get_config_string(LIST_STRING_DELIMITER);
255  // strsplit only support char delimiter
256  if (delim.length() > 1)
257  throw CoolProp::ValueError(format("Length of string delimiter [%d] is bigger than 1 [%d]", delim.length(), delim.size()));
258  std::vector<std::string> _outputs = strsplit(Outputs, delim[0]);
259  if (size_Prop1 != size_Prop2)
260  throw CoolProp::ValueError(
261  format("Length of input parameter 1 [%d] is not equal to length of input parameter 2 [%d]", size_Prop1, size_Prop2));
262  // make vectors out of double pointer
263  std::vector<double> _prop1(Prop1, Prop1 + size_Prop1);
264  std::vector<double> _prop2(Prop2, Prop2 + size_Prop2);
265  // FluidNames is a delimited string separated by LIST_STRING_DELIMITER
266  std::vector<std::string> _fluidNames = strsplit(FluidNames, delim[0]);
267  if (_fluidNames.size() != length_fractions)
268  throw CoolProp::ValueError(
269  format("Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
270  std::vector<double> _fractions(fractions, fractions + length_fractions);
271  std::vector<std::vector<double>> _result =
272  CoolProp::PropsSImulti(_outputs, std::string(Name1), _prop1, std::string(Name2), _prop2, backend, _fluidNames, _fractions);
273  // if CoolProp::PropsSImulti fails it will return an empty vector -> set result dimensions to 0
274  if (_result.size() == 0) {
275  *resdim1 = 0;
276  *resdim2 = 0;
277  } else {
278  if (_result.size() > *resdim1 || _result[0].size() > *resdim2)
279  throw CoolProp::ValueError(
280  format("Result matrix [%d x %d] is bigger than allocated memory [%d x %d]", _result.size(), _result[0].size(), *resdim1, *resdim2));
281  *resdim1 = _result.size();
282  *resdim2 = _result[0].size();
283  for (int i = 0; i < _result.size(); i++) {
284  for (int j = 0; j < _result[i].size(); j++) {
285  result[j + _result[i].size() * i] = _result[i][j];
286  }
287  }
288  }
289  } catch (std::exception& e) {
290  // set result dimensions to 0 to signalize, an error occured
291  *resdim1 = 0;
292  *resdim2 = 0;
293  CoolProp::set_error_string(e.what());
294  } catch (...) {
295  // set result dimensions to 0 to signalize, an error occured
296  *resdim1 = 0;
297  *resdim2 = 0;
298  CoolProp::set_error_string("Undefined error");
299  }
300 }
301 EXPORT_CODE long CONVENTION PhaseSI(const char* Name1, double Prop1, const char* Name2, double Prop2, const char* FluidName, char* phase, int n) {
302  fpu_reset_guard guard;
303  try {
304  std::string s = CoolProp::PhaseSI(std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
305  str2buf(s, phase, n);
306  return 1;
307  } catch (std::exception& e) {
308  CoolProp::set_error_string(e.what());
309  } catch (...) {
310  CoolProp::set_error_string("Undefined error");
311  }
312  return 0;
313 }
314 /*
315  * EXPORT_CODE double CONVENTION PropsSIZ(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, const double *z, int n)
316 {
317  std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
318  double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName, std::vector<double>(z, z+n));
319  reset_fpu();
320  return val;
321 }
322  * */
323 EXPORT_CODE void CONVENTION propssi_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
324  const char* FluidName, double* output) {
325  *output = PropsSI(Output, Name1, *Prop1, Name2, *Prop2, FluidName);
326 }
327 
328 EXPORT_CODE double CONVENTION K2F(double T) {
329  return T * 9 / 5 - 459.67;
330 }
331 EXPORT_CODE double CONVENTION F2K(double T_F) {
332  return (T_F + 459.67) * 5 / 9;
333 }
335  return CoolProp::get_debug_level();
336 }
339 }
340 EXPORT_CODE long CONVENTION get_param_index(const char* param) {
341  try {
342  return CoolProp::get_parameter_index(param);
343  } catch (std::exception& e) {
344  CoolProp::set_error_string(e.what());
345  } catch (...) {
346  CoolProp::set_error_string("Undefined error");
347  }
348  return -1;
349 }
351  try {
352  return CoolProp::get_input_pair_index(pair);
353  } catch (std::exception& e) {
354  CoolProp::set_error_string(e.what());
355  } catch (...) {
356  CoolProp::set_error_string("Undefined error");
357  }
358  return -1;
359 }
360 EXPORT_CODE long CONVENTION get_global_param_string(const char* param, char* Output, int n) {
361  try {
362  std::string s = CoolProp::get_global_param_string(param);
363  str2buf(s, Output, n);
364  return 1;
365  } catch (std::exception& e) {
366  CoolProp::set_error_string(e.what());
367  } catch (...) {
368  CoolProp::set_error_string("Undefined error");
369  }
370  return 0;
371 }
372 EXPORT_CODE long CONVENTION get_parameter_information_string(const char* param, char* Output, int n) {
373  try {
374  int key = CoolProp::get_parameter_index(param);
375  std::string s = CoolProp::get_parameter_information(key, Output);
376  str2buf(s, Output, n);
377  return 1;
378  } catch (std::exception& e) {
379  // if param is wrong, CoolProp::get_parameter_index throws string like
380  // "Your input name [%s] is not valid in get_parameter_index (names are case sensitive)"
381  // CoolProp::get_parameter_information throws string like
382  // "Bad info string [%s] to get_parameter_information" (if Output is wrong)
383  // or "Unable to match the key [%d] in get_parameter_information for info [%s]"
384  // (see src/DataStructures.cpp)
385  // if n is too small, str2buf throws string
386  // "Buffer size is too small"
387  CoolProp::set_error_string(format("get_parameter_information_string(\"%s\", \"%s\", %d): %s", param, Output, n, e.what()));
388  } catch (...) {
389  CoolProp::set_error_string(format("get_parameter_information_string(\"%s\", \"%s\", %d): Undefined error", param, Output, n));
390  }
391  return 0;
392 }
393 EXPORT_CODE long CONVENTION get_fluid_param_string(const char* fluid, const char* param, char* Output, int n) {
394  try {
395  std::string s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param));
396  str2buf(s, Output, n);
397  return 1;
398  } catch (std::exception& e) {
399  CoolProp::set_error_string(e.what());
400  } catch (...) {
401  CoolProp::set_error_string("Undefined error");
402  }
403  return 0;
404 }
405 EXPORT_CODE void CONVENTION set_config_string(const char* key, const char* val) {
406  try {
407  CoolProp::set_config_string(CoolProp::config_string_to_key(std::string(key)), std::string(val));
408  } catch (std::exception& e) {
409  CoolProp::set_error_string(e.what());
410  } catch (...) {
411  CoolProp::set_error_string("Undefined error");
412  }
413 }
414 EXPORT_CODE void CONVENTION set_config_double(const char* key, const double val) {
415  try {
417  } catch (std::exception& e) {
418  CoolProp::set_error_string(e.what());
419  } catch (...) {
420  CoolProp::set_error_string("Undefined error");
421  }
422 }
423 EXPORT_CODE void CONVENTION set_config_bool(const char* key, const bool val) {
424  try {
426  } catch (std::exception& e) {
427  CoolProp::set_error_string(e.what());
428  } catch (...) {
429  CoolProp::set_error_string("Undefined error");
430  }
431 }
432 EXPORT_CODE void CONVENTION set_departure_functions(const char* string_data, long* errcode, char* message_buffer, const long buffer_length) {
433  *errcode = 0;
434  try {
436  } catch (...) {
437  HandleException(errcode, message_buffer, buffer_length);
438  }
439 }
440 EXPORT_CODE double CONVENTION HAPropsSI(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Name3,
441  double Prop3) {
442  fpu_reset_guard guard;
443  return HumidAir::HAPropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
444 }
445 EXPORT_CODE double CONVENTION cair_sat(double T) {
446  fpu_reset_guard guard;
447  return HumidAir::cair_sat(T);
448 }
449 EXPORT_CODE void CONVENTION hapropssi_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
450  const char* Name3, const double* Prop3, double* output) {
451  *output = HAPropsSI(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
452 }
453 EXPORT_CODE double CONVENTION HAProps(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Name3,
454  double Prop3) {
455  fpu_reset_guard guard;
456  try {
457  return HumidAir::HAProps(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
458  } catch (std::exception& e) {
459  CoolProp::set_error_string(e.what());
460  } catch (...) {
461  CoolProp::set_error_string("Undefined error");
462  }
463  return _HUGE;
464 }
465 EXPORT_CODE void CONVENTION haprops_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
466  const char* Name3, const double* Prop3, double* output) {
467  *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
468 }
470 {
471  private:
472  std::map<std::size_t, shared_ptr<CoolProp::AbstractState>> ASlibrary;
473  long next_handle;
474  std::mutex ASLib_mutex;
475 
476  public:
477  AbstractStateLibrary() : next_handle(0){};
478  long add(shared_ptr<CoolProp::AbstractState> AS) {
479  std::lock_guard<std::mutex> guard(ASLib_mutex);
480  ASlibrary.insert(std::pair<std::size_t, shared_ptr<CoolProp::AbstractState>>(this->next_handle, AS));
481  this->next_handle++;
482  return next_handle - 1;
483  }
484  void remove(long handle) {
485  std::lock_guard<std::mutex> guard(ASLib_mutex);
486  std::size_t count_removed = ASlibrary.erase(handle);
487  if (count_removed != 1) {
488  throw CoolProp::HandleError("could not free handle");
489  }
490  }
491  shared_ptr<CoolProp::AbstractState>& get(long handle) {
492  std::lock_guard<std::mutex> guard(ASLib_mutex);
493  std::map<std::size_t, shared_ptr<CoolProp::AbstractState>>::iterator it = ASlibrary.find(handle);
494  if (it != ASlibrary.end()) {
495  return it->second;
496  } else {
497  throw CoolProp::HandleError("could not get handle");
498  }
499  }
500 };
501 static AbstractStateLibrary handle_manager;
502 
503 EXPORT_CODE long CONVENTION AbstractState_factory(const char* backend, const char* fluids, long* errcode, char* message_buffer,
504  const long buffer_length) {
505  *errcode = 0;
506  try {
507  shared_ptr<CoolProp::AbstractState> AS(CoolProp::AbstractState::factory(backend, fluids));
508  return handle_manager.add(AS);
509  } catch (...) {
510  HandleException(errcode, message_buffer, buffer_length);
511  }
512  return -1;
513 }
514 EXPORT_CODE void CONVENTION AbstractState_fluid_names(const long handle, char* fluids, long* errcode, char* message_buffer,
515  const long buffer_length) {
516  *errcode = 0;
517 
518  try {
519  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
520  std::vector<std::string> _fluids = AS->fluid_names();
521  std::string fluidsstring = strjoin(_fluids, CoolProp::get_config_string(LIST_STRING_DELIMITER));
522  if (fluidsstring.size() < static_cast<std::size_t>(buffer_length)) {
523  strcpy(fluids, fluidsstring.c_str());
524  } else {
525  throw CoolProp::ValueError(format("Length of string [%d] is greater than allocated buffer length [%d]", fluidsstring.size(),
526  static_cast<std::size_t>(buffer_length)));
527  }
528 
529  } catch (...) {
530  HandleException(errcode, message_buffer, buffer_length);
531  }
532 }
533 EXPORT_CODE void CONVENTION AbstractState_free(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
534  *errcode = 0;
535  try {
536  handle_manager.remove(handle);
537  } catch (...) {
538  HandleException(errcode, message_buffer, buffer_length);
539  }
540 }
541 EXPORT_CODE void CONVENTION AbstractState_set_fractions(const long handle, const double* fractions, const long N, long* errcode, char* message_buffer,
542  const long buffer_length) {
543  *errcode = 0;
544  std::vector<double> _fractions(fractions, fractions + N);
545  try {
546  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
547  if (AS->using_mole_fractions()) {
548  AS->set_mole_fractions(_fractions);
549  } else if (AS->using_mass_fractions()) {
550  AS->set_mass_fractions(_fractions);
551  } else if (AS->using_volu_fractions()) {
552  AS->set_volu_fractions(_fractions);
553  }
554  } catch (...) {
555  HandleException(errcode, message_buffer, buffer_length);
556  }
557 }
558 EXPORT_CODE void CONVENTION AbstractState_get_mole_fractions(const long handle, double* fractions, const long maxN, long* N, long* errcode,
559  char* message_buffer, const long buffer_length) {
560  *errcode = 0;
561 
562  try {
563  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
564  std::vector<double> _fractions = AS->get_mole_fractions();
565  *N = _fractions.size();
566  if (*N <= maxN) {
567  for (int i = 0; i < *N; i++)
568  fractions[i] = _fractions[i];
569  } else {
570  throw CoolProp::ValueError(format("Length of array [%d] is greater than allocated buffer length [%d]", *N, maxN));
571  }
572  } catch (...) {
573  HandleException(errcode, message_buffer, buffer_length);
574  }
575 }
576 EXPORT_CODE void CONVENTION AbstractState_get_mole_fractions_satState(const long handle, const char* saturated_state, double* fractions,
577  const long maxN, long* N, long* errcode, char* message_buffer,
578  const long buffer_length) {
579  *errcode = 0;
580 
581  try {
582  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
583  std::vector<double> _fractions;
584  double quality = AS->Q();
585  std::string string_state(saturated_state);
586  if (0 <= quality && quality <= 1) {
587  if (string_state == "liquid") {
588  _fractions = AS->mole_fractions_liquid();
589  } else if (string_state == "gas") {
590  _fractions = AS->mole_fractions_vapor();
591  } else {
592  throw CoolProp::ValueError(
593  format("Bad info string [%s] to saturated state mole fractions, options are \"liquid\" and \"gas\"", saturated_state));
594  }
595  } else {
596  throw CoolProp::ValueError(format("AbstractState_get_mole_fractions_satState only returns outputs for saturated states if AbstractState "
597  "quality [%g] is within two-phase region (0 <= quality <= 1)",
598  static_cast<double>(quality)));
599  }
600  *N = _fractions.size();
601  if (*N <= maxN) {
602  for (int i = 0; i < *N; i++) {
603  fractions[i] = _fractions[i];
604  }
605  } else {
606  throw CoolProp::ValueError(format("Length of array [%d] is greater than allocated buffer length [%d]", *N, maxN));
607  }
608  } catch (...) {
609  HandleException(errcode, message_buffer, buffer_length);
610  }
611 }
612 EXPORT_CODE double CONVENTION AbstractState_get_fugacity(const long handle, const long i, long* errcode, char* message_buffer,
613  const long buffer_length) {
614  *errcode = 0;
615  try {
616  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
617  return AS->fugacity(i);
618  } catch (...) {
619  HandleException(errcode, message_buffer, buffer_length);
620  }
621  return _HUGE;
622 }
623 EXPORT_CODE double CONVENTION AbstractState_get_fugacity_coefficient(const long handle, const long i, long* errcode, char* message_buffer,
624  const long buffer_length) {
625  *errcode = 0;
626  try {
627  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
628  return AS->fugacity_coefficient(i);
629  } catch (...) {
630  HandleException(errcode, message_buffer, buffer_length);
631  }
632  return _HUGE;
633 }
634 EXPORT_CODE void CONVENTION AbstractState_update(const long handle, const long input_pair, const double value1, const double value2, long* errcode,
635  char* message_buffer, const long buffer_length) {
636  *errcode = 0;
637  try {
638  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
639  AS->update(static_cast<CoolProp::input_pairs>(input_pair), value1, value2);
640  } catch (...) {
641  HandleException(errcode, message_buffer, buffer_length);
642  }
643 }
644 EXPORT_CODE void CONVENTION AbstractState_specify_phase(const long handle, const char* phase, long* errcode, char* message_buffer,
645  const long buffer_length) {
646  *errcode = 0;
647  try {
648  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
649  return AS->specify_phase(CoolProp::get_phase_index(std::string(phase)));
650  } catch (...) {
651  HandleException(errcode, message_buffer, buffer_length);
652  }
653 }
654 EXPORT_CODE void CONVENTION AbstractState_unspecify_phase(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
655  *errcode = 0;
656  try {
657  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
658  return AS->unspecify_phase();
659  } catch (...) {
660  HandleException(errcode, message_buffer, buffer_length);
661  }
662 }
663 EXPORT_CODE double CONVENTION AbstractState_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
664  const long buffer_length) {
665  *errcode = 0;
666  try {
667  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
668  return AS->keyed_output(static_cast<CoolProp::parameters>(param));
669  } catch (...) {
670  HandleException(errcode, message_buffer, buffer_length);
671  }
672  return _HUGE;
673 }
674 
675 EXPORT_CODE double CONVENTION AbstractState_first_saturation_deriv(const long handle, const long Of, const long Wrt, long* errcode,
676  char* message_buffer, const long buffer_length) {
677  *errcode = 0;
678  try {
679  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
680  return AS->first_saturation_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt));
681  } catch (...) {
682  HandleException(errcode, message_buffer, buffer_length);
683  }
684  return _HUGE;
685 }
686 
687 EXPORT_CODE double CONVENTION AbstractState_first_partial_deriv(const long handle, const long Of, const long Wrt, const long Constant, long* errcode,
688  char* message_buffer, const long buffer_length) {
689  *errcode = 0;
690  try {
691  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
692  return AS->first_partial_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
693  static_cast<CoolProp::parameters>(Constant));
694  } catch (...) {
695  HandleException(errcode, message_buffer, buffer_length);
696  }
697  return _HUGE;
698 }
699 
700 EXPORT_CODE double CONVENTION AbstractState_second_partial_deriv(const long handle, const long Of1, const long Wrt1, const long Constant1,
701  const long Wrt2, const long Constant2, long* errcode, char* message_buffer,
702  const long buffer_length) {
703  *errcode = 0;
704  try {
705  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
706  return AS->second_partial_deriv(static_cast<CoolProp::parameters>(Of1), static_cast<CoolProp::parameters>(Wrt1),
707  static_cast<CoolProp::parameters>(Constant1), static_cast<CoolProp::parameters>(Wrt2),
708  static_cast<CoolProp::parameters>(Constant2));
709  } catch (...) {
710  HandleException(errcode, message_buffer, buffer_length);
711  }
712  return _HUGE;
713 }
714 
715 EXPORT_CODE double CONVENTION AbstractState_second_two_phase_deriv(const long handle, const long Of1, const long Wrt1, const long Constant1,
716  const long Wrt2, const long Constant2, long* errcode, char* message_buffer,
717  const long buffer_length) {
718  *errcode = 0;
719  try {
720  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
721  return AS->second_two_phase_deriv(static_cast<CoolProp::parameters>(Of1), static_cast<CoolProp::parameters>(Wrt1),
722  static_cast<CoolProp::parameters>(Constant1), static_cast<CoolProp::parameters>(Wrt2),
723  static_cast<CoolProp::parameters>(Constant2));
724  } catch (...) {
725  HandleException(errcode, message_buffer, buffer_length);
726  }
727  return _HUGE;
728 }
729 
730 EXPORT_CODE double CONVENTION AbstractState_first_two_phase_deriv(const long handle, const long Of, const long Wrt, const long Constant,
731  long* errcode, char* message_buffer, const long buffer_length) {
732  *errcode = 0;
733  try {
734  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
735  return AS->first_two_phase_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
736  static_cast<CoolProp::parameters>(Constant));
737  } catch (...) {
738  HandleException(errcode, message_buffer, buffer_length);
739  }
740  return _HUGE;
741 }
742 
743 EXPORT_CODE double CONVENTION AbstractState_first_two_phase_deriv_splined(const long handle, const long Of, const long Wrt, const long Constant,
744  const double x_end, long* errcode, char* message_buffer,
745  const long buffer_length) {
746  *errcode = 0;
747  try {
748  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
749  return AS->first_two_phase_deriv_splined(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
750  static_cast<CoolProp::parameters>(Constant), x_end);
751  } catch (...) {
752  HandleException(errcode, message_buffer, buffer_length);
753  }
754  return _HUGE;
755 }
756 
757 
758 EXPORT_CODE void CONVENTION AbstractState_update_and_common_out(const long handle, const long input_pair, const double* value1, const double* value2,
759  const long length, double* T, double* p, double* rhomolar, double* hmolar,
760  double* smolar, long* errcode, char* message_buffer, const long buffer_length) {
761  *errcode = 0;
762  try {
763  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
764 
765  for (int i = 0; i < length; i++) {
766  try {
767  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
768  *(T + i) = AS->T();
769  *(p + i) = AS->p();
770  *(rhomolar + i) = AS->rhomolar();
771  *(hmolar + i) = AS->hmolar();
772  *(smolar + i) = AS->smolar();
773  } catch (...) {
774  }
775  };
776  } catch (...) {
777  HandleException(errcode, message_buffer, buffer_length);
778  }
779 }
780 
781 EXPORT_CODE void CONVENTION AbstractState_update_and_1_out(const long handle, const long input_pair, const double* value1, const double* value2,
782  const long length, const long output, double* out, long* errcode, char* message_buffer,
783  const long buffer_length) {
784  *errcode = 0;
785  try {
786  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
787 
788  for (int i = 0; i < length; i++) {
789  try {
790  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
791  *(out + i) = AS->keyed_output(static_cast<CoolProp::parameters>(output));
792  } catch (...) {
793  }
794  };
795  } catch (...) {
796  HandleException(errcode, message_buffer, buffer_length);
797  }
798 }
799 
800 EXPORT_CODE void CONVENTION AbstractState_update_and_5_out(const long handle, const long input_pair, const double* value1, const double* value2,
801  const long length, long* outputs, double* out1, double* out2, double* out3, double* out4,
802  double* out5, long* errcode, char* message_buffer, const long buffer_length) {
803  *errcode = 0;
804  try {
805  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
806 
807  for (int i = 0; i < length; i++) {
808  try {
809  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
810  *(out1 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[0]));
811  *(out2 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[1]));
812  *(out3 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[2]));
813  *(out4 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[3]));
814  *(out5 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[4]));
815  } catch (...) {
816  }
817  };
818  } catch (...) {
819  HandleException(errcode, message_buffer, buffer_length);
820  }
821 }
822 
823 EXPORT_CODE void CONVENTION AbstractState_set_binary_interaction_double(const long handle, const long i, const long j, const char* parameter,
824  const double value, long* errcode, char* message_buffer,
825  const long buffer_length) {
826  *errcode = 0;
827  try {
828  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
829  AS->set_binary_interaction_double(static_cast<std::size_t>(i), static_cast<std::size_t>(j), parameter, value);
830  } catch (...) {
831  HandleException(errcode, message_buffer, buffer_length);
832  }
833 }
834 
835 EXPORT_CODE void CONVENTION AbstractState_set_cubic_alpha_C(const long handle, const long i, const char* parameter, const double c1, const double c2,
836  const double c3, long* errcode, char* message_buffer, const long buffer_length) {
837  *errcode = 0;
838  try {
839  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
840  AS->set_cubic_alpha_C(static_cast<std::size_t>(i), parameter, c1, c2, c3);
841  } catch (...) {
842  HandleException(errcode, message_buffer, buffer_length);
843  }
844 }
845 
846 EXPORT_CODE void CONVENTION AbstractState_set_fluid_parameter_double(const long handle, const long i, const char* parameter, const double value,
847  long* errcode, char* message_buffer, const long buffer_length) {
848  *errcode = 0;
849  try {
850  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
851  AS->set_fluid_parameter_double(static_cast<std::size_t>(i), parameter, value);
852  } catch (...) {
853  HandleException(errcode, message_buffer, buffer_length);
854  }
855 }
856 
857 EXPORT_CODE void CONVENTION AbstractState_build_phase_envelope(const long handle, const char* level, long* errcode, char* message_buffer,
858  const long buffer_length) {
859  *errcode = 0;
860  try {
861  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
862  AS->build_phase_envelope(level);
863  } catch (...) {
864  HandleException(errcode, message_buffer, buffer_length);
865  }
866 }
867 
868 EXPORT_CODE void CONVENTION AbstractState_get_phase_envelope_data(const long handle, const long length, double* T, double* p, double* rhomolar_vap,
869  double* rhomolar_liq, double* x, double* y, long* errcode, char* message_buffer,
870  const long buffer_length) {
871  *errcode = 0;
872  try {
873  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
874  CoolProp::PhaseEnvelopeData pe = AS->get_phase_envelope_data();
875  if (pe.T.size() > static_cast<std::size_t>(length)) {
876  throw CoolProp::ValueError(format("Length of phase envelope vectors [%d] is greater than allocated buffer length [%d]",
877  static_cast<int>(pe.T.size()), static_cast<int>(length)));
878  }
879  std::size_t N = pe.x.size();
880  for (std::size_t i = 0; i < pe.T.size(); i++) {
881  *(T + i) = pe.T[i];
882  *(p + i) = pe.p[i];
883  *(rhomolar_vap + i) = pe.rhomolar_vap[i];
884  *(rhomolar_liq + i) = pe.rhomolar_liq[i];
885  for (std::size_t j = 0; j < N; ++j) {
886  *(x + i * N + j) = pe.x[j][i];
887  *(y + i * N + j) = pe.y[j][i];
888  }
889  }
890  } catch (...) {
891  HandleException(errcode, message_buffer, buffer_length);
892  }
893 }
894 
895 EXPORT_CODE void CONVENTION AbstractState_get_phase_envelope_data_checkedMemory(const long handle, const long length, const long maxComponents, double* T,
896  double* p, double* rhomolar_vap, double* rhomolar_liq, double* x, double* y,
897  long* actual_length, long* actual_components, long* errcode, char* message_buffer,
898  const long buffer_length) {
899  *errcode = 0;
900  try {
901  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
902  CoolProp::PhaseEnvelopeData pe = AS->get_phase_envelope_data();
903  *actual_length = pe.T.size();
904  if (pe.T.size() > static_cast<std::size_t>(length)) {
905  throw CoolProp::ValueError(format("Length of phase envelope vectors [%d] is greater than allocated buffer length [%d]",
906  static_cast<int>(pe.T.size()), static_cast<int>(length)));
907  }
908  *actual_components = pe.x.size();
909  if (*actual_components > static_cast<std::size_t>(maxComponents)) {
910  throw CoolProp::ValueError(format("Length of phase envelope composition vectors [%d] is greater than allocated buffer length [%d]",
911  static_cast<int>(*actual_components), static_cast<int>(maxComponents)));
912  }
913  for (std::size_t i = 0; i < pe.T.size(); i++) {
914  *(T + i) = pe.T[i];
915  *(p + i) = pe.p[i];
916  *(rhomolar_vap + i) = pe.rhomolar_vap[i];
917  *(rhomolar_liq + i) = pe.rhomolar_liq[i];
918  for (std::size_t j = 0; j < *actual_components; ++j) {
919  *(x + i * *actual_components + j) = pe.x[j][i];
920  *(y + i * *actual_components + j) = pe.y[j][i];
921  }
922  }
923  } catch (...) {
924  HandleException(errcode, message_buffer, buffer_length);
925  }
926 }
927 
928 EXPORT_CODE void CONVENTION AbstractState_build_spinodal(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
929  *errcode = 0;
930  try {
931  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
932  AS->build_spinodal();
933  } catch (...) {
934  HandleException(errcode, message_buffer, buffer_length);
935  }
936 }
937 
938 EXPORT_CODE void CONVENTION AbstractState_get_spinodal_data(const long handle, const long length, double* tau, double* delta, double* M1,
939  long* errcode, char* message_buffer, const long buffer_length) {
940  *errcode = 0;
941  try {
942  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
943  CoolProp::SpinodalData spin = AS->get_spinodal_data();
944  if (spin.tau.size() > static_cast<std::size_t>(length)) {
945  throw CoolProp::ValueError(format("Length of spinodal vectors [%d] is greater than allocated buffer length [%d]",
946  static_cast<int>(spin.tau.size()), static_cast<int>(length)));
947  }
948  for (std::size_t i = 0; i < spin.tau.size(); ++i) {
949  *(tau + i) = spin.tau[i];
950  *(delta + i) = spin.delta[i];
951  *(M1 + i) = spin.M1[i];
952  }
953  } catch (...) {
954  HandleException(errcode, message_buffer, buffer_length);
955  }
956 }
957 
958 EXPORT_CODE void CONVENTION AbstractState_all_critical_points(const long handle, long length, double* T, double* p, double* rhomolar, long* stable,
959  long* errcode, char* message_buffer, const long buffer_length) {
960  *errcode = 0;
961  try {
962  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
963  std::vector<CoolProp::CriticalState> pts = AS->all_critical_points();
964  if (pts.size() > static_cast<std::size_t>(length)) {
965  throw CoolProp::ValueError(format("Length of critical point vector [%d] is greater than allocated buffer length [%d]",
966  static_cast<int>(pts.size()), static_cast<int>(length)));
967  }
968  for (std::size_t i = 0; i < pts.size(); ++i) {
969  *(T + i) = pts[i].T;
970  *(p + i) = pts[i].p;
971  *(rhomolar + i) = pts[i].rhomolar;
972  *(stable + i) = pts[i].stable;
973  }
974  } catch (...) {
975  HandleException(errcode, message_buffer, buffer_length);
976  }
977 }
978 
979 EXPORT_CODE double CONVENTION AbstractState_keyed_output_satState(const long handle, const char* saturated_state, const long param, long* errcode,
980  char* message_buffer, const long buffer_length) {
981  *errcode = 0;
982 
983  try {
984  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
985  double quality = AS->Q();
986  std::string string_state(saturated_state);
987  if (0 <= quality && quality <= 1) {
988  if (string_state == "liquid") {
989  return AS->saturated_liquid_keyed_output(static_cast<CoolProp::parameters>(param));
990  } else if (string_state == "gas") {
991  return AS->saturated_vapor_keyed_output(static_cast<CoolProp::parameters>(param));
992  } else {
993  throw CoolProp::ValueError(
994  format("Bad info string [%s] to saturated state output, options are \"liquid\" and \"gas\"", saturated_state));
995  }
996  } else {
997  throw CoolProp::ValueError(format("AbstractState_keyed_output_satState only returns outputs for saturated states if AbstractState "
998  "quality [%g] is within two-phase region (0 <= quality <= 1)",
999  static_cast<double>(quality)));
1000  }
1001  } catch (...) {
1002  HandleException(errcode, message_buffer, buffer_length);
1003  return _HUGE;
1004  }
1005 }
1006 
1007 EXPORT_CODE void CONVENTION AbstractState_backend_name(const long handle, char* backend, long* errcode, char* message_buffer,
1008  const long buffer_length) {
1009  *errcode = 0;
1010 
1011  try {
1012  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1013  std::string backendstring = AS->backend_name();
1014  if (backendstring.size() < static_cast<std::size_t>(buffer_length)) {
1015  strcpy(backend, backendstring.c_str());
1016  } else {
1017  throw CoolProp::ValueError(format("Length of string [%d] is greater than allocated buffer length [%d]", backendstring.size(),
1018  static_cast<std::size_t>(buffer_length)));
1019  }
1020  } catch (...) {
1021  HandleException(errcode, message_buffer, buffer_length);
1022  }
1023 }
1024 
1025 EXPORT_CODE int CONVENTION AbstractState_phase(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
1026  *errcode = 0;
1027  try {
1028  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1029  return AS->phase();
1030  } catch (...) {
1031  HandleException(errcode, message_buffer, buffer_length);
1032  }
1033  return -1;
1034 }
1035 
1036 EXPORT_CODE void CONVENTION AbstractState_fluid_param_string(const long handle, const char* param, char* return_buffer,
1037  const long return_buffer_length, long* errcode, char* message_buffer,
1038  const long buffer_length) {
1039  *errcode = 0;
1040  try {
1041  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1042  std::string temp = AS->fluid_param_string(param);
1043  if (temp.size() < static_cast<std::size_t>(return_buffer_length)) {
1044  strcpy(return_buffer, temp.c_str());
1045  } else {
1046  *errcode = 2;
1047  }
1048  } catch (...) {
1049  HandleException(errcode, message_buffer, buffer_length);
1050  }
1051 }
1052 
1053 EXPORT_CODE double CONVENTION AbstractState_saturated_liquid_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
1054  const long buffer_length) {
1055  *errcode = 0;
1056  try {
1057  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1058  return AS->saturated_liquid_keyed_output(static_cast<CoolProp::parameters>(param));
1059  } catch (...) {
1060  HandleException(errcode, message_buffer, buffer_length);
1061  }
1062  return _HUGE;
1063 }
1064 
1065 EXPORT_CODE double CONVENTION AbstractState_saturated_vapor_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
1066  const long buffer_length) {
1067  *errcode = 0;
1068  try {
1069  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1070  return AS->saturated_vapor_keyed_output(static_cast<CoolProp::parameters>(param));
1071  } catch (...) {
1072  HandleException(errcode, message_buffer, buffer_length);
1073  }
1074  return _HUGE;
1075 }
1076 
1077 EXPORT_CODE void CONVENTION add_fluids_as_JSON(const char* backend, const char* fluidstring, long* errcode, char* message_buffer,
1078  const long buffer_length) {
1079  *errcode = 0;
1080 
1081  try {
1082  CoolProp::add_fluids_as_JSON(backend, fluidstring);
1083  } catch (...) {
1084  HandleException(errcode, message_buffer, buffer_length);
1085  }
1086 }
1087 
1088 EXPORT_CODE int CONVENTION C_is_valid_fluid_string(const char* fluidName) {
1089  return CoolProp::is_valid_fluid_string(fluidName);
1090 }
1091 
1092 EXPORT_CODE int CONVENTION C_extract_backend(const char* fluid_string, char* backend, const long backend_length, char* fluid,
1093  const long fluid_length) {
1094  std::string _fluid, _backend;
1095  CoolProp::extract_backend(fluid_string, _backend, _fluid);
1096  if (_backend.size() < static_cast<std::size_t>(backend_length)) {
1097  strcpy(backend, _backend.c_str());
1098  } else {
1099  return -1;
1100  }
1101  if (_fluid.size() < static_cast<std::size_t>(fluid_length)) {
1102  strcpy(fluid, _fluid.c_str());
1103  } else {
1104  return -1;
1105  }
1106  return 0;
1107 }