2# define _CRTDBG_MAP_ALLOC
3# define _CRT_SECURE_NO_WARNINGS
24void str2buf(
const std::string& str,
char* buf,
int n) {
25 if (str.size() <
static_cast<unsigned int>(n)) {
26 strncpy(buf, str.c_str(), n - 1);
32void HandleException(
long* errcode,
char* message_buffer,
const long buffer_length) {
36 std::string errmsg = std::string(
"HandleError: ") + e.
what();
37 if (errmsg.size() <
static_cast<std::size_t
>(buffer_length)) {
39 strcpy(message_buffer, errmsg.c_str());
44 std::string errmsg = std::string(
"Error: ") + e.
what();
45 if (errmsg.size() <
static_cast<std::size_t
>(buffer_length)) {
47 strcpy(message_buffer, errmsg.c_str());
65#elif defined(FE_ALL_EXCEPT)
66 feclearexcept(FE_ALL_EXCEPT);
72 std::cout <<
format(
"%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n", __FILE__, __LINE__, iInput, value).c_str();
85 return value * 1000.0;
101 std::cout <<
format(
"%s:%d: convert_from_SI_to_kSI(%d,%g)\n", __FILE__, __LINE__, iInput, value).c_str();
114 return value / 1000.0;
128 FILE* fp = freopen(file,
"a+", stdout);
136 }
catch (std::exception& e) {
148 }
catch (std::exception& e) {
159 double val =
Props1SI(Output, FluidName);
168 return Props(Output, Name1[0], Prop1, Name2[0], Prop2, Ref);
174 std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
186 double val =
PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);
190 }
catch (std::exception& e) {
201 }
catch (std::exception& e) {
213 const long length_fractions,
double* result,
long* resdim1) {
219 if (delim.length() > 1)
221 std::vector<std::string> _outputs =
strsplit(Outputs, delim[0]);
223 std::vector<std::string> _fluidNames =
strsplit(FluidNames, delim[0]);
224 if (_fluidNames.size() != length_fractions)
226 format(
"Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
227 std::vector<double> _fractions(fractions, fractions + length_fractions);
228 std::vector<std::vector<double>> _result =
CoolProp::Props1SImulti(_outputs, backend, _fluidNames, _fractions);
230 if (_result.size() == 0) {
233 if (_result.size() >
static_cast<size_t>(*resdim1))
235 *resdim1 =
static_cast<long>(_result[0].size());
236 for (
size_t i = 0; i < _result[0].size(); i++) {
237 result[i] = _result[0][i];
240 }
catch (std::exception& e) {
248 return CoolProp::PropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
251 double* Prop2,
const long size_Prop2,
char* backend,
const char* FluidNames,
const double* fractions,
252 const long length_fractions,
double* result,
long* resdim1,
long* resdim2) {
258 if (delim.length() > 1)
260 std::vector<std::string> _outputs =
strsplit(Outputs, delim[0]);
261 if (size_Prop1 != size_Prop2)
263 format(
"Length of input parameter 1 [%d] is not equal to length of input parameter 2 [%d]", size_Prop1, size_Prop2));
265 std::vector<double> _prop1(Prop1, Prop1 + size_Prop1);
266 std::vector<double> _prop2(Prop2, Prop2 + size_Prop2);
268 std::vector<std::string> _fluidNames =
strsplit(FluidNames, delim[0]);
269 if (_fluidNames.size() != length_fractions)
271 format(
"Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
272 std::vector<double> _fractions(fractions, fractions + length_fractions);
273 std::vector<std::vector<double>> _result =
274 CoolProp::PropsSImulti(_outputs, std::string(Name1), _prop1, std::string(Name2), _prop2, backend, _fluidNames, _fractions);
276 if (_result.size() == 0) {
280 if (_result.size() >
static_cast<size_t>(*resdim1) || _result[0].size() >
static_cast<size_t>(*resdim2))
282 format(
"Result matrix [%d x %d] is bigger than allocated memory [%d x %d]", _result.size(), _result[0].size(), *resdim1, *resdim2));
283 *resdim1 =
static_cast<long>(_result.size());
284 *resdim2 =
static_cast<long>(_result[0].size());
285 for (
size_t i = 0; i < _result.size(); i++) {
286 for (
size_t j = 0; j < _result[i].size(); j++) {
287 result[j + _result[i].size() * i] = _result[i][j];
291 }
catch (std::exception& e) {
306 std::string s =
CoolProp::PhaseSI(std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
309 }
catch (std::exception& e) {
326 const char* FluidName,
double* output) {
327 *output =
PropsSI(Output, Name1, *Prop1, Name2, *Prop2, FluidName);
331 return T * 9 / 5 - 459.67;
334 return (T_F + 459.67) * 5 / 9;
345 }
catch (std::exception& e) {
355 }
catch (std::exception& e) {
367 }
catch (std::exception& e) {
380 }
catch (std::exception& e) {
400 }
catch (std::exception& e) {
410 return static_cast<long>(s.size());
411 }
catch (std::exception& e) {
421 }
catch (std::exception& e) {
430 }
catch (std::exception& e) {
439 }
catch (std::exception& e) {
456 return HumidAir::HAPropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
463 const char* Name3,
const double* Prop3,
double* output) {
464 *output =
HAPropsSI(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
470 return HumidAir::HAProps(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
471 }
catch (std::exception& e) {
479 const char* Name3,
const double* Prop3,
double* output) {
480 *output =
HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
485 std::map<std::size_t, shared_ptr<CoolProp::AbstractState>> ASlibrary;
487 std::mutex ASLib_mutex;
491 long add(shared_ptr<CoolProp::AbstractState> AS) {
492 std::lock_guard<std::mutex> guard(ASLib_mutex);
493 ASlibrary.insert(std::pair<std::size_t, shared_ptr<CoolProp::AbstractState>>(this->next_handle, AS));
495 return next_handle - 1;
498 std::lock_guard<std::mutex> guard(ASLib_mutex);
499 std::size_t count_removed = ASlibrary.erase(handle);
500 if (count_removed != 1) {
504 shared_ptr<CoolProp::AbstractState>&
get(
long handle) {
505 std::lock_guard<std::mutex> guard(ASLib_mutex);
506 std::map<std::size_t, shared_ptr<CoolProp::AbstractState>>::iterator it = ASlibrary.find(handle);
507 if (it != ASlibrary.end()) {
517 const long buffer_length) {
521 return handle_manager.
add(AS);
528 const long buffer_length) {
532 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
533 std::vector<std::string> _fluids = AS->fluid_names();
535 if (fluidsstring.size() <
static_cast<std::size_t
>(buffer_length)) {
536 strcpy(fluids, fluidsstring.c_str());
539 static_cast<std::size_t
>(buffer_length)));
549 handle_manager.
remove(handle);
555 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) {
576 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
577 std::vector<double> _fractions = AS->get_mole_fractions();
578 *N =
static_cast<long>(_fractions.size());
580 for (
int i = 0; i < *N; i++)
581 fractions[i] = _fractions[i];
590 const long maxN,
long* N,
long* errcode,
char* message_buffer,
591 const long buffer_length) {
595 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
596 std::vector<double> _fractions;
597 double quality = AS->Q();
598 std::string string_state(saturated_state);
599 if (0 <= quality && quality <= 1) {
600 if (string_state ==
"liquid") {
601 _fractions = AS->mole_fractions_liquid();
602 }
else if (string_state ==
"gas") {
603 _fractions = AS->mole_fractions_vapor();
606 format(
"Bad info string [%s] to saturated state mole fractions, options are \"liquid\" and \"gas\"", saturated_state));
609 throw CoolProp::ValueError(
format(
"AbstractState_get_mole_fractions_satState only returns outputs for saturated states if AbstractState "
610 "quality [%g] is within two-phase region (0 <= quality <= 1)",
611 static_cast<double>(quality)));
613 *N =
static_cast<long>(_fractions.size());
615 for (
int i = 0; i < *N; i++) {
616 fractions[i] = _fractions[i];
626 const long buffer_length) {
629 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
630 return AS->fugacity(i);
637 const long buffer_length) {
640 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
641 return AS->fugacity_coefficient(i);
648 char* message_buffer,
const long buffer_length) {
651 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
658 const long buffer_length) {
661 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
670 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
671 return AS->unspecify_phase();
677 const long buffer_length) {
680 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
689 char* message_buffer,
const long buffer_length) {
692 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
701 char* message_buffer,
const long buffer_length) {
704 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
714 const long Wrt2,
const long Constant2,
long* errcode,
char* message_buffer,
715 const long buffer_length) {
718 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
729 const long Wrt2,
const long Constant2,
long* errcode,
char* message_buffer,
730 const long buffer_length) {
733 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
744 long* errcode,
char* message_buffer,
const long buffer_length) {
747 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
757 const double x_end,
long* errcode,
char* message_buffer,
758 const long buffer_length) {
761 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
771 const long length,
double* T,
double* p,
double* rhomolar,
double* hmolar,
772 double* smolar,
long* errcode,
char* message_buffer,
const long buffer_length) {
775 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
777 for (
int i = 0; i < length; i++) {
782 *(rhomolar + i) = AS->rhomolar();
783 *(hmolar + i) = AS->hmolar();
784 *(smolar + i) = AS->smolar();
794 const long length,
const long output,
double* out,
long* errcode,
char* message_buffer,
795 const long buffer_length) {
798 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
800 for (
int i = 0; i < length; i++) {
813 const long length,
long* outputs,
double* out1,
double* out2,
double* out3,
double* out4,
814 double* out5,
long* errcode,
char* message_buffer,
const long buffer_length) {
817 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
819 for (
int i = 0; i < length; i++) {
836 const double value,
long* errcode,
char* message_buffer,
837 const long buffer_length) {
840 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
841 AS->set_binary_interaction_double(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(j), parameter, value);
848 const double c3,
long* errcode,
char* message_buffer,
const long buffer_length) {
851 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
852 AS->set_cubic_alpha_C(
static_cast<std::size_t
>(i), parameter, c1, c2, c3);
859 long* errcode,
char* message_buffer,
const long buffer_length) {
862 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
863 AS->set_fluid_parameter_double(
static_cast<std::size_t
>(i), parameter, value);
870 const long buffer_length) {
873 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
874 AS->build_phase_envelope(level);
881 double* rhomolar_liq,
double* x,
double* y,
long* errcode,
char* message_buffer,
882 const long buffer_length) {
885 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
887 if (pe.T.size() >
static_cast<std::size_t
>(length)) {
889 static_cast<int>(pe.T.size()),
static_cast<int>(length)));
891 std::size_t N = pe.x.size();
892 for (std::size_t i = 0; i < pe.T.size(); i++) {
895 *(rhomolar_vap + i) = pe.rhomolar_vap[i];
896 *(rhomolar_liq + i) = pe.rhomolar_liq[i];
897 for (std::size_t j = 0; j < N; ++j) {
898 *(x + i * N + j) = pe.x[j][i];
899 *(y + i * N + j) = pe.y[j][i];
908 double* T,
double* p,
double* rhomolar_vap,
double* rhomolar_liq,
909 double* x,
double* y,
long* actual_length,
long* actual_components,
910 long* errcode,
char* message_buffer,
const long buffer_length) {
913 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
915 *actual_length =
static_cast<long>(pe.T.size());
916 if (pe.T.size() >
static_cast<std::size_t
>(length)) {
918 static_cast<int>(pe.T.size()),
static_cast<int>(length)));
920 *actual_components =
static_cast<long>(pe.x.size());
921 if (
static_cast<std::size_t
>(*actual_components) >
static_cast<std::size_t
>(maxComponents)) {
922 throw CoolProp::ValueError(
format(
"Length of phase envelope composition vectors [%d] is greater than allocated buffer length [%d]",
923 static_cast<int>(*actual_components),
static_cast<int>(maxComponents)));
925 for (std::size_t i = 0; i < pe.T.size(); i++) {
928 *(rhomolar_vap + i) = pe.rhomolar_vap[i];
929 *(rhomolar_liq + i) = pe.rhomolar_liq[i];
930 for (std::size_t j = 0; j < static_cast<std::size_t>(*actual_components); ++j) {
931 *(x + i * *actual_components + j) = pe.x[j][i];
932 *(y + i * *actual_components + j) = pe.y[j][i];
943 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
944 AS->build_spinodal();
951 long* errcode,
char* message_buffer,
const long buffer_length) {
954 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
956 if (spin.
tau.size() >
static_cast<std::size_t
>(length)) {
958 static_cast<int>(spin.
tau.size()),
static_cast<int>(length)));
960 for (std::size_t i = 0; i < spin.
tau.size(); ++i) {
961 *(tau + i) = spin.
tau[i];
962 *(delta + i) = spin.
delta[i];
963 *(M1 + i) = spin.
M1[i];
971 long* errcode,
char* message_buffer,
const long buffer_length) {
974 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
975 std::vector<CoolProp::CriticalState> pts = AS->all_critical_points();
976 if (pts.size() >
static_cast<std::size_t
>(length)) {
978 static_cast<int>(pts.size()),
static_cast<int>(length)));
980 for (std::size_t i = 0; i < pts.size(); ++i) {
983 *(rhomolar + i) = pts[i].rhomolar;
984 *(stable + i) = pts[i].stable;
992 char* message_buffer,
const long buffer_length) {
996 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
997 double quality = AS->Q();
998 std::string string_state(saturated_state);
999 if (0 <= quality && quality <= 1) {
1000 if (string_state ==
"liquid") {
1002 }
else if (string_state ==
"gas") {
1006 format(
"Bad info string [%s] to saturated state output, options are \"liquid\" and \"gas\"", saturated_state));
1009 throw CoolProp::ValueError(
format(
"AbstractState_keyed_output_satState only returns outputs for saturated states if AbstractState "
1010 "quality [%g] is within two-phase region (0 <= quality <= 1)",
1011 static_cast<double>(quality)));
1020 const long buffer_length) {
1024 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1025 std::string backendstring = AS->backend_name();
1026 if (backendstring.size() <
static_cast<std::size_t
>(buffer_length)) {
1027 strcpy(backend, backendstring.c_str());
1029 throw CoolProp::ValueError(
format(
"Length of string [%d] is greater than allocated buffer length [%d]", backendstring.size(),
1030 static_cast<std::size_t
>(buffer_length)));
1040 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1049 const long return_buffer_length,
long* errcode,
char* message_buffer,
1050 const long buffer_length) {
1053 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1054 std::string temp = AS->fluid_param_string(param);
1055 if (temp.size() <
static_cast<std::size_t
>(return_buffer_length)) {
1056 strcpy(return_buffer, temp.c_str());
1066 const long buffer_length) {
1069 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1078 const long buffer_length) {
1081 shared_ptr<CoolProp::AbstractState>& AS = handle_manager.
get(handle);
1090 const long buffer_length) {
1105 const long fluid_length) {
1106 std::string _fluid, _backend;
1108 if (_backend.size() <
static_cast<std::size_t
>(backend_length)) {
1109 strcpy(backend, _backend.c_str());
1113 if (_fluid.size() <
static_cast<std::size_t
>(fluid_length)) {
1114 strcpy(fluid, _fluid.c_str());