2# ifndef _CRTDBG_MAP_ALLOC
3# define _CRTDBG_MAP_ALLOC
5# ifndef _CRT_SECURE_NO_WARNINGS
6# define _CRT_SECURE_NO_WARNINGS
14#if defined(__ISWINDOWS__)
25# define DBL_EPSILON std::numeric_limits<double>::epsilon()
51#if defined(ENABLE_CATCH)
52# include <catch2/catch_all.hpp>
57static int debug_level = 0;
58static std::string error_string;
59static std::string warning_string;
73 warning_string = warning;
81 i = fluid_string.find(
"::");
82 return i != std::string::npos;
85void extract_backend(std::string fluid_string, std::string& backend, std::string& fluid) {
89 if (fluid_string.find(
"REFPROP-MIX:") == 0) {
90 fluid_string.replace(0, 12,
"REFPROP::");
92 if (fluid_string.find(
"REFPROP-") == 0) {
93 fluid_string.replace(0, 8,
"REFPROP::");
97 backend = fluid_string.substr(0, i);
99 fluid = fluid_string.substr(i + 2);
102 fluid = fluid_string;
105 std::cout <<
format(
"%s:%d: backend extracted. backend: %s. fluid: %s\n", __FILE__, __LINE__, backend.c_str(), fluid.c_str());
110 return (fluid_string.find(
"[") != std::string::npos && fluid_string.find(
"]") != std::string::npos);
114 return (fluid_string.find(
'-') != std::string::npos && fluid_string.find(
'%') != std::string::npos);
130 std::vector<std::string> names;
133 std::vector<std::string> pairs =
strsplit(fluid_string,
'&');
135 for (std::size_t i = 0; i < pairs.size(); ++i) {
136 const std::string& fluid = pairs[i];
139 if (fluid[fluid.size() - 1] !=
']')
throw ValueError(
format(
"Fluid entry [%s] must end with ']' character", pairs[i].c_str()));
142 std::vector<std::string> name_fraction =
strsplit(fluid.substr(0, fluid.size() - 1),
'[');
144 if (name_fraction.size() != 2) {
145 throw ValueError(
format(
"Could not break [%s] into name/fraction", fluid.substr(0, fluid.size() - 1).c_str()));
149 const std::string &name = name_fraction[0], &fraction = name_fraction[1];
155 std::stringstream ssfraction(fraction);
157 ssfraction.imbue(std::locale(ssfraction.getloc(),
new delim(c)));
160 if (ssfraction.rdbuf()->in_avail() != 0) {
161 throw ValueError(
format(
"fraction [%s] was not converted fully", fraction.c_str()));
164 if (f > 1 || f < 0) {
165 throw ValueError(
format(
"fraction [%s] was not converted to a value between 0 and 1 inclusive", fraction.c_str()));
172 fractions.push_back(f);
175 names.push_back(name);
180 std::cout <<
format(
"%s:%d: Detected fractions of %s for %s.", __FILE__, __LINE__,
vec_to_string(fractions).c_str(),
181 (
strjoin(names,
"&")).c_str());
188 std::vector<std::string> fluid_parts =
strsplit(fluid_string,
'-');
190 if (fluid_parts.size() != 2) {
192 format(
"Format of incompressible solution string [%s] is invalid, should be like \"EG-20%\" or \"EG-0.2\" ", fluid_string.c_str()));
197 x = strtod(fluid_parts[1].c_str(), &pEnd);
203 fractions.push_back(x);
205 std::cout <<
format(
"%s:%d: Detected incompressible concentration of %s for %s.", __FILE__, __LINE__,
vec_to_string(fractions).c_str(),
206 fluid_parts[0].c_str());
207 return fluid_parts[0];
213void _PropsSI_initialize(
const std::string& backend,
const std::vector<std::string>& fluid_names,
const std::vector<double>& z,
214 shared_ptr<AbstractState>& State) {
216 if (fluid_names.empty()) {
217 throw ValueError(
"fluid_names cannot be empty");
220 std::vector<double> fractions(1, 1.0);
221 const std::vector<double>* fractions_ptr = NULL;
223 if (fluid_names.size() > 1) {
228 }
else if (fluid_names.size() == 1) {
233 fractions_ptr = &fractions;
239 fractions_ptr = &fractions;
250 if (!State->available_in_high_level()) {
252 "This AbstractState derived class cannot be used in the high-level interface; see www.coolprop.org/dev/coolprop/LowLevelAPI.html");
256 if (State->using_mole_fractions()) {
258 if (State->get_mole_fractions().empty()) {
259 State->set_mole_fractions(*fractions_ptr);
261 }
else if (State->using_mass_fractions()) {
262 State->set_mass_fractions(*fractions_ptr);
263 }
else if (State->using_volu_fractions()) {
264 State->set_volu_fractions(*fractions_ptr);
267 std::cout <<
format(
"%s:%d: _PropsSI, could not set composition to %s, defaulting to mole fraction.\n", __FILE__, __LINE__,
289 std::vector<output_parameter> outputs;
290 for (std::vector<std::string>::const_iterator str = Outputs.begin(); str != Outputs.end(); ++str) {
309 outputs.push_back(out);
316 const std::vector<double>& in1,
const std::vector<double>& in2, std::vector<std::vector<double>>& IO) {
319 if (in1.size() != in2.size()) {
320 throw ValueError(
format(
"lengths of in1 [%d] and in2 [%d] are not the same", in1.size(), in2.size()));
322 const bool one_input_one_output = (in1.size() == 1 && in2.size() == 1 && output_parameters.size() == 1);
324 bool all_trivial_outputs =
true;
325 for (std::size_t j = 0; j < output_parameters.size(); ++j) {
327 all_trivial_outputs =
false;
332 bool all_outputs_in_inputs =
true;
337 for (std::size_t j = 0; j < output_parameters.size(); ++j) {
339 all_outputs_in_inputs =
false;
342 if (!(output_parameters[j].Of1 == p1 || output_parameters[j].Of1 == p2)) {
343 all_outputs_in_inputs =
false;
348 if (!all_trivial_outputs) {
349 throw ValueError(
format(
"Input pair variable is invalid and output(s) are non-trivial; cannot do state update"));
351 all_outputs_in_inputs =
false;
355 std::cout <<
format(
"%s (%d): input pair = %d ", __FILE__, __LINE__, input_pair) << std::endl;
356 std::cout <<
format(
"%s (%d): in1 = %s ", __FILE__, __LINE__,
vec_to_string(in1).c_str()) << std::endl;
357 std::cout <<
format(
"%s (%d): in2 = %s ", __FILE__, __LINE__,
vec_to_string(in2).c_str()) << std::endl;
365 const std::size_t N1 = std::max(
static_cast<std::size_t
>(1), in1.size());
366 const std::size_t N2 = std::max(
static_cast<std::size_t
>(1), output_parameters.size());
367 IO.resize(N1, std::vector<double>(N2, _HUGE));
370 bool success =
false;
371 bool success_inner =
false;
374 std::cout <<
format(
"%s (%d): Iterating over %d input value pairs.", __FILE__, __LINE__, IO.size()) << std::endl;
378 for (std::size_t i = 0; i < IO.size(); ++i) {
380 success_inner =
false;
382 if (input_pair !=
INPUT_PAIR_INVALID && !all_trivial_outputs && !all_outputs_in_inputs) {
384 if (!use_guesses || i == 0) {
385 State->update(input_pair, in1[i], in2[i]);
387 State->update_with_guesses(input_pair, in1[i], in2[i], guesses);
392 if (one_input_one_output) {
397 for (std::size_t j = 0; j < IO[i].size(); ++j) {
403 for (std::size_t j = 0; j < IO[i].size(); ++j) {
405 if (all_outputs_in_inputs) {
406 if (p1 == output_parameters[j].Of1) {
408 success_inner =
true;
410 }
else if (p2 == output_parameters[j].Of1) {
412 success_inner =
true;
420 switch (output.
type) {
423 IO[i][j] = State->keyed_output(output.
Of1);
425 switch (output.
Of1) {
430 guesses.
T = IO[i][j];
433 guesses.
p = IO[i][j];
436 guesses.
hmolar = IO[i][j];
439 guesses.
smolar = IO[i][j];
442 throw ValueError(
"Don't understand this parameter");
447 IO[i][j] = State->first_partial_deriv(output.
Of1, output.
Wrt1, output.
Constant1);
450 IO[i][j] = State->first_saturation_deriv(output.
Of1, output.
Wrt1);
460 success_inner =
true;
462 if (one_input_one_output) {
470 if (use_guesses && success_inner) {
473 guesses.
rhomolar = State->rhomolar();
480 guesses.
T = State->T();
487 success |= success_inner;
489 if (success ==
false) {
495bool StripPhase(std::string& Name, shared_ptr<AbstractState>& State)
498 std::vector<std::string> strVec =
strsplit(Name,
'|');
499 if (strVec.size() > 1) {
501 const std::string strBackend = State->backend_name();
503 throw ValueError(
"Cannot set phase on Incompressible Fluid; always liquid phase");
505 throw ValueError(
"Can't set phase on IF97 Backend");
507 throw ValueError(
"Can't set phase on TTSE Backend in PropsSI");
509 throw ValueError(
"Can't set phase on BICUBIC Backend in PropsSI");
511 throw ValueError(
"Can't set phase on VTPR Backend in PropsSI");
514 if (strVec.size() > 2)
519 std::basic_string<char>::iterator str_Iter;
520 std::string strPhase = strVec[1];
521 if (strPhase.find(
"iphase_") != strPhase.npos) {
522 str_Iter = strPhase.erase(strPhase.begin());
524 if (strPhase.find(
"phase_") == strPhase.npos) {
525 strPhase.insert(0,
"phase_");
529 throw ValueError(
format(
"Phase string \"%s\" is not a valid phase", strVec[1]));
533 State->specify_phase(imposed);
539void _PropsSImulti(
const std::vector<std::string>& Outputs,
const std::string& Name1,
const std::vector<double>& Prop1,
const std::string& Name2,
540 const std::vector<double>& Prop2,
const std::string& backend,
const std::vector<std::string>& fluids,
541 const std::vector<double>& fractions, std::vector<std::vector<double>>& IO) {
542 shared_ptr<AbstractState> State;
545 std::vector<output_parameter> output_parameters;
546 std::vector<double> v1, v2;
551 }
catch (std::exception& e) {
553 throw ValueError(
format(
"Initialize failed for backend: \"%s\", fluid: \"%s\" fractions \"%s\"; error: %s", backend.c_str(),
558 std::string N1 = Name1;
559 std::string N2 = Name2;
562 if (HasPhase1 && HasPhase2)
563 throw ValueError(
"Phase can only be specified on one of the input key strings");
568 }
catch (std::exception& e) {
570 throw ValueError(
format(
"Input pair parsing failed for Name1: \"%s\", Name2: \"%s\"; err: %s", Name1.c_str(), Name2.c_str(), e.what()));
575 }
catch (std::exception& e) {
577 throw ValueError(
format(
"Output parameter parsing failed; error: %s", e.what()));
584std::vector<std::vector<double>>
PropsSImulti(
const std::vector<std::string>& Outputs,
const std::string& Name1,
const std::vector<double>& Prop1,
585 const std::string& Name2,
const std::vector<double>& Prop2,
const std::string& backend,
586 const std::vector<std::string>& fluids,
const std::vector<double>& fractions) {
587 std::vector<std::vector<double>> IO;
589#if !defined(NO_ERROR_CATCHING)
594 _PropsSImulti(Outputs, Name1, Prop1, Name2, Prop2, backend, fluids, fractions, IO);
599#if !defined(NO_ERROR_CATCHING)
600 }
catch (
const std::exception& e) {
602# if defined(PROPSSI_ERROR_STDOUT)
603 std::cout << e.what() << std::endl;
606 std::cout << e.what() << std::endl;
611 return std::vector<std::vector<double>>();
613double PropsSI(
const std::string& Output,
const std::string& Name1,
double Prop1,
const std::string& Name2,
double Prop2,
614 const std::string& FluidName) {
615#if !defined(NO_ERROR_CATCHING)
622 std::string backend, fluid;
624 std::vector<double> fractions(1, 1.0);
627 std::vector<std::vector<double>> IO;
628 _PropsSImulti(
strsplit(Output,
'&'), Name1, std::vector<double>(1, Prop1), Name2, std::vector<double>(1, Prop2), backend,
629 strsplit(fluid_string,
'&'), fractions, IO);
633 if (IO.size() != 1 || IO[0].size() != 1) {
637 const double val = IO[0][0];
640 std::cout <<
format(
"_PropsSI will return %g", val) << std::endl;
644#if !defined(NO_ERROR_CATCHING)
645 }
catch (
const std::exception& e) {
647 +
format(
" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")", Output.c_str(), Name1.c_str(), Prop1, Name2.c_str(), Prop2,
649# if defined(PROPSSI_ERROR_STDOUT)
650 std::cout << e.what() << std::endl;
653 std::cout << e.what() << std::endl;
663 if (backend ==
"SRK" || backend ==
"PR") {
666 }
else if (backend ==
"HEOS") {
669 }
else if (backend ==
"PCSAFT") {
673 throw ValueError(
format(
"You have provided an invalid backend [%s] to add_fluids_as_JSON; valid options are SRK, PR, HEOS", backend.c_str()));
677#if defined(ENABLE_CATCH)
678TEST_CASE(
"Check inputs to PropsSI",
"[PropsSI]") {
679 SECTION(
"Single state, single output") {
682 SECTION(
"Single state, single output, saturation derivative") {
685 SECTION(
"Single state, single output, pure incompressible") {
688 SECTION(
"Single state, trivial output, pure incompressible") {
691 SECTION(
"Bad input pair") {
694 SECTION(
"Single state, single output, 40% incompressible") {
697 SECTION(
"Single state, single output, predefined CoolProp mixture") {
700 SECTION(
"Single state, single output") {
703 SECTION(
"Single state, single output, predefined mixture") {
706 SECTION(
"Single state, single output, predefined mixture from REFPROP") {
709 SECTION(
"Single state, single output, bad predefined mixture from REFPROP") {
712 SECTION(
"Predefined mixture") {
713 std::vector<double> p(1, 101325), Q(1, 1.0), z;
714 std::vector<std::string> outputs(1,
"T");
715 outputs.push_back(
"Dmolar");
716 std::vector<std::vector<double>> IO;
717 std::vector<std::string> fluids(1,
"R410A.mix");
720 SECTION(
"Single state, two outputs") {
721 std::vector<double> p(1, 101325), Q(1, 1.0), z(1, 1.0);
722 std::vector<std::string> outputs(1,
"T");
723 outputs.push_back(
"Dmolar");
724 std::vector<std::string> fluids(1,
"Water");
727 SECTION(
"Single state, two bad outputs") {
728 std::vector<double> p(1, 101325), Q(1, 1.0), z(1, 1.0);
729 std::vector<std::vector<double>> IO;
730 std::vector<std::string> outputs(1,
"???????");
731 outputs.push_back(
"?????????");
732 std::vector<std::string> fluids(1,
"Water");
734 CHECK(IO.size() == 0);
736 SECTION(
"Two states, one output") {
737 std::vector<double> p(2, 101325), Q(2, 1.0), z(1, 1.0);
738 std::vector<std::string> outputs(1,
"T");
739 std::vector<std::string> fluids(1,
"Water");
742 SECTION(
"Two states, two outputs") {
743 std::vector<double> p(2, 101325), Q(2, 1.0), z(1, 1.0);
744 std::vector<std::string> outputs(1,
"T");
745 outputs.push_back(
"Dmolar");
746 std::vector<std::string> fluids(1,
"Water");
749 SECTION(
"cp and its derivative representation") {
750 std::vector<double> p(1, 101325), Q(1, 1.0), z(1, 1.0);
751 std::vector<std::vector<double>> IO;
752 std::vector<std::string> outputs(1,
"Cpmolar");
753 outputs.push_back(
"d(Hmolar)/d(T)|P");
754 std::vector<std::string> fluids(1,
"Water");
758 REQUIRE(!IO.empty());
761 CHECK(std::abs(IO[0][0] - IO[0][1]) < 1e-5);
763 SECTION(
"bad fluid") {
764 std::vector<double> p(1, 101325), Q(1, 1.0), z(1, 1.0);
765 std::vector<std::vector<double>> IO;
766 std::vector<std::string> outputs(1,
"Cpmolar");
767 outputs.push_back(
"d(Hmolar)/d(T)|P");
768 std::vector<std::string> fluids(1,
"????????");
774 SECTION(
"bad mole fraction length") {
775 std::vector<double> p(1, 101325), Q(1, 1.0), z(1, 1.0);
776 std::vector<std::vector<double>> IO;
777 std::vector<std::string> outputs(1,
"T");
778 std::vector<std::string> fluids(1,
"Water&Ethanol");
784 SECTION(
"bad input lengths") {
785 std::vector<double> p(1, 101325), Q(2, 1.0), z(100, 1.0);
786 std::vector<std::vector<double>> IO;
787 std::vector<std::string> outputs(1,
"Cpmolar");
788 outputs.push_back(
"d(Hmolar)/d(T)|P");
789 std::vector<std::string> fluids(1,
"Water");
795 SECTION(
"bad input pair") {
796 std::vector<double> Q(2, 1.0), z(1, 1.0);
797 std::vector<std::vector<double>> IO;
798 std::vector<std::string> outputs(1,
"Cpmolar");
799 outputs.push_back(
"d(Hmolar)/d(T)|P");
800 std::vector<std::string> fluids(1,
"Water");
813double Props1SI(std::string FluidName, std::string Output) {
816 if (valid_fluid1 && valid_fluid2) {
817 set_error_string(
format(
"Both inputs to Props1SI [%s,%s] are valid fluids", Output.c_str(), FluidName.c_str()));
820 if (!valid_fluid1 && !valid_fluid2) {
821 set_error_string(
format(
"Neither input to Props1SI [%s,%s] is a valid fluid", Output.c_str(), FluidName.c_str()));
824 if (!valid_fluid1 && valid_fluid2) {
826 std::swap(Output, FluidName);
830 const double val1 =
PropsSI(Output,
"", 0,
"", 0, FluidName);
832 set_error_string(
format(
"Unable to use input parameter [%s] in Props1SI for fluid %s; error was %s", Output.c_str(), FluidName.c_str(),
840std::vector<std::vector<double>>
Props1SImulti(
const std::vector<std::string>& Outputs,
const std::string& backend,
841 const std::vector<std::string>& fluids,
const std::vector<double>& fractions) {
842 std::vector<double> zero_vector(1, 0.);
843 std::vector<std::vector<double>> val1 =
PropsSImulti(Outputs,
"", zero_vector,
"", zero_vector, backend, fluids, fractions);
848#if defined(ENABLE_CATCH)
849TEST_CASE(
"Check inputs to Props1SI",
"[Props1SI],[PropsSI]") {
850 SECTION(
"Good fluid, good parameter") {
853 SECTION(
"Good fluid, good parameter") {
856 SECTION(
"Good fluid, good parameter, inverted") {
859 SECTION(
"Good fluid, bad parameter") {
862 SECTION(
"Bad fluid, good parameter") {
870 std::string backend, fluid;
871 std::vector<double> fractions;
882double saturation_ancillary(
const std::string& fluid_name,
const std::string& output,
int Q,
const std::string& input,
double value) {
885 std::vector<std::string> names(1, fluid_name);
894 std::string backend, fluid;
896 if (backend ==
"REFPROP") {
898 int ierr = 0, ixflag = 1;
899 double h0 = 0, s0 = 0, t0 = 0, p0 = 0;
900 char herr[255], hrf[4];
902 const char* refstate = reference_state.c_str();
903 if (strlen(refstate) > 3) {
904 if (reference_state ==
"ASHRAE") {
905 strncpy(hrf,
"ASH",
sizeof(hrf) - 1);
906 hrf[
sizeof(hrf) - 1] =
'\0';
908 throw ValueError(
format(
"Reference state string [%s] is more than 3 characters long", reference_state.c_str()));
911 strncpy(hrf, refstate,
sizeof(hrf) - 1);
912 hrf[
sizeof(hrf) - 1] =
'\0';
914 REFPROP_SETREF(hrf, ixflag, x0, h0, s0, t0, p0, ierr, herr, 3, 255);
915 }
else if (backend ==
"HEOS" || backend ==
"?") {
917 if (reference_state ==
"IIR") {
919 throw ValueError(
format(
"Cannot use IIR reference state; Ttriple [%Lg] is greater than 273.15 K", HEOS.
Ttriple()));
924 double deltah = HEOS.
hmass() - 200000;
925 double deltas = HEOS.
smass() - 1000;
931 std::cout <<
format(
"set offsets to %0.15g and %0.15g\n", delta_a1, delta_a2);
933 }
else if (reference_state ==
"ASHRAE") {
935 throw ValueError(
format(
"Cannot use ASHRAE reference state; Ttriple [%Lg] is greater than than 233.15 K", HEOS.
Ttriple()));
940 double deltah = HEOS.
hmass() - 0;
941 double deltas = HEOS.
smass() - 0;
947 std::cout <<
format(
"set offsets to %0.15g and %0.15g\n", delta_a1, delta_a2);
949 }
else if (reference_state ==
"NBP") {
951 throw ValueError(
format(
"Cannot use NBP reference state; p_triple [%Lg Pa] is greater than than 101325 Pa", HEOS.
p_triple()));
956 double deltah = HEOS.
hmass() - 0;
957 double deltas = HEOS.
smass() - 0;
963 std::cout <<
format(
"set offsets to %0.15g and %0.15g\n", delta_a1, delta_a2);
965 }
else if (reference_state ==
"DEF") {
967 }
else if (reference_state ==
"RESET") {
970 throw ValueError(
format(
"Reference state string is invalid: [%s]", reference_state.c_str()));
974void set_reference_stateD(
const std::string& FluidName,
double T,
double rhomolar,
double hmolar0,
double smolar0) {
975 std::vector<std::string> _comps(1, FluidName);
981 double deltah = HEOS.
hmolar() - hmolar0;
982 double deltas = HEOS.
smolar() - smolar0;
989 if (ParamName ==
"version") {
991 }
else if (ParamName ==
"gitrevision") {
993 }
else if (ParamName ==
"errstring") {
994 std::string temp = error_string;
997 }
else if (ParamName ==
"warnstring") {
998 std::string temp = warning_string;
1001 }
else if (ParamName ==
"FluidsList" || ParamName ==
"fluids_list" || ParamName ==
"fluidslist") {
1003 }
else if (ParamName ==
"incompressible_list_pure") {
1005 }
else if (ParamName ==
"incompressible_list_solution") {
1007 }
else if (ParamName ==
"mixture_binary_pairs_list") {
1009 }
else if (ParamName ==
"parameter_list") {
1011 }
else if (ParamName ==
"predefined_mixtures") {
1013 }
else if (ParamName ==
"HOME") {
1015 }
else if (ParamName ==
"REFPROP_version") {
1017 }
else if (ParamName ==
"cubic_fluids_schema") {
1019 }
else if (ParamName ==
"cubic_fluids_list") {
1021 }
else if (ParamName ==
"pcsaft_fluids_schema") {
1024 throw ValueError(
format(
"Input parameter [%s] is invalid", ParamName.c_str()));
1027#if defined(ENABLE_CATCH)
1028TEST_CASE(
"Check inputs to get_global_param_string",
"[get_global_param_string]") {
1029 const int num_good_inputs = 8;
1030 std::string good_inputs[num_good_inputs] = {
1031 "version",
"gitrevision",
"fluids_list",
"incompressible_list_pure",
"incompressible_list_solution",
"mixture_binary_pairs_list",
1032 "parameter_list",
"predefined_mixtures"};
1033 std::ostringstream ss3c;
1034 for (
int i = 0; i < num_good_inputs; ++i) {
1035 ss3c <<
"Test for" << good_inputs[i];
1036 SECTION(ss3c.str(),
"") {
1044 std::string backend, fluid;
1047 return AS->fluid_param_string(ParamName);
1049#if defined(ENABLE_CATCH)
1050TEST_CASE(
"Check inputs to get_fluid_param_string",
"[get_fluid_param_string]") {
1051 const int num_good_inputs = 10;
1052 std::string good_inputs[num_good_inputs] = {
"aliases",
1056 "BibTeX-CONDUCTIVITY",
1059 "BibTeX-SURFACE_TENSION",
1060 "BibTeX-MELTING_LINE",
1061 "BibTeX-VISCOSITY"};
1062 std::ostringstream ss3c;
1063 for (
int i = 0; i < num_good_inputs; ++i) {
1064 ss3c <<
"Test for" << good_inputs[i];
1065 SECTION(ss3c.str(),
"") {
1082 return "supercritical";
1084 return "supercritical_gas";
1086 return "supercritical_liquid";
1088 return "critical_point";
1096 return "not_imposed";
1098 throw ValueError(
"I should never be thrown");
1100std::string
PhaseSI(
const std::string& Name1,
double Prop1,
const std::string& Name2,
double Prop2,
const std::string& FluidName) {
1101 double Phase_double =
PropsSI(
"Phase", Name1, Prop1, Name2, Prop2, FluidName);
1105 if (strError !=
"") {
1106 strPhase.append(
": " + strError);
1110 std::size_t Phase_int =
static_cast<std::size_t
>(Phase_double);