8#ifndef _CRT_SECURE_NO_WARNINGS
9#define _CRT_SECURE_NO_WARNINGS
22#if !defined(NO_TABULAR_BACKENDS)
35 std::map<backend_families, shared_ptr<AbstractStateGenerator>>
backends;
42 std::map<
backend_families, shared_ptr<AbstractStateGenerator>>::const_iterator& generator,
43 std::map<
backend_families, shared_ptr<AbstractStateGenerator>>::const_iterator& end) {
64 if (fluid_names.size() == 1) {
65 const std::string str = fluid_names[0];
66 if ((
upper(str) ==
"WATER") || (
upper(str) ==
"H2O")) {
69 throw ValueError(
format(
"The IF97 backend returns Water props only; fluid name [%s] not allowed", fluid_names[0].c_str()));
72 throw ValueError(
format(
"The IF97 backend does not support mixtures, only Water"));
98 if (fluid_names.size() != 1) {
99 throw ValueError(
format(
"For INCOMP backend, name vector must be one element long"));
135 std::map<backend_families, shared_ptr<AbstractStateGenerator>>::const_iterator gen, end;
144 return gen->second->get_AbstractState(
fluid_names);
146#if !defined(NO_TABULAR_BACKENDS)
157 else if (backend ==
"?" || backend.empty()) {
158 const std::size_t idel =
fluid_names[0].find(
"::");
160 if (idel == std::string::npos)
170 throw ValueError(
format(
"Invalid backend name [%s] to factory function", backend.c_str()));
203 switch (input_pair) {
225 switch (input_pair) {
571 return -3.0 * (Ar01 - Ar11) / Ar20;
711 R = AS.
gas_constant(), delta = rho / rhor, tau = Tr / T;
777 const double dTau_dT = 1 / dT_dtau;
781 const double dDelta_drho = 1 / rhor;
815 dT = R / T * pow(tau, 2)
824 dT -= ((R / rho * delta
832 drho = R / rho * delta
858 const double dbb_dTau =
861 dT = 1.0 / 2.0 / w / T
865 - (2 * aa / bb * daa_dTau - pow(aa / bb, 2) * dbb_dTau)));
867 const double daa_dDelta =
870 drho = R * T / 2.0 / AS.
molar_mass() / w / rhor
873 - (2 * aa / bb * daa_dDelta - pow(aa / bb, 2) * dbb_dDelta));
896 dT2 = 2 * Tr / pow(T, 3);
919 dT2 = R / T * pow(tau, 2)
923 drho_dT = R / rho * delta
968 CoolPropDbl dOf_dT, dOf_drho, dWrt_dT, dWrt_drho, dConstant_dT, dConstant_drho;
972 get_dT_drho(*
this, Constant, dConstant_dT, dConstant_drho);
974 return (dOf_dT * dConstant_drho - dOf_drho * dConstant_dT) / (dWrt_dT * dConstant_drho - dWrt_drho * dConstant_dT);
977 CoolPropDbl dOf1_dT, dOf1_drho, dWrt1_dT, dWrt1_drho, dConstant1_dT, dConstant1_drho, d2Of1_dT2, d2Of1_drhodT, d2Of1_drho2, d2Wrt1_dT2,
978 d2Wrt1_drhodT, d2Wrt1_drho2, d2Constant1_dT2, d2Constant1_drhodT, d2Constant1_drho2, dWrt2_dT, dWrt2_drho, dConstant2_dT, dConstant2_drho, N, D,
979 dNdrho__T, dDdrho__T, dNdT__rho, dDdT__rho, dderiv1_drho, dderiv1_dT, second;
984 get_dT_drho(*
this, Constant1, dConstant1_dT, dConstant1_drho);
991 get_dT_drho(*
this, Constant2, dConstant2_dT, dConstant2_drho);
994 N = dOf1_dT * dConstant1_drho - dOf1_drho * dConstant1_dT;
995 D = dWrt1_dT * dConstant1_drho - dWrt1_drho * dConstant1_dT;
999 dNdrho__T = dOf1_dT * d2Constant1_drho2 + d2Of1_drhodT * dConstant1_drho - dOf1_drho * d2Constant1_drhodT - d2Of1_drho2 * dConstant1_dT;
1000 dDdrho__T = dWrt1_dT * d2Constant1_drho2 + d2Wrt1_drhodT * dConstant1_drho - dWrt1_drho * d2Constant1_drhodT - d2Wrt1_drho2 * dConstant1_dT;
1004 dNdT__rho = dOf1_dT * d2Constant1_drhodT + d2Of1_dT2 * dConstant1_drho - dOf1_drho * d2Constant1_dT2 - d2Of1_drhodT * dConstant1_dT;
1005 dDdT__rho = dWrt1_dT * d2Constant1_drhodT + d2Wrt1_dT2 * dConstant1_drho - dWrt1_drho * d2Constant1_dT2 - d2Wrt1_drhodT * dConstant1_dT;
1008 dderiv1_drho = (D * dNdrho__T - N * dDdrho__T) / pow(D, 2);
1011 dderiv1_dT = (D * dNdT__rho - N * dDdT__rho) / pow(D, 2);
1014 second = (dderiv1_dT * dConstant2_drho - dderiv1_drho * dConstant2_dT) / (dWrt2_dT * dConstant2_drho - dWrt2_drho * dConstant2_dT);
1032#include <catch2/catch_all.hpp>
1034TEST_CASE(
"Check AbstractState",
"[AbstractState]") {
1035 SECTION(
"bad backend") {
1038 SECTION(
"good backend - bad fluid") {
1041 SECTION(
"good backend - helmholtz") {
1044 SECTION(
"good backend - incomp") {
1047 SECTION(
"good backend - REFPROP") {
1052TEST_CASE(
"Check derivatives in first_partial_deriv",
"[derivs_in_first_partial_deriv]") {
1059 double dT = 1e-3, drho = 1;
1067 CoolPropDbl dP_dT_num = (WaterplusT->p() - WaterminusT->p()) / (2 * dT);
1068 CoolPropDbl dP_drho_num = (Waterplusrho->p() - Waterminusrho->p()) / (2 * drho);
1070 CoolPropDbl dHmolar_dT_num = (WaterplusT->hmolar() - WaterminusT->hmolar()) / (2 * dT);
1071 CoolPropDbl dHmolar_drho_num = (Waterplusrho->hmolar() - Waterminusrho->hmolar()) / (2 * drho);
1072 CoolPropDbl dHmass_dT_num = (WaterplusT->hmass() - WaterminusT->hmass()) / (2 * dT);
1073 CoolPropDbl dHmass_drho_num = (Waterplusrho->hmass() - Waterminusrho->hmass()) / (2 * drho);
1075 CoolPropDbl dSmolar_dT_num = (WaterplusT->smolar() - WaterminusT->smolar()) / (2 * dT);
1076 CoolPropDbl dSmolar_drho_num = (Waterplusrho->smolar() - Waterminusrho->smolar()) / (2 * drho);
1077 CoolPropDbl dSmass_dT_num = (WaterplusT->smass() - WaterminusT->smass()) / (2 * dT);
1078 CoolPropDbl dSmass_drho_num = (Waterplusrho->smass() - Waterminusrho->smass()) / (2 * drho);
1080 CoolPropDbl dUmolar_dT_num = (WaterplusT->umolar() - WaterminusT->umolar()) / (2 * dT);
1081 CoolPropDbl dUmolar_drho_num = (Waterplusrho->umolar() - Waterminusrho->umolar()) / (2 * drho);
1082 CoolPropDbl dUmass_dT_num = (WaterplusT->umass() - WaterminusT->umass()) / (2 * dT);
1083 CoolPropDbl dUmass_drho_num = (Waterplusrho->umass() - Waterminusrho->umass()) / (2 * drho);
1085 CoolPropDbl dGmolar_dT_num = (WaterplusT->gibbsmolar() - WaterminusT->gibbsmolar()) / (2 * dT);
1086 CoolPropDbl dGmolar_drho_num = (Waterplusrho->gibbsmolar() - Waterminusrho->gibbsmolar()) / (2 * drho);
1087 CoolPropDbl dGmass_dT_num = (WaterplusT->gibbsmass() - WaterminusT->gibbsmass()) / (2 * dT);
1088 CoolPropDbl dGmass_drho_num = (Waterplusrho->gibbsmass() - Waterminusrho->gibbsmass()) / (2 * drho);
1090 CoolPropDbl dCvmolar_dT_num = (WaterplusT->cvmolar() - WaterminusT->cvmolar()) / (2 * dT);
1091 CoolPropDbl dCvmolar_drho_num = (Waterplusrho->cvmolar() - Waterminusrho->cvmolar()) / (2 * drho);
1092 CoolPropDbl dCvmass_dT_num = (WaterplusT->cvmass() - WaterminusT->cvmass()) / (2 * dT);
1093 CoolPropDbl dCvmass_drho_num = (Waterplusrho->cvmass() - Waterminusrho->cvmass()) / (2 * drho);
1095 CoolPropDbl dCpmolar_dT_num = (WaterplusT->cpmolar() - WaterminusT->cpmolar()) / (2 * dT);
1096 CoolPropDbl dCpmolar_drho_num = (Waterplusrho->cpmolar() - Waterminusrho->cpmolar()) / (2 * drho);
1097 CoolPropDbl dCpmass_dT_num = (WaterplusT->cpmass() - WaterminusT->cpmass()) / (2 * dT);
1098 CoolPropDbl dCpmass_drho_num = (Waterplusrho->cpmass() - Waterminusrho->cpmass()) / (2 * drho);
1100 CoolPropDbl dspeed_sound_dT_num = (WaterplusT->speed_sound() - WaterminusT->speed_sound()) / (2 * dT);
1101 CoolPropDbl dspeed_sound_drho_num = (Waterplusrho->speed_sound() - Waterminusrho->speed_sound()) / (2 * drho);
1107 CoolPropDbl dHmolar_dT_analyt, dHmolar_drho_analyt;
1112 CoolPropDbl dSmolar_dT_analyt, dSmolar_drho_analyt;
1117 CoolPropDbl dUmolar_dT_analyt, dUmolar_drho_analyt;
1122 CoolPropDbl dGmolar_dT_analyt, dGmolar_drho_analyt;
1127 CoolPropDbl dCvmolar_dT_analyt, dCvmolar_drho_analyt;
1129 CoolPropDbl dCvmass_dT_analyt, dCvmass_drho_analyt;
1132 CoolPropDbl dCpmolar_dT_analyt, dCpmolar_drho_analyt;
1134 CoolPropDbl dCpmass_dT_analyt, dCpmass_drho_analyt;
1137 CoolPropDbl dspeed_sound_dT_analyt, dspeed_sound_drho_analyt;
1142 CHECK(std::abs(dP_dT_analyt / dP_dT_num - 1) < eps);
1143 CHECK(std::abs(dP_drho_analyt / dP_drho_num - 1) < eps);
1145 CHECK(std::abs(dHmolar_dT_analyt / dHmolar_dT_num - 1) < eps);
1146 CHECK(std::abs(dHmolar_drho_analyt / dHmolar_drho_num - 1) < eps);
1147 CHECK(std::abs(dHmass_dT_analyt / dHmass_dT_num - 1) < eps);
1148 CHECK(std::abs(dHmass_drho_analyt / dHmass_drho_num - 1) < eps);
1150 CHECK(std::abs(dSmolar_dT_analyt / dSmolar_dT_num - 1) < eps);
1151 CHECK(std::abs(dSmolar_drho_analyt / dSmolar_drho_num - 1) < eps);
1152 CHECK(std::abs(dSmass_dT_analyt / dSmass_dT_num - 1) < eps);
1153 CHECK(std::abs(dSmass_drho_analyt / dSmass_drho_num - 1) < eps);
1155 CHECK(std::abs(dUmolar_dT_analyt / dUmolar_dT_num - 1) < eps);
1156 CHECK(std::abs(dUmolar_drho_analyt / dUmolar_drho_num - 1) < eps);
1157 CHECK(std::abs(dUmass_dT_analyt / dUmass_dT_num - 1) < eps);
1158 CHECK(std::abs(dUmass_drho_analyt / dUmass_drho_num - 1) < eps);
1160 CHECK(std::abs(dGmolar_dT_analyt / dGmolar_dT_num - 1) < eps);
1161 CHECK(std::abs(dGmolar_drho_analyt / dGmolar_drho_num - 1) < eps);
1162 CHECK(std::abs(dGmass_dT_analyt / dGmass_dT_num - 1) < eps);
1163 CHECK(std::abs(dGmass_drho_analyt / dGmass_drho_num - 1) < eps);
1165 CHECK(std::abs(dCvmolar_dT_analyt / dCvmolar_dT_num - 1) < eps);
1166 CHECK(std::abs(dCvmolar_drho_analyt / dCvmolar_drho_num - 1) < eps);
1167 CHECK(std::abs(dCvmass_dT_analyt / dCvmass_dT_num - 1) < eps);
1168 CHECK(std::abs(dCvmass_drho_analyt / dCvmass_drho_num - 1) < eps);
1170 CHECK(std::abs(dCpmolar_dT_analyt / dCpmolar_dT_num - 1) < eps);
1171 CHECK(std::abs(dCpmolar_drho_analyt / dCpmolar_drho_num - 1) < eps);
1172 CHECK(std::abs(dCpmass_dT_analyt / dCpmass_dT_num - 1) < eps);
1173 CHECK(std::abs(dCpmass_drho_analyt / dCpmass_drho_num - 1) < eps);
1175 CHECK(std::abs(dspeed_sound_dT_analyt / dspeed_sound_dT_num - 1) < eps);
1176 CHECK(std::abs(dspeed_sound_drho_analyt / dspeed_sound_drho_num - 1) < eps);