2# define _CRTDBG_MAP_ALLOC
3# define _CRT_SECURE_NO_WARNINGS
25void str2buf(
const std::string& str,
char* buf,
int n) {
26 if (str.size() <
static_cast<unsigned int>(n)) {
27 strncpy(buf, str.c_str(), n - 1);
30 throw CoolProp::ValueError(
"Buffer is too small; must be at least " + std::to_string(str.size()) +
" characters in size");
33void HandleException(
long* errcode,
char* message_buffer,
const long buffer_length) {
37 std::string errmsg = std::string(
"HandleError: ") + e.
what();
38 if (errmsg.size() <
static_cast<std::size_t
>(buffer_length)) {
40 std::memcpy(message_buffer, errmsg.c_str(), errmsg.size() + 1);
45 std::string errmsg = std::string(
"Error: ") + e.
what();
46 if (errmsg.size() <
static_cast<std::size_t
>(buffer_length)) {
48 std::memcpy(message_buffer, errmsg.c_str(), errmsg.size() + 1);
67 std::cout <<
format(
"%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n", __FILE__, __LINE__, iInput, value).c_str();
80 return value * 1000.0;
96 std::cout <<
format(
"%s:%d: convert_from_SI_to_kSI(%d,%g)\n", __FILE__, __LINE__, iInput, value).c_str();
109 return value / 1000.0;
123 FILE* fp = freopen(file,
"a+", stdout);
131 }
catch (std::exception& e) {
143 }
catch (std::exception& e) {
154 double val =
Props1SI(Output, FluidName);
163 return Props(Output, Name1[0], Prop1, Name2[0], Prop2, Ref);
169 std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
181 double val =
PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);
185 }
catch (std::exception& e) {
196 }
catch (std::exception& e) {
208 const long length_fractions,
double* result,
long* resdim1) {
214 if (delim.length() > 1)
216 std::vector<std::string> _outputs =
strsplit(Outputs, delim[0]);
218 std::vector<std::string> _fluidNames =
strsplit(FluidNames, delim[0]);
219 if (_fluidNames.size() != length_fractions)
221 format(
"Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
222 std::vector<double> _fractions(fractions, fractions + length_fractions);
223 std::vector<std::vector<double>> _result =
CoolProp::Props1SImulti(_outputs, backend, _fluidNames, _fractions);
225 if (_result.size() == 0) {
228 if (_result.size() >
static_cast<size_t>(*resdim1))
230 *resdim1 =
static_cast<long>(_result[0].size());
231 for (
size_t i = 0; i < _result[0].size(); i++) {
232 result[i] = _result[0][i];
235 }
catch (std::exception& e) {
243 return CoolProp::PropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
246 double* Prop2,
const long size_Prop2,
char* backend,
const char* FluidNames,
const double* fractions,
247 const long length_fractions,
double* result,
long* resdim1,
long* resdim2) {
253 if (delim.length() > 1)
255 std::vector<std::string> _outputs =
strsplit(Outputs, delim[0]);
256 if (size_Prop1 != size_Prop2)
258 format(
"Length of input parameter 1 [%d] is not equal to length of input parameter 2 [%d]", size_Prop1, size_Prop2));
260 std::vector<double> _prop1(Prop1, Prop1 + size_Prop1);
261 std::vector<double> _prop2(Prop2, Prop2 + size_Prop2);
263 std::vector<std::string> _fluidNames =
strsplit(FluidNames, delim[0]);
264 if (_fluidNames.size() != length_fractions)
266 format(
"Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
267 std::vector<double> _fractions(fractions, fractions + length_fractions);
268 std::vector<std::vector<double>> _result =
269 CoolProp::PropsSImulti(_outputs, std::string(Name1), _prop1, std::string(Name2), _prop2, backend, _fluidNames, _fractions);
271 if (_result.size() == 0) {
275 if (_result.size() >
static_cast<size_t>(*resdim1) || _result[0].size() >
static_cast<size_t>(*resdim2))
277 format(
"Result matrix [%d x %d] is bigger than allocated memory [%d x %d]", _result.size(), _result[0].size(), *resdim1, *resdim2));
278 *resdim1 =
static_cast<long>(_result.size());
279 *resdim2 =
static_cast<long>(_result[0].size());
280 for (
size_t i = 0; i < _result.size(); i++) {
281 for (
size_t j = 0; j < _result[i].size(); j++) {
282 result[j + _result[i].size() * i] = _result[i][j];
286 }
catch (std::exception& e) {
301 std::string s =
CoolProp::PhaseSI(std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
304 }
catch (std::exception& e) {
321 const char* FluidName,
double* output) {
322 *output =
PropsSI(Output, Name1, *Prop1, Name2, *Prop2, FluidName);
326 return T * 9 / 5 - 459.67;
329 return (T_F + 459.67) * 5 / 9;
340 }
catch (std::exception& e) {
350 }
catch (std::exception& e) {
362 }
catch (std::exception& e) {
375 }
catch (std::exception& e) {
395 }
catch (std::exception& e) {
405 return static_cast<long>(s.size());
406 }
catch (std::exception& e) {
416 }
catch (std::exception& e) {
425 }
catch (std::exception& e) {
434 }
catch (std::exception& e) {
452 return HumidAir::HAPropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
459 const char* Name3,
const double* Prop3,
double* output) {
460 *output =
HAPropsSI(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
466 return HumidAir::HAProps(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
467 }
catch (std::exception& e) {
475 const char* Name3,
const double* Prop3,
double* output) {
476 *output =
HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
481 std::map<std::size_t, shared_ptr<CoolProp::AbstractState>> ASlibrary;
482 long next_handle = 0;
483 std::mutex ASLib_mutex;
487 long add(
const shared_ptr<CoolProp::AbstractState>& AS) {
488 std::scoped_lock guard(ASLib_mutex);
489 ASlibrary.insert(std::pair<std::size_t, shared_ptr<CoolProp::AbstractState>>(this->next_handle, AS));
491 return next_handle - 1;
494 std::scoped_lock guard(ASLib_mutex);
495 std::size_t count_removed = ASlibrary.erase(handle);
496 if (count_removed != 1) {
500 shared_ptr<CoolProp::AbstractState>&
get(
long handle) {
501 std::scoped_lock guard(ASLib_mutex);
502 auto it = ASlibrary.find(handle);
503 if (it != ASlibrary.end()) {
513 const long buffer_length) {
518 return handle_manager.
add(AS);
525 const long buffer_length) {
530 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
531 std::vector<std::string> _fluids = AS->fluid_names();
533 if (fluidsstring.size() <
static_cast<std::size_t
>(buffer_length)) {
534 std::memcpy(fluids, fluidsstring.c_str(), fluidsstring.size() + 1);
537 static_cast<std::size_t
>(buffer_length)));
548 handle_manager.
remove(handle);
554 const long buffer_length) {
557 std::vector<double> _fractions(fractions, fractions + N);
559 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
560 if (AS->using_mole_fractions()) {
561 AS->set_mole_fractions(_fractions);
562 }
else if (AS->using_mass_fractions()) {
563 AS->set_mass_fractions(_fractions);
564 }
else if (AS->using_volu_fractions()) {
565 AS->set_volu_fractions(_fractions);
572 char* message_buffer,
const long buffer_length) {
577 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
578 std::vector<double> _fractions = AS->get_mole_fractions();
579 *N =
static_cast<long>(_fractions.size());
581 for (
int i = 0; i < *N; i++)
582 fractions[i] = _fractions[i];
591 const long maxN,
long* N,
long* errcode,
char* message_buffer,
592 const long buffer_length) {
597 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
598 std::vector<double> _fractions;
599 double quality = AS->Q();
600 std::string string_state(saturated_state);
601 if (0 <= quality && quality <= 1) {
602 if (string_state ==
"liquid") {
603 _fractions = AS->mole_fractions_liquid();
604 }
else if (string_state ==
"gas") {
605 _fractions = AS->mole_fractions_vapor();
608 format(R
"(Bad info string [%s] to saturated state mole fractions, options are "liquid" and "gas")", saturated_state));
611 throw CoolProp::ValueError(
format(
"AbstractState_get_mole_fractions_satState only returns outputs for saturated states if AbstractState "
612 "quality [%g] is within two-phase region (0 <= quality <= 1)",
613 static_cast<double>(quality)));
615 *N =
static_cast<long>(_fractions.size());
617 for (
int i = 0; i < *N; i++) {
618 fractions[i] = _fractions[i];
628 const long buffer_length) {
632 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
633 return AS->fugacity(i);
640 const long buffer_length) {
644 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
645 return AS->fugacity_coefficient(i);
652 char* message_buffer,
const long buffer_length) {
656 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
663 const long buffer_length) {
667 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
677 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
678 return AS->unspecify_phase();
684 const long buffer_length) {
688 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
697 char* message_buffer,
const long buffer_length) {
701 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
710 char* message_buffer,
const long buffer_length) {
714 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
724 const long Wrt2,
const long Constant2,
long* errcode,
char* message_buffer,
725 const long buffer_length) {
729 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
740 const long Wrt2,
const long Constant2,
long* errcode,
char* message_buffer,
741 const long buffer_length) {
745 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
756 long* errcode,
char* message_buffer,
const long buffer_length) {
760 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
770 const double x_end,
long* errcode,
char* message_buffer,
771 const long buffer_length) {
775 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
785 const long length,
double*
T,
double* p,
double* rhomolar,
double* hmolar,
786 double* smolar,
long* errcode,
char* message_buffer,
const long buffer_length) {
790 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
792 for (
int i = 0; i < length; i++) {
797 *(rhomolar + i) = AS->rhomolar();
798 *(hmolar + i) = AS->hmolar();
799 *(smolar + i) = AS->smolar();
813 const long length,
const long output,
double* out,
long* errcode,
char* message_buffer,
814 const long buffer_length) {
818 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
820 for (
int i = 0; i < length; i++) {
837 const long length,
long* outputs,
double* out1,
double* out2,
double* out3,
double* out4,
838 double* out5,
long* errcode,
char* message_buffer,
const long buffer_length) {
842 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
844 for (
int i = 0; i < length; i++) {
865 const double value,
long* errcode,
char* message_buffer,
866 const long buffer_length) {
870 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
871 AS->set_binary_interaction_double(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(j), parameter, value);
878 const double c3,
long* errcode,
char* message_buffer,
const long buffer_length) {
882 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
883 AS->set_cubic_alpha_C(
static_cast<std::size_t
>(i), parameter, c1, c2, c3);
890 long* errcode,
char* message_buffer,
const long buffer_length) {
894 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
895 AS->set_fluid_parameter_double(
static_cast<std::size_t
>(i), parameter, value);
902 const long buffer_length) {
906 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
907 AS->build_phase_envelope(level);
914 double* rhomolar_liq,
double* x,
double* y,
long* errcode,
char* message_buffer,
915 const long buffer_length) {
919 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
921 if (pe.T.size() >
static_cast<std::size_t
>(length)) {
923 static_cast<int>(pe.T.size()),
static_cast<int>(length)));
925 std::size_t N = pe.x.size();
926 for (std::size_t i = 0; i < pe.T.size(); i++) {
929 *(rhomolar_vap + i) = pe.rhomolar_vap[i];
930 *(rhomolar_liq + i) = pe.rhomolar_liq[i];
931 for (std::size_t j = 0; j < N; ++j) {
932 *(x + i * N + j) = pe.x[j][i];
933 *(y + i * N + j) = pe.y[j][i];
942 double*
T,
double* p,
double* rhomolar_vap,
double* rhomolar_liq,
943 double* x,
double* y,
long* actual_length,
long* actual_components,
944 long* errcode,
char* message_buffer,
const long buffer_length) {
948 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
950 *actual_length =
static_cast<long>(pe.T.size());
951 if (pe.T.size() >
static_cast<std::size_t
>(length)) {
953 static_cast<int>(pe.T.size()),
static_cast<int>(length)));
955 *actual_components =
static_cast<long>(pe.x.size());
956 if (
static_cast<std::size_t
>(*actual_components) >
static_cast<std::size_t
>(maxComponents)) {
957 throw CoolProp::ValueError(
format(
"Length of phase envelope composition vectors [%d] is greater than allocated buffer length [%d]",
958 static_cast<int>(*actual_components),
static_cast<int>(maxComponents)));
960 for (std::size_t i = 0; i < pe.T.size(); i++) {
963 *(rhomolar_vap + i) = pe.rhomolar_vap[i];
964 *(rhomolar_liq + i) = pe.rhomolar_liq[i];
965 for (std::size_t j = 0; j < static_cast<std::size_t>(*actual_components); ++j) {
966 *(x + i * *actual_components + j) = pe.x[j][i];
967 *(y + i * *actual_components + j) = pe.y[j][i];
979 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
980 AS->build_spinodal();
987 long* errcode,
char* message_buffer,
const long buffer_length) {
991 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
993 if (spin.
tau.size() >
static_cast<std::size_t
>(length)) {
995 static_cast<int>(spin.
tau.size()),
static_cast<int>(length)));
997 for (std::size_t i = 0; i < spin.
tau.size(); ++i) {
998 *(tau + i) = spin.
tau[i];
999 *(delta + i) = spin.
delta[i];
1000 *(M1 + i) = spin.
M1[i];
1008 long* errcode,
char* message_buffer,
const long buffer_length) {
1012 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1013 std::vector<CoolProp::CriticalState> pts = AS->all_critical_points();
1014 if (pts.size() >
static_cast<std::size_t
>(length)) {
1016 static_cast<int>(pts.size()),
static_cast<int>(length)));
1018 for (std::size_t i = 0; i < pts.size(); ++i) {
1019 *(
T + i) = pts[i].
T;
1020 *(p + i) = pts[i].p;
1021 *(rhomolar + i) = pts[i].rhomolar;
1022 *(stable + i) =
static_cast<long>(pts[i].stable);
1030 char* message_buffer,
const long buffer_length) {
1035 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1036 double quality = AS->Q();
1037 std::string string_state(saturated_state);
1038 if (0 <= quality && quality <= 1) {
1039 if (string_state ==
"liquid") {
1041 }
else if (string_state ==
"gas") {
1045 format(R
"(Bad info string [%s] to saturated state output, options are "liquid" and "gas")", saturated_state));
1048 throw CoolProp::ValueError(
format(
"AbstractState_keyed_output_satState only returns outputs for saturated states if AbstractState "
1049 "quality [%g] is within two-phase region (0 <= quality <= 1)",
1050 static_cast<double>(quality)));
1059 const long buffer_length) {
1064 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1065 std::string backendstring = AS->backend_name();
1066 if (backendstring.size() <
static_cast<std::size_t
>(buffer_length)) {
1067 std::memcpy(backend, backendstring.c_str(), backendstring.size() + 1);
1069 throw CoolProp::ValueError(
format(
"Length of string [%d] is greater than allocated buffer length [%d]", backendstring.size(),
1070 static_cast<std::size_t
>(buffer_length)));
1081 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1090 const long return_buffer_length,
long* errcode,
char* message_buffer,
1091 const long buffer_length) {
1095 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1096 std::string temp = AS->fluid_param_string(param);
1097 if (temp.size() <
static_cast<std::size_t
>(return_buffer_length)) {
1098 std::memcpy(return_buffer, temp.c_str(), temp.size() + 1);
1108 const long buffer_length) {
1112 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1121 const long buffer_length) {
1125 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1134 const long buffer_length) {
1150 const long fluid_length) {
1151 std::string _fluid, _backend;
1153 if (_backend.size() <
static_cast<std::size_t
>(backend_length)) {
1154 std::memcpy(backend, _backend.c_str(), _backend.size() + 1);
1158 if (_fluid.size() <
static_cast<std::size_t
>(fluid_length)) {
1159 std::memcpy(fluid, _fluid.c_str(), _fluid.size() + 1);