PropsSImulti is integrated into Python wrapper; extract_fractions is exported

Signed-off-by: Ian Bell <ian.h.bell@gmail.com>
This commit is contained in:
Ian Bell
2014-12-30 20:08:35 -05:00
parent f3fe64b486
commit f8576b1d49
4 changed files with 93 additions and 44 deletions

View File

@@ -176,6 +176,14 @@ You might want to start by looking at CoolProp.h
*/
void extract_backend(const std::string &fluid_string, std::string &backend, std::string &fluid);
/**
* @brief Extract fractions (molar, mass, etc.) encoded in the string if any
* @param fluid_string The input string
* @param fractions The fractions
* @return The fluids, as a '&' delimited string
*/
std::string extract_fractions(const std::string &fluid_string, std::vector<double> &fractions);
} /* namespace CoolProp */
#endif

View File

@@ -292,26 +292,36 @@ void _PropsSI_outputs(shared_ptr<AbstractState> &State,
// Iterate over the state variable inputs
for (std::size_t i = 0; i < IO.size(); ++i){
if (input_pair != INPUT_PAIR_INVALID){
// Update the state since it is a valid set of inputs
State->update(input_pair, in1[i], in2[i]);
}
for (std::size_t j = 0; j < IO[i].size(); ++j){
output_parameter &output = output_parameters[j];
switch (output.type){
case output_parameter::OUTPUT_TYPE_TRIVIAL:
case output_parameter::OUTPUT_TYPE_NORMAL:
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_SECOND_DERIVATIVE:
IO[i][j] = State->second_partial_deriv(output.Of1, output.Wrt1, output.Constant1, output.Wrt2, output.Constant2); break;
default:
throw ValueError(format("")); break;
}
}
try{
if (input_pair != INPUT_PAIR_INVALID){
// Update the state since it is a valid set of inputs
State->update(input_pair, in1[i], in2[i]);
}
}
catch(std::exception &){
// All the outputs are filled with _HUGE
for (std::size_t j = 0; j < IO[i].size(); ++j){ IO[i][j] = _HUGE; }
}
for (std::size_t j = 0; j < IO[i].size(); ++j){
try{
output_parameter &output = output_parameters[j];
switch (output.type){
case output_parameter::OUTPUT_TYPE_TRIVIAL:
case output_parameter::OUTPUT_TYPE_NORMAL:
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_SECOND_DERIVATIVE:
IO[i][j] = State->second_partial_deriv(output.Of1, output.Wrt1, output.Constant1, output.Wrt2, output.Constant2); break;
default:
throw ValueError(format("")); break;
}
}
catch(std::exception &){
IO[i][j] = _HUGE;
}
}
}
}
std::vector<std::vector<double> > PropsSImulti(const std::vector<std::string> &Outputs,
@@ -339,7 +349,7 @@ std::vector<std::vector<double> > PropsSImulti(const std::vector<std::string> &O
}
catch(std::exception &e){
// Initialization failed. Stop.
throw ValueError(format("_PropsSI_initialize failed for backend: \"%s\", fluid: \"%s\" fractions \"%s\"",backend.c_str(), strjoin(fluids,"&").c_str(), vec_to_string(fractions, "%0.10f").c_str()) );
throw ValueError(format("_PropsSI_initialize failed for backend: \"%s\", fluid: \"%s\" fractions \"%s\"; error: %s",backend.c_str(), strjoin(fluids,"&").c_str(), vec_to_string(fractions, "%0.10f").c_str(), e.what()) );
}
try{
@@ -350,17 +360,17 @@ std::vector<std::vector<double> > PropsSImulti(const std::vector<std::string> &O
is_valid_parameter(Name2, key2);
input_pair = generate_update_pair(key1, Prop1, key2, Prop2, v1, v2);
}
catch (std::exception &){
// Initialization failed. Stop.
throw ValueError(format("_PropsSI input pair parsing failed for Name1: \"%s\", Name2: \"%s\"", Name1.c_str(), Name2.c_str()));
catch (std::exception &e){
// Input parameter parsing failed. Stop
throw ValueError(format("_PropsSI input pair parsing failed for Name1: \"%s\", Name2: \"%s\"; error: %s", Name1.c_str(), Name2.c_str(),e.what()));
}
try{
output_parameters = output_parameter::get_output_parameters(Outputs);
}
catch (std::exception &){
// Initialization failed. Stop.
throw ValueError(format("_PropsSI output parameter parsing failed"));
catch (std::exception &e){
// Output parameter parsing failed. Stop.
throw ValueError(format("_PropsSI output parameter parsing failed; error: %s", e.what()));
}
// Calculate the output(s). In the case of a failure, all values will be filled with _HUGE

View File

@@ -33,12 +33,13 @@ cdef extern from "CoolProp.h" namespace "CoolProp":
double _Props1SI "CoolProp::Props1SI"(string Ref, string Output)
double _PropsSI "CoolProp::PropsSI"(string Output, string Name1, double Prop1, string Name2, double Prop2, string FluidName)
string _PhaseSI "CoolProp::PhaseSI"(string Name1, double Prop1, string Name2, double Prop2, string FluidName)
vector[double] _PropsSI "CoolProp::PropsSI"(string Output, string Name1, vector[double] Prop1, string Name2, vector[double] Prop2, string FluidName, vector[double] fractions)
vector[double] _PropsSII "CoolProp::PropsSI"(string Output, string Name1, vector[double] Prop1, string Name2, vector[double] Prop2, string FluidName)
vector[vector[double]] _PropsSImulti "CoolProp::PropsSImulti"(vector[string] Outputs, string Name1, vector[double] Prop1, string Name2, vector[double] Prop2, string backend, vector[string] FluidName, vector[double] fractions)
string _get_global_param_string "CoolProp::get_global_param_string"(string ParamName) except +
int _get_debug_level "CoolProp::get_debug_level"() except +
void _set_debug_level "CoolProp::set_debug_level"(int level) except +
string _get_fluid_param_string "CoolProp::get_fluid_param_string"(string ParamName, string FluidName) except +
void _extract_backend "CoolProp::extract_backend"(string input, string backend, string fluids) except +
string _extract_fractions "CoolProp::extract_fractions"(string input, vector[double] fractions) except +
void _set_reference_stateS "CoolProp::set_reference_stateS"(string, string) except +
void _set_reference_stateD "CoolProp::set_reference_stateD"(string, double, double, double, double) except +

View File

@@ -205,7 +205,11 @@ cpdef PropsSI(in1, in2, in3 = None, in4 = None, in5 = None, in6 = None, in7 = No
"""
A Python wrapper of C++ function :cpapi:`CoolProp::PropsSI` .
"""
cdef vector[string] vin1
cdef vector[double] fractions
cdef double val
cdef string backend, fluid, delimitedfluids
cdef bool is_iterable1, is_iterable3, is_iterable5
# Two parameter inputs
if in3 is None and in4 is None and in5 is None and in6 is None and in7 is None:
@@ -216,19 +220,47 @@ cpdef PropsSI(in1, in2, in3 = None, in4 = None, in5 = None, in6 = None, in7 = No
return val
# Six parameter inputs
elif in7 is None:
if iterable(in3) and iterable(in5):
if len(in3) != len(in5):
raise TypeError("Sizes of Prop1 {n1:d} and Prop2 {n2:d} to PropsSI are not the same".format(n1 = len(in3), n2 = len(in5)))
# This version takes iterables
return ndarray_or_iterable(_PropsSII(in1, in2, in3, in4, in5, in6))
elif iterable(in3) and not(iterable(in5)):
i5 = [in5]*len(in3)
# This version takes iterables
return ndarray_or_iterable(_PropsSII(in1, in2, in3, in4, i5, in6))
elif iterable(in5) and not(iterable(in3)):
i3 = [in3]*len(in5)
# This version takes iterables
return ndarray_or_iterable(_PropsSII(in1, in2, i3, in4, in5, in6))
is_iterable1 = iterable(in1)
is_iterable3 = iterable(in3)
is_iterable5 = iterable(in5)
if is_iterable1 or is_iterable3 or is_iterable5:
# Prepare the output datatype
if not is_iterable1:
vin1.push_back(in1)
else:
vin1 = in1
# Resize state variable inputs
if is_iterable3 and is_iterable5:
if len(in3) != len(in5):
raise TypeError("Sizes of Prop1 {n1:d} and Prop2 {n2:d} to PropsSI are not the same".format(n1 = len(in3), n2 = len(in5)))
else:
vval1 = in3
vval2 = in5
elif is_iterable3 and not is_iterable5:
vval1 = in3
vval2 = [in5]*len(in3)
elif is_iterable5 and not is_iterable3:
vval1 = [in3]*len(in5)
vval2 = in5
# Extract the backend and the fluid from the input string
_extract_backend(in6, backend, fluid)
# Extract the fractions
fractions.push_back(1.0)
delimitedfluids = _extract_fractions(fluid, fractions)
# Extract the fluids
fluids = delimitedfluids.split('&')
# Call the function - this version takes iterables
outmat = _PropsSImulti(in1, in2, vval1, in4, vval2, backend, fluids, fractions)
# Check that we got some output
if outmat.empty():
raise ValueError(_get_global_param_string('errstring'))
return outmat
else:
# This version takes doubles
val = _PropsSI(in1, in2, in3, in4, in5, in6)
@@ -236,8 +268,6 @@ cpdef PropsSI(in1, in2, in3 = None, in4 = None, in5 = None, in6 = None, in7 = No
__Props_err2("PropsSI", in1, in2, in3, in4, in5, in6)
else:
return val
else:
return _PropsSI(in1, in2, in3, in4, in5, in6, in7)
cpdef list FluidsList():
"""