From b6b73192f94015efdbfbc5a233efbbda57e2cd5a Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Tue, 7 Jul 2015 22:37:36 -0600 Subject: [PATCH] Expose saturation derivatives through PropsSI; closes #712 --- include/DataStructures.h | 5 +++++ src/CoolProp.cpp | 10 +++++++++- src/DataStructures.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/DataStructures.h b/include/DataStructures.h index 5dc880c7..1bcabdd5 100644 --- a/include/DataStructures.h +++ b/include/DataStructures.h @@ -169,6 +169,11 @@ bool is_valid_parameter(const std::string & name, parameters & iOutput); /// If it is a value derivative, the variables are set to the parts of the derivative bool is_valid_first_derivative(const std::string & name, parameters &iOf, parameters &iWrt, parameters &iConstant); +/// Returns true if the string corresponds to a valid first saturation derivative - e.g. "d(P)/d(T)|sigma" for instance +/// +/// If it is a valid derivative, the variables are set to the parts of the derivative +bool is_valid_first_saturation_derivative(const std::string & name, parameters &iOf, parameters &iWrt); + /// Returns true if the string corresponds to a valid second derivative /// /// If it is a value derivative, the variables are set to the parts of the derivative diff --git a/src/CoolProp.cpp b/src/CoolProp.cpp index 562ae95b..99fcc7b5 100644 --- a/src/CoolProp.cpp +++ b/src/CoolProp.cpp @@ -242,7 +242,7 @@ void _PropsSI_initialize(const std::string &backend, } struct output_parameter{ - enum OutputParametersType {OUTPUT_TYPE_UNSET = 0, OUTPUT_TYPE_TRIVIAL, OUTPUT_TYPE_NORMAL, OUTPUT_TYPE_FIRST_DERIVATIVE, OUTPUT_TYPE_SECOND_DERIVATIVE}; + enum OutputParametersType {OUTPUT_TYPE_UNSET = 0, OUTPUT_TYPE_TRIVIAL, OUTPUT_TYPE_NORMAL, OUTPUT_TYPE_FIRST_DERIVATIVE, OUTPUT_TYPE_FIRST_SATURATION_DERIVATIVE, OUTPUT_TYPE_SECOND_DERIVATIVE}; CoolProp::parameters Of1, Wrt1, Constant1, Wrt2, Constant2; OutputParametersType type; /// Parse a '&' separated string into a data structure with one entry per output @@ -257,6 +257,9 @@ struct output_parameter{ if (is_trivial_parameter(iOutput)){ out.type = OUTPUT_TYPE_TRIVIAL; } else{ out.type = OUTPUT_TYPE_NORMAL; } } + else if (is_valid_first_saturation_derivative(*str, out.Of1, out.Wrt1)){ + out.type = OUTPUT_TYPE_FIRST_SATURATION_DERIVATIVE; + } else if (is_valid_first_derivative(*str, out.Of1, out.Wrt1, out.Constant1)){ out.type = OUTPUT_TYPE_FIRST_DERIVATIVE; } @@ -364,6 +367,8 @@ void _PropsSI_outputs(shared_ptr &State, IO[i][j] = State->keyed_output(output.Of1); break; case output_parameter::OUTPUT_TYPE_FIRST_DERIVATIVE: IO[i][j] = State->first_partial_deriv(output.Of1, output.Wrt1, output.Constant1); break; + case output_parameter::OUTPUT_TYPE_FIRST_SATURATION_DERIVATIVE: + IO[i][j] = State->first_saturation_deriv(output.Of1, output.Wrt1); break; case output_parameter::OUTPUT_TYPE_SECOND_DERIVATIVE: IO[i][j] = State->second_partial_deriv(output.Of1, output.Wrt1, output.Constant1, output.Wrt2, output.Constant2); break; default: @@ -510,6 +515,9 @@ TEST_CASE("Check inputs to PropsSI","[PropsSI]") SECTION("Single state, single output"){ CHECK(ValidNumber(CoolProp::PropsSI("T","P",101325,"Q",0,"Water"))); }; + SECTION("Single state, single output, saturation derivative"){ + CHECK(ValidNumber(CoolProp::PropsSI("d(P)/d(T)|sigma","P",101325,"Q",0,"Water"))); + }; SECTION("Single state, single output, pure incompressible"){ CHECK(ValidNumber(CoolProp::PropsSI("D","P",101325,"T",300,"INCOMP::DowQ"))); }; diff --git a/src/DataStructures.cpp b/src/DataStructures.cpp index c82a4dc3..6764777a 100644 --- a/src/DataStructures.cpp +++ b/src/DataStructures.cpp @@ -253,6 +253,38 @@ bool is_valid_first_derivative(const std::string &name, parameters &iOf, paramet } } +bool is_valid_first_saturation_derivative(const std::string &name, parameters &iOf, parameters &iWrt) +{ + if (get_debug_level() > 5){ std::cout << format("is_valid_first_saturation_derivative(%s)", name.c_str()); } + // There should be exactly one / + // There should be exactly one | + + // Suppose we start with "d(P)/d(T)|sigma" + std::vector split_at_bar = strsplit(name, '|'); // "d(P)/d(T)" and "sigma" + if (split_at_bar.size() != 2){ return false; } + + std::vector split_at_slash = strsplit(split_at_bar[0], '/'); // "d(P)" and "d(T)" + if (split_at_slash.size() != 2){ return false; } + + std::size_t i0 = split_at_slash[0].find("("); + std::size_t i1 = split_at_slash[0].find(")", i0); + if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0+1)) && (i1 != std::string::npos))){ return false; } + std::string num = split_at_slash[0].substr(i0+1, i1-i0-1); + + i0 = split_at_slash[1].find("("); + i1 = split_at_slash[1].find(")", i0); + if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0+1)) && (i1 != std::string::npos))){ return false; } + std::string den = split_at_slash[1].substr(i0+1, i1-i0-1); + + parameters Of, Wrt, Constant; + if (is_valid_parameter(num, Of) && is_valid_parameter(den, Wrt) && upper(split_at_bar[1]) == "SIGMA"){ + iOf = Of; iWrt = Wrt; return true; + } + else{ + return false; + } +} + bool is_valid_second_derivative(const std::string &name, parameters &iOf1, parameters &iWrt1, parameters &iConstant1, parameters &iWrt2, parameters &iConstant2) { if (get_debug_level() > 5){std::cout << format("is_valid_second_derivative(%s)",name.c_str());}