From 8327d54ea23a75d0b712d335ce4fcb59dc201319 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Wed, 19 Nov 2014 12:16:14 -0500 Subject: [PATCH] Replaced all tabs with spaces (finally) in C++ files Signed-off-by: Ian Bell --- include/AbstractState.h | 22 +- include/Ancillaries.h | 42 +- include/CachedElement.h | 88 +- include/CoolProp.h | 136 +- include/CoolPropFluid.h | 4 +- include/CoolPropTools.h | 240 +-- include/DataStructures.h | 4 +- include/Exceptions.h | 62 +- include/IncompressibleFluid.h | 488 ++--- include/MatrixMath.h | 942 ++++----- include/PolyMath.h | 1454 +++++++------- include/Solvers.h | 16 +- include/crossplatform_shared_ptr.h | 2 +- include/rapidjson/rapidjson/document.h | 1296 ++++++------ include/rapidjson/rapidjson/filestream.h | 48 +- include/rapidjson/rapidjson/internal/pow10.h | 76 +- include/rapidjson/rapidjson/internal/stack.h | 104 +- .../rapidjson/rapidjson/internal/strfunc.h | 16 +- include/rapidjson/rapidjson/prettywriter.h | 238 +-- include/rapidjson/rapidjson/rapidjson.h | 526 ++--- include/rapidjson/rapidjson/reader.h | 988 ++++----- include/rapidjson/rapidjson/stringbuffer.h | 34 +- include/rapidjson/rapidjson/writer.h | 352 ++-- include/rapidjson/rapidjson_include.h | 286 +-- src/AbstractState.cpp | 58 +- src/Backends/Helmholtz/ExcessHEFunction.h | 238 +-- src/Backends/Helmholtz/FlashRoutines.cpp | 130 +- src/Backends/Helmholtz/FlashRoutines.h | 4 +- src/Backends/Helmholtz/Fluids/Ancillaries.cpp | 364 ++-- .../Helmholtz/Fluids/FluidLibrary.cpp | 8 +- src/Backends/Helmholtz/Fluids/FluidLibrary.h | 16 +- .../Helmholtz/HelmholtzEOSMixtureBackend.cpp | 150 +- .../Helmholtz/HelmholtzEOSMixtureBackend.h | 24 +- src/Backends/Helmholtz/MixtureDerivatives.h | 300 +-- src/Backends/Helmholtz/MixtureParameters.cpp | 6 +- src/Backends/Helmholtz/ReducingFunctions.cpp | 70 +- src/Backends/Helmholtz/ReducingFunctions.h | 178 +- src/Backends/Helmholtz/TransportRoutines.cpp | 622 +++--- src/Backends/Helmholtz/VLERoutines.cpp | 102 +- src/Backends/Helmholtz/VLERoutines.h | 182 +- .../Incompressible/IncompressibleBackend.cpp | 988 ++++----- .../Incompressible/IncompressibleBackend.h | 8 +- .../Incompressible/IncompressibleFluid.cpp | 1416 ++++++------- .../Incompressible/IncompressibleLibrary.cpp | 648 +++--- .../Incompressible/IncompressibleLibrary.h | 168 +- src/Backends/REFPROP/REFPROPBackend.cpp | 20 +- src/Backends/REFPROP/REFPROPBackend.h | 8 +- .../REFPROP/REFPROPMixtureBackend.cpp | 132 +- src/Backends/REFPROP/REFPROPMixtureBackend.h | 114 +- src/CoolProp.cpp | 1004 +++++----- src/CoolPropLib.cpp | 124 +- src/CoolPropTools.cpp | 290 +-- src/DataStructures.cpp | 36 +- src/HumidAirProp.cpp | 12 +- src/Ice.cpp | 164 +- src/MatrixMath.cpp | 140 +- src/PolyMath.cpp | 1760 ++++++++--------- src/Solvers.cpp | 278 +-- src/Tests/TestObjects.cpp | 352 ++-- 59 files changed, 8789 insertions(+), 8789 deletions(-) diff --git a/include/AbstractState.h b/include/AbstractState.h index d2393c35..4b4ddf53 100644 --- a/include/AbstractState.h +++ b/include/AbstractState.h @@ -174,7 +174,7 @@ protected: /// Using this backend, calculate the maximum temperature in K virtual long double calc_Tmax(void){throw NotImplementedError("calc_Tmax is not implemented for this backend");}; - /// Using this backend, calculate the minimum temperature in K + /// Using this backend, calculate the minimum temperature in K virtual long double calc_Tmin(void){throw NotImplementedError("calc_Tmin is not implemented for this backend");}; /// Using this backend, calculate the maximum pressure in Pa virtual long double calc_pmax(void){throw NotImplementedError("calc_pmax is not implemented for this backend");}; @@ -242,17 +242,17 @@ protected: /// Update the states after having changed the reference state for enthalpy and entropy virtual void update_states(void){throw NotImplementedError("This backend does not implement update_states function");}; - - virtual long double calc_melting_line(int param, int given, long double value){throw NotImplementedError("This backend does not implement calc_melting_line function");}; + + virtual long double calc_melting_line(int param, int given, long double value){throw NotImplementedError("This backend does not implement calc_melting_line function");}; /// @param param The key for the parameter to be returned /// @param Q The quality for the parameter that is given (0 = saturated liquid, 1 = saturated vapor) /// @param given The key for the parameter that is given /// @param value The value for the parameter that is given virtual long double calc_saturation_ancillary(parameters param, int Q, parameters given, double value){throw NotImplementedError("This backend does not implement calc_saturation_ancillary");}; - + /// Using this backend, calculate the phase - virtual phases calc_phase(void){throw NotImplementedError("This backend does not implement calc_phase function");}; + virtual phases calc_phase(void){throw NotImplementedError("This backend does not implement calc_phase function");}; /// Using this backend, specify the phase to be used for all further calculations virtual void calc_specify_phase(phases phase){throw NotImplementedError("This backend does not implement calc_specify_phase function");}; /// Using this backend, unspecify the phase @@ -314,13 +314,13 @@ public: const CoolProp::SimpleState & get_state(const std::string &state){return calc_state(state);}; // Limits - double Tmin(void); + double Tmin(void); double Tmax(void); double pmax(void); double Ttriple(void); - + /// Get the phase of the state - phases phase(void){return calc_phase();}; + phases phase(void){return calc_phase();}; /// Specify the phase for all further calculations with this state class void specify_phase(phases phase){calc_specify_phase(phase);}; /// Unspecify the phase and go back to calculating it based on the inputs @@ -357,7 +357,7 @@ public: /// Retrieve a value by key double keyed_output(int key); /// A trivial keyed output like molar mass that does not depend on the state - double trivial_keyed_output(int key); + double trivial_keyed_output(int key); /// Return the temperature in K double T(void) {return _T;}; @@ -462,7 +462,7 @@ public: void build_phase_envelope(const std::string &type); const CoolProp::PhaseEnvelopeData &get_phase_envelope_data(){return calc_phase_envelope_data();}; - + // ---------------------------------------- // Ancillary equations // ---------------------------------------- @@ -473,7 +473,7 @@ public: /// @param param The key for the parameter to be returned /// @param given The key for the parameter that is given /// @param value The value for the parameter that is given - double melting_line(int param, int given, double value); + double melting_line(int param, int given, double value); /// Return the value from a saturation ancillary curve (if the backend implements it) /// @param param The key for the parameter to be returned /// @param Q The quality for the parameter that is given (0 = saturated liquid, 1 = saturated vapor) diff --git a/include/Ancillaries.h b/include/Ancillaries.h index c6345275..1e03d5f3 100644 --- a/include/Ancillaries.h +++ b/include/Ancillaries.h @@ -86,9 +86,9 @@ private: bool using_tau_r; long double Tmax, Tmin, reducing_value, T_r, max_abs_error; enum ancillaryfunctiontypes{TYPE_NOT_SET = 0, - TYPE_NOT_EXPONENTIAL, - TYPE_EXPONENTIAL, - TYPE_RATIONAL_POLYNOMIAL}; + TYPE_NOT_EXPONENTIAL, + TYPE_EXPONENTIAL, + TYPE_RATIONAL_POLYNOMIAL}; ancillaryfunctiontypes type; std::size_t N; public: @@ -100,29 +100,29 @@ public: bool enabled(void){return type != TYPE_NOT_SET;} /// Get the maximum absolute error for this fit - /// @returns max_abs_error the maximum absolute error for ancillaries that are characterized by maximum absolute error + /// @returns max_abs_error the maximum absolute error for ancillaries that are characterized by maximum absolute error long double get_max_abs_error(){return max_abs_error;}; - /// Evaluate this ancillary function, yielding for instance the saturated liquid density - /// @param T The temperature in K - /// @returns y the value of the ancillary function at temperature T + /// Evaluate this ancillary function, yielding for instance the saturated liquid density + /// @param T The temperature in K + /// @returns y the value of the ancillary function at temperature T double evaluate(double T); - - /// Invert this ancillary function, and calculate the temperature given the output the value of the function - /// @param value The value of the output + + /// Invert this ancillary function, and calculate the temperature given the output the value of the function + /// @param value The value of the output /// @param min_bound (optional) The minimum value for T; ignored if < 0 /// @param max_bound (optional) The maximum value for T; ignored if < 0 - /// @returns T The temperature in K + /// @returns T The temperature in K double invert(double value, double min_bound = -1, double max_bound = -1); /// Get the minimum temperature - /// @returns T The minimum temperature in K + /// @returns T The minimum temperature in K double get_Tmin(void){return Tmin;}; /// Get the maximum temperature - /// @returns T The maximum temperature in K + /// @returns T The maximum temperature in K double get_Tmax(void){return Tmax;}; - + }; struct MeltingLinePiecewiseSimonSegment @@ -179,14 +179,14 @@ public: MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE, MELTING_LINE_NOT_SET }; - long double Tmin, Tmax, pmin, pmax; + long double Tmin, Tmax, pmin, pmax; - long double evaluate(int OF, int GIVEN, long double value); - - /// Evaluate the melting line to calculate the limits of the curve (Tmin/Tmax and pmin/pmax) - void set_limits(); - - bool enabled(){return type != MELTING_LINE_NOT_SET;}; + long double evaluate(int OF, int GIVEN, long double value); + + /// Evaluate the melting line to calculate the limits of the curve (Tmin/Tmax and pmin/pmax) + void set_limits(); + + bool enabled(){return type != MELTING_LINE_NOT_SET;}; std::string BibTeX; long double T_m; ///< Melting temperature at 1 atmosphere MeltingLinePiecewiseSimonData simon; diff --git a/include/CachedElement.h b/include/CachedElement.h index 90026b00..9335f8c3 100644 --- a/include/CachedElement.h +++ b/include/CachedElement.h @@ -20,62 +20,62 @@ Includes an "=" assignment operator and casting to boolean so you can do something like:: double CoolPropStateClassSI::d3phir_dTau3(double tau, double delta){ - if (cache.d3phir_dTau3) { - return cache.d3phir_dTau3; - } else { - cache.d3phir_dTau3 = pFluid->d3phir_dTau3(tau,delta); - return cache.d3phir_dTau3; - } + if (cache.d3phir_dTau3) { + return cache.d3phir_dTau3; + } else { + cache.d3phir_dTau3 = pFluid->d3phir_dTau3(tau,delta); + return cache.d3phir_dTau3; + } }; */ class CachedElement { private: - bool is_cached; - long double value; + bool is_cached; + long double value; public: - /// Default constructor - CachedElement() { - this->clear(); - }; + /// Default constructor + CachedElement() { + this->clear(); + }; - /// Function to carry out the caching - void _do_cache(double value) - { - this->value = value; - this->is_cached = true; - } + /// Function to carry out the caching + void _do_cache(double value) + { + this->value = value; + this->is_cached = true; + } - /// Assignment operator - sets the value and sets the flag - void operator=(const double& value) { - _do_cache(value); - }; + /// Assignment operator - sets the value and sets the flag + void operator=(const double& value) { + _do_cache(value); + }; - /// Cast to boolean, for checking if cached - operator bool() {return is_cached;}; + /// Cast to boolean, for checking if cached + operator bool() {return is_cached;}; - /// Cast to double, for returning value - operator double() { - if (is_cached) {return static_cast(value); } - else { - throw std::exception(); - } - } + /// Cast to double, for returning value + operator double() { + if (is_cached) {return static_cast(value); } + else { + throw std::exception(); + } + } operator long double() { - if (is_cached) {return value; } - else { - throw std::exception(); - } - } - /// Clear the flag and the value - void clear() { - is_cached = false; - this->value = _HUGE; - }; - long double &pt(){ - return this->value; - } + if (is_cached) {return value; } + else { + throw std::exception(); + } + } + /// Clear the flag and the value + void clear() { + is_cached = false; + this->value = _HUGE; + }; + long double &pt(){ + return this->value; + } }; } /* namespace CoolProp */ diff --git a/include/CoolProp.h b/include/CoolProp.h index 9df4f995..779494c6 100644 --- a/include/CoolProp.h +++ b/include/CoolProp.h @@ -22,42 +22,42 @@ You might want to start by looking at CoolProp.h namespace CoolProp { /// Return a value that does not depend on the thermodynamic state - this is a convenience function that does the call PropsSI(Output, "", 0, "", 0, FluidName) - /// @param FluidName The fluid name + /// @param FluidName The fluid name /// @param Output The output parameter, one of "Tcrit","D","H",etc. double Props1SI(const std::string &FluidName, const std::string &Output); /// Return a value that depends on the thermodynamic state - /// @param Output The output parameter, one of "T","D","H",etc. - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name + /// @param Output The output parameter, one of "T","D","H",etc. + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &FluidName); /// Return a value that depends on the thermodynamic state - /// @param Output The output parameter, one of "T","D","H",etc. - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name + /// @param Output The output parameter, one of "T","D","H",etc. + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name /// @param z The mole or mass fractions depending on the requirements of the backend double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &FluidName, const std::vector &z); /// Return a value that depends on the thermodynamic state - /// @param Output The output parameter, one of "T","D","H",etc. - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name, or names seperated by '&' if a mixture + /// @param Output The output parameter, one of "T","D","H",etc. + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name, or names seperated by '&' if a mixture /// @param z The mole or mass fractions depending on the requirements of the backend std::vector PropsSI(const std::string &Output, const std::string &Name1, const std::vector &Prop1, const std::string &Name2, const std::vector Prop2, const std::string &FluidName, const std::vector &z); /// Return a value that depends on the thermodynamic state - /// @param Output The output parameter, one of "T","D","H",etc. - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name + /// @param Output The output parameter, one of "T","D","H",etc. + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name std::vector PropsSI(const std::string &Output, const std::string &Name1, const std::vector &Prop1, const std::string &Name2, const std::vector Prop2, const std::string &FluidName); /** @@ -74,27 +74,27 @@ You might want to start by looking at CoolProp.h void set_debug_level(int level); /// Set the global error string - /// @param error The error string to use - void set_error_string(std::string error); + /// @param error The error string to use + void set_error_string(std::string error); /// An internal function to set the global warning string - /// @param warning The string to set as the warning string - void set_warning_string(std::string warning); + /// @param warning The string to set as the warning string + void set_warning_string(std::string warning); /// Get a globally-defined string - /// @param ParamName A string, one of "version", "errstring", "warnstring", "gitrevision", "FluidsList", "fluids_list", "parameter_list" - /// @returns str The string, or an error message if not valid input - std::string get_global_param_string(std::string ParamName); + /// @param ParamName A string, one of "version", "errstring", "warnstring", "gitrevision", "FluidsList", "fluids_list", "parameter_list" + /// @returns str The string, or an error message if not valid input + std::string get_global_param_string(std::string ParamName); - /*/// Get a long that represents the fluid type - /// @param FluidName The fluid name as a string - /// @returns long element from global type enumeration - long getFluidType(std::string FluidName);*/ + /*/// Get a long that represents the fluid type + /// @param FluidName The fluid name as a string + /// @returns long element from global type enumeration + long getFluidType(std::string FluidName);*/ - /** + /** \brief Get a string for a value from a fluid (numerical values for the fluid can be obtained from Props1SI function) - @param FluidName The name of the fluid that is part of CoolProp, for instance "n-Propane" - @param ParamName A string, can be in one of the terms described in the following table + @param FluidName The name of the fluid that is part of CoolProp, for instance "n-Propane" + @param ParamName A string, can be in one of the terms described in the following table ParamName | Description -------------------------- | ---------------------------------------- @@ -102,22 +102,22 @@ You might want to start by looking at CoolProp.h "CAS", "CAS_number" | The CAS number "ASHRAE34" | The ASHRAE standard 34 safety rating "REFPROPName","REFPROP_name" | The name of the fluid used in REFPROP - + @returns The string, or an error message if not valid input */ - std::string get_fluid_param_string(std::string FluidName, std::string ParamName); + std::string get_fluid_param_string(std::string FluidName, std::string ParamName); - /// Returns the BibTeX key from the bibtex library of CoolProp corresponding to the item requested - /// @param FluidName The name of the fluid that is part of CoolProp, for instance "n-Propane" - /// @param item The key that is desired, one of "EOS", "CP0", "VISCOSITY", "CONDUCTIVITY", "ECS_LENNARD_JONES", "ECS_FITS", "SURFACE_TENSION" - /// @returns The BibTeX key - std::string get_BibTeXKey(std::string FluidName, std::string item); - - /** + /// Returns the BibTeX key from the bibtex library of CoolProp corresponding to the item requested + /// @param FluidName The name of the fluid that is part of CoolProp, for instance "n-Propane" + /// @param item The key that is desired, one of "EOS", "CP0", "VISCOSITY", "CONDUCTIVITY", "ECS_LENNARD_JONES", "ECS_FITS", "SURFACE_TENSION" + /// @returns The BibTeX key + std::string get_BibTeXKey(std::string FluidName, std::string item); + + /** \brief Set the reference state based on a string representation - @param FluidName The name of the fluid - @param reference_state The reference state to use, one of + @param FluidName The name of the fluid + @param reference_state The reference state to use, one of Reference State | Description ------------- | ------------------- @@ -133,30 +133,30 @@ You might want to start by looking at CoolProp.h \f] where \f$ \Delta s = s-_{spec} \f$ and \f$ \Delta h = h-_{spec} \f$ */ - void set_reference_stateS(std::string FluidName, std::string reference_state); + void set_reference_stateS(std::string FluidName, std::string reference_state); - /// Set the reference state based on a thermodynamic state point specified by temperature and molar density - /// @param FluidName The name of the fluid - /// @param T Temperature at reference state [K] - /// @param rhomolar Density at reference state [mol/m^3] - /// @param h0 Enthalpy at reference state [J/kg] - /// @param s0 Entropy at references state [J/kg/K] - void set_reference_stateD(std::string FluidName, double T, double rhomolar, double h0, double s0); + /// Set the reference state based on a thermodynamic state point specified by temperature and molar density + /// @param FluidName The name of the fluid + /// @param T Temperature at reference state [K] + /// @param rhomolar Density at reference state [mol/m^3] + /// @param h0 Enthalpy at reference state [J/kg] + /// @param s0 Entropy at references state [J/kg/K] + void set_reference_stateD(std::string FluidName, double T, double rhomolar, double h0, double s0); /// Return a string representation of the phase - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name /// \note Returns empty string if there was an error; use get_global_param_string("errstring") to retrieve the error std::string PhaseSI(const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &FluidName); /// Return a string representation of the phase - /// @param Name1 The first state variable name, one of "T","D","H",etc. - /// @param Prop1 The first state variable value - /// @param Name2 The second state variable name, one of "T","D","H",etc. - /// @param Prop2 The second state variable value - /// @param FluidName The fluid name + /// @param Name1 The first state variable name, one of "T","D","H",etc. + /// @param Prop1 The first state variable value + /// @param Name2 The second state variable name, one of "T","D","H",etc. + /// @param Prop2 The second state variable value + /// @param FluidName The fluid name /// @param z The mole or mass fractions depending on the requirements of the backend /// \note Returns empty string if there was an error; use get_global_param_string("errstring") to retrieve the error std::string PhaseSI(const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &FluidName, const std::vector &z); diff --git a/include/CoolPropFluid.h b/include/CoolPropFluid.h index c7185a9b..983fb5cd 100644 --- a/include/CoolPropFluid.h +++ b/include/CoolPropFluid.h @@ -149,8 +149,8 @@ struct ConductivityCriticalSimplifiedOlchowySengersData{ // Universal constants - can still be adjusted if need be k = 1.3806488e-23; //[J/K] R0 = 1.03; //[-] - gamma = 1.239; //[-] - nu = 0.63; //[-] + gamma = 1.239; //[-] + nu = 0.63; //[-] // Suggested default values - can be over-written GAMMA = 0.0496; //[-] zeta0 = 1.94e-10; //[m] diff --git a/include/CoolPropTools.h b/include/CoolPropTools.h index 25b4eeaf..27491002 100644 --- a/include/CoolPropTools.h +++ b/include/CoolPropTools.h @@ -4,7 +4,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "PlatformDetermination.h" - #include "Exceptions.h" + #include "Exceptions.h" #include #include @@ -28,113 +28,113 @@ #endif #endif - #if defined(_MSC_VER) - // Microsoft version of math.h doesn't include acosh or asinh, so we just define them here. - // It was included from Visual Studio 2013 - #if _MSC_VER < 1800 - static double acosh(double x) - { - return log(x + sqrt(x*x - 1.0)); - } - static double asinh(double value) - { - if(value>0){ - return log(value + sqrt(value * value + 1)); - } - else{ - return -log(-value + sqrt(value * value + 1)); - } - } - #endif - #endif + #if defined(_MSC_VER) + // Microsoft version of math.h doesn't include acosh or asinh, so we just define them here. + // It was included from Visual Studio 2013 + #if _MSC_VER < 1800 + static double acosh(double x) + { + return log(x + sqrt(x*x - 1.0)); + } + static double asinh(double value) + { + if(value>0){ + return log(value + sqrt(value * value + 1)); + } + else{ + return -log(-value + sqrt(value * value + 1)); + } + } + #endif + #endif - #if defined(__powerpc__) - // PPC version of math.h doesn't include acosh or asinh, so we just define them here - static double acosh(double x) - { - return log(x + sqrt(x*x - 1.0) ); - } - static double asinh(double value) - { - if(value>0){ - return log(value + sqrt(value * value + 1)); - } - else{ - return -log(-value + sqrt(value * value + 1)); - } - } - #endif + #if defined(__powerpc__) + // PPC version of math.h doesn't include acosh or asinh, so we just define them here + static double acosh(double x) + { + return log(x + sqrt(x*x - 1.0) ); + } + static double asinh(double value) + { + if(value>0){ + return log(value + sqrt(value * value + 1)); + } + else{ + return -log(-value + sqrt(value * value + 1)); + } + } + #endif - #if defined(__powerpc__) - #undef min - #undef max - #undef EOS - #endif + #if defined(__powerpc__) + #undef min + #undef max + #undef EOS + #endif - inline bool ValidNumber(double x) - { - // Idea from http://www.johndcook.com/IEEE_exceptions_in_cpp.html - return (x <= DBL_MAX && x >= -DBL_MAX); - }; + inline bool ValidNumber(double x) + { + // Idea from http://www.johndcook.com/IEEE_exceptions_in_cpp.html + return (x <= DBL_MAX && x >= -DBL_MAX); + }; - /// Define the deprecated macro to give compile-time warnings - #ifdef __GNUC__ - #define DEPRECATED(func) func __attribute__ ((deprecated)) - #elif defined(_MSC_VER) - #define DEPRECATED(func) __declspec(deprecated) func - #else - #pragma message("WARNING: You need to implement DEPRECATED for this compiler") - #define DEPRECATED(func) func - #endif + /// Define the deprecated macro to give compile-time warnings + #ifdef __GNUC__ + #define DEPRECATED(func) func __attribute__ ((deprecated)) + #elif defined(_MSC_VER) + #define DEPRECATED(func) __declspec(deprecated) func + #else + #pragma message("WARNING: You need to implement DEPRECATED for this compiler") + #define DEPRECATED(func) func + #endif - #include - #include - #include + #include + #include + #include #include - #include - #include - #include - #include + #include + #include + #include + #include - /// The following code for the trim functions was taken from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring - // trim from start - inline std::string &strlstrip(std::string &s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); - return s; - } - // trim from end - inline std::string &strrstrip(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); - return s; - } - // trim from both ends - inline std::string &strstrip(std::string &s) { - return strlstrip(strrstrip(s)); - } + /// The following code for the trim functions was taken from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring + // trim from start + inline std::string &strlstrip(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + return s; + } + // trim from end + inline std::string &strrstrip(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; + } + // trim from both ends + inline std::string &strstrip(std::string &s) { + return strlstrip(strrstrip(s)); + } - // Get all the contents of a file and dump into a STL string - // Thanks to http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring - std::string get_file_contents(const char *filename); + // Get all the contents of a file and dump into a STL string + // Thanks to http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring + std::string get_file_contents(const char *filename); // Missing string printf std::string format(const char* fmt, ...); - // Missing string split - like in Python - std::vector strsplit(std::string s, char del); + // Missing string split - like in Python + std::vector strsplit(std::string s, char del); - inline std::string upper(const std::string str_) - { - std::string str = str_; - std::transform(str.begin(), str.end(), str.begin(), ::toupper); - return str; - } + inline std::string upper(const std::string str_) + { + std::string str = str_; + std::transform(str.begin(), str.end(), str.begin(), ::toupper); + return str; + } - std::string strjoin(std::vector strings, std::string delim); + std::string strjoin(std::vector strings, std::string delim); - void MatInv_2(double A[2][2] , double B[2][2]); + void MatInv_2(double A[2][2] , double B[2][2]); - double root_sum_square(std::vector x); - double interp1d(std::vector *x, std::vector *y, double x0); - double powInt(double x, int y); + double root_sum_square(std::vector x); + double interp1d(std::vector *x, std::vector *y, double x0); + double powInt(double x, int y); #define POW2(x) ((x)*(x)) #define POW3(x) ((x)*(x)*(x)) @@ -164,23 +164,23 @@ L2=((x-x0)*(x-x1))/((x2-x0)*(x2-x1)); return L0*f0+L1*f1+L2*f2; }; - template T QuadInterp(std::vector x, std::vector y, std::size_t i0, std::size_t i1, std::size_t i2, T val) + template T QuadInterp(std::vector x, std::vector y, std::size_t i0, std::size_t i1, std::size_t i2, T val) { return QuadInterp(x[i0],x[i1],x[i2],y[i0],y[i1],y[i2],val); }; template T CubicInterp( T x0, T x1, T x2, T x3, T f0, T f1, T f2, T f3, T x) { - /* - Lagrange cubic interpolation as from - http://nd.edu/~jjwteach/441/PdfNotes/lecture6.pdf - */ - T L0,L1,L2,L3; - L0=((x-x1)*(x-x2)*(x-x3))/((x0-x1)*(x0-x2)*(x0-x3)); - L1=((x-x0)*(x-x2)*(x-x3))/((x1-x0)*(x1-x2)*(x1-x3)); - L2=((x-x0)*(x-x1)*(x-x3))/((x2-x0)*(x2-x1)*(x2-x3)); - L3=((x-x0)*(x-x1)*(x-x2))/((x3-x0)*(x3-x1)*(x3-x2)); - return L0*f0+L1*f1+L2*f2+L3*f3; + /* + Lagrange cubic interpolation as from + http://nd.edu/~jjwteach/441/PdfNotes/lecture6.pdf + */ + T L0,L1,L2,L3; + L0=((x-x1)*(x-x2)*(x-x3))/((x0-x1)*(x0-x2)*(x0-x3)); + L1=((x-x0)*(x-x2)*(x-x3))/((x1-x0)*(x1-x2)*(x1-x3)); + L2=((x-x0)*(x-x1)*(x-x3))/((x2-x0)*(x2-x1)*(x2-x3)); + L3=((x-x0)*(x-x1)*(x-x2))/((x3-x0)*(x3-x1)*(x3-x2)); + return L0*f0+L1*f1+L2*f2+L3*f3; }; template T CubicInterp(std::vector x, std::vector y, std::size_t i0, std::size_t i1, std::size_t i2, std::size_t i3, T val) { @@ -189,7 +189,7 @@ template T is_in_closed_range( T x1, T x2, T x) { - return (x >= std::min(x1,x2) && x <= std::max(x1,x2)); + return (x >= std::min(x1,x2) && x <= std::max(x1,x2)); }; /** \brief Solve a cubic with coefficients in decreasing order @@ -205,12 +205,12 @@ * @param x1 The second solution found * @param x2 The third solution found */ - void solve_cubic(double a, double b, double c, double d, int &N, double &x0, double &x1, double &x2); + void solve_cubic(double a, double b, double c, double d, int &N, double &x0, double &x1, double &x2); - inline double min3(double x1, double x2, double x3){return std::min(std::min(x1, x2), x3);}; - inline double max3(double x1, double x2, double x3){return std::max(std::max(x1, x2), x3);}; + inline double min3(double x1, double x2, double x3){return std::min(std::min(x1, x2), x3);}; + inline double max3(double x1, double x2, double x3){return std::max(std::max(x1, x2), x3);}; - inline bool double_equal(double a, double b){return std::abs(a - b) <= 1 * DBL_EPSILON * std::max(std::abs(a), std::abs(b));}; + inline bool double_equal(double a, double b){return std::abs(a - b) <= 1 * DBL_EPSILON * std::max(std::abs(a), std::abs(b));}; template T max_abs_value(std::vector x) { @@ -236,7 +236,7 @@ return min; } - inline int Kronecker_delta(int i, int j){if (i == j) {return 1;} else {return 0;}}; + inline int Kronecker_delta(int i, int j){if (i == j) {return 1;} else {return 0;}}; class Dictionary { @@ -313,18 +313,18 @@ /// Some functions related to testing and comparison of values bool inline check_abs(double A, double B, double D){ - double max = std::abs(A); - double min = std::abs(B); - if (min>max) { - max = min; - min = std::abs(A); - } - if (max>DBL_EPSILON*1e3) return ( ( 1.0-min/max*1e0 ) < D ); - else throw CoolProp::ValueError(format("Too small numbers: %f cannot be tested with an accepted error of %f for a machine precision of %f. ",max,D,DBL_EPSILON)); + double max = std::abs(A); + double min = std::abs(B); + if (min>max) { + max = min; + min = std::abs(A); + } + if (max>DBL_EPSILON*1e3) return ( ( 1.0-min/max*1e0 ) < D ); + else throw CoolProp::ValueError(format("Too small numbers: %f cannot be tested with an accepted error of %f for a machine precision of %f. ",max,D,DBL_EPSILON)); }; bool inline check_abs(double A, double B){ - return check_abs(A,B,1e5*DBL_EPSILON); - }; + return check_abs(A,B,1e5*DBL_EPSILON); + }; template void normalize_vector(std::vector &x) { diff --git a/include/DataStructures.h b/include/DataStructures.h index 7d8c3564..5c6cc818 100644 --- a/include/DataStructures.h +++ b/include/DataStructures.h @@ -46,13 +46,13 @@ enum parameters{ irhomolar_critical, iT_reducing, iT_critical, - irhomass_reducing, + irhomass_reducing, irhomass_critical, iP_critical, iT_triple, iP_triple, iT_min, - iT_max, + iT_max, iP_max, iP_min, diff --git a/include/Exceptions.h b/include/Exceptions.h index 2c7388e9..81c0c4e7 100644 --- a/include/Exceptions.h +++ b/include/Exceptions.h @@ -12,92 +12,92 @@ namespace CoolProp class CoolPropBaseError: public std::exception { protected: - std::string err; // Can be accessed by subclasses since it is protected + std::string err; // Can be accessed by subclasses since it is protected public: - CoolPropBaseError() throw() {}; - ~CoolPropBaseError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + CoolPropBaseError() throw() {}; + ~CoolPropBaseError() throw() {}; + virtual const char* what() const throw(){ return err.c_str(); } }; class NotImplementedError: public CoolPropBaseError { public: - NotImplementedError() throw() {}; - NotImplementedError(std::string errstring) throw(){err=errstring;}; + NotImplementedError() throw() {}; + NotImplementedError(std::string errstring) throw(){err=errstring;}; ~NotImplementedError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class SolutionError: public CoolPropBaseError { public: - SolutionError()throw() {}; - SolutionError(std::string errstring) throw(){err=errstring;}; + SolutionError()throw() {}; + SolutionError(std::string errstring) throw(){err=errstring;}; ~SolutionError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class ValueError: public CoolPropBaseError { public: - ValueError() throw() {}; - ValueError(std::string errstring) throw(){err=errstring;}; + ValueError() throw() {}; + ValueError(std::string errstring) throw(){err=errstring;}; ~ValueError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class AttributeError: public CoolPropBaseError { public: - AttributeError() throw() {}; - AttributeError(std::string errstring) throw() {err=errstring;}; + AttributeError() throw() {}; + AttributeError(std::string errstring) throw() {err=errstring;}; ~AttributeError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class OutOfRangeError: public ValueError { public: - OutOfRangeError() throw() {}; - OutOfRangeError(std::string errstring) throw() {err=errstring;}; + OutOfRangeError() throw() {}; + OutOfRangeError(std::string errstring) throw() {err=errstring;}; ~OutOfRangeError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class WrongFluidError: public ValueError { public: - WrongFluidError() throw() {}; - WrongFluidError(std::string errstring) throw() {err=errstring;}; + WrongFluidError() throw() {}; + WrongFluidError(std::string errstring) throw() {err=errstring;}; ~WrongFluidError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class CompositionError: public ValueError { public: - CompositionError() throw() {}; - CompositionError(std::string errstring) throw() {err=errstring;}; + CompositionError() throw() {}; + CompositionError(std::string errstring) throw() {err=errstring;}; ~CompositionError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class InputError: public ValueError { public: - InputError() throw() {}; - InputError(std::string errstring) throw() {err=errstring;}; + InputError() throw() {}; + InputError(std::string errstring) throw() {err=errstring;}; ~InputError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; class NotAvailableError: public ValueError { public: - NotAvailableError() throw() {}; - NotAvailableError(std::string errstring) throw() {err=errstring;}; + NotAvailableError() throw() {}; + NotAvailableError(std::string errstring) throw() {err=errstring;}; ~NotAvailableError() throw() {}; - virtual const char* what() const throw(){ return err.c_str(); } + virtual const char* what() const throw(){ return err.c_str(); } }; }; /* namespace CoolProp */ diff --git a/include/IncompressibleFluid.h b/include/IncompressibleFluid.h index b5c9e449..a5f2c6df 100644 --- a/include/IncompressibleFluid.h +++ b/include/IncompressibleFluid.h @@ -26,20 +26,20 @@ namespace CoolProp { struct IncompressibleData { - enum IncompressibleTypeEnum { - INCOMPRESSIBLE_NOT_SET, - INCOMPRESSIBLE_POLYNOMIAL, - INCOMPRESSIBLE_EXPPOLYNOMIAL, - INCOMPRESSIBLE_EXPONENTIAL, - INCOMPRESSIBLE_LOGEXPONENTIAL, - INCOMPRESSIBLE_POLYOFFSET - }; - IncompressibleTypeEnum type; - Eigen::MatrixXd coeffs; //TODO: Can we store the Eigen::Matrix objects more efficiently? - //std::vector > coeffs; - IncompressibleData() { - type = INCOMPRESSIBLE_NOT_SET; - }; + enum IncompressibleTypeEnum { + INCOMPRESSIBLE_NOT_SET, + INCOMPRESSIBLE_POLYNOMIAL, + INCOMPRESSIBLE_EXPPOLYNOMIAL, + INCOMPRESSIBLE_EXPONENTIAL, + INCOMPRESSIBLE_LOGEXPONENTIAL, + INCOMPRESSIBLE_POLYOFFSET + }; + IncompressibleTypeEnum type; + Eigen::MatrixXd coeffs; //TODO: Can we store the Eigen::Matrix objects more efficiently? + //std::vector > coeffs; + IncompressibleData() { + type = INCOMPRESSIBLE_NOT_SET; + }; }; /// A property provider for incompressible solutions and pure fluids @@ -49,273 +49,273 @@ This fluid instance is populated using an entry from a JSON file class IncompressibleFluid{ protected: - bool strict; + bool strict; - std::string name; - std::string description; - std::string reference; + std::string name; + std::string description; + std::string reference; - double Tmin, Tmax; - double xmin, xmax; - composition_types xid; + double Tmin, Tmax; + double xmin, xmax; + composition_types xid; - double TminPsat; - double xref, Tref, pref; - double href, sref; - double uref, rhoref; - double xbase, Tbase; + double TminPsat; + double xref, Tref, pref; + double href, sref; + double uref, rhoref; + double xbase, Tbase; - /// These are the objects that hold the coefficients - /** Note that all polynomials require a 2-dimensional array - * of coefficients. This array may have only one row or - * column, but the structure should be 2D. This behaviour is - * hard-coded in the JSON file reader that resides inside - * the IncompressibleLibrary.cpp - * All other functions, also polyoffset, can only handle 1D - * input and throw an error if you feed them other coefficients. - */ + /// These are the objects that hold the coefficients + /** Note that all polynomials require a 2-dimensional array + * of coefficients. This array may have only one row or + * column, but the structure should be 2D. This behaviour is + * hard-coded in the JSON file reader that resides inside + * the IncompressibleLibrary.cpp + * All other functions, also polyoffset, can only handle 1D + * input and throw an error if you feed them other coefficients. + */ - /// Density coefficients - /** If 2D, the rows are temperature and the columns are concentration. - * If 1D, should be a column vector of temperature coefficients - */ - IncompressibleData density; - /// Specific heat coefficients - /** If 2D, the rows are temperature and the columns are concentration. - * If 1D, should be a column vector of temperature coefficients - * Fails for all other forms than polynomial due to the automatic - * integration for internal energy and entropy. - */ - IncompressibleData specific_heat; - /// Viscosity coefficients - /** If 2D, the rows are temperature and the columns are concentration. - * If 1D, should be a column vector of temperature coefficients - */ - IncompressibleData viscosity; - /// Conductivity coefficients - /** If 2D, the rows are temperature and the columns are concentration. - * If 1D, should be a column vector of temperature coefficients - */ - IncompressibleData conductivity; - /// Saturation pressure coefficients - /** If 2D, the rows are temperature and the columns are concentration. - * If 1D, should be a column vector of temperature coefficients - */ - IncompressibleData p_sat; - /// Freezing temperature coefficients - /** If 2D, the rows are concentration and the columns are pressure. - * If 1D, should be a column vector of concentration coefficients - */ - IncompressibleData T_freeze; + /// Density coefficients + /** If 2D, the rows are temperature and the columns are concentration. + * If 1D, should be a column vector of temperature coefficients + */ + IncompressibleData density; + /// Specific heat coefficients + /** If 2D, the rows are temperature and the columns are concentration. + * If 1D, should be a column vector of temperature coefficients + * Fails for all other forms than polynomial due to the automatic + * integration for internal energy and entropy. + */ + IncompressibleData specific_heat; + /// Viscosity coefficients + /** If 2D, the rows are temperature and the columns are concentration. + * If 1D, should be a column vector of temperature coefficients + */ + IncompressibleData viscosity; + /// Conductivity coefficients + /** If 2D, the rows are temperature and the columns are concentration. + * If 1D, should be a column vector of temperature coefficients + */ + IncompressibleData conductivity; + /// Saturation pressure coefficients + /** If 2D, the rows are temperature and the columns are concentration. + * If 1D, should be a column vector of temperature coefficients + */ + IncompressibleData p_sat; + /// Freezing temperature coefficients + /** If 2D, the rows are concentration and the columns are pressure. + * If 1D, should be a column vector of concentration coefficients + */ + IncompressibleData T_freeze; - /// Mass fraction conversion coefficients - /** If the fluid type is mass-based, it does not do anything. Otherwise, - * it converts the mass fraction to the required input. - */ - IncompressibleData mass2input; - /// Volume fraction conversion coefficients - /** If the fluid type is volume-based, it does not do anything. Otherwise, - * it converts the volume fraction to the required input. - */ - IncompressibleData volume2input; - /// Mole fraction conversion coefficients - /** If the fluid type is mole-based, it does not do anything. Otherwise, - * it converts the mole fraction to the required input. - */ - IncompressibleData mole2input; + /// Mass fraction conversion coefficients + /** If the fluid type is mass-based, it does not do anything. Otherwise, + * it converts the mass fraction to the required input. + */ + IncompressibleData mass2input; + /// Volume fraction conversion coefficients + /** If the fluid type is volume-based, it does not do anything. Otherwise, + * it converts the volume fraction to the required input. + */ + IncompressibleData volume2input; + /// Mole fraction conversion coefficients + /** If the fluid type is mole-based, it does not do anything. Otherwise, + * it converts the mole fraction to the required input. + */ + IncompressibleData mole2input; - Polynomial2DFrac poly; + Polynomial2DFrac poly; - // Forward declaration of the some internal functions - //double h_u(double T, double p, double x); - //double u_h(double T, double p, double x); + // Forward declaration of the some internal functions + //double h_u(double T, double p, double x); + //double u_h(double T, double p, double x); public: - IncompressibleFluid(){strict = true; xid = IFRAC_UNDEFINED;}; - virtual ~IncompressibleFluid(){}; + IncompressibleFluid(){strict = true; xid = IFRAC_UNDEFINED;}; + virtual ~IncompressibleFluid(){}; - std::string getName() const {return name;} - std::string get_name() const {return getName();}// For backwards-compatibility. - std::string getDescription() const {return description;} - std::string getReference() const {return reference;} + std::string getName() const {return name;} + std::string get_name() const {return getName();}// For backwards-compatibility. + std::string getDescription() const {return description;} + std::string getReference() const {return reference;} - double getTmax() const {return Tmax;} - double getTmin() const {return Tmin;} - double getxmax() const {return xmax;} - double getxmin() const {return xmin;} - composition_types getxid() const {return xid;} - double getTminPsat() const {return TminPsat;} - double getTref() const {return Tref;} - double getpref() const {return pref;} - double getxref() const {return xref;} - double gethref() const {return href;} - double getsref() const {return sref;} - double getTbase() const {return Tbase;} - double getxbase() const {return xbase;} + double getTmax() const {return Tmax;} + double getTmin() const {return Tmin;} + double getxmax() const {return xmax;} + double getxmin() const {return xmin;} + composition_types getxid() const {return xid;} + double getTminPsat() const {return TminPsat;} + double getTref() const {return Tref;} + double getpref() const {return pref;} + double getxref() const {return xref;} + double gethref() const {return href;} + double getsref() const {return sref;} + double getTbase() const {return Tbase;} + double getxbase() const {return xbase;} - void setName(std::string name) {this->name = name;} - void setDescription(std::string description) {this->description = description;} - void setReference(std::string reference) {this->reference = reference;} - void setTmax(double Tmax) {this->Tmax = Tmax;} - void setTmin(double Tmin) {this->Tmin = Tmin;} - void setxmax(double xmax) {this->xmax = xmax;} - void setxmin(double xmin) {this->xmin = xmin;} - void setxid(composition_types xid) {this->xid = xid;} - void setTminPsat(double TminPsat) {this->TminPsat = TminPsat;} - //void setTref(double Tref) {this->Tref = Tref;} - //void setpref(double pref) {this->pref = pref;} - //void setxref(double xref) {this->xref = xref;} - void set_reference_state(double T0, double p0, double x0, double h0, double s0); - void setTbase(double Tbase) {this->Tbase = Tbase;} - void setxbase(double xbase) {this->xbase = xbase;} + void setName(std::string name) {this->name = name;} + void setDescription(std::string description) {this->description = description;} + void setReference(std::string reference) {this->reference = reference;} + void setTmax(double Tmax) {this->Tmax = Tmax;} + void setTmin(double Tmin) {this->Tmin = Tmin;} + void setxmax(double xmax) {this->xmax = xmax;} + void setxmin(double xmin) {this->xmin = xmin;} + void setxid(composition_types xid) {this->xid = xid;} + void setTminPsat(double TminPsat) {this->TminPsat = TminPsat;} + //void setTref(double Tref) {this->Tref = Tref;} + //void setpref(double pref) {this->pref = pref;} + //void setxref(double xref) {this->xref = xref;} + void set_reference_state(double T0, double p0, double x0, double h0, double s0); + void setTbase(double Tbase) {this->Tbase = Tbase;} + void setxbase(double xbase) {this->xbase = xbase;} - /// Setters for the coefficients - void setDensity(IncompressibleData density){this->density = density;} - void setSpecificHeat(IncompressibleData specific_heat){this->specific_heat = specific_heat;} - void setViscosity(IncompressibleData viscosity){this->viscosity = viscosity;} - void setConductivity(IncompressibleData conductivity){this->conductivity = conductivity;} - void setPsat(IncompressibleData p_sat){this->p_sat = p_sat;} - void setTfreeze(IncompressibleData T_freeze){this->T_freeze = T_freeze;} + /// Setters for the coefficients + void setDensity(IncompressibleData density){this->density = density;} + void setSpecificHeat(IncompressibleData specific_heat){this->specific_heat = specific_heat;} + void setViscosity(IncompressibleData viscosity){this->viscosity = viscosity;} + void setConductivity(IncompressibleData conductivity){this->conductivity = conductivity;} + void setPsat(IncompressibleData p_sat){this->p_sat = p_sat;} + void setTfreeze(IncompressibleData T_freeze){this->T_freeze = T_freeze;} - /// Setters for the concentration conversion coefficients - void setMass2input(IncompressibleData mass2input){this->mass2input = mass2input;} - void setVolume2input(IncompressibleData volume2input){this->volume2input = volume2input;} - void setMole2input(IncompressibleData mole2input){this->mole2input = mole2input;} + /// Setters for the concentration conversion coefficients + void setMass2input(IncompressibleData mass2input){this->mass2input = mass2input;} + void setVolume2input(IncompressibleData volume2input){this->volume2input = volume2input;} + void setMole2input(IncompressibleData mole2input){this->mole2input = mole2input;} - /// A function to check coefficients and equation types. - void validate(); - /// A function to test the density coefficients for 1D or 2D - bool is_pure(); + /// A function to check coefficients and equation types. + void validate(); + /// A function to test the density coefficients for 1D or 2D + bool is_pure(); protected: - /// Base functions that handle the custom function types - double baseExponential(IncompressibleData data, double y, double ybase); - double baseLogexponential(IncompressibleData data, double y, double ybase); - double baseExponentialOffset(IncompressibleData data, double y); - double basePolyOffset(IncompressibleData data, double y, double z=0.0); + /// Base functions that handle the custom function types + double baseExponential(IncompressibleData data, double y, double ybase); + double baseLogexponential(IncompressibleData data, double y, double ybase); + double baseExponentialOffset(IncompressibleData data, double y); + double basePolyOffset(IncompressibleData data, double y, double z=0.0); public: - /* All functions need T and p as input. Might not - * be necessary, but gives a clearer structure. - */ - /// Density as a function of temperature, pressure and composition. - double rho (double T, double p, double x); - /// Heat capacities as a function of temperature, pressure and composition. - double c (double T, double p, double x); - double cp (double T, double p, double x){return c(T,p,x);}; - double cv (double T, double p, double x){return c(T,p,x);}; - /// Entropy as a function of temperature, pressure and composition. - double s (double T, double p, double x); - /// Internal energy as a function of temperature, pressure and composition. - double u (double T, double p, double x); - /// Enthalpy as a function of temperature, pressure and composition. - double h (double T, double p, double x); - /// Viscosity as a function of temperature, pressure and composition. - double visc(double T, double p, double x); - /// Thermal conductivity as a function of temperature, pressure and composition. - double cond(double T, double p, double x); - /// Saturation pressure as a function of temperature and composition. - double psat(double T, double x); - /// Freezing temperature as a function of pressure and composition. - double Tfreeze( double p, double x); + /* All functions need T and p as input. Might not + * be necessary, but gives a clearer structure. + */ + /// Density as a function of temperature, pressure and composition. + double rho (double T, double p, double x); + /// Heat capacities as a function of temperature, pressure and composition. + double c (double T, double p, double x); + double cp (double T, double p, double x){return c(T,p,x);}; + double cv (double T, double p, double x){return c(T,p,x);}; + /// Entropy as a function of temperature, pressure and composition. + double s (double T, double p, double x); + /// Internal energy as a function of temperature, pressure and composition. + double u (double T, double p, double x); + /// Enthalpy as a function of temperature, pressure and composition. + double h (double T, double p, double x); + /// Viscosity as a function of temperature, pressure and composition. + double visc(double T, double p, double x); + /// Thermal conductivity as a function of temperature, pressure and composition. + double cond(double T, double p, double x); + /// Saturation pressure as a function of temperature and composition. + double psat(double T, double x); + /// Freezing temperature as a function of pressure and composition. + double Tfreeze( double p, double x); - /// Mass fraction conversion function - /** If the fluid type is mass-based, it does not do anything. Otherwise, - * it converts the mass fraction to the required input. */ - double inputFromMass (double T, double x); - /// Volume fraction conversion function - /** If the fluid type is volume-based, it does not do anything. Otherwise, - * it converts the volume fraction to the required input. */ - double inputFromVolume (double T, double x); - /// Mole fraction conversion function - /** If the fluid type is mole-based, it does not do anything. Otherwise, - * it converts the mole fraction to the required input. */ - double inputFromMole (double T, double x); + /// Mass fraction conversion function + /** If the fluid type is mass-based, it does not do anything. Otherwise, + * it converts the mass fraction to the required input. */ + double inputFromMass (double T, double x); + /// Volume fraction conversion function + /** If the fluid type is volume-based, it does not do anything. Otherwise, + * it converts the volume fraction to the required input. */ + double inputFromVolume (double T, double x); + /// Mole fraction conversion function + /** If the fluid type is mole-based, it does not do anything. Otherwise, + * it converts the mole fraction to the required input. */ + double inputFromMole (double T, double x); - /* Some functions can be inverted directly, those are listed - * here. It is also possible to solve for other quantities, but - * that involves some more sophisticated processing and is not - * done here, but in the backend, T(h,p) for example. - */ - /// Temperature as a function of density, pressure and composition. - double T_rho (double Dmass, double p, double x); - /// Temperature as a function of heat capacities as a function of temperature, pressure and composition. - double T_c (double Cmass, double p, double x); - /// Temperature as a function of entropy as a function of temperature, pressure and composition. - double T_s (double Smass, double p, double x); - /// Temperature as a function of internal energy as a function of temperature, pressure and composition. - double T_u (double Umass, double p, double x); - /// Temperature as a function of enthalpy, pressure and composition. - double T_h (double Hmass, double p, double x){throw NotImplementedError(format("%s (%d): T from enthalpy is not implemented in the fluid, use the backend.",__FILE__,__LINE__));} - /// Viscosity as a function of temperature, pressure and composition. - double T_visc(double visc, double p, double x){throw NotImplementedError(format("%s (%d): T from viscosity is not implemented.",__FILE__,__LINE__));} - /// Thermal conductivity as a function of temperature, pressure and composition. - double T_cond(double cond, double p, double x){throw NotImplementedError(format("%s (%d): T from conductivity is not implemented.",__FILE__,__LINE__));} - /// Saturation pressure as a function of temperature and composition. - double T_psat(double psat, double x){throw NotImplementedError(format("%s (%d): T from psat is not implemented.",__FILE__,__LINE__));} - /// Composition as a function of freezing temperature and pressure. - double x_Tfreeze( double Tfreeze, double p){throw NotImplementedError(format("%s (%d): x from T_freeze is not implemented.",__FILE__,__LINE__));} + /* Some functions can be inverted directly, those are listed + * here. It is also possible to solve for other quantities, but + * that involves some more sophisticated processing and is not + * done here, but in the backend, T(h,p) for example. + */ + /// Temperature as a function of density, pressure and composition. + double T_rho (double Dmass, double p, double x); + /// Temperature as a function of heat capacities as a function of temperature, pressure and composition. + double T_c (double Cmass, double p, double x); + /// Temperature as a function of entropy as a function of temperature, pressure and composition. + double T_s (double Smass, double p, double x); + /// Temperature as a function of internal energy as a function of temperature, pressure and composition. + double T_u (double Umass, double p, double x); + /// Temperature as a function of enthalpy, pressure and composition. + double T_h (double Hmass, double p, double x){throw NotImplementedError(format("%s (%d): T from enthalpy is not implemented in the fluid, use the backend.",__FILE__,__LINE__));} + /// Viscosity as a function of temperature, pressure and composition. + double T_visc(double visc, double p, double x){throw NotImplementedError(format("%s (%d): T from viscosity is not implemented.",__FILE__,__LINE__));} + /// Thermal conductivity as a function of temperature, pressure and composition. + double T_cond(double cond, double p, double x){throw NotImplementedError(format("%s (%d): T from conductivity is not implemented.",__FILE__,__LINE__));} + /// Saturation pressure as a function of temperature and composition. + double T_psat(double psat, double x){throw NotImplementedError(format("%s (%d): T from psat is not implemented.",__FILE__,__LINE__));} + /// Composition as a function of freezing temperature and pressure. + double x_Tfreeze( double Tfreeze, double p){throw NotImplementedError(format("%s (%d): x from T_freeze is not implemented.",__FILE__,__LINE__));} protected: - /* Define internal energy and enthalpy as functions of the - * other properties to provide data in case there are no - * coefficients. - */ - /// Enthalpy from u, p and rho. - /** Calculate enthalpy as a function of temperature and - * pressure employing functions for internal energy and - * density. Provides consistent formulations. */ - double h_u(double T, double p, double x) { - return u(T,p,x)+p/rho(T,p,x)-href; - }; + /* Define internal energy and enthalpy as functions of the + * other properties to provide data in case there are no + * coefficients. + */ + /// Enthalpy from u, p and rho. + /** Calculate enthalpy as a function of temperature and + * pressure employing functions for internal energy and + * density. Provides consistent formulations. */ + double h_u(double T, double p, double x) { + return u(T,p,x)+p/rho(T,p,x)-href; + }; - /// Internal energy from h, p and rho. - /** Calculate internal energy as a function of temperature - * and pressure employing functions for enthalpy and - * density. Provides consistent formulations. */ - double u_h(double T, double p, double x) { - return h(T,p,x)-p/rho(T,p,x)+href; - }; + /// Internal energy from h, p and rho. + /** Calculate internal energy as a function of temperature + * and pressure employing functions for enthalpy and + * density. Provides consistent formulations. */ + double u_h(double T, double p, double x) { + return h(T,p,x)-p/rho(T,p,x)+href; + }; - /* - * Some more functions to provide a single implementation - * of important routines. - * We start with the check functions that can validate input - * in terms of pressure p, temperature T and composition x. - */ - /// Check validity of temperature input. - /** Compares the given temperature T to the result of a - * freezing point calculation. This is not necessarily - * defined for all fluids, default values do not cause errors. */ - bool checkT(double T, double p, double x); + /* + * Some more functions to provide a single implementation + * of important routines. + * We start with the check functions that can validate input + * in terms of pressure p, temperature T and composition x. + */ + /// Check validity of temperature input. + /** Compares the given temperature T to the result of a + * freezing point calculation. This is not necessarily + * defined for all fluids, default values do not cause errors. */ + bool checkT(double T, double p, double x); - /// Check validity of pressure input. - /** Compares the given pressure p to the saturation pressure at - * temperature T and throws and exception if p is lower than - * the saturation conditions. - * The default value for psat is -1 yielding true if psat - * is not redefined in the subclass. - * */ - bool checkP(double T, double p, double x); + /// Check validity of pressure input. + /** Compares the given pressure p to the saturation pressure at + * temperature T and throws and exception if p is lower than + * the saturation conditions. + * The default value for psat is -1 yielding true if psat + * is not redefined in the subclass. + * */ + bool checkP(double T, double p, double x); - /// Check validity of composition input. - /** Compares the given composition x to a stored minimum and - * maximum value. Enforces the redefinition of xmin and - * xmax since the default values cause an error. */ - bool checkX(double x); + /// Check validity of composition input. + /** Compares the given composition x to a stored minimum and + * maximum value. Enforces the redefinition of xmin and + * xmax since the default values cause an error. */ + bool checkX(double x); public: - /// Check validity of temperature, pressure and composition input. - bool checkTPX(double T, double p, double x){ - return (checkT(T,p,x) && checkP(T,p,x) && checkX(x)); - }; + /// Check validity of temperature, pressure and composition input. + bool checkTPX(double T, double p, double x){ + return (checkT(T,p,x) && checkP(T,p,x) && checkX(x)); + }; }; } /* namespace CoolProp */ diff --git a/include/MatrixMath.h b/include/MatrixMath.h index 8c0d3512..bbefe5b9 100644 --- a/include/MatrixMath.h +++ b/include/MatrixMath.h @@ -23,7 +23,7 @@ template struct VectorNd { typedef std::vector< typename VectorNd::type > type; }; template struct VectorNd<0,T> { - typedef T type; + typedef T type; }; @@ -34,36 +34,36 @@ template std::size_t num_rows ( std::vector co template std::size_t num_rows (std::vector > const& in){ return in.size(); } template std::size_t max_cols (std::vector > const& in){ - std::size_t cols = 0; - std::size_t col = 0; - for (std::size_t i = 0; i < in.size(); i++) { - col = in[i].size(); - if (cols bool is_squared(std::vector > const& in){ - std::size_t cols = max_cols(in); - if (cols!=num_rows(in)) { return false;} - else { - for (std::size_t i = 0; i < in.size(); i++) { - if (cols!=in[i].size()) {return false; } - } - } - return true; + std::size_t cols = max_cols(in); + if (cols!=num_rows(in)) { return false;} + else { + for (std::size_t i = 0; i < in.size(); i++) { + if (cols!=in[i].size()) {return false; } + } + } + return true; }; template std::size_t num_cols ( std::vector const& in){ return 1; } template std::size_t num_cols (std::vector > const& in){ - if (num_rows(in)>0) { - if (is_squared(in)) { - return in[0].size(); - } else { - return max_cols(in); - } - } else { - return 0; - } + if (num_rows(in)>0) { + if (is_squared(in)) { + return in[0].size(); + } else { + return max_cols(in); + } + } else { + return 0; + } }; /// Convert vectors and matrices @@ -74,74 +74,74 @@ template std::size_t num_cols (std::vector > co * @param axis axis along which to extract */ template std::vector eigen_to_vec1D(const Eigen::Matrix &coefficients, int axis = 0){ - std::vector result; - size_t r = coefficients.rows(), c = coefficients.cols(); - if (axis==0) { - if (c!=1) throw ValueError(format("Your matrix has the wrong dimensions: %d,%d",r,c)); - result.resize(r); - for (size_t i = 0; i < r; ++i) { - result[i] = coefficients(i,0); - } - } else if (axis==1) { - if (r!=1) throw ValueError(format("Your matrix has the wrong dimensions: %d,%d",r,c)); - result.resize(c); - for (size_t i = 0; i < c; ++i) { - result[i] = coefficients(0,i); - } - } else { - throw ValueError(format("You have to provide axis information: %d is not valid. ",axis)); - } - return result; + std::vector result; + size_t r = coefficients.rows(), c = coefficients.cols(); + if (axis==0) { + if (c!=1) throw ValueError(format("Your matrix has the wrong dimensions: %d,%d",r,c)); + result.resize(r); + for (size_t i = 0; i < r; ++i) { + result[i] = coefficients(i,0); + } + } else if (axis==1) { + if (r!=1) throw ValueError(format("Your matrix has the wrong dimensions: %d,%d",r,c)); + result.resize(c); + for (size_t i = 0; i < c; ++i) { + result[i] = coefficients(0,i); + } + } else { + throw ValueError(format("You have to provide axis information: %d is not valid. ",axis)); + } + return result; } /// @param coefficients matrix containing the ordered coefficients template std::vector > eigen_to_vec(const Eigen::Matrix &coefficients){ - // Eigen uses columns as major axis, this might be faster than the row iteration. - // However, the 2D vector stores things differently, no idea what is faster... - std::vector > result; - size_t r = coefficients.rows(), c = coefficients.cols(); - result.resize(r, std::vector(c, 0)); // extends vector if necessary - for (size_t i = 0; i < r; ++i) { - result[i].resize(c, 0); - for (size_t j = 0; j < c; ++j) { - result[i][j] = coefficients(i,j); - } - } - return result; + // Eigen uses columns as major axis, this might be faster than the row iteration. + // However, the 2D vector stores things differently, no idea what is faster... + std::vector > result; + size_t r = coefficients.rows(), c = coefficients.cols(); + result.resize(r, std::vector(c, 0)); // extends vector if necessary + for (size_t i = 0; i < r; ++i) { + result[i].resize(c, 0); + for (size_t j = 0; j < c; ++j) { + result[i][j] = coefficients(i,j); + } + } + return result; } /// @param coefficients matrix containing the ordered coefficients template Eigen::Matrix vec_to_eigen(const std::vector > &coefficients){ - size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); - Eigen::Matrix result(nRows,nCols); - for (size_t i = 0; i < nCols; ++i) { - for (size_t j = 0; j < nRows; ++j) { - result(j,i) = coefficients[j][i]; - } - } - return result; + size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); + Eigen::Matrix result(nRows,nCols); + for (size_t i = 0; i < nCols; ++i) { + for (size_t j = 0; j < nRows; ++j) { + result(j,i) = coefficients[j][i]; + } + } + return result; } /** * @param coefficients matrix containing the ordered coefficients * @param axis axis along which to extract data */ template Eigen::Matrix vec_to_eigen(const std::vector &coefficients, int axis = 0){ - size_t nRows = num_rows(coefficients); - Eigen::Matrix result; - if (axis==0) result.resize(nRows,1); - else if (axis==1) result.resize(1,nRows); - else throw ValueError(format("You have to provide axis information: %d is not valid. ",axis)); - for (size_t i = 0; i < nRows; ++i) { - if (axis==0) result(i,0) = coefficients[i]; - if (axis==1) result(0,i) = coefficients[i]; - } - return result; + size_t nRows = num_rows(coefficients); + Eigen::Matrix result; + if (axis==0) result.resize(nRows,1); + else if (axis==1) result.resize(1,nRows); + else throw ValueError(format("You have to provide axis information: %d is not valid. ",axis)); + for (size_t i = 0; i < nRows; ++i) { + if (axis==0) result(i,0) = coefficients[i]; + if (axis==1) result(0,i) = coefficients[i]; + } + return result; } /// @param coefficient template Eigen::Matrix vec_to_eigen(const T &coefficient){ - Eigen::Matrix result = Eigen::Matrix(1,1); - result(0,0) = coefficient; - return result; + Eigen::Matrix result = Eigen::Matrix(1,1); + result(0,0) = coefficient; + return result; } @@ -152,33 +152,33 @@ template Eigen::Matrix vec_to_eigen(c */ template< class T> Eigen::Matrix makeColVector(const Eigen::Matrix &matrix){ - std::size_t r = matrix.rows(); - std::size_t c = matrix.cols(); - Eigen::Matrix vector; - if (r==1&&c>=1) { // Check passed, matrix can be transformed - vector = matrix.transpose().block(0,0,c,r); - } else if ( r>=1&&c==1) { // Check passed, matrix can be transformed - vector = matrix.block(0,0,r,c); - } else { // Check failed, throw error - throw ValueError(format("Your matrix (%d,%d) cannot be converted into a vector (x,1).",r,c)); - } - return vector; + std::size_t r = matrix.rows(); + std::size_t c = matrix.cols(); + Eigen::Matrix vector; + if (r==1&&c>=1) { // Check passed, matrix can be transformed + vector = matrix.transpose().block(0,0,c,r); + } else if ( r>=1&&c==1) { // Check passed, matrix can be transformed + vector = matrix.block(0,0,r,c); + } else { // Check failed, throw error + throw ValueError(format("Your matrix (%d,%d) cannot be converted into a vector (x,1).",r,c)); + } + return vector; } template< class T> Eigen::Matrix makeVector(const Eigen::Matrix &matrix) { - return makeColVector(matrix); + return makeColVector(matrix); } template< class T> Eigen::Matrix makeRowVector(const Eigen::Matrix &matrix){ - std::size_t r = matrix.rows(); - std::size_t c = matrix.cols(); - Eigen::Matrix vector; - if (r==1&&c>=1) { // Check passed, matrix can be transformed - vector = matrix.block(0,0,r,c); - } else if ( r>=1&&c==1) { // Check passed, matrix can be transformed - vector = matrix.transpose().block(0,0,c,r); - } else { // Check failed, throw error - throw ValueError(format("Your matrix (%d,%d) cannot be converted into a vector (1,x).",r,c)); - } - return vector; + std::size_t r = matrix.rows(); + std::size_t c = matrix.cols(); + Eigen::Matrix vector; + if (r==1&&c>=1) { // Check passed, matrix can be transformed + vector = matrix.block(0,0,r,c); + } else if ( r>=1&&c==1) { // Check passed, matrix can be transformed + vector = matrix.transpose().block(0,0,c,r); + } else { // Check failed, throw error + throw ValueError(format("Your matrix (%d,%d) cannot be converted into a vector (1,x).",r,c)); + } + return vector; } @@ -190,15 +190,15 @@ template< class T> void removeRow(Eigen::Matrix //template void removeRow(Eigen::MatrixXd& matrix, std::size_t rowToRemove){ //void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove){ //template void removeRow(Eigen::MatrixBase &matrix, std::size_t rowToRemove){ - std::size_t numRows = matrix.rows()-1; - std::size_t numCols = matrix.cols(); + std::size_t numRows = matrix.rows()-1; + std::size_t numCols = matrix.cols(); if( rowToRemove < numRows ){ - matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) = matrix.block(rowToRemove+1,0,numRows-rowToRemove,numCols); + matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) = matrix.block(rowToRemove+1,0,numRows-rowToRemove,numCols); } else { - if( rowToRemove > numRows ){ - throw ValueError(format("Your matrix does not have enough rows, %d is not greater or equal to %d.",numRows,rowToRemove)); - } - // Do nothing, resize removes the last row + if( rowToRemove > numRows ){ + throw ValueError(format("Your matrix does not have enough rows, %d is not greater or equal to %d.",numRows,rowToRemove)); + } + // Do nothing, resize removes the last row } matrix.conservativeResize(numRows,numCols); } @@ -207,55 +207,55 @@ template void removeColumn(Eigen::Matrix void removeColumn(Eigen::MatrixXd& matrix, std::size_t colToRemove){ //void removeColumn(Eigen::MatrixXd& matrix, unsigned int colToRemove){ //template void removeColumn(Eigen::MatrixBase &matrix, std::size_t colToRemove){ - std::size_t numRows = matrix.rows(); - std::size_t numCols = matrix.cols()-1; + std::size_t numRows = matrix.rows(); + std::size_t numCols = matrix.cols()-1; if( colToRemove < numCols ) { matrix.block(0,colToRemove,numRows,numCols-colToRemove) = matrix.block(0,colToRemove+1,numRows,numCols-colToRemove); } else { - if( colToRemove > numCols ) { - throw ValueError(format("Your matrix does not have enough columns, %d is not greater or equal to %d.",numCols,colToRemove)); - } - // Do nothing, resize removes the last column + if( colToRemove > numCols ) { + throw ValueError(format("Your matrix does not have enough columns, %d is not greater or equal to %d.",numCols,colToRemove)); + } + // Do nothing, resize removes the last column } matrix.conservativeResize(numRows,numCols); } ///// @param coefficients matrix containing the ordered coefficients //template Eigen::Matrix convert(const std::vector > &coefficients){ -// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); -// Eigen::MatrixBase result(nRows,nCols); -// for (size_t i = 0; i < nCols; ++i) { -// for (size_t j = 0; j < nRows; ++j) { -// result(j,i) = coefficients[j][i]; -// } -// } -// return result; +// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); +// Eigen::MatrixBase result(nRows,nCols); +// for (size_t i = 0; i < nCols; ++i) { +// for (size_t j = 0; j < nRows; ++j) { +// result(j,i) = coefficients[j][i]; +// } +// } +// return result; //} // ///// @param coefficients matrix containing the ordered coefficients //template void convert(const std::vector > &coefficients, Eigen::Matrix &result){ -// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); -// //Eigen::MatrixBase result(nRows,nCols); -// for (size_t i = 0; i < nCols; ++i) { -// for (size_t j = 0; j < nRows; ++j) { -// result(j,i) = coefficients[j][i]; -// } -// } -// //return result; +// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); +// //Eigen::MatrixBase result(nRows,nCols); +// for (size_t i = 0; i < nCols; ++i) { +// for (size_t j = 0; j < nRows; ++j) { +// result(j,i) = coefficients[j][i]; +// } +// } +// //return result; //} // //template void convert(const std::vector > &coefficients, Eigen::MatrixBase &result){ -// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); -// //Eigen::MatrixBase result; -// //if ((R!=nRows) || (C!=nCols)) -// result.resize(nRows,nCols); -// for (size_t i = 0; i < nCols; ++i) { -// for (size_t j = 0; j < nRows; ++j) { -// result(j,i) = coefficients[j][i]; -// } -// } -// //return result; +// size_t nRows = num_rows(coefficients), nCols = num_cols(coefficients); +// //Eigen::MatrixBase result; +// //if ((R!=nRows) || (C!=nCols)) +// result.resize(nRows,nCols); +// for (size_t i = 0; i < nCols; ++i) { +// for (size_t j = 0; j < nRows; ++j) { +// result(j,i) = coefficients[j][i]; +// } +// } +// //return result; //} //template @@ -297,69 +297,69 @@ static const char* stdFmt = "%8.3f"; ///Templates for turning vectors (1D-matrices) into strings template std::string vec_to_string(const std::vector &a, const char *fmt) { - if (a.size()<1) return std::string(""); - std::stringstream out; - out << "[ " << format(fmt,a[0]); - for (size_t j = 1; j < a.size(); j++) { - out << ", " << format(fmt, a[j]); + if (a.size()<1) return std::string(""); + std::stringstream out; + out << "[ " << format(fmt,a[0]); + for (size_t j = 1; j < a.size(); j++) { + out << ", " << format(fmt, a[j]); } - out << " ]"; + out << " ]"; return out.str(); }; template std::string vec_to_string(const std::vector &a) { - return vec_to_string(std::vector(a.begin(), a.end()), stdFmt); + return vec_to_string(std::vector(a.begin(), a.end()), stdFmt); }; /// Templates for turning numbers (0D-matrices) into strings template std::string vec_to_string(const T &a, const char *fmt) { - std::vector vec; - vec.push_back(a); - return vec_to_string(vec, fmt); + std::vector vec; + vec.push_back(a); + return vec_to_string(vec, fmt); }; template std::string vec_to_string(const T &a) { - return vec_to_string((double) a, stdFmt); + return vec_to_string((double) a, stdFmt); }; ///Templates for turning 2D-matrices into strings template std::string vec_to_string(const std::vector > &A, const char *fmt) { - if (A.size()<1) return std::string(""); - std::stringstream out; - out << "[ " << vec_to_string(A[0], fmt); - for (size_t j = 1; j < A.size(); j++) { - out << ", " << std::endl << " " << vec_to_string(A[j], fmt); + if (A.size()<1) return std::string(""); + std::stringstream out; + out << "[ " << vec_to_string(A[0], fmt); + for (size_t j = 1; j < A.size(); j++) { + out << ", " << std::endl << " " << vec_to_string(A[j], fmt); } - out << " ]"; + out << " ]"; return out.str(); }; template std::string vec_to_string(const std::vector > &A) { - return vec_to_string(A, stdFmt); + return vec_to_string(A, stdFmt); }; ///Templates for turning Eigen matrices into strings template std::string mat_to_string(const Eigen::Matrix &A, const char *fmt) { //std::string mat_to_string(const Eigen::MatrixXd &A, const char *fmt) { - std::size_t r = A.rows(); - std::size_t c = A.cols(); - if ((r<1)||(c<1)) return std::string(""); - std::stringstream out; - out << "[ "; - if (r==1) { - out << format(fmt, A(0,0)); - for (size_t j = 1; j < c; j++) { - out << ", " << format(fmt, A(0,j)); - } - } else { - out << mat_to_string(Eigen::Matrix(A.row(0)), fmt); - for (size_t i = 1; i < r; i++) { - out << ", " << std::endl << " " << mat_to_string(Eigen::Matrix(A.row(i)), fmt); - } - } - out << " ]"; + std::size_t r = A.rows(); + std::size_t c = A.cols(); + if ((r<1)||(c<1)) return std::string(""); + std::stringstream out; + out << "[ "; + if (r==1) { + out << format(fmt, A(0,0)); + for (size_t j = 1; j < c; j++) { + out << ", " << format(fmt, A(0,j)); + } + } else { + out << mat_to_string(Eigen::Matrix(A.row(0)), fmt); + for (size_t i = 1; i < r; i++) { + out << ", " << std::endl << " " << mat_to_string(Eigen::Matrix(A.row(i)), fmt); + } + } + out << " ]"; return out.str(); }; template std::string mat_to_string(const Eigen::Matrix &A) { //std::string vec_to_string(const Eigen::MatrixXd &A) { - return mat_to_string(A, stdFmt); + return mat_to_string(A, stdFmt); }; @@ -384,119 +384,119 @@ template std::string mat_to_string(const Eigen::Matrix std::string vec_to_string(const std::vector &a, const char *fmt) { -// if (a.size()<1) return std::string(""); -// std::stringstream out; -// out << "[ " << format(fmt,a[0]); -// for (size_t j = 1; j < a.size(); j++) { -// out << ", " << format(fmt, a[j]); +// if (a.size()<1) return std::string(""); +// std::stringstream out; +// out << "[ " << format(fmt,a[0]); +// for (size_t j = 1; j < a.size(); j++) { +// out << ", " << format(fmt, a[j]); // } -// out << " ]"; +// out << " ]"; // return out.str(); //}; //template std::string vec_to_string(const std::vector &a) { -// return vec_to_string(a, stdFmt); +// return vec_to_string(a, stdFmt); //}; // ///// Templates for turning numbers (0D-matrices) into strings //template std::string vec_to_string(const T &a, const char *fmt) { -// std::vector vec; -// vec.push_back(a); -// return vec_to_string(vec, fmt); +// std::vector vec; +// vec.push_back(a); +// return vec_to_string(vec, fmt); //}; //template std::string vec_to_string(const T &a) { -// return vec_to_string(a, stdFmt); +// return vec_to_string(a, stdFmt); //}; // /////Templates for turning 2D-matrices into strings //template std::string vec_to_string(const std::vector > &A, const char *fmt) { -// if (A.size()<1) return std::string(""); -// std::stringstream out; -// out << "[ " << vec_to_string(A[0], fmt); -// for (size_t j = 1; j < A.size(); j++) { -// out << ", " << std::endl << " " << vec_to_string(A[j], fmt); +// if (A.size()<1) return std::string(""); +// std::stringstream out; +// out << "[ " << vec_to_string(A[0], fmt); +// for (size_t j = 1; j < A.size(); j++) { +// out << ", " << std::endl << " " << vec_to_string(A[j], fmt); // } -// out << " ]"; +// out << " ]"; // return out.str(); //}; //template std::string vec_to_string(const std::vector > &A) { -// return vec_to_string(A, stdFmt); +// return vec_to_string(A, stdFmt); //}; // /////Templates for turning Eigen matrices into strings //template std::string mat_to_string(const Eigen::Matrix &A, const char *fmt) { ////std::string mat_to_string(const Eigen::MatrixXd &A, const char *fmt) { -// std::size_t r = A.rows(); -// std::size_t c = A.cols(); -// if ((r<1)||(c<1)) return std::string(""); -// std::stringstream out; -// out << "[ "; -// if (r==1) { -// out << format(fmt, A(0,0)); -// for (size_t j = 1; j < c; j++) { -// out << ", " << format(fmt, A(0,j)); -// } -// } else { -// out << mat_to_string(Eigen::Matrix(A.row(0)), fmt); -// for (size_t i = 1; i < r; i++) { -// out << ", " << std::endl << " " << mat_to_string(Eigen::Matrix(A.row(i)), fmt); -// } -// } -// out << " ]"; +// std::size_t r = A.rows(); +// std::size_t c = A.cols(); +// if ((r<1)||(c<1)) return std::string(""); +// std::stringstream out; +// out << "[ "; +// if (r==1) { +// out << format(fmt, A(0,0)); +// for (size_t j = 1; j < c; j++) { +// out << ", " << format(fmt, A(0,j)); +// } +// } else { +// out << mat_to_string(Eigen::Matrix(A.row(0)), fmt); +// for (size_t i = 1; i < r; i++) { +// out << ", " << std::endl << " " << mat_to_string(Eigen::Matrix(A.row(i)), fmt); +// } +// } +// out << " ]"; // return out.str(); //}; //template std::string mat_to_string(const Eigen::Matrix &A) { ////std::string vec_to_string(const Eigen::MatrixXd &A) { -// return mat_to_string(A, stdFmt); +// return mat_to_string(A, stdFmt); //}; /// Template class for turning numbers (0D-matrices) into strings //template std::string vec_to_string(const T &a){ -// return vec_to_string(a, stdFmt); -// std::stringstream out; -// out << format("[ %7.3f ]",a); -// return out.str(); +// return vec_to_string(a, stdFmt); +// std::stringstream out; +// out << format("[ %7.3f ]",a); +// return out.str(); //}; //template std::string vec_to_string(const VectorNd<0, T> &a){ -// return vec_to_string(a, stdFmt); +// return vec_to_string(a, stdFmt); //}; //template std::string vec_to_string(const VectorNd<0, T> &a, const char *fmt) { -// VectorNd<1, T> vec; -// vec.push_back(a); -// return vec_to_string(vec, fmt); +// VectorNd<1, T> vec; +// vec.push_back(a); +// return vec_to_string(vec, fmt); //}; // /////Template classes for turning vectors (1D-matrices) into strings //template std::string vec_to_string(const VectorNd<1, T> &a) { -// return vec_to_string(a, stdFmt); +// return vec_to_string(a, stdFmt); //}; //template std::string vec_to_string(const VectorNd<1, T> &a, const char *fmt) { -// if (a.size()<1) { -// return std::string(""); -// } else { -// std::stringstream out; -// out << "[ "; -// out << format(fmt,a[0]); -// for (size_t j = 1; j < a.size(); j++) { -// out << ", "; -// out << format(fmt,a[j]); -// } -// out << " ]"; -// return out.str(); -// } +// if (a.size()<1) { +// return std::string(""); +// } else { +// std::stringstream out; +// out << "[ "; +// out << format(fmt,a[0]); +// for (size_t j = 1; j < a.size(); j++) { +// out << ", "; +// out << format(fmt,a[j]); +// } +// out << " ]"; +// return out.str(); +// } //}; // /////Template classes for turning 2D-matrices into strings //template std::string vec_to_string(const VectorNd<2, T> &A) { -// return vec_to_string(A, stdFmt); +// return vec_to_string(A, stdFmt); //} //template std::string vec_to_string(const VectorNd<2, T> &A, const char *fmt) { -// if (A.size()<1) return std::string(""); -// std::stringstream out; -// out << "[ " << format(fmt,A[0]); -// for (size_t j = 1; j < A.size(); j++) { -// out << ", " << std::endl << " " << vec_to_string(A[j], fmt); +// if (A.size()<1) return std::string(""); +// std::stringstream out; +// out << "[ " << format(fmt,A[0]); +// for (size_t j = 1; j < A.size(); j++) { +// out << ", " << std::endl << " " << vec_to_string(A[j], fmt); // } -// out << " ]"; +// out << " ]"; // return out.str(); //} @@ -541,167 +541,167 @@ Owe a debt of gratitude to http://sole.ooz.ie/en - very clear treatment of GJ */ template void swap_rows(std::vector > *A, size_t row1, size_t row2) { - for (size_t col = 0; col < (*A)[0].size(); col++){ - std::swap((*A)[row1][col],(*A)[row2][col]); - } + for (size_t col = 0; col < (*A)[0].size(); col++){ + std::swap((*A)[row1][col],(*A)[row2][col]); + } }; template void subtract_row_multiple(std::vector > *A, size_t row, T multiple, size_t pivot_row) { - for (size_t col = 0; col < (*A)[0].size(); col++){ - (*A)[row][col] -= multiple*(*A)[pivot_row][col]; - } + for (size_t col = 0; col < (*A)[0].size(); col++){ + (*A)[row][col] -= multiple*(*A)[pivot_row][col]; + } }; template void divide_row_by(std::vector > *A, size_t row, T value) { - for (size_t col = 0; col < (*A)[0].size(); col++){ - (*A)[row][col] /= value; - } + for (size_t col = 0; col < (*A)[0].size(); col++){ + (*A)[row][col] /= value; + } }; template size_t get_pivot_row(std::vector > *A, size_t col) { - std::size_t index = col; - T max = 0, val; + std::size_t index = col; + T max = 0, val; - for (size_t row = col; row < (*A).size(); row++) - { - val = (*A)[row][col]; - if (std::abs(val) > max) - { - max = std::abs(val); - index = row; - } - } - return index; + for (size_t row = col; row < (*A).size(); row++) + { + val = (*A)[row][col]; + if (std::abs(val) > max) + { + max = std::abs(val); + index = row; + } + } + return index; }; template std::vector > linsolve_Gauss_Jordan(std::vector > const& A, std::vector > const& B) { - std::vector > AB; - std::vector > X; - size_t pivot_row; - T pivot_element; + std::vector > AB; + std::vector > X; + size_t pivot_row; + T pivot_element; - size_t NrowA = num_rows(A); - size_t NrowB = num_rows(B); - size_t NcolA = num_cols(A); - size_t NcolB = num_cols(B); + size_t NrowA = num_rows(A); + size_t NrowB = num_rows(B); + size_t NcolA = num_cols(A); + size_t NcolB = num_cols(B); - if (NrowA!=NrowB) throw ValueError(format("You have to provide matrices with the same number of rows: %d is not %d. ",NrowA,NrowB)); + if (NrowA!=NrowB) throw ValueError(format("You have to provide matrices with the same number of rows: %d is not %d. ",NrowA,NrowB)); - AB.resize(NrowA, std::vector(NcolA+NcolB, 0)); - X.resize(NrowA, std::vector(NcolB, 0)); + AB.resize(NrowA, std::vector(NcolA+NcolB, 0)); + X.resize(NrowA, std::vector(NcolB, 0)); - // Build the augmented matrix - for (size_t row = 0; row < NrowA; row++){ - for (size_t col = 0; col < NcolA; col++){ - AB[row][col] = A[row][col]; - } - for (size_t col = NcolA; col < NcolA+NcolB; col++){ - AB[row][col] = B[row][col-NcolA]; - } - } + // Build the augmented matrix + for (size_t row = 0; row < NrowA; row++){ + for (size_t col = 0; col < NcolA; col++){ + AB[row][col] = A[row][col]; + } + for (size_t col = NcolA; col < NcolA+NcolB; col++){ + AB[row][col] = B[row][col-NcolA]; + } + } - for (size_t col = 0; col < NcolA; col++){ - // Find the pivot value - pivot_row = get_pivot_row(&AB, col); + for (size_t col = 0; col < NcolA; col++){ + // Find the pivot value + pivot_row = get_pivot_row(&AB, col); - if (std::abs(AB[pivot_row][col]) < 10*DBL_EPSILON){ throw ValueError(format("Zero occurred in row %d, the matrix is singular. ",pivot_row));} + if (std::abs(AB[pivot_row][col]) < 10*DBL_EPSILON){ throw ValueError(format("Zero occurred in row %d, the matrix is singular. ",pivot_row));} - if (pivot_row>=col){ - // Swap pivot row and current row - swap_rows(&AB, col, pivot_row); - } - // Get the pivot element - pivot_element = AB[col][col]; - // Divide the pivot row by the pivot element - divide_row_by(&AB,col,pivot_element); + if (pivot_row>=col){ + // Swap pivot row and current row + swap_rows(&AB, col, pivot_row); + } + // Get the pivot element + pivot_element = AB[col][col]; + // Divide the pivot row by the pivot element + divide_row_by(&AB,col,pivot_element); - if (col < NrowA-1) - { - // All the rest of the rows, subtract the value of the [r][c] combination - for (size_t row = col + 1; row < NrowA; row++) - { - subtract_row_multiple(&AB,row,AB[row][col],col); - } - } - } - for (std::size_t col = NcolA - 1; col > 0; col--) - { - for (int row = col - 1; row >=0; row--) - { - subtract_row_multiple(&AB,row,AB[row][col],col); - } - } - // Set the output value - for (size_t row = 0; row < NrowA; row++){ - for (size_t col = 0; col < NcolB; col++){ - X[row][col] = AB[row][NcolA+col]; - } - } - return X; + if (col < NrowA-1) + { + // All the rest of the rows, subtract the value of the [r][c] combination + for (size_t row = col + 1; row < NrowA; row++) + { + subtract_row_multiple(&AB,row,AB[row][col],col); + } + } + } + for (std::size_t col = NcolA - 1; col > 0; col--) + { + for (int row = col - 1; row >=0; row--) + { + subtract_row_multiple(&AB,row,AB[row][col],col); + } + } + // Set the output value + for (size_t row = 0; row < NrowA; row++){ + for (size_t col = 0; col < NcolB; col++){ + X[row][col] = AB[row][NcolA+col]; + } + } + return X; }; //std::vector > linsolve_Gauss_Jordan_reimpl(std::vector > const& A, std::vector > const& B) { -// std::vector > AB; -// std::vector > X; -// size_t pivot_row; -// double pivot_element; -// double tmp_element; +// std::vector > AB; +// std::vector > X; +// size_t pivot_row; +// double pivot_element; +// double tmp_element; // -// size_t NrowA = num_rows(A); -// size_t NrowB = num_rows(B); -// size_t NcolA = num_cols(A); -// size_t NcolB = num_cols(B); +// size_t NrowA = num_rows(A); +// size_t NrowB = num_rows(B); +// size_t NcolA = num_cols(A); +// size_t NcolB = num_cols(B); // -// if (NrowA!=NrowB) throw ValueError(format("You have to provide matrices with the same number of rows: %d is not %d. ",NrowA,NrowB)); +// if (NrowA!=NrowB) throw ValueError(format("You have to provide matrices with the same number of rows: %d is not %d. ",NrowA,NrowB)); // -// AB.resize(NrowA, std::vector(NcolA+NcolB, 0)); -// X.resize(NrowA, std::vector(NcolB, 0)); +// AB.resize(NrowA, std::vector(NcolA+NcolB, 0)); +// X.resize(NrowA, std::vector(NcolB, 0)); // -// // Build the augmented matrix -// for (size_t row = 0; row < NrowA; row++){ -// for (size_t col = 0; col < NcolA; col++){ -// AB[row][col] = A[row][col]; -// } -// for (size_t col = NcolA; col < NcolA+NcolB; col++){ -// AB[row][col] = B[row][col-NcolA]; -// } -// } +// // Build the augmented matrix +// for (size_t row = 0; row < NrowA; row++){ +// for (size_t col = 0; col < NcolA; col++){ +// AB[row][col] = A[row][col]; +// } +// for (size_t col = NcolA; col < NcolA+NcolB; col++){ +// AB[row][col] = B[row][col-NcolA]; +// } +// } // -// for (size_t col = 0; col < NcolA; col++){ -// // Find the pivot row -// pivot_row = 0; -// pivot_element = 0.0; -// for (size_t row = col; row < NrowA; row++){ -// tmp_element = std::abs(AB[row][col]); -// if (tmp_element>pivot_element) { -// pivot_element = tmp_element; -// pivot_row = row; -// } -// } -// // Check for errors -// if (AB[pivot_row][col]<1./_HUGE) throw ValueError(format("Zero occurred in row %d, the matrix is singular. ",pivot_row)); -// // Swap the rows -// if (pivot_row>col) { -// for (size_t colInt = 0; colInt < NcolA; colInt++){ -// std::swap(AB[pivot_row][colInt],AB[pivot_row][colInt]); -// } -// } -// // Process the entries below current element -// for (size_t row = col; row < NrowA; row++){ -// // Entries to the right of current element (until end of A) -// for (size_t colInt = col+1; colInt < NcolA; colInt++){ -// // All entries in augmented matrix -// for (size_t colFull = col; colFull < NcolA+NcolB; colFull++){ -// AB[colInt][colFull] -= AB[col][colFull] * AB[colInt][col] / AB[col][col]; -// } -// AB[colInt][col] = 0.0; -// } -// } -// } -// return AB; +// for (size_t col = 0; col < NcolA; col++){ +// // Find the pivot row +// pivot_row = 0; +// pivot_element = 0.0; +// for (size_t row = col; row < NrowA; row++){ +// tmp_element = std::abs(AB[row][col]); +// if (tmp_element>pivot_element) { +// pivot_element = tmp_element; +// pivot_row = row; +// } +// } +// // Check for errors +// if (AB[pivot_row][col]<1./_HUGE) throw ValueError(format("Zero occurred in row %d, the matrix is singular. ",pivot_row)); +// // Swap the rows +// if (pivot_row>col) { +// for (size_t colInt = 0; colInt < NcolA; colInt++){ +// std::swap(AB[pivot_row][colInt],AB[pivot_row][colInt]); +// } +// } +// // Process the entries below current element +// for (size_t row = col; row < NrowA; row++){ +// // Entries to the right of current element (until end of A) +// for (size_t colInt = col+1; colInt < NcolA; colInt++){ +// // All entries in augmented matrix +// for (size_t colFull = col; colFull < NcolA+NcolB; colFull++){ +// AB[colInt][colFull] -= AB[col][colFull] * AB[colInt][col] / AB[col][col]; +// } +// AB[colInt][col] = 0.0; +// } +// } +// } +// return AB; //} @@ -710,66 +710,66 @@ template std::vector > linsolve_Gauss_Jordan(std::vec template std::vector > linsolve(std::vector > const& A, std::vector > const& B){ - return linsolve_Gauss_Jordan(A, B); + return linsolve_Gauss_Jordan(A, B); }; template std::vector linsolve(std::vector > const& A, std::vector const& b){ - std::vector > B; - for (size_t i = 0; i < b.size(); i++){ - B.push_back(std::vector(1,b[i])); - } - B = linsolve(A, B); - B[0].resize(B.size(),0.0); - for (size_t i = 1; i < B.size(); i++){ - B[0][i] = B[i][0]; - } - return B[0]; + std::vector > B; + for (size_t i = 0; i < b.size(); i++){ + B.push_back(std::vector(1,b[i])); + } + B = linsolve(A, B); + B[0].resize(B.size(),0.0); + for (size_t i = 1; i < B.size(); i++){ + B[0][i] = B[i][0]; + } + return B[0]; }; template std::vector get_row(std::vector< std::vector > const& in, size_t row) { return in[row]; }; template std::vector get_col(std::vector< std::vector > const& in, size_t col) { - std::size_t sizeX = in.size(); - if (sizeX<1) throw ValueError(format("You have to provide values, a vector length of %d is not valid. ",sizeX)); - size_t sizeY = in[0].size(); - if (sizeY<1) throw ValueError(format("You have to provide values, a vector length of %d is not valid. ",sizeY)); - std::vector out; - for (std::size_t i = 0; i < sizeX; i++) { - sizeY = in[i].size(); - if (sizeY-1 out; + for (std::size_t i = 0; i < sizeX; i++) { + sizeY = in[i].size(); + if (sizeY-1 std::vector > make_squared(std::vector > const& in){ - std::size_t cols = max_cols(in); - std::size_t rows = num_rows(in); - std::size_t maxVal = 0; - std::vector > out; - std::vector tmp; + std::size_t cols = max_cols(in); + std::size_t rows = num_rows(in); + std::size_t maxVal = 0; + std::vector > out; + std::vector tmp; - if (cols>rows) {maxVal = cols; } - else {maxVal = rows; } - out.clear(); - for (std::size_t i = 0; i < in.size(); i++) { - tmp.clear(); - for (std::size_t j = 0; j < in[i].size(); j++) { - tmp.push_back(in[i][j]); - } - while (maxVal>tmp.size()) { - tmp.push_back(0.0); - } - out.push_back(tmp); + if (cols>rows) {maxVal = cols; } + else {maxVal = rows; } + out.clear(); + for (std::size_t i = 0; i < in.size(); i++) { + tmp.clear(); + for (std::size_t j = 0; j < in[i].size(); j++) { + tmp.push_back(in[i][j]); + } + while (maxVal>tmp.size()) { + tmp.push_back(0.0); + } + out.push_back(tmp); } - // Check rows - tmp.clear(); - tmp.resize(maxVal,0.0); - while (maxVal>out.size()) { - out.push_back(tmp); - } - return out; + // Check rows + tmp.clear(); + tmp.resize(maxVal,0.0); + while (maxVal>out.size()) { + out.push_back(tmp); + } + return out; }; template T multiply( std::vector const& a, std::vector const& b){ @@ -777,80 +777,80 @@ template T multiply( std::vector< }; template std::vector multiply(std::vector > const& A, std::vector const& b){ - std::vector > B; - for (size_t i = 0; i < b.size(); i++){ - B.push_back(std::vector(1,b[i])); - } - B = multiply(A, B); - B[0].resize(B.size(),0.0); - for (size_t i = 1; i < B.size(); i++){ - B[0][i] = B[i][0]; - } - return B[0]; + std::vector > B; + for (size_t i = 0; i < b.size(); i++){ + B.push_back(std::vector(1,b[i])); + } + B = multiply(A, B); + B[0].resize(B.size(),0.0); + for (size_t i = 1; i < B.size(); i++){ + B[0][i] = B[i][0]; + } + return B[0]; } template std::vector > multiply(std::vector > const& A, std::vector > const& B){ - if (num_cols(A) != num_rows(B)){ - throw ValueError(format("You have to provide matrices with the same columns and rows: %d is not equal to %d. ",num_cols(A),num_rows(B))); - } - size_t rows = num_rows(A); - size_t cols = num_cols(B); - T tmp; - std::vector > outVec; - std::vector tmpVec; + if (num_cols(A) != num_rows(B)){ + throw ValueError(format("You have to provide matrices with the same columns and rows: %d is not equal to %d. ",num_cols(A),num_rows(B))); + } + size_t rows = num_rows(A); + size_t cols = num_cols(B); + T tmp; + std::vector > outVec; + std::vector tmpVec; outVec.clear(); - for (size_t i = 0; i < rows; i++){ - tmpVec.clear(); - for (size_t j = 0; j < cols; j++){ - tmp = 0.0; - for (size_t k = 0; k < num_cols(A); k++){ - tmp += A[i][k] * B[k][j]; - } - tmpVec.push_back(tmp); - } - outVec.push_back(tmpVec); - } - return outVec; + for (size_t i = 0; i < rows; i++){ + tmpVec.clear(); + for (size_t j = 0; j < cols; j++){ + tmp = 0.0; + for (size_t k = 0; k < num_cols(A); k++){ + tmp += A[i][k] * B[k][j]; + } + tmpVec.push_back(tmp); + } + outVec.push_back(tmpVec); + } + return outVec; }; template T dot_product(std::vector const& a, std::vector const& b){ - if (a.size()==b.size()){ - return std::inner_product(a.begin(), a.end(), b.begin(), 0.0); - } - throw ValueError(format("You have to provide vectors with the same length: %d is not equal to %d. ",a.size(),b.size())); + if (a.size()==b.size()){ + return std::inner_product(a.begin(), a.end(), b.begin(), 0.0); + } + throw ValueError(format("You have to provide vectors with the same length: %d is not equal to %d. ",a.size(),b.size())); }; template std::vector cross_product(std::vector const& a, std::vector const& b){ - throw NotImplementedError("The cross product function has not been implemented, yet"); + throw NotImplementedError("The cross product function has not been implemented, yet"); }; template std::vector< std::vector > transpose(std::vector > const& in){ - size_t sizeX = in.size(); - if (sizeX<1) throw ValueError(format("You have to provide values, a vector length of %d is not a valid. ",sizeX)); - size_t sizeY = in[0].size(); - size_t sizeYOld = sizeY; - if (sizeY<1) throw ValueError(format("You have to provide values, a vector length of %d is not a valid. ",sizeY)); - std::vector< std::vector > out(sizeY,std::vector(sizeX)); - for (size_t i = 0; i < sizeX; ++i){ - sizeY = in[i].size(); - if (sizeY!=sizeYOld) throw ValueError(format("You have to provide a rectangular matrix: %d is not equal to %d. ",sizeY,sizeYOld)); - for (size_t j = 0; j < sizeY; ++j){ - out[j][i] = in[i][j]; - } - } - return out; + size_t sizeX = in.size(); + if (sizeX<1) throw ValueError(format("You have to provide values, a vector length of %d is not a valid. ",sizeX)); + size_t sizeY = in[0].size(); + size_t sizeYOld = sizeY; + if (sizeY<1) throw ValueError(format("You have to provide values, a vector length of %d is not a valid. ",sizeY)); + std::vector< std::vector > out(sizeY,std::vector(sizeX)); + for (size_t i = 0; i < sizeX; ++i){ + sizeY = in[i].size(); + if (sizeY!=sizeYOld) throw ValueError(format("You have to provide a rectangular matrix: %d is not equal to %d. ",sizeY,sizeYOld)); + for (size_t j = 0; j < sizeY; ++j){ + out[j][i] = in[i][j]; + } + } + return out; }; template std::vector< std::vector > invert(std::vector > const& in){ - if (!is_squared(in)) throw ValueError(format("Only square matrices can be inverted: %d is not equal to %d. ",num_rows(in),num_cols(in))); - std::vector > identity; - // Build the identity matrix - size_t dim = num_rows(in); - identity.resize(dim, std::vector(dim, 0)); - for (size_t row = 0; row < dim; row++){ - identity[row][row] = 1.0; - } - return linsolve(in,identity); + if (!is_squared(in)) throw ValueError(format("Only square matrices can be inverted: %d is not equal to %d. ",num_rows(in),num_cols(in))); + std::vector > identity; + // Build the identity matrix + size_t dim = num_rows(in); + identity.resize(dim, std::vector(dim, 0)); + for (size_t row = 0; row < dim; row++){ + identity[row][row] = 1.0; + } + return linsolve(in,identity); }; diff --git a/include/PolyMath.h b/include/PolyMath.h index ec4e7a34..9ef18197 100644 --- a/include/PolyMath.h +++ b/include/PolyMath.h @@ -24,175 +24,175 @@ class Poly2DFracResidual; class Polynomial2D { public: - /// Constructors - Polynomial2D(){}; + /// Constructors + Polynomial2D(){}; - /// Destructor. No implementation - virtual ~Polynomial2D(){}; + /// Destructor. No implementation + virtual ~Polynomial2D(){}; public: - /// Convert the coefficient vector. - /// @param coefficients vector containing the ordered coefficients - Eigen::MatrixXd convertCoefficients(const std::vector &coefficients){return vec_to_eigen(coefficients);} - /// Convert the coefficient matrix. - /// @param coefficients matrix containing the ordered coefficients - Eigen::MatrixXd convertCoefficients(const std::vector > &coefficients){return vec_to_eigen(coefficients);} + /// Convert the coefficient vector. + /// @param coefficients vector containing the ordered coefficients + Eigen::MatrixXd convertCoefficients(const std::vector &coefficients){return vec_to_eigen(coefficients);} + /// Convert the coefficient matrix. + /// @param coefficients matrix containing the ordered coefficients + Eigen::MatrixXd convertCoefficients(const std::vector > &coefficients){return vec_to_eigen(coefficients);} - /// Basic checks for coefficient vectors. - /** Starts with only the first coefficient dimension - * and checks the matrix size against the parameters rows and columns. */ - /// @param coefficients matrix containing the ordered coefficients - /// @param rows unsigned integer value that represents the desired degree of the polynomial in the 1st dimension - /// @param columns unsigned integer value that represents the desired degree of the polynomial in the 2nd dimension - bool checkCoefficients(const Eigen::MatrixXd &coefficients, const unsigned int rows, const unsigned int columns); + /// Basic checks for coefficient vectors. + /** Starts with only the first coefficient dimension + * and checks the matrix size against the parameters rows and columns. */ + /// @param coefficients matrix containing the ordered coefficients + /// @param rows unsigned integer value that represents the desired degree of the polynomial in the 1st dimension + /// @param columns unsigned integer value that represents the desired degree of the polynomial in the 2nd dimension + bool checkCoefficients(const Eigen::MatrixXd &coefficients, const unsigned int rows, const unsigned int columns); public: - /// Integration functions - /** Integrating coefficients for polynomials is done by dividing the - * original coefficients by (i+1) and elevating the order by 1 - * through adding a zero as first coefficient. - * Some reslicing needs to be applied to integrate along the x-axis. - * In the brine/solution equations, reordering of the parameters - * avoids this expensive operation. However, it is included for the - * sake of completeness. - */ - /// @param coefficients matrix containing the ordered coefficients - /// @param axis unsigned integer value that represents the desired direction of integration - /// @param times integer value that represents the desired order of integration - Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×); + /// Integration functions + /** Integrating coefficients for polynomials is done by dividing the + * original coefficients by (i+1) and elevating the order by 1 + * through adding a zero as first coefficient. + * Some reslicing needs to be applied to integrate along the x-axis. + * In the brine/solution equations, reordering of the parameters + * avoids this expensive operation. However, it is included for the + * sake of completeness. + */ + /// @param coefficients matrix containing the ordered coefficients + /// @param axis unsigned integer value that represents the desired direction of integration + /// @param times integer value that represents the desired order of integration + Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×); - /// Derivative coefficients calculation - /** Deriving coefficients for polynomials is done by multiplying the - * original coefficients with i and lowering the order by 1. - */ - /// @param coefficients matrix containing the ordered coefficients - /// @param axis unsigned integer value that represents the desired direction of derivation - /// @param times integer value that represents the desired order of derivation - Eigen::MatrixXd deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis=-1, const int ×=1); + /// Derivative coefficients calculation + /** Deriving coefficients for polynomials is done by multiplying the + * original coefficients with i and lowering the order by 1. + */ + /// @param coefficients matrix containing the ordered coefficients + /// @param axis unsigned integer value that represents the desired direction of derivation + /// @param times integer value that represents the desired order of derivation + Eigen::MatrixXd deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis=-1, const int ×=1); public: - /// The core functions to evaluate the polynomial - /** It is here we implement the different special - * functions that allow us to specify certain - * types of polynomials. - * - * Try to avoid many calls to the derivative and integral functions. - * Both of them have to calculate the new coefficients internally, - * which slows things down. Instead, you should use the deriveCoeffs - * and integrateCoeffs functions and store the coefficient matrix - * you need for future calls to evaluate derivative and integral. - */ - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in); + /// The core functions to evaluate the polynomial + /** It is here we implement the different special + * functions that allow us to specify certain + * types of polynomials. + * + * Try to avoid many calls to the derivative and integral functions. + * Both of them have to calculate the new coefficients internally, + * which slows things down. Instead, you should use the deriveCoeffs + * and integrateCoeffs functions and store the coefficient matrix + * you need for future calls to evaluate derivative and integral. + */ + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in); - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in); + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in); - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - /// @param axis unsigned integer value that represents the axis to derive for (0=x, 1=y) - double derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis); + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + /// @param axis unsigned integer value that represents the axis to derive for (0=x, 1=y) + double derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis); - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - /// @param axis unsigned integer value that represents the axis to integrate for (0=x, 1=y) - double integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis); + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + /// @param axis unsigned integer value that represents the axis to integrate for (0=x, 1=y) + double integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis); protected: - // TODO: Why doe these base definitions not work with derived classes? - /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in - /// @param res Poly2DResidual object to calculate residuals and derivatives - /// @param min double value that represents the minimum value - /// @param max double value that represents the maximum value - double solve_limits(Poly2DResidual* res, const double &min, const double &max); + // TODO: Why doe these base definitions not work with derived classes? + /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in + /// @param res Poly2DResidual object to calculate residuals and derivatives + /// @param min double value that represents the minimum value + /// @param max double value that represents the maximum value + double solve_limits(Poly2DResidual* res, const double &min, const double &max); - // TODO: Why doe these base definitions not work with derived classes? - /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in - /// @param res Poly2DResidual object to calculate residuals and derivatives - /// @param guess double value that represents the start value - double solve_guess(Poly2DResidual* res, const double &guess); + // TODO: Why doe these base definitions not work with derived classes? + /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in + /// @param res Poly2DResidual object to calculate residuals and derivatives + /// @param guess double value that represents the start value + double solve_guess(Poly2DResidual* res, const double &guess); public: - /// Returns a vector with ALL the real roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - Eigen::VectorXd solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis); + /// Returns a vector with ALL the real roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + Eigen::VectorXd solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis); - /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param min double value that represents the minimum value - /// @param max double value that represents the maximum value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - double solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis); + /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param min double value that represents the minimum value + /// @param max double value that represents the maximum value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + double solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis); - /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param guess double value that represents the start value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - double solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis); + /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param guess double value that represents the start value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + double solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis); protected: - /// Simple polynomial function generator. <- Deprecated due to poor performance, use Horner-scheme instead - /** Base function to produce n-th order polynomials - * based on the length of the coefficient vector. - * Starts with only the first coefficient at x^0. */ + /// Simple polynomial function generator. <- Deprecated due to poor performance, use Horner-scheme instead + /** Base function to produce n-th order polynomials + * based on the length of the coefficient vector. + * Starts with only the first coefficient at x^0. */ double simplePolynomial(const std::vector &coefficients, double x); - DEPRECATED(double simplePolynomial(const std::vector > &coefficients, double x, double y)); - /// Horner function generator implementations - /** Represent polynomials according to Horner's scheme. - * This avoids unnecessary multiplication and thus - * speeds up calculation. - * Deprecated since we moved everything to the Eigen framework. - */ - double baseHorner(const std::vector &coefficients, double x); - DEPRECATED(double baseHorner(const std::vector > &coefficients, double x, double y)); + DEPRECATED(double simplePolynomial(const std::vector > &coefficients, double x, double y)); + /// Horner function generator implementations + /** Represent polynomials according to Horner's scheme. + * This avoids unnecessary multiplication and thus + * speeds up calculation. + * Deprecated since we moved everything to the Eigen framework. + */ + double baseHorner(const std::vector &coefficients, double x); + DEPRECATED(double baseHorner(const std::vector > &coefficients, double x, double y)); - bool do_debug(void){return get_debug_level()>=18;} + bool do_debug(void){return get_debug_level()>=18;} }; class Poly2DResidual : public FuncWrapper1D { protected: - enum dims {iX, iY}; - Eigen::MatrixXd coefficients; - bool derIsSet; - Eigen::MatrixXd coefficientsDer; - int axis; - /// the fixed input != targetDim - double in; - /// Object that evaluates the equation - Polynomial2D poly; - /// Current output value - double z_in; + enum dims {iX, iY}; + Eigen::MatrixXd coefficients; + bool derIsSet; + Eigen::MatrixXd coefficientsDer; + int axis; + /// the fixed input != targetDim + double in; + /// Object that evaluates the equation + Polynomial2D poly; + /// Current output value + double z_in; protected: - Poly2DResidual(); + Poly2DResidual(); public: - /// Residual of a polynomial - /// @param poly polynomial object used to evaluate the calls - /// @param coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - Poly2DResidual(Polynomial2D &poly, const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis); - virtual ~Poly2DResidual(){}; + /// Residual of a polynomial + /// @param poly polynomial object used to evaluate the calls + /// @param coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + Poly2DResidual(Polynomial2D &poly, const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis); + virtual ~Poly2DResidual(){}; - double call(double target); - double deriv(double target); + double call(double target); + double deriv(double target); }; @@ -206,230 +206,230 @@ public: class Polynomial2DFrac : public Polynomial2D { public: - /// Constructors - Polynomial2DFrac(){}; + /// Constructors + Polynomial2DFrac(){}; - /// Destructor. No implementation - virtual ~Polynomial2DFrac(){}; + /// Destructor. No implementation + virtual ~Polynomial2DFrac(){}; public: -// /// Integration functions -// /** Integrating coefficients for polynomials is done by dividing the -// * original coefficients by (i+1) and elevating the order by 1 -// * through adding a zero as first coefficient. -// * Some reslicing needs to be applied to integrate along the x-axis. -// * In the brine/solution equations, reordering of the parameters -// * avoids this expensive operation. However, it is included for the -// * sake of completeness. -// */ -// /// @param coefficients matrix containing the ordered coefficients -// /// @param axis unsigned integer value that represents the desired direction of integration -// /// @param times integer value that represents the desired order of integration -// /// @param firstExponent integer value that represents the first exponent of the polynomial in axis direction -// Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); +// /// Integration functions +// /** Integrating coefficients for polynomials is done by dividing the +// * original coefficients by (i+1) and elevating the order by 1 +// * through adding a zero as first coefficient. +// * Some reslicing needs to be applied to integrate along the x-axis. +// * In the brine/solution equations, reordering of the parameters +// * avoids this expensive operation. However, it is included for the +// * sake of completeness. +// */ +// /// @param coefficients matrix containing the ordered coefficients +// /// @param axis unsigned integer value that represents the desired direction of integration +// /// @param times integer value that represents the desired order of integration +// /// @param firstExponent integer value that represents the first exponent of the polynomial in axis direction +// Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); // - /// Derivative coefficients calculation - /** Deriving coefficients for polynomials is done by multiplying the - * original coefficients with i and lowering the order by 1. - * - * Remember that the first exponent might need to be adjusted after derivation. - * It has to be lowered by times: - * derCoeffs = deriveCoeffs(coefficients, axis, times, firstExponent); - * firstExponent -= times; - */ - /// @param coefficients matrix containing the ordered coefficients - /// @param axis unsigned integer value that represents the desired direction of derivation - /// @param times integer value that represents the desired order of derivation - /// @param firstExponent integer value that represents the lowest exponent of the polynomial in axis direction - Eigen::MatrixXd deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); + /// Derivative coefficients calculation + /** Deriving coefficients for polynomials is done by multiplying the + * original coefficients with i and lowering the order by 1. + * + * Remember that the first exponent might need to be adjusted after derivation. + * It has to be lowered by times: + * derCoeffs = deriveCoeffs(coefficients, axis, times, firstExponent); + * firstExponent -= times; + */ + /// @param coefficients matrix containing the ordered coefficients + /// @param axis unsigned integer value that represents the desired direction of derivation + /// @param times integer value that represents the desired order of derivation + /// @param firstExponent integer value that represents the lowest exponent of the polynomial in axis direction + Eigen::MatrixXd deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); public: - /// The core functions to evaluate the polynomial - /** It is here we implement the different special - * functions that allow us to specify certain - * types of polynomials. - * - * Try to avoid many calls to the derivative and integral functions. - * Both of them have to calculate the new coefficients internally, - * which slows things down. Instead, you should use the deriveCoeffs - * and integrateCoeffs functions and store the coefficient matrix - * you need for future calls to evaluate derivative and integral. - */ - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param firstExponent integer value that represents the lowest exponent of the polynomial - /// @param x_base double value that represents the base value for a centered fit in the 1st dimension - double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const int &firstExponent=0, const double &x_base=0.0); + /// The core functions to evaluate the polynomial + /** It is here we implement the different special + * functions that allow us to specify certain + * types of polynomials. + * + * Try to avoid many calls to the derivative and integral functions. + * Both of them have to calculate the new coefficients internally, + * which slows things down. Instead, you should use the deriveCoeffs + * and integrateCoeffs functions and store the coefficient matrix + * you need for future calls to evaluate derivative and integral. + */ + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param firstExponent integer value that represents the lowest exponent of the polynomial + /// @param x_base double value that represents the base value for a centered fit in the 1st dimension + double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const int &firstExponent=0, const double &x_base=0.0); - /// @param coefficients matrix containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centered fit in the 1st dimension - /// @param y_base double value that represents the base value for a centered fit in the 2nd dimension - double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// @param coefficients matrix containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centered fit in the 1st dimension + /// @param y_base double value that represents the base value for a centered fit in the 2nd dimension + double evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - /// @param axis unsigned integer value that represents the axis to derive for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - double derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + /// @param axis unsigned integer value that represents the axis to derive for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + double derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input in the 1st dimension - /// @param y_in double value that represents the current input in the 2nd dimension - /// @param axis unsigned integer value that represents the axis to integrate for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - double integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input in the 1st dimension + /// @param y_in double value that represents the current input in the 2nd dimension + /// @param axis unsigned integer value that represents the axis to integrate for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + double integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); public: - /// Returns a vector with ALL the real roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - Eigen::VectorXd solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// Returns a vector with ALL the real roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + Eigen::VectorXd solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); - /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param min double value that represents the minimum value - /// @param max double value that represents the maximum value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - double solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param min double value that represents the minimum value + /// @param max double value that represents the maximum value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + double solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); - /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param guess double value that represents the start value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - double solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); + /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param guess double value that represents the start value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + double solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0); - /// Uses the Brent solver to find the roots of Int(p(x_in,y_in))-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param min double value that represents the minimum value - /// @param max double value that represents the maximum value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - /// @param int_axis axis for the integration (0=x, 1=y) - double solve_limitsInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0, const int &int_axis=0); + /// Uses the Brent solver to find the roots of Int(p(x_in,y_in))-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param min double value that represents the minimum value + /// @param max double value that represents the maximum value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + /// @param int_axis axis for the integration (0=x, 1=y) + double solve_limitsInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0, const int &int_axis=0); - /// Uses the Newton solver to find the roots of Int(p(x_in,y_in))-z_in - /// @param coefficients vector containing the ordered coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param guess double value that represents the start value - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension - /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension - /// @param x_base double value that represents the base value for a centred fit in the 1st dimension - /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension - /// @param int_axis axis for the integration (0=x, 1=y) - double solve_guessInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0, const int &int_axis=0); + /// Uses the Newton solver to find the roots of Int(p(x_in,y_in))-z_in + /// @param coefficients vector containing the ordered coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param guess double value that represents the start value + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp integer value that represents the lowest exponent of the polynomial in the 1st dimension + /// @param y_exp integer value that represents the lowest exponent of the polynomial in the 2nd dimension + /// @param x_base double value that represents the base value for a centred fit in the 1st dimension + /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension + /// @param int_axis axis for the integration (0=x, 1=y) + double solve_guessInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base=0.0, const double &y_base=0.0, const int &int_axis=0); protected: - /// @param nValue integer value that represents the order of the factorial - double factorial(const int &nValue); + /// @param nValue integer value that represents the order of the factorial + double factorial(const int &nValue); - /// @param nValue integer value that represents the upper part of the factorial - /// @param nValue2 integer value that represents the lower part of the factorial - double binom(const int &nValue, const int &nValue2); + /// @param nValue integer value that represents the upper part of the factorial + /// @param nValue2 integer value that represents the lower part of the factorial + double binom(const int &nValue, const int &nValue2); - ///Helper function to calculate the D vector: - /// @param m integer value that represents order - /// @param x_in double value that represents the current input - /// @param x_base double value that represents the basis for the fit - Eigen::MatrixXd fracIntCentralDvector(const int &m, const double &x_in, const double &x_base); + ///Helper function to calculate the D vector: + /// @param m integer value that represents order + /// @param x_in double value that represents the current input + /// @param x_base double value that represents the basis for the fit + Eigen::MatrixXd fracIntCentralDvector(const int &m, const double &x_in, const double &x_base); - ///Indefinite integral of a centred polynomial divided by its independent variable - /// @param coefficients vector containing the ordered coefficients - /// @param x_in double value that represents the current input - /// @param x_base double value that represents the basis for the fit - double fracIntCentral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &x_base); + ///Indefinite integral of a centred polynomial divided by its independent variable + /// @param coefficients vector containing the ordered coefficients + /// @param x_in double value that represents the current input + /// @param x_base double value that represents the basis for the fit + double fracIntCentral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &x_base); }; class Poly2DFracResidual : public Poly2DResidual { protected: - int x_exp, y_exp; - double x_base, y_base; - /// Object that evaluates the equation - Polynomial2DFrac poly; + int x_exp, y_exp; + double x_base, y_base; + /// Object that evaluates the equation + Polynomial2DFrac poly; protected: - Poly2DFracResidual(); + Poly2DFracResidual(); public: - /// Residual of a polynomial divided by the independent variable - /// @param poly polynomial object used to evaluate the calls - /// @param coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp first exponent in x-direction - /// @param y_exp first exponent in y-direction - /// @param x_base base value for x (x = x_in - x_base) - /// @param y_base base value for y (y = y_in - y_base) - Poly2DFracResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, - const double &in, const double &z_in, const int &axis, - const int &x_exp, const int &y_exp, const double &x_base, const double &y_base); - virtual ~Poly2DFracResidual(){}; - double call(double target); - double deriv(double target); + /// Residual of a polynomial divided by the independent variable + /// @param poly polynomial object used to evaluate the calls + /// @param coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp first exponent in x-direction + /// @param y_exp first exponent in y-direction + /// @param x_base base value for x (x = x_in - x_base) + /// @param y_base base value for y (y = y_in - y_base) + Poly2DFracResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, + const double &in, const double &z_in, const int &axis, + const int &x_exp, const int &y_exp, const double &x_base, const double &y_base); + virtual ~Poly2DFracResidual(){}; + double call(double target); + double deriv(double target); }; class Poly2DFracIntResidual : public Poly2DFracResidual { protected: - int int_axis; - Poly2DFracIntResidual(); + int int_axis; + Poly2DFracIntResidual(); public: - /// Residual of an integrated polynomial divided by the independent variable - /// @param poly polynomial object used to evaluate the calls - /// @param coefficients vector of coefficients - /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) - /// @param z_in double value that represents the current output in the 3rd dimension - /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) - /// @param x_exp first exponent in x-direction - /// @param y_exp first exponent in y-direction - /// @param x_base base value for x (x = x_in - x_base) - /// @param y_base base value for y (y = y_in - y_base) - /// @param int_axis axis for the integration (0=x, 1=y) - Poly2DFracIntResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, - const double &in, const double &z_in, const int &axis, - const int &x_exp, const int &y_exp, const double &x_base, const double &y_base, - const int &int_axis); - virtual ~Poly2DFracIntResidual(){}; - double call(double target); - double deriv(double target); + /// Residual of an integrated polynomial divided by the independent variable + /// @param poly polynomial object used to evaluate the calls + /// @param coefficients vector of coefficients + /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) + /// @param z_in double value that represents the current output in the 3rd dimension + /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) + /// @param x_exp first exponent in x-direction + /// @param y_exp first exponent in y-direction + /// @param x_base base value for x (x = x_in - x_base) + /// @param y_base base value for y (y = y_in - y_base) + /// @param int_axis axis for the integration (0=x, 1=y) + Poly2DFracIntResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, + const double &in, const double &z_in, const int &axis, + const int &x_exp, const int &y_exp, const double &x_base, const double &y_base, + const int &int_axis); + virtual ~Poly2DFracIntResidual(){}; + double call(double target); + double deriv(double target); }; @@ -447,279 +447,279 @@ public: //class BasePolynomial{ // //public: -// // Constructor -// BasePolynomial(); -// // Destructor. No implementation -// virtual ~BasePolynomial(){}; +// // Constructor +// BasePolynomial(); +// // Destructor. No implementation +// virtual ~BasePolynomial(){}; // //public: -// /// Basic checks for coefficient vectors. -// /** Starts with only the first coefficient dimension -// * and checks the vector length against parameter n. */ -// bool checkCoefficients(const Eigen::VectorXd &coefficients, const unsigned int n); -// bool checkCoefficients(const Eigen::MatrixXd &coefficients, const unsigned int rows, const unsigned int columns); -// bool checkCoefficients(const std::vector &coefficients, const unsigned int n); -// bool checkCoefficients(const std::vector< std::vector > &coefficients, const unsigned int rows, const unsigned int columns); +// /// Basic checks for coefficient vectors. +// /** Starts with only the first coefficient dimension +// * and checks the vector length against parameter n. */ +// bool checkCoefficients(const Eigen::VectorXd &coefficients, const unsigned int n); +// bool checkCoefficients(const Eigen::MatrixXd &coefficients, const unsigned int rows, const unsigned int columns); +// bool checkCoefficients(const std::vector &coefficients, const unsigned int n); +// bool checkCoefficients(const std::vector< std::vector > &coefficients, const unsigned int rows, const unsigned int columns); // -// /** Integrating coefficients for polynomials is done by dividing the -// * original coefficients by (i+1) and elevating the order by 1 -// * through adding a zero as first coefficient. -// * Some reslicing needs to be applied to integrate along the x-axis. -// * In the brine/solution equations, reordering of the parameters -// * avoids this expensive operation. However, it is included for the -// * sake of completeness. -// */ -// std::vector integrateCoeffs(const std::vector &coefficients); -// std::vector< std::vector > integrateCoeffs(const std::vector< std::vector > &coefficients, bool axis); +// /** Integrating coefficients for polynomials is done by dividing the +// * original coefficients by (i+1) and elevating the order by 1 +// * through adding a zero as first coefficient. +// * Some reslicing needs to be applied to integrate along the x-axis. +// * In the brine/solution equations, reordering of the parameters +// * avoids this expensive operation. However, it is included for the +// * sake of completeness. +// */ +// std::vector integrateCoeffs(const std::vector &coefficients); +// std::vector< std::vector > integrateCoeffs(const std::vector< std::vector > &coefficients, bool axis); // -// /** Deriving coefficients for polynomials is done by multiplying the -// * original coefficients with i and lowering the order by 1. -// * -// * It is not really deprecated, but untested and therefore a warning -// * is issued. Please check this method before you use it. -// */ -// std::vector deriveCoeffs(const std::vector &coefficients); -// std::vector< std::vector > deriveCoeffs(const std::vector< std::vector > &coefficients, unsigned int axis); +// /** Deriving coefficients for polynomials is done by multiplying the +// * original coefficients with i and lowering the order by 1. +// * +// * It is not really deprecated, but untested and therefore a warning +// * is issued. Please check this method before you use it. +// */ +// std::vector deriveCoeffs(const std::vector &coefficients); +// std::vector< std::vector > deriveCoeffs(const std::vector< std::vector > &coefficients, unsigned int axis); // //private: -// /** The core of the polynomial wrappers are the different -// * implementations that follow below. In case there are -// * new calculation schemes available, please do not delete -// * the implementations, but mark them as deprecated. -// * The old functions are good for debugging since the -// * structure is easier to read than the backward Horner-scheme -// * or the recursive Horner-scheme. -// */ +// /** The core of the polynomial wrappers are the different +// * implementations that follow below. In case there are +// * new calculation schemes available, please do not delete +// * the implementations, but mark them as deprecated. +// * The old functions are good for debugging since the +// * structure is easier to read than the backward Horner-scheme +// * or the recursive Horner-scheme. +// */ // -// /// Simple polynomial function generator. <- Deprecated due to poor performance, use Horner-scheme instead -// /** Base function to produce n-th order polynomials -// * based on the length of the coefficient vector. -// * Starts with only the first coefficient at x^0. */ -// DEPRECATED(double simplePolynomial(const std::vector &coefficients, double x)); -// DEPRECATED(double simplePolynomial(const std::vector > &coefficients, double x, double y)); +// /// Simple polynomial function generator. <- Deprecated due to poor performance, use Horner-scheme instead +// /** Base function to produce n-th order polynomials +// * based on the length of the coefficient vector. +// * Starts with only the first coefficient at x^0. */ +// DEPRECATED(double simplePolynomial(const std::vector &coefficients, double x)); +// DEPRECATED(double simplePolynomial(const std::vector > &coefficients, double x, double y)); // -// /// Simple integrated polynomial function generator. -// /** Base function to produce integrals of n-th order polynomials based on -// * the length of the coefficient vector. -// * Starts with only the first coefficient at x^0 */ -// ///Indefinite integral in x-direction -// double simplePolynomialInt(const std::vector &coefficients, double x); -// ///Indefinite integral in y-direction only -// double simplePolynomialInt(const std::vector > &coefficients, double x, double y); +// /// Simple integrated polynomial function generator. +// /** Base function to produce integrals of n-th order polynomials based on +// * the length of the coefficient vector. +// * Starts with only the first coefficient at x^0 */ +// ///Indefinite integral in x-direction +// double simplePolynomialInt(const std::vector &coefficients, double x); +// ///Indefinite integral in y-direction only +// double simplePolynomialInt(const std::vector > &coefficients, double x, double y); // -// /// Simple integrated polynomial function generator divided by independent variable. -// /** Base function to produce integrals of n-th order -// * polynomials based on the length of the coefficient -// * vector. Starts with only the first coefficient at x^0 */ -// ///Indefinite integral of a polynomial divided by its independent variable -// double simpleFracInt(const std::vector &coefficients, double x); -// ///Indefinite integral of a polynomial divided by its 2nd independent variable -// double simpleFracInt(const std::vector > &coefficients, double x, double y); +// /// Simple integrated polynomial function generator divided by independent variable. +// /** Base function to produce integrals of n-th order +// * polynomials based on the length of the coefficient +// * vector. Starts with only the first coefficient at x^0 */ +// ///Indefinite integral of a polynomial divided by its independent variable +// double simpleFracInt(const std::vector &coefficients, double x); +// ///Indefinite integral of a polynomial divided by its 2nd independent variable +// double simpleFracInt(const std::vector > &coefficients, double x, double y); // -// /** Simple integrated centred(!) polynomial function generator divided by independent variable. -// * We need to rewrite some of the functions in order to -// * use central fit. Having a central temperature xbase -// * allows for a better fit, but requires a different -// * formulation of the fracInt function group. Other -// * functions are not affected. -// * Starts with only the first coefficient at x^0 */ -// ///Helper function to calculate the D vector: -// double factorial(double nValue); -// double binom(double nValue, double nValue2); -// std::vector fracIntCentralDvector(int m, double x, double xbase); -// ///Indefinite integral of a centred polynomial divided by its independent variable -// double fracIntCentral(const std::vector &coefficients, double x, double xbase); +// /** Simple integrated centred(!) polynomial function generator divided by independent variable. +// * We need to rewrite some of the functions in order to +// * use central fit. Having a central temperature xbase +// * allows for a better fit, but requires a different +// * formulation of the fracInt function group. Other +// * functions are not affected. +// * Starts with only the first coefficient at x^0 */ +// ///Helper function to calculate the D vector: +// double factorial(double nValue); +// double binom(double nValue, double nValue2); +// std::vector fracIntCentralDvector(int m, double x, double xbase); +// ///Indefinite integral of a centred polynomial divided by its independent variable +// double fracIntCentral(const std::vector &coefficients, double x, double xbase); // -// /// Horner function generator implementations -// /** Represent polynomials according to Horner's scheme. -// * This avoids unnecessary multiplication and thus -// * speeds up calculation. -// */ -// double baseHorner(const std::vector &coefficients, double x); -// double baseHorner(const std::vector< std::vector > &coefficients, double x, double y); -// ///Indefinite integral in x-direction -// double baseHornerInt(const std::vector &coefficients, double x); -// ///Indefinite integral in y-direction only -// double baseHornerInt(const std::vector > &coefficients, double x, double y); -// ///Indefinite integral of a polynomial divided by its independent variable -// double baseHornerFracInt(const std::vector &coefficients, double x); -// ///Indefinite integral of a polynomial divided by its 2nd independent variable -// double baseHornerFracInt(const std::vector > &coefficients, double x, double y); +// /// Horner function generator implementations +// /** Represent polynomials according to Horner's scheme. +// * This avoids unnecessary multiplication and thus +// * speeds up calculation. +// */ +// double baseHorner(const std::vector &coefficients, double x); +// double baseHorner(const std::vector< std::vector > &coefficients, double x, double y); +// ///Indefinite integral in x-direction +// double baseHornerInt(const std::vector &coefficients, double x); +// ///Indefinite integral in y-direction only +// double baseHornerInt(const std::vector > &coefficients, double x, double y); +// ///Indefinite integral of a polynomial divided by its independent variable +// double baseHornerFracInt(const std::vector &coefficients, double x); +// ///Indefinite integral of a polynomial divided by its 2nd independent variable +// double baseHornerFracInt(const std::vector > &coefficients, double x, double y); // -// /** Alternatives -// * Simple functions that heavily rely on other parts of this file. -// * We still need to check which combinations yield the best -// * performance. -// */ -// ///Derivative in x-direction -// double deriveIn2Steps(const std::vector &coefficients, double x); // TODO: Check results! -// ///Derivative in terms of x(axis=true) or y(axis=false). -// double deriveIn2Steps(const std::vector< std::vector > &coefficients, double x, double y, bool axis); // TODO: Check results! -// ///Indefinite integral in x-direction -// double integrateIn2Steps(const std::vector &coefficients, double x); -// ///Indefinite integral in terms of x(axis=true) or y(axis=false). -// double integrateIn2Steps(const std::vector< std::vector > &coefficients, double x, double y, bool axis); -// ///Indefinite integral in x-direction of a polynomial divided by its independent variable -// double fracIntIn2Steps(const std::vector &coefficients, double x); -// ///Indefinite integral in y-direction of a polynomial divided by its 2nd independent variable -// double fracIntIn2Steps(const std::vector > &coefficients, double x, double y); -// ///Indefinite integral of a centred polynomial divided by its 2nd independent variable -// double fracIntCentral2Steps(const std::vector > &coefficients, double x, double y, double ybase); +// /** Alternatives +// * Simple functions that heavily rely on other parts of this file. +// * We still need to check which combinations yield the best +// * performance. +// */ +// ///Derivative in x-direction +// double deriveIn2Steps(const std::vector &coefficients, double x); // TODO: Check results! +// ///Derivative in terms of x(axis=true) or y(axis=false). +// double deriveIn2Steps(const std::vector< std::vector > &coefficients, double x, double y, bool axis); // TODO: Check results! +// ///Indefinite integral in x-direction +// double integrateIn2Steps(const std::vector &coefficients, double x); +// ///Indefinite integral in terms of x(axis=true) or y(axis=false). +// double integrateIn2Steps(const std::vector< std::vector > &coefficients, double x, double y, bool axis); +// ///Indefinite integral in x-direction of a polynomial divided by its independent variable +// double fracIntIn2Steps(const std::vector &coefficients, double x); +// ///Indefinite integral in y-direction of a polynomial divided by its 2nd independent variable +// double fracIntIn2Steps(const std::vector > &coefficients, double x, double y); +// ///Indefinite integral of a centred polynomial divided by its 2nd independent variable +// double fracIntCentral2Steps(const std::vector > &coefficients, double x, double y, double ybase); // //public: -// /** Here we define the functions that should be used by the -// * respective implementations. Please do no use any other -// * method since this would break the purpose of this interface. -// * Note that the functions below are supposed to be aliases -// * to implementations declared elsewhere in this file. -// */ +// /** Here we define the functions that should be used by the +// * respective implementations. Please do no use any other +// * method since this would break the purpose of this interface. +// * Note that the functions below are supposed to be aliases +// * to implementations declared elsewhere in this file. +// */ // -// /** Everything related to the normal polynomials goes in this -// * section, holds all the functions for evaluating polynomials. -// */ -// /// Evaluates a one-dimensional polynomial for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input -// virtual inline double polyval(const std::vector &coefficients, double x){ -// return baseHorner(coefficients,x); -// } +// /** Everything related to the normal polynomials goes in this +// * section, holds all the functions for evaluating polynomials. +// */ +// /// Evaluates a one-dimensional polynomial for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input +// virtual inline double polyval(const std::vector &coefficients, double x){ +// return baseHorner(coefficients,x); +// } // -// /// Evaluates a two-dimensional polynomial for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyval(const std::vector< std::vector > &coefficients, double x, double y){ -// return baseHorner(coefficients,x,y); -// } +// /// Evaluates a two-dimensional polynomial for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyval(const std::vector< std::vector > &coefficients, double x, double y){ +// return baseHorner(coefficients,x,y); +// } // // -// /** Everything related to the integrated polynomials goes in this -// * section, holds all the functions for evaluating polynomials. -// */ -// /// Evaluates the indefinite integral of a one-dimensional polynomial -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input -// virtual inline double polyint(const std::vector &coefficients, double x){ -// return baseHornerInt(coefficients,x); -// } +// /** Everything related to the integrated polynomials goes in this +// * section, holds all the functions for evaluating polynomials. +// */ +// /// Evaluates the indefinite integral of a one-dimensional polynomial +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input +// virtual inline double polyint(const std::vector &coefficients, double x){ +// return baseHornerInt(coefficients,x); +// } // -// /// Evaluates the indefinite integral of a two-dimensional polynomial along the 2nd axis (y) -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyint(const std::vector< std::vector > &coefficients, double x, double y){ -// return baseHornerInt(coefficients,x,y); -// } +// /// Evaluates the indefinite integral of a two-dimensional polynomial along the 2nd axis (y) +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyint(const std::vector< std::vector > &coefficients, double x, double y){ +// return baseHornerInt(coefficients,x,y); +// } // // -// /** Everything related to the derived polynomials goes in this -// * section, holds all the functions for evaluating polynomials. -// */ -// /// Evaluates the derivative of a one-dimensional polynomial -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input -// virtual inline double polyder(const std::vector &coefficients, double x){ -// return deriveIn2Steps(coefficients,x); -// } +// /** Everything related to the derived polynomials goes in this +// * section, holds all the functions for evaluating polynomials. +// */ +// /// Evaluates the derivative of a one-dimensional polynomial +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input +// virtual inline double polyder(const std::vector &coefficients, double x){ +// return deriveIn2Steps(coefficients,x); +// } // -// /// Evaluates the derivative of a two-dimensional polynomial along the 2nd axis (y) -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyder(const std::vector< std::vector > &coefficients, double x, double y){ -// return deriveIn2Steps(coefficients,x,y,false); -// } +// /// Evaluates the derivative of a two-dimensional polynomial along the 2nd axis (y) +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyder(const std::vector< std::vector > &coefficients, double x, double y){ +// return deriveIn2Steps(coefficients,x,y,false); +// } // // -// /** Everything related to the polynomials divided by one variable goes in this -// * section, holds all the functions for evaluating polynomials. -// */ -// /// Evaluates the indefinite integral of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current position -// virtual inline double polyfracval(const std::vector &coefficients, double x){ -// return baseHorner(coefficients,x)/x; -// } +// /** Everything related to the polynomials divided by one variable goes in this +// * section, holds all the functions for evaluating polynomials. +// */ +// /// Evaluates the indefinite integral of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current position +// virtual inline double polyfracval(const std::vector &coefficients, double x){ +// return baseHorner(coefficients,x)/x; +// } // -// /// Evaluates the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyfracval(const std::vector< std::vector > &coefficients, double x, double y){ -// return baseHorner(coefficients,x,y)/y; -// } +// /// Evaluates the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyfracval(const std::vector< std::vector > &coefficients, double x, double y){ +// return baseHorner(coefficients,x,y)/y; +// } // // -// /** Everything related to the integrated polynomials divided by one variable goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Evaluates the indefinite integral of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current position -// virtual inline double polyfracint(const std::vector &coefficients, double x){ -// return baseHornerFracInt(coefficients,x); -// } +// /** Everything related to the integrated polynomials divided by one variable goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Evaluates the indefinite integral of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current position +// virtual inline double polyfracint(const std::vector &coefficients, double x){ +// return baseHornerFracInt(coefficients,x); +// } // -// /// Evaluates the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyfracint(const std::vector< std::vector > &coefficients, double x, double y){ -// return baseHornerFracInt(coefficients,x,y); -// } +// /// Evaluates the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyfracint(const std::vector< std::vector > &coefficients, double x, double y){ +// return baseHornerFracInt(coefficients,x,y); +// } // -// /// Evaluates the indefinite integral of a centred one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current position -// /// @param xbase central temperature for fitted function -// virtual inline double polyfracintcentral(const std::vector &coefficients, double x, double xbase){ -// return fracIntCentral(coefficients,x,xbase); -// } +// /// Evaluates the indefinite integral of a centred one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current position +// /// @param xbase central temperature for fitted function +// virtual inline double polyfracintcentral(const std::vector &coefficients, double x, double xbase){ +// return fracIntCentral(coefficients,x,xbase); +// } // -// /// Evaluates the indefinite integral of a centred two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// /// @param ybase central temperature for fitted function -// virtual inline double polyfracintcentral(const std::vector< std::vector > &coefficients, double x, double y, double ybase){ -// return fracIntCentral2Steps(coefficients,x,y,ybase); -// } +// /// Evaluates the indefinite integral of a centred two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// /// @param ybase central temperature for fitted function +// virtual inline double polyfracintcentral(const std::vector< std::vector > &coefficients, double x, double y, double ybase){ +// return fracIntCentral2Steps(coefficients,x,y,ybase); +// } // // -// /** Everything related to the derived polynomials divided by one variable goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Evaluates the derivative of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current position -// virtual inline double polyfracder(const std::vector &coefficients, double x){ -// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracder1D -// } +// /** Everything related to the derived polynomials divided by one variable goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Evaluates the derivative of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current position +// virtual inline double polyfracder(const std::vector &coefficients, double x){ +// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracder1D +// } // -// /// Evaluates the derivative of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// virtual inline double polyfracder(const std::vector< std::vector > &coefficients, double x, double y){ -// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracder2D -// } +// /// Evaluates the derivative of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// virtual inline double polyfracder(const std::vector< std::vector > &coefficients, double x, double y){ +// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracder2D +// } // -// /// Evaluates the derivative of a centred one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current position -// /// @param xbase central temperature for fitted function -// virtual inline double polyfracdercentral(const std::vector &coefficients, double x, double xbase){ -// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracdercentral1D -// } +// /// Evaluates the derivative of a centred one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current position +// /// @param xbase central temperature for fitted function +// virtual inline double polyfracdercentral(const std::vector &coefficients, double x, double xbase){ +// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracdercentral1D +// } // -// /// Evaluates the derivative of a centred two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// /// @param ybase central temperature for fitted function -// virtual inline double polyfracdercentral(const std::vector< std::vector > &coefficients, double x, double y, double ybase){ -// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracdercentral2D -// } +// /// Evaluates the derivative of a centred two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// /// @param ybase central temperature for fitted function +// virtual inline double polyfracdercentral(const std::vector< std::vector > &coefficients, double x, double y, double ybase){ +// throw CoolProp::NotImplementedError("Derivatives of polynomials divided by their independent variable have not been implemented."); // TODO: Implement polyfracdercentral2D +// } //}; // // @@ -731,52 +731,52 @@ public: // */ //class PolyResidual : public FuncWrapper1D { //protected: -// enum dims {i1D, i2D}; -// /// Object that evaluates the equation -// BasePolynomial poly; -// /// Current output value -// double output, firstDim; -// int dim; -// std::vector< std::vector > coefficients; +// enum dims {i1D, i2D}; +// /// Object that evaluates the equation +// BasePolynomial poly; +// /// Current output value +// double output, firstDim; +// int dim; +// std::vector< std::vector > coefficients; //private: -// PolyResidual(); +// PolyResidual(); //public: -// PolyResidual(const std::vector &coefficients, double y); -// PolyResidual(const std::vector< std::vector > &coefficients, double x, double z); -// virtual ~PolyResidual(){}; -// bool is2D(){return (this->dim==i2D);}; -// virtual double call(double x); -// virtual double deriv(double x); +// PolyResidual(const std::vector &coefficients, double y); +// PolyResidual(const std::vector< std::vector > &coefficients, double x, double z); +// virtual ~PolyResidual(){}; +// bool is2D(){return (this->dim==i2D);}; +// virtual double call(double x); +// virtual double deriv(double x); //}; //class PolyIntResidual : public PolyResidual { //public: -// PolyIntResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; -// PolyIntResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; -// virtual double call(double x); -// virtual double deriv(double x); +// PolyIntResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; +// PolyIntResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; +// virtual double call(double x); +// virtual double deriv(double x); //}; //class PolyFracIntResidual : public PolyResidual { //public: -// PolyFracIntResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; -// PolyFracIntResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; -// virtual double call(double x); -// virtual double deriv(double x); +// PolyFracIntResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; +// PolyFracIntResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; +// virtual double call(double x); +// virtual double deriv(double x); //}; //class PolyFracIntCentralResidual : public PolyResidual { //protected: -// double baseVal; +// double baseVal; //public: -// PolyFracIntCentralResidual(const std::vector &coefficients, double y, double xBase):PolyResidual(coefficients, y){this->baseVal = xBase;}; -// PolyFracIntCentralResidual(const std::vector< std::vector > &coefficients, double x, double z, double yBase): PolyResidual(coefficients, x, z){this->baseVal = yBase;}; -// virtual double call(double x); -// virtual double deriv(double x); +// PolyFracIntCentralResidual(const std::vector &coefficients, double y, double xBase):PolyResidual(coefficients, y){this->baseVal = xBase;}; +// PolyFracIntCentralResidual(const std::vector< std::vector > &coefficients, double x, double z, double yBase): PolyResidual(coefficients, x, z){this->baseVal = yBase;}; +// virtual double call(double x); +// virtual double deriv(double x); //}; //class PolyDerResidual : public PolyResidual { //public: -// PolyDerResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; -// PolyDerResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; -// virtual double call(double x); -// virtual double deriv(double x); +// PolyDerResidual(const std::vector &coefficients, double y):PolyResidual(coefficients, y){}; +// PolyDerResidual(const std::vector< std::vector > &coefficients, double x, double z):PolyResidual(coefficients, x, z){}; +// virtual double call(double x); +// virtual double deriv(double x); //}; // // @@ -791,154 +791,154 @@ public: // */ //class PolynomialSolver : public BasePolynomial{ //private: -// enum solvers {iNewton, iBrent}; -// int uses; -// double guess, min, max; -// double macheps, tol; -// int maxiter; +// enum solvers {iNewton, iBrent}; +// int uses; +// double guess, min, max; +// double macheps, tol; +// int maxiter; // //public: -// // Constructor -// PolynomialSolver(); -// // Destructor. No implementation -// virtual ~PolynomialSolver(){}; +// // Constructor +// PolynomialSolver(); +// // Destructor. No implementation +// virtual ~PolynomialSolver(){}; // //public: -// /** Here we redefine the functions that solve the polynomials. -// * These implementations all use the base class to evaluate -// * the polynomial during the solution process. -// */ +// /** Here we redefine the functions that solve the polynomials. +// * These implementations all use the base class to evaluate +// * the polynomial during the solution process. +// */ // -// /** Everything related to the normal polynomials goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves a one-dimensional polynomial for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current input -// virtual double polyval(const std::vector &coefficients, double y); +// /** Everything related to the normal polynomials goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves a one-dimensional polynomial for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current input +// virtual double polyval(const std::vector &coefficients, double y); // -// /// Solves a two-dimensional polynomial for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyval(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves a two-dimensional polynomial for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyval(const std::vector< std::vector > &coefficients, double x, double z); // // -// /** Everything related to the integrated polynomials goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves the indefinite integral of a one-dimensional polynomial -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// virtual double polyint(const std::vector &coefficients, double y); +// /** Everything related to the integrated polynomials goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves the indefinite integral of a one-dimensional polynomial +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// virtual double polyint(const std::vector &coefficients, double y); // -// /// Solves the indefinite integral of a two-dimensional polynomial along the 2nd axis (y) -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyint(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves the indefinite integral of a two-dimensional polynomial along the 2nd axis (y) +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyint(const std::vector< std::vector > &coefficients, double x, double z); // // -// /** Everything related to the derived polynomials goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves the derivative of a one-dimensional polynomial -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// virtual double polyder(const std::vector &coefficients, double y); +// /** Everything related to the derived polynomials goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves the derivative of a one-dimensional polynomial +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// virtual double polyder(const std::vector &coefficients, double y); // -// /// Solves the derivative of a two-dimensional polynomial along the 2nd axis (y) -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyder(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves the derivative of a two-dimensional polynomial along the 2nd axis (y) +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyder(const std::vector< std::vector > &coefficients, double x, double z); // // -// /** Everything related to the polynomials divided by one variable goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves the indefinite integral of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// virtual double polyfracval(const std::vector &coefficients, double y); +// /** Everything related to the polynomials divided by one variable goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves the indefinite integral of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// virtual double polyfracval(const std::vector &coefficients, double y); // -// /// Solves the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyfracval(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyfracval(const std::vector< std::vector > &coefficients, double x, double z); // // -// /** Everything related to the integrated polynomials divided by one variable goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves the indefinite integral of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// virtual double polyfracint(const std::vector &coefficients, double y); +// /** Everything related to the integrated polynomials divided by one variable goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves the indefinite integral of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// virtual double polyfracint(const std::vector &coefficients, double y); // -// /// Solves the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyfracint(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves the indefinite integral of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyfracint(const std::vector< std::vector > &coefficients, double x, double z); // -// /// Solves the indefinite integral of a centred one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// /// @param xbase central x-value for fitted function -// virtual double polyfracintcentral(const std::vector &coefficients, double y, double xbase); +// /// Solves the indefinite integral of a centred one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// /// @param xbase central x-value for fitted function +// virtual double polyfracintcentral(const std::vector &coefficients, double y, double xbase); // -// /// Solves the indefinite integral of a centred two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// /// @param ybase central y-value for fitted function -// virtual double polyfracintcentral(const std::vector< std::vector > &coefficients, double x, double z, double ybase); +// /// Solves the indefinite integral of a centred two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// /// @param ybase central y-value for fitted function +// virtual double polyfracintcentral(const std::vector< std::vector > &coefficients, double x, double z, double ybase); // // -// /** Everything related to the derived polynomials divided by one variable goes in this -// * section, holds all the functions for solving polynomials. -// */ -// /// Solves the derivative of a one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// virtual double polyfracder(const std::vector &coefficients, double y); +// /** Everything related to the derived polynomials divided by one variable goes in this +// * section, holds all the functions for solving polynomials. +// */ +// /// Solves the derivative of a one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// virtual double polyfracder(const std::vector &coefficients, double y); // -// /// Solves the derivative of a two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// virtual double polyfracder(const std::vector< std::vector > &coefficients, double x, double z); +// /// Solves the derivative of a two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// virtual double polyfracder(const std::vector< std::vector > &coefficients, double x, double z); // -// /// Solves the derivative of a centred one-dimensional polynomial divided by its independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param y double value that represents the current output -// /// @param xbase central x-value for fitted function -// virtual double polyfracdercentral(const std::vector &coefficients, double y, double xbase); +// /// Solves the derivative of a centred one-dimensional polynomial divided by its independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param y double value that represents the current output +// /// @param xbase central x-value for fitted function +// virtual double polyfracdercentral(const std::vector &coefficients, double y, double xbase); // -// /// Solves the derivative of a centred two-dimensional polynomial divided by its 2nd independent variable -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param z double value that represents the current output -// /// @param ybase central y-value for fitted function -// virtual double polyfracdercentral(const std::vector< std::vector > &coefficients, double x, double z, double ybase); +// /// Solves the derivative of a centred two-dimensional polynomial divided by its 2nd independent variable +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param z double value that represents the current output +// /// @param ybase central y-value for fitted function +// virtual double polyfracdercentral(const std::vector< std::vector > &coefficients, double x, double z, double ybase); // // -// /** Set the solvers and updates either the guess values or the -// * boundaries for the variable to solve for. -// */ -// /// Sets the guess value for the Newton solver and enables it. -// /// @param guess double value that represents the guess value -// virtual void setGuess(double guess); -// /// Sets the limits for the Brent solver and enables it. -// /// @param min double value that represents the lower boundary -// /// @param max double value that represents the upper boundary -// virtual void setLimits(double min, double max); -// /// Solves the equations based on previously defined parameters. -// /// @param min double value that represents the lower boundary -// /// @param max double value that represents the upper boundary -// virtual double solve(PolyResidual &res); +// /** Set the solvers and updates either the guess values or the +// * boundaries for the variable to solve for. +// */ +// /// Sets the guess value for the Newton solver and enables it. +// /// @param guess double value that represents the guess value +// virtual void setGuess(double guess); +// /// Sets the limits for the Brent solver and enables it. +// /// @param min double value that represents the lower boundary +// /// @param max double value that represents the upper boundary +// virtual void setLimits(double min, double max); +// /// Solves the equations based on previously defined parameters. +// /// @param min double value that represents the lower boundary +// /// @param max double value that represents the upper boundary +// virtual double solve(PolyResidual &res); //}; // // @@ -946,26 +946,26 @@ public: //class BaseExponential{ // //protected: -// BasePolynomial poly; -// bool POLYMATH_DEBUG; +// BasePolynomial poly; +// bool POLYMATH_DEBUG; // //public: -// BaseExponential(); -// virtual ~BaseExponential(){}; +// BaseExponential(); +// virtual ~BaseExponential(){}; // //public: -// /// Evaluates an exponential function for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input -// /// @param n int value that determines the kind of exponential function -// double expval(const std::vector &coefficients, double x, int n); +// /// Evaluates an exponential function for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input +// /// @param n int value that determines the kind of exponential function +// double expval(const std::vector &coefficients, double x, int n); // -// /// Evaluates an exponential function for the given coefficients -// /// @param coefficients vector containing the ordered coefficients -// /// @param x double value that represents the current input in the 1st dimension -// /// @param y double value that represents the current input in the 2nd dimension -// /// @param n int value that determines the kind of exponential function -// double expval(const std::vector< std::vector > &coefficients, double x, double y, int n); +// /// Evaluates an exponential function for the given coefficients +// /// @param coefficients vector containing the ordered coefficients +// /// @param x double value that represents the current input in the 1st dimension +// /// @param y double value that represents the current input in the 2nd dimension +// /// @param n int value that determines the kind of exponential function +// double expval(const std::vector< std::vector > &coefficients, double x, double y, int n); //}; diff --git a/include/Solvers.h b/include/Solvers.h index 5923f667..be7fb70a 100644 --- a/include/Solvers.h +++ b/include/Solvers.h @@ -11,19 +11,19 @@ namespace CoolProp class FuncWrapper1D { public: - FuncWrapper1D(){}; - virtual ~FuncWrapper1D(){}; - virtual double call(double) = 0; - virtual double deriv(double){throw NotImplementedError("deriv function not implemented");}; + FuncWrapper1D(){}; + virtual ~FuncWrapper1D(){}; + virtual double call(double) = 0; + virtual double deriv(double){throw NotImplementedError("deriv function not implemented");}; }; class FuncWrapperND { public: - FuncWrapperND(){}; - virtual ~FuncWrapperND(){}; - virtual std::vector call(std::vector) = 0;// must be provided - virtual std::vector > Jacobian(std::vector){std::vector > J; return J;}; // optional + FuncWrapperND(){}; + virtual ~FuncWrapperND(){}; + virtual std::vector call(std::vector) = 0;// must be provided + virtual std::vector > Jacobian(std::vector){std::vector > J; return J;}; // optional }; // Single-Dimensional solvers, pointer versions diff --git a/include/crossplatform_shared_ptr.h b/include/crossplatform_shared_ptr.h index 8a19a7ba..c2398143 100644 --- a/include/crossplatform_shared_ptr.h +++ b/include/crossplatform_shared_ptr.h @@ -6,7 +6,7 @@ // Based on the platform and compiler, include the necessary header to give access to std::tr1::shared_ptr directly as shared_ptr #if defined(__ISLINUX__) && (defined(__llvm__) || defined(__clang__)) // CLANG - #if __has_include() + #if __has_include() // CLANG and -stdlib=libstdc++ // See also http://stackoverflow.com/questions/13445742/apple-and-shared-ptr #include diff --git a/include/rapidjson/rapidjson/document.h b/include/rapidjson/rapidjson/document.h index 3c79f5e8..7779d799 100644 --- a/include/rapidjson/rapidjson/document.h +++ b/include/rapidjson/rapidjson/document.h @@ -3,7 +3,7 @@ #include "reader.h" #include "internal/strfunc.h" -#include // placement new +#include // placement new #ifdef _MSC_VER #pragma warning(push) @@ -17,664 +17,664 @@ namespace rapidjson { //! Represents a JSON value. Use Value for UTF8 encoding and default allocator. /*! - A JSON value can be one of 7 types. This class is a variant type supporting - these types. + A JSON value can be one of 7 types. This class is a variant type supporting + these types. - Use the Value if UTF8 and default allocator + Use the Value if UTF8 and default allocator - \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) - \tparam Allocator Allocator type for allocating memory of object, array and string. + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. */ #pragma pack (push, 4) template > class GenericValue { public: - //! Name-value pair in an object. - struct Member { - GenericValue name; //!< name of member (must be a string) - GenericValue value; //!< value of member. - }; + //! Name-value pair in an object. + struct Member { + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. + }; - typedef Encoding EncodingType; //!< Encoding type from template parameter. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef Member* MemberIterator; //!< Member iterator for iterating in object. - typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object. - typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. - typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef Member* MemberIterator; //!< Member iterator for iterating in object. + typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. - //!@name Constructors and destructor. - //@{ + //!@name Constructors and destructor. + //@{ - //! Default constructor creates a null value. - GenericValue() : flags_(kNullFlag) {} + //! Default constructor creates a null value. + GenericValue() : flags_(kNullFlag) {} - //! Copy constructor is not permitted. + //! Copy constructor is not permitted. private: - GenericValue(const GenericValue& rhs); + GenericValue(const GenericValue& rhs); public: - //! Constructor with JSON value type. - /*! This creates a Value of specified type with default content. - \param type Type of the value. - \note Default content for number is zero. - */ - GenericValue(Type type) { - static const unsigned defaultFlags[7] = { - kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, - kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag - }; - RAPIDJSON_ASSERT(type <= kNumberType); - flags_ = defaultFlags[type]; - memset(&data_, 0, sizeof(data_)); - } + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + GenericValue(Type type) { + static const unsigned defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, + kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + flags_ = defaultFlags[type]; + memset(&data_, 0, sizeof(data_)); + } - //! Constructor for boolean value. - GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {} + //! Constructor for boolean value. + GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {} - //! Constructor for int value. - GenericValue(int i) : flags_(kNumberIntFlag) { - data_.n.i64 = i; - if (i >= 0) - flags_ |= kUintFlag | kUint64Flag; - } + //! Constructor for int value. + GenericValue(int i) : flags_(kNumberIntFlag) { + data_.n.i64 = i; + if (i >= 0) + flags_ |= kUintFlag | kUint64Flag; + } - //! Constructor for unsigned value. - GenericValue(unsigned u) : flags_(kNumberUintFlag) { - data_.n.u64 = u; - if (!(u & 0x80000000)) - flags_ |= kIntFlag | kInt64Flag; - } + //! Constructor for unsigned value. + GenericValue(unsigned u) : flags_(kNumberUintFlag) { + data_.n.u64 = u; + if (!(u & 0x80000000)) + flags_ |= kIntFlag | kInt64Flag; + } - //! Constructor for int64_t value. - GenericValue(int64_t i64) : flags_(kNumberInt64Flag) { - data_.n.i64 = i64; - if (i64 >= 0) { - flags_ |= kNumberUint64Flag; - if (!(i64 & 0xFFFFFFFF00000000LL)) - flags_ |= kUintFlag; - if (!(i64 & 0xFFFFFFFF80000000LL)) - flags_ |= kIntFlag; - } - else if (i64 >= -2147483648LL) - flags_ |= kIntFlag; - } + //! Constructor for int64_t value. + GenericValue(int64_t i64) : flags_(kNumberInt64Flag) { + data_.n.i64 = i64; + if (i64 >= 0) { + flags_ |= kNumberUint64Flag; + if (!(i64 & 0xFFFFFFFF00000000LL)) + flags_ |= kUintFlag; + if (!(i64 & 0xFFFFFFFF80000000LL)) + flags_ |= kIntFlag; + } + else if (i64 >= -2147483648LL) + flags_ |= kIntFlag; + } - //! Constructor for uint64_t value. - GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) { - data_.n.u64 = u64; - if (!(u64 & 0x8000000000000000ULL)) - flags_ |= kInt64Flag; - if (!(u64 & 0xFFFFFFFF00000000ULL)) - flags_ |= kUintFlag; - if (!(u64 & 0xFFFFFFFF80000000ULL)) - flags_ |= kIntFlag; - } + //! Constructor for uint64_t value. + GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) { + data_.n.u64 = u64; + if (!(u64 & 0x8000000000000000ULL)) + flags_ |= kInt64Flag; + if (!(u64 & 0xFFFFFFFF00000000ULL)) + flags_ |= kUintFlag; + if (!(u64 & 0xFFFFFFFF80000000ULL)) + flags_ |= kIntFlag; + } - //! Constructor for double value. - GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; } + //! Constructor for double value. + GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; } - //! Constructor for constant string (i.e. do not make a copy of string) - GenericValue(const Ch* s, SizeType length) { - RAPIDJSON_ASSERT(s != NULL); - flags_ = kConstStringFlag; - data_.s.str = s; - data_.s.length = length; - } + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) { + RAPIDJSON_ASSERT(s != NULL); + flags_ = kConstStringFlag; + data_.s.str = s; + data_.s.length = length; + } - //! Constructor for constant string (i.e. do not make a copy of string) - GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); } + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); } - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); } + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); } - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); } + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); } - //! Destructor. - /*! Need to destruct elements of array, members of object, or copy-string. - */ - ~GenericValue() { - if (Allocator::kNeedFree) { // Shortcut by Allocator's trait - switch(flags_) { - case kArrayFlag: - for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) - v->~GenericValue(); - Allocator::Free(data_.a.elements); - break; + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(flags_) { + case kArrayFlag: + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(data_.a.elements); + break; - case kObjectFlag: - for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { - m->name.~GenericValue(); - m->value.~GenericValue(); - } - Allocator::Free(data_.o.members); - break; + case kObjectFlag: + for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { + m->name.~GenericValue(); + m->value.~GenericValue(); + } + Allocator::Free(data_.o.members); + break; - case kCopyStringFlag: - Allocator::Free(const_cast(data_.s.str)); - break; - } - } - } + case kCopyStringFlag: + Allocator::Free(const_cast(data_.s.str)); + break; + } + } + } - //@} + //@} - //!@name Assignment operators - //@{ + //!@name Assignment operators + //@{ - //! Assignment with move semantics. - /*! \param rhs Source of the assignment. It will become a null value after assignment. - */ - GenericValue& operator=(GenericValue& rhs) { - RAPIDJSON_ASSERT(this != &rhs); - this->~GenericValue(); - memcpy(this, &rhs, sizeof(GenericValue)); - rhs.flags_ = kNullFlag; - return *this; - } + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + memcpy(this, &rhs, sizeof(GenericValue)); + rhs.flags_ = kNullFlag; + return *this; + } - //! Assignment with primitive types. - /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch* - \param value The value to be assigned. - */ - template - GenericValue& operator=(T value) { - this->~GenericValue(); - new (this) GenericValue(value); - return *this; - } - //@} + //! Assignment with primitive types. + /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch* + \param value The value to be assigned. + */ + template + GenericValue& operator=(T value) { + this->~GenericValue(); + new (this) GenericValue(value); + return *this; + } + //@} - //!@name Type - //@{ + //!@name Type + //@{ - Type GetType() const { return static_cast(flags_ & kTypeMask); } - bool IsNull() const { return flags_ == kNullFlag; } - bool IsFalse() const { return flags_ == kFalseFlag; } - bool IsTrue() const { return flags_ == kTrueFlag; } - bool IsBool() const { return (flags_ & kBoolFlag) != 0; } - bool IsObject() const { return flags_ == kObjectFlag; } - bool IsArray() const { return flags_ == kArrayFlag; } - bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } - bool IsInt() const { return (flags_ & kIntFlag) != 0; } - bool IsUint() const { return (flags_ & kUintFlag) != 0; } - bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } - bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } - bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } - bool IsString() const { return (flags_ & kStringFlag) != 0; } + Type GetType() const { return static_cast(flags_ & kTypeMask); } + bool IsNull() const { return flags_ == kNullFlag; } + bool IsFalse() const { return flags_ == kFalseFlag; } + bool IsTrue() const { return flags_ == kTrueFlag; } + bool IsBool() const { return (flags_ & kBoolFlag) != 0; } + bool IsObject() const { return flags_ == kObjectFlag; } + bool IsArray() const { return flags_ == kArrayFlag; } + bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } + bool IsInt() const { return (flags_ & kIntFlag) != 0; } + bool IsUint() const { return (flags_ & kUintFlag) != 0; } + bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } + bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } + bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } + bool IsString() const { return (flags_ & kStringFlag) != 0; } - //@} + //@} - //!@name Null - //@{ + //!@name Null + //@{ - GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } - //@} + //@} - //!@name Bool - //@{ + //!@name Bool + //@{ - bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } - GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } - //@} + //@} - //!@name Object - //@{ + //!@name Object + //@{ - //! Set this value as an empty object. - GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + //! Set this value as an empty object. + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } - //! Get the value associated with the object's name. - GenericValue& operator[](const Ch* name) { - if (Member* member = FindMember(name)) - return member->value; - else { - static GenericValue NullValue; - return NullValue; - } - } - const GenericValue& operator[](const Ch* name) const { return const_cast(*this)[name]; } + //! Get the value associated with the object's name. + GenericValue& operator[](const Ch* name) { + if (Member* member = FindMember(name)) + return member->value; + else { + static GenericValue NullValue; + return NullValue; + } + } + const GenericValue& operator[](const Ch* name) const { return const_cast(*this)[name]; } - //! Member iterators. - ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } - ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } - MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } - MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } + //! Member iterators. + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } - //! Check whether a member exists in the object. - bool HasMember(const Ch* name) const { return FindMember(name) != 0; } + //! Check whether a member exists in the object. + bool HasMember(const Ch* name) const { return FindMember(name) != 0; } - //! Add a member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value Value of any type. - \param allocator Allocator for reallocating memory. - \return The value itself for fluent API. - \note The ownership of name and value will be transfered to this object if success. - */ - GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(name.IsString()); - Object& o = data_.o; - if (o.size >= o.capacity) { - if (o.capacity == 0) { - o.capacity = kDefaultObjectCapacity; - o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member)); - } - else { - SizeType oldCapacity = o.capacity; - o.capacity *= 2; - o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)); - } - } - o.members[o.size].name.RawAssign(name); - o.members[o.size].value.RawAssign(value); - o.size++; - return *this; - } + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. + \return The value itself for fluent API. + \note The ownership of name and value will be transfered to this object if success. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + Object& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member)); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity *= 2; + o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)); + } + } + o.members[o.size].name.RawAssign(name); + o.members[o.size].value.RawAssign(value); + o.size++; + return *this; + } - GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) { - GenericValue n(name, internal::StrLen(name), nameAllocator); - return AddMember(n, value, allocator); - } + GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) { + GenericValue n(name, internal::StrLen(name), nameAllocator); + return AddMember(n, value, allocator); + } - GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) { - GenericValue n(name, internal::StrLen(name)); - return AddMember(n, value, allocator); - } + GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) { + GenericValue n(name, internal::StrLen(name)); + return AddMember(n, value, allocator); + } - template - GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) { - GenericValue n(name, internal::StrLen(name)); - GenericValue v(value); - return AddMember(n, v, allocator); - } + template + GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) { + GenericValue n(name, internal::StrLen(name)); + GenericValue v(value); + return AddMember(n, v, allocator); + } - //! Remove a member in object by its name. - /*! \param name Name of member to be removed. - \return Whether the member existed. - \note Removing member is implemented by moving the last member. So the ordering of members is changed. - */ - bool RemoveMember(const Ch* name) { - RAPIDJSON_ASSERT(IsObject()); - if (Member* m = FindMember(name)) { - RAPIDJSON_ASSERT(data_.o.size > 0); - RAPIDJSON_ASSERT(data_.o.members != 0); + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Removing member is implemented by moving the last member. So the ordering of members is changed. + */ + bool RemoveMember(const Ch* name) { + RAPIDJSON_ASSERT(IsObject()); + if (Member* m = FindMember(name)) { + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(data_.o.members != 0); - Member* last = data_.o.members + (data_.o.size - 1); - if (data_.o.size > 1 && m != last) { - // Move the last one to this place - m->name = last->name; - m->value = last->value; - } - else { - // Only one left, just destroy - m->name.~GenericValue(); - m->value.~GenericValue(); - } - --data_.o.size; - return true; - } - return false; - } + Member* last = data_.o.members + (data_.o.size - 1); + if (data_.o.size > 1 && m != last) { + // Move the last one to this place + m->name = last->name; + m->value = last->value; + } + else { + // Only one left, just destroy + m->name.~GenericValue(); + m->value.~GenericValue(); + } + --data_.o.size; + return true; + } + return false; + } - //@} + //@} - //!@name Array - //@{ + //!@name Array + //@{ - //! Set this value as an empty array. - GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + //! Set this value as an empty array. + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } - //! Get the number of elements in array. - SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } - //! Get the capacity of array. - SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } - //! Check whether the array is empty. - bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } - //! Check whether the array is empty. - bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + //! Check whether the array is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } - //! Remove all elements in the array. - /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. - */ - void Clear() { - RAPIDJSON_ASSERT(IsArray()); - for (SizeType i = 0; i < data_.a.size; ++i) - data_.a.elements[i].~GenericValue(); - data_.a.size = 0; - } + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + for (SizeType i = 0; i < data_.a.size; ++i) + data_.a.elements[i].~GenericValue(); + data_.a.size = 0; + } - //! Get an element from array by index. - /*! \param index Zero-based index of element. - \note + //! Get an element from array by index. + /*! \param index Zero-based index of element. + \note \code Value a(kArrayType); a.PushBack(123); -int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. -int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. -int z = a[0u].GetInt(); // This works too. +int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. +int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. +int z = a[0u].GetInt(); // This works too. \endcode - */ - GenericValue& operator[](SizeType index) { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(index < data_.a.size); - return data_.a.elements[index]; - } - const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return data_.a.elements[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } - //! Element iterator - ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } - ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } - ConstValueIterator Begin() const { return const_cast(*this).Begin(); } - ConstValueIterator End() const { return const_cast(*this).End(); } + //! Element iterator + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + ConstValueIterator End() const { return const_cast(*this).End(); } - //! Request the array to have enough capacity to store elements. - /*! \param newCapacity The capacity that the array at least need to have. - \param allocator The allocator for allocating memory. It must be the same one use previously. - \return The value itself for fluent API. - */ - GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (newCapacity > data_.a.capacity) { - data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); - data_.a.capacity = newCapacity; - } - return *this; - } + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator The allocator for allocating memory. It must be the same one use previously. + \return The value itself for fluent API. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); + data_.a.capacity = newCapacity; + } + return *this; + } - //! Append a value at the end of the array. - /*! \param value The value to be appended. - \param allocator The allocator for allocating memory. It must be the same one use previously. - \return The value itself for fluent API. - \note The ownership of the value will be transfered to this object if success. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - */ - GenericValue& PushBack(GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (data_.a.size >= data_.a.capacity) - Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); - data_.a.elements[data_.a.size++].RawAssign(value); - return *this; - } + //! Append a value at the end of the array. + /*! \param value The value to be appended. + \param allocator The allocator for allocating memory. It must be the same one use previously. + \return The value itself for fluent API. + \note The ownership of the value will be transfered to this object if success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); + data_.a.elements[data_.a.size++].RawAssign(value); + return *this; + } - template - GenericValue& PushBack(T value, Allocator& allocator) { - GenericValue v(value); - return PushBack(v, allocator); - } + template + GenericValue& PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } - //! Remove the last element in the array. - GenericValue& PopBack() { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(!Empty()); - data_.a.elements[--data_.a.size].~GenericValue(); - return *this; - } - //@} + //! Remove the last element in the array. + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + data_.a.elements[--data_.a.size].~GenericValue(); + return *this; + } + //@} - //!@name Number - //@{ + //!@name Number + //@{ - int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } - unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } - int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } - uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } + int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } - double GetDouble() const { - RAPIDJSON_ASSERT(IsNumber()); - if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. - if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double - if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double - if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) - RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) - } + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) + } - GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } - GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } - GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } - GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } - GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } - //@} + //@} - //!@name String - //@{ + //!@name String + //@{ - const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; } + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; } - //! Get the length of string. - /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). - */ - SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; } + //! Get the length of string. + /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; } - //! Set this value as a string without copying source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string pointer. - \param length The length of source string, excluding the trailing null terminator. - \return The value itself for fluent API. - */ - GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; } + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + */ + GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; } - //! Set this value as a string without copying source string. - /*! \param s source string pointer. - \return The value itself for fluent API. - */ - GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); } + //! Set this value as a string without copying source string. + /*! \param s source string pointer. + \return The value itself for fluent API. + */ + GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); } - //! Set this value as a string by copying from source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string. - \param length The length of source string, excluding the trailing null terminator. - \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). - \return The value itself for fluent API. - */ - GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; } + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). + \return The value itself for fluent API. + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; } - //! Set this value as a string by copying from source string. - /*! \param s source string. - \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). - \return The value itself for fluent API. - */ - GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; } + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). + \return The value itself for fluent API. + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; } - //@} + //@} - //! Generate events of this value to a Handler. - /*! This function adopts the GoF visitor pattern. - Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. - It can also be used to deep clone this value via GenericDocument, which is also a Handler. - \tparam Handler type of handler. - \param handler An object implementing concept Handler. - */ - template - const GenericValue& Accept(Handler& handler) const { - switch(GetType()) { - case kNullType: handler.Null(); break; - case kFalseType: handler.Bool(false); break; - case kTrueType: handler.Bool(true); break; + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + const GenericValue& Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: handler.Null(); break; + case kFalseType: handler.Bool(false); break; + case kTrueType: handler.Bool(true); break; - case kObjectType: - handler.StartObject(); - for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { - handler.String(m->name.data_.s.str, m->name.data_.s.length, false); - m->value.Accept(handler); - } - handler.EndObject(data_.o.size); - break; + case kObjectType: + handler.StartObject(); + for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { + handler.String(m->name.data_.s.str, m->name.data_.s.length, false); + m->value.Accept(handler); + } + handler.EndObject(data_.o.size); + break; - case kArrayType: - handler.StartArray(); - for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) - v->Accept(handler); - handler.EndArray(data_.a.size); - break; + case kArrayType: + handler.StartArray(); + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + v->Accept(handler); + handler.EndArray(data_.a.size); + break; - case kStringType: - handler.String(data_.s.str, data_.s.length, false); - break; + case kStringType: + handler.String(data_.s.str, data_.s.length, false); + break; - case kNumberType: - if (IsInt()) handler.Int(data_.n.i.i); - else if (IsUint()) handler.Uint(data_.n.u.u); - else if (IsInt64()) handler.Int64(data_.n.i64); - else if (IsUint64()) handler.Uint64(data_.n.u64); - else handler.Double(data_.n.d); - break; - } - return *this; - } + case kNumberType: + if (IsInt()) handler.Int(data_.n.i.i); + else if (IsUint()) handler.Uint(data_.n.u.u); + else if (IsInt64()) handler.Int64(data_.n.i64); + else if (IsUint64()) handler.Uint64(data_.n.u64); + else handler.Double(data_.n.d); + break; + } + return *this; + } private: - template - friend class GenericDocument; + template + friend class GenericDocument; - enum { - kBoolFlag = 0x100, - kNumberFlag = 0x200, - kIntFlag = 0x400, - kUintFlag = 0x800, - kInt64Flag = 0x1000, - kUint64Flag = 0x2000, - kDoubleFlag = 0x4000, - kStringFlag = 0x100000, - kCopyFlag = 0x200000, + enum { + kBoolFlag = 0x100, + kNumberFlag = 0x200, + kIntFlag = 0x400, + kUintFlag = 0x800, + kInt64Flag = 0x1000, + kUint64Flag = 0x2000, + kDoubleFlag = 0x4000, + kStringFlag = 0x100000, + kCopyFlag = 0x200000, - // Initial flags of different types. - kNullFlag = kNullType, - kTrueFlag = kTrueType | kBoolFlag, - kFalseFlag = kFalseType | kBoolFlag, - kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, - kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, - kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, - kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, - kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, - kConstStringFlag = kStringType | kStringFlag, - kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, - kObjectFlag = kObjectType, - kArrayFlag = kArrayType, + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, - kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler - }; + kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler + }; - static const SizeType kDefaultArrayCapacity = 16; - static const SizeType kDefaultObjectCapacity = 16; + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; - struct String { - const Ch* str; - SizeType length; - unsigned hashcode; //!< reserved - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + struct String { + const Ch* str; + SizeType length; + unsigned hashcode; //!< reserved + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - // By using proper binary layout, retrieval of different integer types do not need conversions. - union Number { + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN - struct I { - int i; - char padding[4]; - }i; - struct U { - unsigned u; - char padding2[4]; - }u; + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; #else - struct I { - char padding[4]; - int i; - }i; - struct U { - char padding2[4]; - unsigned u; - }u; + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; #endif - int64_t i64; - uint64_t u64; - double d; - }; // 8 bytes + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes - struct Object { - Member* members; - SizeType size; - SizeType capacity; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + struct Object { + Member* members; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - struct Array { - GenericValue* elements; - SizeType size; - SizeType capacity; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + struct Array { + GenericValue* elements; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - union Data { - String s; - Number n; - Object o; - Array a; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + union Data { + String s; + Number n; + Object o; + Array a; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - //! Find member by name. - Member* FindMember(const Ch* name) { - RAPIDJSON_ASSERT(name); - RAPIDJSON_ASSERT(IsObject()); + //! Find member by name. + Member* FindMember(const Ch* name) { + RAPIDJSON_ASSERT(name); + RAPIDJSON_ASSERT(IsObject()); - SizeType length = internal::StrLen(name); + SizeType length = internal::StrLen(name); - Object& o = data_.o; - for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) - if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0) - return member; + Object& o = data_.o; + for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) + if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0) + return member; - return 0; - } - const Member* FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + return 0; + } + const Member* FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } - // Initialize this value as array with initial data, without calling destructor. - void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) { - flags_ = kArrayFlag; - data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue)); - memcpy(data_.a.elements, values, count * sizeof(GenericValue)); - data_.a.size = data_.a.capacity = count; - } + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) { + flags_ = kArrayFlag; + data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue)); + memcpy(data_.a.elements, values, count * sizeof(GenericValue)); + data_.a.size = data_.a.capacity = count; + } - //! Initialize this value as object with initial data, without calling destructor. - void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) { - flags_ = kObjectFlag; - data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member)); - memcpy(data_.o.members, members, count * sizeof(Member)); - data_.o.size = data_.o.capacity = count; - } + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) { + flags_ = kObjectFlag; + data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member)); + memcpy(data_.o.members, members, count * sizeof(Member)); + data_.o.size = data_.o.capacity = count; + } - //! Initialize this value as constant string, without calling destructor. - void SetStringRaw(const Ch* s, SizeType length) { - RAPIDJSON_ASSERT(s != NULL); - flags_ = kConstStringFlag; - data_.s.str = s; - data_.s.length = length; - } + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(const Ch* s, SizeType length) { + RAPIDJSON_ASSERT(s != NULL); + flags_ = kConstStringFlag; + data_.s.str = s; + data_.s.length = length; + } - //! Initialize this value as copy string with initial data, without calling destructor. - void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) { - RAPIDJSON_ASSERT(s != NULL); - flags_ = kCopyStringFlag; - data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); - data_.s.length = length; - memcpy(const_cast(data_.s.str), s, length * sizeof(Ch)); - const_cast(data_.s.str)[length] = '\0'; - } + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) { + RAPIDJSON_ASSERT(s != NULL); + flags_ = kCopyStringFlag; + data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); + data_.s.length = length; + memcpy(const_cast(data_.s.str), s, length * sizeof(Ch)); + const_cast(data_.s.str)[length] = '\0'; + } - //! Assignment without calling destructor - void RawAssign(GenericValue& rhs) { - memcpy(this, &rhs, sizeof(GenericValue)); - rhs.flags_ = kNullFlag; - } + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) { + memcpy(this, &rhs, sizeof(GenericValue)); + rhs.flags_ = kNullFlag; + } - Data data_; - unsigned flags_; + Data data_; + unsigned flags_; }; #pragma pack (pop) @@ -686,131 +686,131 @@ typedef GenericValue > Value; //! A document for parsing JSON text as DOM. /*! - \implements Handler - \tparam Encoding encoding for both parsing and string storage. - \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing. + \implements Handler + \tparam Encoding encoding for both parsing and string storage. + \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing. */ template > class GenericDocument : public GenericValue { public: - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef GenericValue ValueType; //!< Value type of the document. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. - //! Constructor - /*! \param allocator Optional allocator for allocating stack memory. - \param stackCapacity Initial capacity of stack in bytes. - */ - GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} + //! Constructor + /*! \param allocator Optional allocator for allocating stack memory. + \param stackCapacity Initial capacity of stack in bytes. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} - //! Parse JSON text from an input stream. - /*! \tparam parseFlags Combination of ParseFlag. - \param stream Input stream to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseStream(Stream& stream) { - ValueType::SetNull(); // Remove existing root if exist - GenericReader reader; - if (reader.template Parse(stream, *this)) { - RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object - this->RawAssign(*stack_.template Pop(1)); // Add this-> to prevent issue 13. - parseError_ = 0; - errorOffset_ = 0; - } - else { - parseError_ = reader.GetParseError(); - errorOffset_ = reader.GetErrorOffset(); - ClearStack(); - } - return *this; - } + //! Parse JSON text from an input stream. + /*! \tparam parseFlags Combination of ParseFlag. + \param stream Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(Stream& stream) { + ValueType::SetNull(); // Remove existing root if exist + GenericReader reader; + if (reader.template Parse(stream, *this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + this->RawAssign(*stack_.template Pop(1)); // Add this-> to prevent issue 13. + parseError_ = 0; + errorOffset_ = 0; + } + else { + parseError_ = reader.GetParseError(); + errorOffset_ = reader.GetErrorOffset(); + ClearStack(); + } + return *this; + } - //! Parse JSON text from a mutable string. - /*! \tparam parseFlags Combination of ParseFlag. - \param str Mutable zero-terminated string to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseInsitu(Ch* str) { - GenericInsituStringStream s(str); - return ParseStream(s); - } + //! Parse JSON text from a mutable string. + /*! \tparam parseFlags Combination of ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } - //! Parse JSON text from a read-only string. - /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). - \param str Read-only zero-terminated string to be parsed. - */ - template - GenericDocument& Parse(const Ch* str) { - RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); - GenericStringStream s(str); - return ParseStream(s); - } + //! Parse JSON text from a read-only string. + /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } - //! Whether a parse error was occured in the last parsing. - bool HasParseError() const { return parseError_ != 0; } + //! Whether a parse error was occured in the last parsing. + bool HasParseError() const { return parseError_ != 0; } - //! Get the message of parsing error. - const char* GetParseError() const { return parseError_; } + //! Get the message of parsing error. + const char* GetParseError() const { return parseError_; } - //! Get the offset in character of the parsing error. - size_t GetErrorOffset() const { return errorOffset_; } + //! Get the offset in character of the parsing error. + size_t GetErrorOffset() const { return errorOffset_; } - //! Get the allocator of this document. - Allocator& GetAllocator() { return stack_.GetAllocator(); } + //! Get the allocator of this document. + Allocator& GetAllocator() { return stack_.GetAllocator(); } - //! Get the capacity of stack in bytes. - size_t GetStackCapacity() const { return stack_.GetCapacity(); } + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } private: - // Prohibit assignment - GenericDocument& operator=(const GenericDocument&); + // Prohibit assignment + GenericDocument& operator=(const GenericDocument&); - friend class GenericReader; // for Reader to call the following private handler functions + friend class GenericReader; // for Reader to call the following private handler functions - // Implementation of Handler - void Null() { new (stack_.template Push()) ValueType(); } - void Bool(bool b) { new (stack_.template Push()) ValueType(b); } - void Int(int i) { new (stack_.template Push()) ValueType(i); } - void Uint(unsigned i) { new (stack_.template Push()) ValueType(i); } - void Int64(int64_t i) { new (stack_.template Push()) ValueType(i); } - void Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); } - void Double(double d) { new (stack_.template Push()) ValueType(d); } + // Implementation of Handler + void Null() { new (stack_.template Push()) ValueType(); } + void Bool(bool b) { new (stack_.template Push()) ValueType(b); } + void Int(int i) { new (stack_.template Push()) ValueType(i); } + void Uint(unsigned i) { new (stack_.template Push()) ValueType(i); } + void Int64(int64_t i) { new (stack_.template Push()) ValueType(i); } + void Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); } + void Double(double d) { new (stack_.template Push()) ValueType(d); } - void String(const Ch* str, SizeType length, bool copy) { - if (copy) - new (stack_.template Push()) ValueType(str, length, GetAllocator()); - else - new (stack_.template Push()) ValueType(str, length); - } + void String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + } - void StartObject() { new (stack_.template Push()) ValueType(kObjectType); } + void StartObject() { new (stack_.template Push()) ValueType(kObjectType); } - void EndObject(SizeType memberCount) { - typename ValueType::Member* members = stack_.template Pop(memberCount); - stack_.template Top()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); - } + void EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); + } - void StartArray() { new (stack_.template Push()) ValueType(kArrayType); } + void StartArray() { new (stack_.template Push()) ValueType(kArrayType); } - void EndArray(SizeType elementCount) { - ValueType* elements = stack_.template Pop(elementCount); - stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); - } + void EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + } - void ClearStack() { - if (Allocator::kNeedFree) - while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) - (stack_.template Pop(1))->~ValueType(); - else - stack_.Clear(); - } + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + } - static const size_t kDefaultStackCapacity = 1024; - internal::Stack stack_; - const char* parseError_; - size_t errorOffset_; + static const size_t kDefaultStackCapacity = 1024; + internal::Stack stack_; + const char* parseError_; + size_t errorOffset_; }; typedef GenericDocument > Document; diff --git a/include/rapidjson/rapidjson/filestream.h b/include/rapidjson/rapidjson/filestream.h index 88589496..5d2e49f4 100644 --- a/include/rapidjson/rapidjson/filestream.h +++ b/include/rapidjson/rapidjson/filestream.h @@ -7,38 +7,38 @@ namespace rapidjson { //! Wrapper of C file stream for input or output. /*! - This simple wrapper does not check the validity of the stream. - \implements Stream + This simple wrapper does not check the validity of the stream. + \implements Stream */ class FileStream { public: - typedef char Ch; //!< Character type. Only support char. + typedef char Ch; //!< Character type. Only support char. - FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } - char Peek() const { return current_; } - char Take() { char c = current_; Read(); return c; } - size_t Tell() const { return count_; } - void Put(char c) { fputc(c, fp_); } + FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } + char Peek() const { return current_; } + char Take() { char c = current_; Read(); return c; } + size_t Tell() const { return count_; } + void Put(char c) { fputc(c, fp_); } - // Not implemented - char* PutBegin() { return 0; } - size_t PutEnd(char*) { return 0; } + // Not implemented + char* PutBegin() { return 0; } + size_t PutEnd(char*) { return 0; } private: - void Read() { - RAPIDJSON_ASSERT(fp_ != 0); - int c = fgetc(fp_); - if (c != EOF) { - current_ = (char)c; - count_++; - } - else - current_ = '\0'; - } + void Read() { + RAPIDJSON_ASSERT(fp_ != 0); + int c = fgetc(fp_); + if (c != EOF) { + current_ = (char)c; + count_++; + } + else + current_ = '\0'; + } - FILE* fp_; - char current_; - size_t count_; + FILE* fp_; + char current_; + size_t count_; }; } // namespace rapidjson diff --git a/include/rapidjson/rapidjson/internal/pow10.h b/include/rapidjson/rapidjson/internal/pow10.h index bf3a9afb..adb3654e 100644 --- a/include/rapidjson/rapidjson/internal/pow10.h +++ b/include/rapidjson/rapidjson/internal/pow10.h @@ -6,46 +6,46 @@ namespace internal { //! Computes integer powers of 10 in double (10.0^n). /*! This function uses lookup table for fast and accurate results. - \param n positive/negative exponent. Must <= 308. - \return 10.0^n + \param n positive/negative exponent. Must <= 308. + \return 10.0^n */ inline double Pow10(int n) { - static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes - 1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300, - 1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280, - 1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260, - 1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240, - 1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220, - 1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200, - 1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180, - 1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160, - 1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140, - 1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120, - 1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100, - 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, - 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, - 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, - 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, - 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0, - 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, - 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, - 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, - 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, - 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, - 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, - 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, - 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, - 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, - 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, - 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, - 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, - 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, - 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, - 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, - 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 - }; - RAPIDJSON_ASSERT(n <= 308); - return n < -308 ? 0.0 : e[n + 308]; + static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes + 1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300, + 1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280, + 1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260, + 1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240, + 1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220, + 1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200, + 1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180, + 1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160, + 1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140, + 1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120, + 1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100, + 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, + 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, + 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, + 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, + 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n <= 308); + return n < -308 ? 0.0 : e[n + 308]; } } // namespace internal diff --git a/include/rapidjson/rapidjson/internal/stack.h b/include/rapidjson/rapidjson/internal/stack.h index 966893b3..d9d76c9a 100644 --- a/include/rapidjson/rapidjson/internal/stack.h +++ b/include/rapidjson/rapidjson/internal/stack.h @@ -13,67 +13,67 @@ namespace internal { template class Stack { public: - Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) { - RAPIDJSON_ASSERT(stack_capacity_ > 0); - if (!allocator_) - own_allocator_ = allocator_ = new Allocator(); - stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_); - stack_end_ = stack_ + stack_capacity_; - } + Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) { + RAPIDJSON_ASSERT(stack_capacity_ > 0); + if (!allocator_) + own_allocator_ = allocator_ = new Allocator(); + stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_); + stack_end_ = stack_ + stack_capacity_; + } - ~Stack() { - Allocator::Free(stack_); - delete own_allocator_; // Only delete if it is owned by the stack - } + ~Stack() { + Allocator::Free(stack_); + delete own_allocator_; // Only delete if it is owned by the stack + } - void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; } + void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; } - template - T* Push(size_t count = 1) { - // Expand the stack if needed - if (stack_top_ + sizeof(T) * count >= stack_end_) { - size_t new_capacity = stack_capacity_ * 2; - size_t size = GetSize(); - size_t new_size = GetSize() + sizeof(T) * count; - if (new_capacity < new_size) - new_capacity = new_size; - stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity); - stack_capacity_ = new_capacity; - stack_top_ = stack_ + size; - stack_end_ = stack_ + stack_capacity_; - } - T* ret = (T*)stack_top_; - stack_top_ += sizeof(T) * count; - return ret; - } + template + T* Push(size_t count = 1) { + // Expand the stack if needed + if (stack_top_ + sizeof(T) * count >= stack_end_) { + size_t new_capacity = stack_capacity_ * 2; + size_t size = GetSize(); + size_t new_size = GetSize() + sizeof(T) * count; + if (new_capacity < new_size) + new_capacity = new_size; + stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity); + stack_capacity_ = new_capacity; + stack_top_ = stack_ + size; + stack_end_ = stack_ + stack_capacity_; + } + T* ret = (T*)stack_top_; + stack_top_ += sizeof(T) * count; + return ret; + } - template - T* Pop(size_t count) { - RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); - stack_top_ -= count * sizeof(T); - return (T*)stack_top_; - } + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stack_top_ -= count * sizeof(T); + return (T*)stack_top_; + } - template - T* Top() { - RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); - return (T*)(stack_top_ - sizeof(T)); - } + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return (T*)(stack_top_ - sizeof(T)); + } - template - T* Bottom() { return (T*)stack_; } + template + T* Bottom() { return (T*)stack_; } - Allocator& GetAllocator() { return *allocator_; } - size_t GetSize() const { return stack_top_ - stack_; } - size_t GetCapacity() const { return stack_capacity_; } + Allocator& GetAllocator() { return *allocator_; } + size_t GetSize() const { return stack_top_ - stack_; } + size_t GetCapacity() const { return stack_capacity_; } private: - Allocator* allocator_; - Allocator* own_allocator_; - char *stack_; - char *stack_top_; - char *stack_end_; - size_t stack_capacity_; + Allocator* allocator_; + Allocator* own_allocator_; + char *stack_; + char *stack_top_; + char *stack_end_; + size_t stack_capacity_; }; } // namespace internal diff --git a/include/rapidjson/rapidjson/internal/strfunc.h b/include/rapidjson/rapidjson/internal/strfunc.h index bbf444fe..226a8db8 100644 --- a/include/rapidjson/rapidjson/internal/strfunc.h +++ b/include/rapidjson/rapidjson/internal/strfunc.h @@ -5,17 +5,17 @@ namespace rapidjson { namespace internal { //! Custom strlen() which works on different character types. -/*! \tparam Ch Character type (e.g. char, wchar_t, short) - \param s Null-terminated input string. - \return Number of characters in the string. - \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. */ template inline SizeType StrLen(const Ch* s) { - const Ch* p = s; - while (*p != '\0') - ++p; - return SizeType(p - s); + const Ch* p = s; + while (*p != '\0') + ++p; + return SizeType(p - s); } } // namespace internal diff --git a/include/rapidjson/rapidjson/prettywriter.h b/include/rapidjson/rapidjson/prettywriter.h index 238ff5ff..d4633942 100644 --- a/include/rapidjson/rapidjson/prettywriter.h +++ b/include/rapidjson/rapidjson/prettywriter.h @@ -7,148 +7,148 @@ namespace rapidjson { //! Writer with indentation and spacing. /*! - \tparam Stream Type of ouptut stream. - \tparam Encoding Encoding of both source strings and output. - \tparam Allocator Type of allocator for allocating memory of stack. + \tparam Stream Type of ouptut stream. + \tparam Encoding Encoding of both source strings and output. + \tparam Allocator Type of allocator for allocating memory of stack. */ template, typename Allocator = MemoryPoolAllocator<> > class PrettyWriter : public Writer { public: - typedef Writer Base; - typedef typename Base::Ch Ch; + typedef Writer Base; + typedef typename Base::Ch Ch; - //! Constructor - /*! \param stream Output stream. - \param allocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of - */ - PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + //! Constructor + /*! \param stream Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of + */ + PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} - //! Set custom indentation. - /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r'). - \param indentCharCount Number of indent characters for each indentation level. - \note The default indentation is 4 spaces. - */ - PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { - RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); - indentChar_ = indentChar; - indentCharCount_ = indentCharCount; - return *this; - } + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } - //@name Implementation of Handler. - //@{ + //@name Implementation of Handler. + //@{ - PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } - PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; } - PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; } - PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; } - PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } - PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } - PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } + PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } + PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; } + PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; } + PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; } + PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } + PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } + PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } - PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { - (void)copy; - PrettyPrefix(kStringType); - Base::WriteString(str, length); - return *this; - } + PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + Base::WriteString(str, length); + return *this; + } - PrettyWriter& StartObject() { - PrettyPrefix(kObjectType); - new (Base::level_stack_.template Push()) typename Base::Level(false); - Base::WriteStartObject(); - return *this; - } + PrettyWriter& StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + Base::WriteStartObject(); + return *this; + } - PrettyWriter& EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); - RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); - bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + PrettyWriter& EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; - if (!empty) { - Base::stream_.Put('\n'); - WriteIndent(); - } - Base::WriteEndObject(); - return *this; - } + if (!empty) { + Base::stream_.Put('\n'); + WriteIndent(); + } + Base::WriteEndObject(); + return *this; + } - PrettyWriter& StartArray() { - PrettyPrefix(kArrayType); - new (Base::level_stack_.template Push()) typename Base::Level(true); - Base::WriteStartArray(); - return *this; - } + PrettyWriter& StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + Base::WriteStartArray(); + return *this; + } - PrettyWriter& EndArray(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); - RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); - bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + PrettyWriter& EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; - if (!empty) { - Base::stream_.Put('\n'); - WriteIndent(); - } - Base::WriteEndArray(); - return *this; - } + if (!empty) { + Base::stream_.Put('\n'); + WriteIndent(); + } + Base::WriteEndArray(); + return *this; + } - //@} + //@} - //! Simpler but slower overload. - PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } + //! Simpler but slower overload. + PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } protected: - void PrettyPrefix(Type type) { - (void)type; - if (Base::level_stack_.GetSize() != 0) { // this value is not at root - typename Base::Level* level = Base::level_stack_.template Top(); + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); - if (level->inArray) { - if (level->valueCount > 0) { - Base::stream_.Put(','); // add comma if it is not the first element in array - Base::stream_.Put('\n'); - } - else - Base::stream_.Put('\n'); - WriteIndent(); - } - else { // in object - if (level->valueCount > 0) { - if (level->valueCount % 2 == 0) { - Base::stream_.Put(','); - Base::stream_.Put('\n'); - } - else { - Base::stream_.Put(':'); - Base::stream_.Put(' '); - } - } - else - Base::stream_.Put('\n'); + if (level->inArray) { + if (level->valueCount > 0) { + Base::stream_.Put(','); // add comma if it is not the first element in array + Base::stream_.Put('\n'); + } + else + Base::stream_.Put('\n'); + WriteIndent(); + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::stream_.Put(','); + Base::stream_.Put('\n'); + } + else { + Base::stream_.Put(':'); + Base::stream_.Put(' '); + } + } + else + Base::stream_.Put('\n'); - if (level->valueCount % 2 == 0) - WriteIndent(); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else - RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); - } + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else + RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); + } - void WriteIndent() { - size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; - PutN(Base::stream_, indentChar_, count); - } + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(Base::stream_, indentChar_, count); + } - Ch indentChar_; - unsigned indentCharCount_; + Ch indentChar_; + unsigned indentCharCount_; }; } // namespace rapidjson diff --git a/include/rapidjson/rapidjson/rapidjson.h b/include/rapidjson/rapidjson/rapidjson.h index 7acb2aa4..765dccba 100644 --- a/include/rapidjson/rapidjson/rapidjson.h +++ b/include/rapidjson/rapidjson/rapidjson.h @@ -4,8 +4,8 @@ // Copyright (c) 2011-2012 Milo Yip (miloyip@gmail.com) // Version 0.11 -#include // malloc(), realloc(), free() -#include // memcpy() +#include // malloc(), realloc(), free() +#include // memcpy() /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_NO_INT64DEFINE @@ -23,13 +23,13 @@ typedef unsigned __int64 uint64_t; /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_ENDIAN -#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine -#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine //! Endianness of the machine. -/*! GCC provided macro for detecting endianness of the target machine. But other - compilers may not have this. User can define RAPIDJSON_ENDIAN to either - RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN. +/*! GCC provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN. */ #ifndef RAPIDJSON_ENDIAN #ifdef __BYTE_ORDER__ @@ -39,7 +39,7 @@ typedef unsigned __int64 uint64_t; #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN #endif // __BYTE_ORDER__ #else -#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise. +#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise. #endif #endif // RAPIDJSON_ENDIAN @@ -73,7 +73,7 @@ typedef unsigned SizeType; //! Assertion. /*! By default, rapidjson uses C assert() for assertion. - User can override it by defining RAPIDJSON_ASSERT(x) macro. + User can override it by defining RAPIDJSON_ASSERT(x) macro. */ #ifndef RAPIDJSON_ASSERT #include @@ -93,31 +93,31 @@ namespace rapidjson { // Allocator /*! \class rapidjson::Allocator - \brief Concept for allocating, resizing and freeing memory block. - - Note that Malloc() and Realloc() are non-static but Free() is static. - - So if an allocator need to support Free(), it needs to put its pointer in - the header of memory block. + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. \code concept Allocator { - static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). - // Allocate a memory block. - // \param size of the memory block in bytes. - // \returns pointer to the memory block. - void* Malloc(size_t size); + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); - // Resize a memory block. - // \param originalPtr The pointer to current memory block. Null pointer is permitted. - // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) - // \param newSize the new size in bytes. - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); - // Free a memory block. - // \param pointer to the memory block. Null pointer is permitted. - static void Free(void *ptr); + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); }; \endcode */ @@ -127,14 +127,14 @@ concept Allocator { //! C-runtime library allocator. /*! This class is just wrapper for standard C library memory routines. - \implements Allocator + \implements Allocator */ class CrtAllocator { public: - static const bool kNeedFree = true; - void* Malloc(size_t size) { return malloc(size); } - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); } - static void Free(void *ptr) { free(ptr); } + static const bool kNeedFree = true; + void* Malloc(size_t size) { return malloc(size); } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); } + static void Free(void *ptr) { free(ptr); } }; /////////////////////////////////////////////////////////////////////////////// @@ -154,171 +154,171 @@ public: The user-buffer is not deallocated by this allocator. \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. - \implements Allocator + \implements Allocator */ template class MemoryPoolAllocator { public: - static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) - //! Constructor with chunkSize. - /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - if (!baseAllocator_) - ownBaseAllocator_ = baseAllocator_ = new BaseAllocator(); - AddChunk(chunk_capacity_); - } + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = new BaseAllocator(); + AddChunk(chunk_capacity_); + } - //! Constructor with user-supplied buffer. - /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. - The user buffer will not be deallocated when this allocator is destructed. + The user buffer will not be deallocated when this allocator is destructed. - \param buffer User supplied buffer. - \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). - \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - RAPIDJSON_ASSERT(buffer != 0); - RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); - chunkHead_ = (ChunkHeader*)buffer; - chunkHead_->capacity = size - sizeof(ChunkHeader); - chunkHead_->size = 0; - chunkHead_->next = 0; - } + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = (ChunkHeader*)buffer; + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } - //! Destructor. - /*! This deallocates all memory chunks, excluding the user-supplied buffer. - */ - ~MemoryPoolAllocator() { - Clear(); - delete ownBaseAllocator_; - } + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + delete ownBaseAllocator_; + } - //! Deallocates all memory chunks, excluding the user-supplied buffer. - void Clear() { - while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) { - ChunkHeader* next = chunkHead_->next; - baseAllocator_->Free(chunkHead_); - chunkHead_ = next; - } - } + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + } - //! Computes the total capacity of allocated memory chunks. - /*! \return total capacity in bytes. - */ - size_t Capacity() { - size_t capacity = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - capacity += c->capacity; - return capacity; - } + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } - //! Computes the memory blocks allocated. - /*! \return total used bytes. - */ - size_t Size() { - size_t size = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - size += c->size; - return size; - } + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } - //! Allocates a memory block. (concept Allocator) - void* Malloc(size_t size) { - size = (size + 3) & ~3; // Force aligning size to 4 + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + size = (size + 3) & ~3; // Force aligning size to 4 - if (chunkHead_->size + size > chunkHead_->capacity) - AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); + if (chunkHead_->size + size > chunkHead_->capacity) + AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); - char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size; - RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4 - chunkHead_->size += size; + char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size; + RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4 + chunkHead_->size += size; - return buffer; - } + return buffer; + } - //! Resizes a memory block (concept Allocator) - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { - if (originalPtr == 0) - return Malloc(newSize); + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); - // Do not shrink if new size is smaller than original - if (originalSize >= newSize) - return originalPtr; + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; - // Simply expand it if it is the last allocation and there is sufficient space - if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { - size_t increment = newSize - originalSize; - increment = (increment + 3) & ~3; // Force aligning size to 4 - if (chunkHead_->size + increment <= chunkHead_->capacity) { - chunkHead_->size += increment; - RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0); // returned buffer is aligned to 4 - return originalPtr; - } - } + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { + size_t increment = newSize - originalSize; + increment = (increment + 3) & ~3; // Force aligning size to 4 + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0); // returned buffer is aligned to 4 + return originalPtr; + } + } - // Realloc process: allocate and copy memory, do not free original buffer. - void* newBuffer = Malloc(newSize); - RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly. - return memcpy(newBuffer, originalPtr, originalSize); - } + // Realloc process: allocate and copy memory, do not free original buffer. + void* newBuffer = Malloc(newSize); + RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly. + return memcpy(newBuffer, originalPtr, originalSize); + } - //! Frees a memory block (concept Allocator) - static void Free(void *) {} // Do nothing + //! Frees a memory block (concept Allocator) + static void Free(void *) {} // Do nothing private: - //! Creates a new chunk. - /*! \param capacity Capacity of the chunk in bytes. - */ - void AddChunk(size_t capacity) { - ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity); - chunk->capacity = capacity; - chunk->size = 0; - chunk->next = chunkHead_; - chunkHead_ = chunk; - } + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + */ + void AddChunk(size_t capacity) { + ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity); + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + } - static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. - //! Chunk header for perpending to each chunk. - /*! Chunks are stored as a singly linked list. - */ - struct ChunkHeader { - size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). - size_t size; //!< Current size of allocated memory in bytes. - ChunkHeader *next; //!< Next chunk in the linked list. - }; + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; - ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. - size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. - char *userBuffer_; //!< User supplied buffer. - BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. - BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + char *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. }; /////////////////////////////////////////////////////////////////////////////// // Encoding /*! \class rapidjson::Encoding - \brief Concept for encoding of Unicode characters. + \brief Concept for encoding of Unicode characters. \code concept Encoding { - typename Ch; //! Type of character. + typename Ch; //! Type of character. - //! \brief Encode a Unicode codepoint to a buffer. - //! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character. - //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. - //! \returns the pointer to the next character after the encoded data. - static Ch* Encode(Ch *buffer, unsigned codepoint); + //! \brief Encode a Unicode codepoint to a buffer. + //! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + //! \returns the pointer to the next character after the encoded data. + static Ch* Encode(Ch *buffer, unsigned codepoint); }; \endcode */ @@ -328,34 +328,34 @@ concept Encoding { //! UTF-8 encoding. /*! http://en.wikipedia.org/wiki/UTF-8 - \tparam CharType Type for storing 8-bit UTF-8 data. Default is char. - \implements Encoding + \tparam CharType Type for storing 8-bit UTF-8 data. Default is char. + \implements Encoding */ template struct UTF8 { - typedef CharType Ch; + typedef CharType Ch; - static Ch* Encode(Ch *buffer, unsigned codepoint) { - if (codepoint <= 0x7F) - *buffer++ = codepoint & 0xFF; - else if (codepoint <= 0x7FF) { - *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF); - *buffer++ = 0x80 | ((codepoint & 0x3F)); - } - else if (codepoint <= 0xFFFF) { - *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF); - *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); - *buffer++ = 0x80 | (codepoint & 0x3F); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF); - *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F); - *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); - *buffer++ = 0x80 | (codepoint & 0x3F); - } - return buffer; - } + static Ch* Encode(Ch *buffer, unsigned codepoint) { + if (codepoint <= 0x7F) + *buffer++ = codepoint & 0xFF; + else if (codepoint <= 0x7FF) { + *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF); + *buffer++ = 0x80 | ((codepoint & 0x3F)); + } + else if (codepoint <= 0xFFFF) { + *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF); + *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); + *buffer++ = 0x80 | (codepoint & 0x3F); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF); + *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F); + *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); + *buffer++ = 0x80 | (codepoint & 0x3F); + } + return buffer; + } }; /////////////////////////////////////////////////////////////////////////////// @@ -363,26 +363,26 @@ struct UTF8 { //! UTF-16 encoding. /*! http://en.wikipedia.org/wiki/UTF-16 - \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. - \implements Encoding + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \implements Encoding */ template struct UTF16 { - typedef CharType Ch; + typedef CharType Ch; - static Ch* Encode(Ch* buffer, unsigned codepoint) { - if (codepoint <= 0xFFFF) { - RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair - *buffer++ = static_cast(codepoint); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - unsigned v = codepoint - 0x10000; - *buffer++ = static_cast((v >> 10) + 0xD800); - *buffer++ = (v & 0x3FF) + 0xDC00; - } - return buffer; - } + static Ch* Encode(Ch* buffer, unsigned codepoint) { + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + *buffer++ = static_cast(codepoint); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + *buffer++ = static_cast((v >> 10) + 0xD800); + *buffer++ = (v & 0x3FF) + 0xDC00; + } + return buffer; + } }; /////////////////////////////////////////////////////////////////////////////// @@ -390,55 +390,55 @@ struct UTF16 { //! UTF-32 encoding. /*! http://en.wikipedia.org/wiki/UTF-32 - \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. - \implements Encoding + \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \implements Encoding */ template struct UTF32 { - typedef CharType Ch; + typedef CharType Ch; - static Ch *Encode(Ch* buffer, unsigned codepoint) { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - *buffer++ = codepoint; - return buffer; - } + static Ch *Encode(Ch* buffer, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + *buffer++ = codepoint; + return buffer; + } }; /////////////////////////////////////////////////////////////////////////////// // Stream /*! \class rapidjson::Stream - \brief Concept for reading and writing characters. + \brief Concept for reading and writing characters. - For read-only stream, no need to implement PutBegin(), Put() and PutEnd(). + For read-only stream, no need to implement PutBegin(), Put() and PutEnd(). - For write-only stream, only need to implement Put(). + For write-only stream, only need to implement Put(). \code concept Stream { - typename Ch; //!< Character type of the stream. + typename Ch; //!< Character type of the stream. - //! Read the current character from stream without moving the read cursor. - Ch Peek() const; + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; - //! Read the current character from stream and moving the read cursor to next character. - Ch Take(); + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); - //! Get the current read cursor. - //! \return Number of characters read from start. - size_t Tell(); + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); - //! Begin writing operation at the current read pointer. - //! \return The begin writer pointer. - Ch* PutBegin(); + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); - //! Write a character. - void Put(Ch c); + //! Write a character. + void Put(Ch c); - //! End the writing operation. - //! \param begin The begin write pointer returned by PutBegin(). - //! \return Number of characters written. - size_t PutEnd(Ch* begin); + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); } \endcode */ @@ -446,8 +446,8 @@ concept Stream { //! Put N copies of a character to a stream. template inline void PutN(Stream& stream, Ch c, size_t n) { - for (size_t i = 0; i < n; i++) - stream.Put(c); + for (size_t i = 0; i < n; i++) + stream.Put(c); } /////////////////////////////////////////////////////////////////////////////// @@ -458,20 +458,20 @@ inline void PutN(Stream& stream, Ch c, size_t n) { */ template struct GenericStringStream { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - GenericStringStream(const Ch *src) : src_(src), head_(src) {} + GenericStringStream(const Ch *src) : src_(src), head_(src) {} - Ch Peek() const { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() const { return src_ - head_; } + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return src_ - head_; } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - const Ch* src_; //!< Current read position. - const Ch* head_; //!< Original head of the string. + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. }; typedef GenericStringStream > StringStream; @@ -481,27 +481,27 @@ typedef GenericStringStream > StringStream; //! A read-write string stream. /*! This string stream is particularly designed for in-situ parsing. - \implements Stream + \implements Stream */ template struct GenericInsituStringStream { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} - // Read - Ch Peek() { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() { return src_ - head_; } + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return src_ - head_; } - // Write - Ch* PutBegin() { return dst_ = src_; } - void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } - size_t PutEnd(Ch* begin) { return dst_ - begin; } + // Write + Ch* PutBegin() { return dst_ = src_; } + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + size_t PutEnd(Ch* begin) { return dst_ - begin; } - Ch* src_; - Ch* dst_; - Ch* head_; + Ch* src_; + Ch* dst_; + Ch* head_; }; typedef GenericInsituStringStream > InsituStringStream; @@ -511,13 +511,13 @@ typedef GenericInsituStringStream > InsituStringStream; //! Type of JSON value enum Type { - kNullType = 0, //!< null - kFalseType = 1, //!< false - kTrueType = 2, //!< true - kObjectType = 3, //!< object - kArrayType = 4, //!< array - kStringType = 5, //!< string - kNumberType = 6, //!< number + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6, //!< number }; } // namespace rapidjson diff --git a/include/rapidjson/rapidjson/reader.h b/include/rapidjson/rapidjson/reader.h index f90b9d2d..086242d7 100644 --- a/include/rapidjson/rapidjson/reader.h +++ b/include/rapidjson/rapidjson/reader.h @@ -22,11 +22,11 @@ #ifndef RAPIDJSON_PARSE_ERROR #define RAPIDJSON_PARSE_ERROR(msg, offset) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - parseError_ = msg; \ - errorOffset_ = offset; \ - longjmp(jmpbuf_, 1); \ - RAPIDJSON_MULTILINEMACRO_END + RAPIDJSON_MULTILINEMACRO_BEGIN \ + parseError_ = msg; \ + errorOffset_ = offset; \ + longjmp(jmpbuf_, 1); \ + RAPIDJSON_MULTILINEMACRO_END #endif namespace rapidjson { @@ -36,31 +36,31 @@ namespace rapidjson { //! Combination of parseFlags enum ParseFlag { - kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. - kParseInsituFlag = 1 //!< In-situ(destructive) parsing. + kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. + kParseInsituFlag = 1 //!< In-situ(destructive) parsing. }; /////////////////////////////////////////////////////////////////////////////// // Handler -/*! \class rapidjson::Handler - \brief Concept for receiving events from GenericReader upon parsing. +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. \code concept Handler { - typename Ch; + typename Ch; - void Null(); - void Bool(bool b); - void Int(int i); - void Uint(unsigned i); - void Int64(int64_t i); - void Uint64(uint64_t i); - void Double(double d); - void String(const Ch* str, SizeType length, bool copy); - void StartObject(); - void EndObject(SizeType memberCount); - void StartArray(); - void EndArray(SizeType elementCount); + void Null(); + void Bool(bool b); + void Int(int i); + void Uint(unsigned i); + void Int64(int64_t i); + void Uint64(uint64_t i); + void Double(double d); + void String(const Ch* str, SizeType length, bool copy); + void StartObject(); + void EndObject(SizeType memberCount); + void StartArray(); + void EndArray(SizeType elementCount); }; \endcode */ @@ -69,25 +69,25 @@ concept Handler { //! Default implementation of Handler. /*! This can be used as base class of any reader handler. - \implements Handler + \implements Handler */ template > struct BaseReaderHandler { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - void Default() {} - void Null() { Default(); } - void Bool(bool) { Default(); } - void Int(int) { Default(); } - void Uint(unsigned) { Default(); } - void Int64(int64_t) { Default(); } - void Uint64(uint64_t) { Default(); } - void Double(double) { Default(); } - void String(const Ch*, SizeType, bool) { Default(); } - void StartObject() { Default(); } - void EndObject(SizeType) { Default(); } - void StartArray() { Default(); } - void EndArray(SizeType) { Default(); } + void Default() {} + void Null() { Default(); } + void Bool(bool) { Default(); } + void Int(int) { Default(); } + void Uint(unsigned) { Default(); } + void Int64(int64_t) { Default(); } + void Uint64(uint64_t) { Default(); } + void Double(double) { Default(); } + void String(const Ch*, SizeType, bool) { Default(); } + void StartObject() { Default(); } + void EndObject(SizeType) { Default(); } + void StartArray() { Default(); } + void EndArray(SizeType) { Default(); } }; /////////////////////////////////////////////////////////////////////////////// @@ -95,75 +95,75 @@ struct BaseReaderHandler { //! Skip the JSON white spaces in a stream. /*! \param stream A input stream for skipping white spaces. - \note This function has SSE2/SSE4.2 specialization. + \note This function has SSE2/SSE4.2 specialization. */ template void SkipWhitespace(Stream& stream) { - Stream s = stream; // Use a local copy for optimization - while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') - s.Take(); - stream = s; + Stream s = stream; // Use a local copy for optimization + while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') + s.Take(); + stream = s; } #ifdef RAPIDJSON_SSE42 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. inline const char *SkipWhitespace_SIMD(const char* p) { - static const char whitespace[16] = " \n\r\t"; - __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]); + static const char whitespace[16] = " \n\r\t"; + __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]); - for (;;) { - __m128i s = _mm_loadu_si128((const __m128i *)p); - unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); - if (r == 0) // all 16 characters are whitespace - p += 16; - else { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - if (_BitScanForward(&offset, r)) - return p + offset; + for (;;) { + __m128i s = _mm_loadu_si128((const __m128i *)p); + unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r == 0) // all 16 characters are whitespace + p += 16; + else { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + if (_BitScanForward(&offset, r)) + return p + offset; #else - if (r != 0) - return p + __builtin_ffs(r) - 1; + if (r != 0) + return p + __builtin_ffs(r) - 1; #endif - } - } + } + } } #elif defined(RAPIDJSON_SSE2) //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. inline const char *SkipWhitespace_SIMD(const char* p) { - static const char whitespaces[4][17] = { - " ", - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", - "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; + static const char whitespaces[4][17] = { + " ", + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", + "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; - __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); - __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); - __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); - __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); + __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); + __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); + __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); + __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); - for (;;) { - __m128i s = _mm_loadu_si128((const __m128i *)p); - __m128i x = _mm_cmpeq_epi8(s, w0); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); - unsigned short r = ~_mm_movemask_epi8(x); - if (r == 0) // all 16 characters are whitespace - p += 16; - else { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - if (_BitScanForward(&offset, r)) - return p + offset; + for (;;) { + __m128i s = _mm_loadu_si128((const __m128i *)p); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = ~_mm_movemask_epi8(x); + if (r == 0) // all 16 characters are whitespace + p += 16; + else { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + if (_BitScanForward(&offset, r)) + return p + offset; #else - if (r != 0) - return p + __builtin_ffs(r) - 1; + if (r != 0) + return p + __builtin_ffs(r) - 1; #endif - } - } + } + } } #endif // RAPIDJSON_SSE2 @@ -171,12 +171,12 @@ inline const char *SkipWhitespace_SIMD(const char* p) { #ifdef RAPIDJSON_SIMD //! Template function specialization for InsituStringStream template<> inline void SkipWhitespace(InsituStringStream& stream) { - stream.src_ = const_cast(SkipWhitespace_SIMD(stream.src_)); + stream.src_ = const_cast(SkipWhitespace_SIMD(stream.src_)); } //! Template function specialization for StringStream template<> inline void SkipWhitespace(StringStream& stream) { - stream.src_ = SkipWhitespace_SIMD(stream.src_); + stream.src_ = SkipWhitespace_SIMD(stream.src_); } #endif // RAPIDJSON_SIMD @@ -201,474 +201,474 @@ template<> inline void SkipWhitespace(StringStream& stream) { template > class GenericReader { public: - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - //! Constructor. - /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) - \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) - */ - GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} + //! Constructor. + /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} - //! Parse JSON text. - /*! \tparam parseFlags Combination of ParseFlag. - \tparam Stream Type of input stream. - \tparam Handler Type of handler which must implement Handler concept. - \param stream Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template - bool Parse(Stream& stream, Handler& handler) { - parseError_ = 0; - errorOffset_ = 0; + //! Parse JSON text. + /*! \tparam parseFlags Combination of ParseFlag. + \tparam Stream Type of input stream. + \tparam Handler Type of handler which must implement Handler concept. + \param stream Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + bool Parse(Stream& stream, Handler& handler) { + parseError_ = 0; + errorOffset_ = 0; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable #endif - if (setjmp(jmpbuf_)) { + if (setjmp(jmpbuf_)) { #ifdef _MSC_VER #pragma warning(pop) #endif - stack_.Clear(); - return false; - } + stack_.Clear(); + return false; + } - SkipWhitespace(stream); + SkipWhitespace(stream); - if (stream.Peek() == '\0') - RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell()); - else { - switch (stream.Peek()) { - case '{': ParseObject(stream, handler); break; - case '[': ParseArray(stream, handler); break; - default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell()); - } - SkipWhitespace(stream); + if (stream.Peek() == '\0') + RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell()); + else { + switch (stream.Peek()) { + case '{': ParseObject(stream, handler); break; + case '[': ParseArray(stream, handler); break; + default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell()); + } + SkipWhitespace(stream); - if (stream.Peek() != '\0') - RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell()); - } + if (stream.Peek() != '\0') + RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell()); + } - return true; - } + return true; + } - bool HasParseError() const { return parseError_ != 0; } - const char* GetParseError() const { return parseError_; } - size_t GetErrorOffset() const { return errorOffset_; } + bool HasParseError() const { return parseError_ != 0; } + const char* GetParseError() const { return parseError_; } + size_t GetErrorOffset() const { return errorOffset_; } private: - // Parse object: { string : value, ... } - template - void ParseObject(Stream& stream, Handler& handler) { - RAPIDJSON_ASSERT(stream.Peek() == '{'); - stream.Take(); // Skip '{' - handler.StartObject(); - SkipWhitespace(stream); + // Parse object: { string : value, ... } + template + void ParseObject(Stream& stream, Handler& handler) { + RAPIDJSON_ASSERT(stream.Peek() == '{'); + stream.Take(); // Skip '{' + handler.StartObject(); + SkipWhitespace(stream); - if (stream.Peek() == '}') { - stream.Take(); - handler.EndObject(0); // empty object - return; - } + if (stream.Peek() == '}') { + stream.Take(); + handler.EndObject(0); // empty object + return; + } - for (SizeType memberCount = 0;;) { - if (stream.Peek() != '"') { - RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell()); - break; - } + for (SizeType memberCount = 0;;) { + if (stream.Peek() != '"') { + RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell()); + break; + } - ParseString(stream, handler); - SkipWhitespace(stream); + ParseString(stream, handler); + SkipWhitespace(stream); - if (stream.Take() != ':') { - RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell()); - break; - } - SkipWhitespace(stream); + if (stream.Take() != ':') { + RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell()); + break; + } + SkipWhitespace(stream); - ParseValue(stream, handler); - SkipWhitespace(stream); + ParseValue(stream, handler); + SkipWhitespace(stream); - ++memberCount; + ++memberCount; - switch(stream.Take()) { - case ',': SkipWhitespace(stream); break; - case '}': handler.EndObject(memberCount); return; - default: RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell()); - } - } - } + switch(stream.Take()) { + case ',': SkipWhitespace(stream); break; + case '}': handler.EndObject(memberCount); return; + default: RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell()); + } + } + } - // Parse array: [ value, ... ] - template - void ParseArray(Stream& stream, Handler& handler) { - RAPIDJSON_ASSERT(stream.Peek() == '['); - stream.Take(); // Skip '[' - handler.StartArray(); - SkipWhitespace(stream); + // Parse array: [ value, ... ] + template + void ParseArray(Stream& stream, Handler& handler) { + RAPIDJSON_ASSERT(stream.Peek() == '['); + stream.Take(); // Skip '[' + handler.StartArray(); + SkipWhitespace(stream); - if (stream.Peek() == ']') { - stream.Take(); - handler.EndArray(0); // empty array - return; - } + if (stream.Peek() == ']') { + stream.Take(); + handler.EndArray(0); // empty array + return; + } - for (SizeType elementCount = 0;;) { - ParseValue(stream, handler); - ++elementCount; - SkipWhitespace(stream); + for (SizeType elementCount = 0;;) { + ParseValue(stream, handler); + ++elementCount; + SkipWhitespace(stream); - switch (stream.Take()) { - case ',': SkipWhitespace(stream); break; - case ']': handler.EndArray(elementCount); return; - default: RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell()); - } - } - } + switch (stream.Take()) { + case ',': SkipWhitespace(stream); break; + case ']': handler.EndArray(elementCount); return; + default: RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell()); + } + } + } - template - void ParseNull(Stream& stream, Handler& handler) { - RAPIDJSON_ASSERT(stream.Peek() == 'n'); - stream.Take(); + template + void ParseNull(Stream& stream, Handler& handler) { + RAPIDJSON_ASSERT(stream.Peek() == 'n'); + stream.Take(); - if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l') - handler.Null(); - else - RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); - } + if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l') + handler.Null(); + else + RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); + } - template - void ParseTrue(Stream& stream, Handler& handler) { - RAPIDJSON_ASSERT(stream.Peek() == 't'); - stream.Take(); + template + void ParseTrue(Stream& stream, Handler& handler) { + RAPIDJSON_ASSERT(stream.Peek() == 't'); + stream.Take(); - if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e') - handler.Bool(true); - else - RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell()); - } + if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e') + handler.Bool(true); + else + RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell()); + } - template - void ParseFalse(Stream& stream, Handler& handler) { - RAPIDJSON_ASSERT(stream.Peek() == 'f'); - stream.Take(); + template + void ParseFalse(Stream& stream, Handler& handler) { + RAPIDJSON_ASSERT(stream.Peek() == 'f'); + stream.Take(); - if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e') - handler.Bool(false); - else - RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); - } + if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e') + handler.Bool(false); + else + RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); + } - // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). - template - unsigned ParseHex4(Stream& stream) { - Stream s = stream; // Use a local copy for optimization - unsigned codepoint = 0; - for (int i = 0; i < 4; i++) { - Ch c = s.Take(); - codepoint <<= 4; - codepoint += c; - if (c >= '0' && c <= '9') - codepoint -= '0'; - else if (c >= 'A' && c <= 'F') - codepoint -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - codepoint -= 'a' - 10; - else - RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1); - } - stream = s; // Restore stream - return codepoint; - } + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(Stream& stream) { + Stream s = stream; // Use a local copy for optimization + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = s.Take(); + codepoint <<= 4; + codepoint += c; + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else + RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1); + } + stream = s; // Restore stream + return codepoint; + } - // Parse string, handling the prefix and suffix double quotes and escaping. - template - void ParseString(Stream& stream, Handler& handler) { + // Parse string, handling the prefix and suffix double quotes and escaping. + template + void ParseString(Stream& stream, Handler& handler) { #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - static const Ch escape[256] = { - Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', - Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, - 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, - 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 - }; + static const Ch escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; #undef Z16 - Stream s = stream; // Use a local copy for optimization - RAPIDJSON_ASSERT(s.Peek() == '\"'); - s.Take(); // Skip '\"' - Ch *head; - SizeType len; - if (parseFlags & kParseInsituFlag) - head = s.PutBegin(); - else - len = 0; + Stream s = stream; // Use a local copy for optimization + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + Ch *head; + SizeType len; + if (parseFlags & kParseInsituFlag) + head = s.PutBegin(); + else + len = 0; #define RAPIDJSON_PUT(x) \ - do { \ - if (parseFlags & kParseInsituFlag) \ - s.Put(x); \ - else { \ - *stack_.template Push() = x; \ - ++len; \ - } \ - } while(false) + do { \ + if (parseFlags & kParseInsituFlag) \ + s.Put(x); \ + else { \ + *stack_.template Push() = x; \ + ++len; \ + } \ + } while(false) - for (;;) { - Ch c = s.Take(); - if (c == '\\') { // Escape - Ch e = s.Take(); - if ((sizeof(Ch) == 1 ) && escape[(unsigned char)e]) - RAPIDJSON_PUT(escape[(unsigned char)e]); - else if (e == 'u') { // Unicode - unsigned codepoint = ParseHex4(s); - if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair - if (s.Take() != '\\' || s.Take() != 'u') { - RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2); - return; - } - unsigned codepoint2 = ParseHex4(s); - if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) { - RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2); - return; - } - codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; - } + for (;;) { + Ch c = s.Take(); + if (c == '\\') { // Escape + Ch e = s.Take(); + if ((sizeof(Ch) == 1 ) && escape[(unsigned char)e]) + RAPIDJSON_PUT(escape[(unsigned char)e]); + else if (e == 'u') { // Unicode + unsigned codepoint = ParseHex4(s); + if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair + if (s.Take() != '\\' || s.Take() != 'u') { + RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2); + return; + } + unsigned codepoint2 = ParseHex4(s); + if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) { + RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2); + return; + } + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } - Ch buffer[4]; - SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]); + Ch buffer[4]; + SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]); - if (parseFlags & kParseInsituFlag) - for (SizeType i = 0; i < count; i++) - s.Put(buffer[i]); - else { - memcpy(stack_.template Push(count), buffer, count * sizeof(Ch)); - len += count; - } - } - else { - RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1); - return; - } - } - else if (c == '"') { // Closing double quote - if (parseFlags & kParseInsituFlag) { - size_t length = s.PutEnd(head); - RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - RAPIDJSON_PUT('\0'); // null-terminate the string - handler.String(head, SizeType(length), false); - } - else { - RAPIDJSON_PUT('\0'); - handler.String(stack_.template Pop(len), len - 1, true); - } - stream = s; // restore stream - return; - } - else if (c == '\0') { - RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1); - return; - } - else if ((unsigned)c < 0x20) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF - RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1); - return; - } - else - RAPIDJSON_PUT(c); // Normal character, just copy - } + if (parseFlags & kParseInsituFlag) + for (SizeType i = 0; i < count; i++) + s.Put(buffer[i]); + else { + memcpy(stack_.template Push(count), buffer, count * sizeof(Ch)); + len += count; + } + } + else { + RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1); + return; + } + } + else if (c == '"') { // Closing double quote + if (parseFlags & kParseInsituFlag) { + size_t length = s.PutEnd(head); + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + RAPIDJSON_PUT('\0'); // null-terminate the string + handler.String(head, SizeType(length), false); + } + else { + RAPIDJSON_PUT('\0'); + handler.String(stack_.template Pop(len), len - 1, true); + } + stream = s; // restore stream + return; + } + else if (c == '\0') { + RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1); + return; + } + else if ((unsigned)c < 0x20) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1); + return; + } + else + RAPIDJSON_PUT(c); // Normal character, just copy + } #undef RAPIDJSON_PUT - } + } - template - void ParseNumber(Stream& stream, Handler& handler) { - Stream s = stream; // Local copy for optimization - // Parse minus - bool minus = false; - if (s.Peek() == '-') { - minus = true; - s.Take(); - } + template + void ParseNumber(Stream& stream, Handler& handler) { + Stream s = stream; // Local copy for optimization + // Parse minus + bool minus = false; + if (s.Peek() == '-') { + minus = true; + s.Take(); + } - // Parse int: zero / ( digit1-9 *DIGIT ) - unsigned i; - bool try64bit = false; - if (s.Peek() == '0') { - i = 0; - s.Take(); - } - else if (s.Peek() >= '1' && s.Peek() <= '9') { - i = s.Take() - '0'; + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i; + bool try64bit = false; + if (s.Peek() == '0') { + i = 0; + s.Take(); + } + else if (s.Peek() >= '1' && s.Peek() <= '9') { + i = s.Take() - '0'; - if (minus) - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (i >= 214748364) { // 2^31 = 2147483648 - if (i != 214748364 || s.Peek() > '8') { - try64bit = true; - break; - } - } - i = i * 10 + (s.Take() - '0'); - } - else - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (i >= 429496729) { // 2^32 - 1 = 4294967295 - if (i != 429496729 || s.Peek() > '5') { - try64bit = true; - break; - } - } - i = i * 10 + (s.Take() - '0'); - } - } - else { - RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell()); - return; - } + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 214748364) { // 2^31 = 2147483648 + if (i != 214748364 || s.Peek() > '8') { + try64bit = true; + break; + } + } + i = i * 10 + (s.Take() - '0'); + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 429496729) { // 2^32 - 1 = 4294967295 + if (i != 429496729 || s.Peek() > '5') { + try64bit = true; + break; + } + } + i = i * 10 + (s.Take() - '0'); + } + } + else { + RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell()); + return; + } - // Parse 64bit int - uint64_t i64 = 0; - bool useDouble = false; - if (try64bit) { - i64 = i; - if (minus) - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808 - if (i64 != 922337203685477580uLL || s.Peek() > '8') { - useDouble = true; - break; - } - i64 = i64 * 10 + (s.Take() - '0'); - } - else - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615 - if (i64 != 1844674407370955161uLL || s.Peek() > '5') { - useDouble = true; - break; - } - i64 = i64 * 10 + (s.Take() - '0'); - } - } + // Parse 64bit int + uint64_t i64 = 0; + bool useDouble = false; + if (try64bit) { + i64 = i; + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808 + if (i64 != 922337203685477580uLL || s.Peek() > '8') { + useDouble = true; + break; + } + i64 = i64 * 10 + (s.Take() - '0'); + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615 + if (i64 != 1844674407370955161uLL || s.Peek() > '5') { + useDouble = true; + break; + } + i64 = i64 * 10 + (s.Take() - '0'); + } + } - // Force double for big integer - double d = 0.0; - if (useDouble) { - d = (double)i64; - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (d >= 1E307) { - RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); - return; - } - d = d * 10 + (s.Take() - '0'); - } - } + // Force double for big integer + double d = 0.0; + if (useDouble) { + d = (double)i64; + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (d >= 1E307) { + RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); + return; + } + d = d * 10 + (s.Take() - '0'); + } + } - // Parse frac = decimal-point 1*DIGIT - int expFrac = 0; - if (s.Peek() == '.') { - if (!useDouble) { - d = try64bit ? (double)i64 : (double)i; - useDouble = true; - } - s.Take(); + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + if (s.Peek() == '.') { + if (!useDouble) { + d = try64bit ? (double)i64 : (double)i; + useDouble = true; + } + s.Take(); - if (s.Peek() >= '0' && s.Peek() <= '9') { - d = d * 10 + (s.Take() - '0'); - --expFrac; - } - else { - RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell()); - return; - } + if (s.Peek() >= '0' && s.Peek() <= '9') { + d = d * 10 + (s.Take() - '0'); + --expFrac; + } + else { + RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell()); + return; + } - while (s.Peek() >= '0' && s.Peek() <= '9') { - if (expFrac > -16) { - d = d * 10 + (s.Peek() - '0'); - --expFrac; - } - s.Take(); - } - } + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (expFrac > -16) { + d = d * 10 + (s.Peek() - '0'); + --expFrac; + } + s.Take(); + } + } - // Parse exp = e [ minus / plus ] 1*DIGIT - int exp = 0; - if (s.Peek() == 'e' || s.Peek() == 'E') { - if (!useDouble) { - d = try64bit ? (double)i64 : (double)i; - useDouble = true; - } - s.Take(); + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (s.Peek() == 'e' || s.Peek() == 'E') { + if (!useDouble) { + d = try64bit ? (double)i64 : (double)i; + useDouble = true; + } + s.Take(); - bool expMinus = false; - if (s.Peek() == '+') - s.Take(); - else if (s.Peek() == '-') { - s.Take(); - expMinus = true; - } + bool expMinus = false; + if (s.Peek() == '+') + s.Take(); + else if (s.Peek() == '-') { + s.Take(); + expMinus = true; + } - if (s.Peek() >= '0' && s.Peek() <= '9') { - exp = s.Take() - '0'; - while (s.Peek() >= '0' && s.Peek() <= '9') { - exp = exp * 10 + (s.Take() - '0'); - if (exp > 308) { - RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); - return; - } - } - } - else { - RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell()); - return; - } + if (s.Peek() >= '0' && s.Peek() <= '9') { + exp = s.Take() - '0'; + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp > 308) { + RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); + return; + } + } + } + else { + RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell()); + return; + } - if (expMinus) - exp = -exp; - } + if (expMinus) + exp = -exp; + } - // Finish parsing, call event according to the type of number. - if (useDouble) { - d *= internal::Pow10(exp + expFrac); - handler.Double(minus ? -d : d); - } - else { - if (try64bit) { - if (minus) - handler.Int64(-(int64_t)i64); - else - handler.Uint64(i64); - } - else { - if (minus) - handler.Int(-(int)i); - else - handler.Uint(i); - } - } + // Finish parsing, call event according to the type of number. + if (useDouble) { + d *= internal::Pow10(exp + expFrac); + handler.Double(minus ? -d : d); + } + else { + if (try64bit) { + if (minus) + handler.Int64(-(int64_t)i64); + else + handler.Uint64(i64); + } + else { + if (minus) + handler.Int(-(int)i); + else + handler.Uint(i); + } + } - stream = s; // restore stream - } + stream = s; // restore stream + } - // Parse any JSON value - template - void ParseValue(Stream& stream, Handler& handler) { - switch (stream.Peek()) { - case 'n': ParseNull (stream, handler); break; - case 't': ParseTrue (stream, handler); break; - case 'f': ParseFalse (stream, handler); break; - case '"': ParseString(stream, handler); break; - case '{': ParseObject(stream, handler); break; - case '[': ParseArray (stream, handler); break; - default : ParseNumber(stream, handler); - } - } + // Parse any JSON value + template + void ParseValue(Stream& stream, Handler& handler) { + switch (stream.Peek()) { + case 'n': ParseNull (stream, handler); break; + case 't': ParseTrue (stream, handler); break; + case 'f': ParseFalse (stream, handler); break; + case '"': ParseString(stream, handler); break; + case '{': ParseObject(stream, handler); break; + case '[': ParseArray (stream, handler); break; + default : ParseNumber(stream, handler); + } + } - static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. - internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. - jmp_buf jmpbuf_; //!< setjmp buffer for fast exit from nested parsing function calls. - const char* parseError_; - size_t errorOffset_; + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + jmp_buf jmpbuf_; //!< setjmp buffer for fast exit from nested parsing function calls. + const char* parseError_; + size_t errorOffset_; }; // class GenericReader //! Reader with UTF8 encoding and default allocator. diff --git a/include/rapidjson/rapidjson/stringbuffer.h b/include/rapidjson/rapidjson/stringbuffer.h index 269ae107..c6e72748 100644 --- a/include/rapidjson/rapidjson/stringbuffer.h +++ b/include/rapidjson/rapidjson/stringbuffer.h @@ -8,32 +8,32 @@ namespace rapidjson { //! Represents an in-memory output stream. /*! - \tparam Encoding Encoding of the stream. - \tparam Allocator type for allocating memory buffer. - \implements Stream + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \implements Stream */ template struct GenericStringBuffer { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - void Put(Ch c) { *stack_.template Push() = c; } + void Put(Ch c) { *stack_.template Push() = c; } - void Clear() { stack_.Clear(); } + void Clear() { stack_.Clear(); } - const char* GetString() const { - // Push and pop a null terminator. This is safe. - *stack_.template Push() = '\0'; - stack_.template Pop(1); + const char* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); - return stack_.template Bottom(); - } + return stack_.template Bottom(); + } - size_t Size() const { return stack_.GetSize(); } + size_t Size() const { return stack_.GetSize(); } - static const size_t kDefaultCapacity = 256; - mutable internal::Stack stack_; + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; }; typedef GenericStringBuffer > StringBuffer; @@ -41,7 +41,7 @@ typedef GenericStringBuffer > StringBuffer; //! Implement specialized version of PutN() with memset() for better performance. template<> inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { - memset(stream.stack_.Push(n), c, n * sizeof(c)); + memset(stream.stack_.Push(n), c, n * sizeof(c)); } } // namespace rapidjson diff --git a/include/rapidjson/rapidjson/writer.h b/include/rapidjson/rapidjson/writer.h index e842104c..5e3793c2 100644 --- a/include/rapidjson/rapidjson/writer.h +++ b/include/rapidjson/rapidjson/writer.h @@ -4,8 +4,8 @@ #include "rapidjson.h" #include "internal/stack.h" #include "internal/strfunc.h" -#include // snprintf() or _sprintf_s() -#include // placement new +#include // snprintf() or _sprintf_s() +#include // placement new #ifdef _MSC_VER #pragma warning(push) @@ -16,220 +16,220 @@ namespace rapidjson { //! JSON writer /*! Writer implements the concept Handler. - It generates JSON text by events to an output stream. + It generates JSON text by events to an output stream. - User may programmatically calls the functions of a writer to generate JSON text. + User may programmatically calls the functions of a writer to generate JSON text. - On the other side, a writer can also be passed to objects that generates events, + On the other side, a writer can also be passed to objects that generates events, - for example Reader::Parse() and Document::Accept(). + for example Reader::Parse() and Document::Accept(). - \tparam Stream Type of ouptut stream. - \tparam Encoding Encoding of both source strings and output. - \implements Handler + \tparam Stream Type of ouptut stream. + \tparam Encoding Encoding of both source strings and output. + \implements Handler */ template, typename Allocator = MemoryPoolAllocator<> > class Writer { public: - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : - stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {} + Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {} - //@name Implementation of Handler - //@{ - Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } - Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } - Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } - Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } - Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } - Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } - Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } + //@name Implementation of Handler + //@{ + Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } + Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } + Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } + Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } + Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } + Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } + Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } - Writer& String(const Ch* str, SizeType length, bool copy = false) { - (void)copy; - Prefix(kStringType); - WriteString(str, length); - return *this; - } + Writer& String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + WriteString(str, length); + return *this; + } - Writer& StartObject() { - Prefix(kObjectType); - new (level_stack_.template Push()) Level(false); - WriteStartObject(); - return *this; - } + Writer& StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + WriteStartObject(); + return *this; + } - Writer& EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); - level_stack_.template Pop(1); - WriteEndObject(); - return *this; - } + Writer& EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + WriteEndObject(); + return *this; + } - Writer& StartArray() { - Prefix(kArrayType); - new (level_stack_.template Push()) Level(true); - WriteStartArray(); - return *this; - } + Writer& StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + WriteStartArray(); + return *this; + } - Writer& EndArray(SizeType elementCount = 0) { - (void)elementCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); - level_stack_.template Pop(1); - WriteEndArray(); - return *this; - } - //@} + Writer& EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + WriteEndArray(); + return *this; + } + //@} - //! Simpler but slower overload. - Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } + //! Simpler but slower overload. + Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } protected: - //! Information for each nested level - struct Level { - Level(bool inArray_) : inArray(inArray_), valueCount(0) {} - bool inArray; //!< true if in array, otherwise in object - size_t valueCount; //!< number of values in this level - }; + //! Information for each nested level + struct Level { + Level(bool inArray_) : inArray(inArray_), valueCount(0) {} + bool inArray; //!< true if in array, otherwise in object + size_t valueCount; //!< number of values in this level + }; - static const size_t kDefaultLevelDepth = 32; + static const size_t kDefaultLevelDepth = 32; - void WriteNull() { - stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l'); - } + void WriteNull() { + stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l'); + } - void WriteBool(bool b) { - if (b) { - stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e'); - } - else { - stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e'); - } - } + void WriteBool(bool b) { + if (b) { + stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e'); + } + else { + stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e'); + } + } - void WriteInt(int i) { - if (i < 0) { - stream_.Put('-'); - i = -i; - } - WriteUint((unsigned)i); - } + void WriteInt(int i) { + if (i < 0) { + stream_.Put('-'); + i = -i; + } + WriteUint((unsigned)i); + } - void WriteUint(unsigned u) { - char buffer[10]; - char *p = buffer; - do { - *p++ = (u % 10) + '0'; - u /= 10; - } while (u > 0); + void WriteUint(unsigned u) { + char buffer[10]; + char *p = buffer; + do { + *p++ = (u % 10) + '0'; + u /= 10; + } while (u > 0); - do { - --p; - stream_.Put(*p); - } while (p != buffer); - } + do { + --p; + stream_.Put(*p); + } while (p != buffer); + } - void WriteInt64(int64_t i64) { - if (i64 < 0) { - stream_.Put('-'); - i64 = -i64; - } - WriteUint64((uint64_t)i64); - } + void WriteInt64(int64_t i64) { + if (i64 < 0) { + stream_.Put('-'); + i64 = -i64; + } + WriteUint64((uint64_t)i64); + } - void WriteUint64(uint64_t u64) { - char buffer[20]; - char *p = buffer; - do { - *p++ = char(u64 % 10) + '0'; - u64 /= 10; - } while (u64 > 0); + void WriteUint64(uint64_t u64) { + char buffer[20]; + char *p = buffer; + do { + *p++ = char(u64 % 10) + '0'; + u64 /= 10; + } while (u64 > 0); - do { - --p; - stream_.Put(*p); - } while (p != buffer); - } + do { + --p; + stream_.Put(*p); + } while (p != buffer); + } - //! \todo Optimization with custom double-to-string converter. - void WriteDouble(double d) { - char buffer[100]; + //! \todo Optimization with custom double-to-string converter. + void WriteDouble(double d) { + char buffer[100]; #if _MSC_VER - int ret = sprintf_s(buffer, sizeof(buffer), "%0.16g", d); + int ret = sprintf_s(buffer, sizeof(buffer), "%0.16g", d); #else - int ret = snprintf(buffer, sizeof(buffer), "%0.16g", d); + int ret = snprintf(buffer, sizeof(buffer), "%0.16g", d); #endif - RAPIDJSON_ASSERT(ret >= 1); - for (int i = 0; i < ret; i++) - stream_.Put(buffer[i]); - } + RAPIDJSON_ASSERT(ret >= 1); + for (int i = 0; i < ret; i++) + stream_.Put(buffer[i]); + } - void WriteString(const Ch* str, SizeType length) { - static const char hexDigits[] = "0123456789ABCDEF"; - static const char escape[256] = { + void WriteString(const Ch* str, SizeType length) { + static const char hexDigits[] = "0123456789ABCDEF"; + static const char escape[256] = { #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 - 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - Z16, Z16, // 30~4F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF #undef Z16 - }; + }; - stream_.Put('\"'); - for (const Ch* p = str; p != str + length; ++p) { - if ((sizeof(Ch) == 1) && escape[(unsigned char)*p]) { - stream_.Put('\\'); - stream_.Put(escape[(unsigned char)*p]); - if (escape[(unsigned char)*p] == 'u') { - stream_.Put('0'); - stream_.Put('0'); - stream_.Put(hexDigits[(*p) >> 4]); - stream_.Put(hexDigits[(*p) & 0xF]); - } - } - else - stream_.Put(*p); - } - stream_.Put('\"'); - } + stream_.Put('\"'); + for (const Ch* p = str; p != str + length; ++p) { + if ((sizeof(Ch) == 1) && escape[(unsigned char)*p]) { + stream_.Put('\\'); + stream_.Put(escape[(unsigned char)*p]); + if (escape[(unsigned char)*p] == 'u') { + stream_.Put('0'); + stream_.Put('0'); + stream_.Put(hexDigits[(*p) >> 4]); + stream_.Put(hexDigits[(*p) & 0xF]); + } + } + else + stream_.Put(*p); + } + stream_.Put('\"'); + } - void WriteStartObject() { stream_.Put('{'); } - void WriteEndObject() { stream_.Put('}'); } - void WriteStartArray() { stream_.Put('['); } - void WriteEndArray() { stream_.Put(']'); } + void WriteStartObject() { stream_.Put('{'); } + void WriteEndObject() { stream_.Put('}'); } + void WriteStartArray() { stream_.Put('['); } + void WriteEndArray() { stream_.Put(']'); } - void Prefix(Type type) { - (void)type; - if (level_stack_.GetSize() != 0) { // this value is not at root - Level* level = level_stack_.template Top(); - if (level->valueCount > 0) { - if (level->inArray) - stream_.Put(','); // add comma if it is not the first element in array - else // in object - stream_.Put((level->valueCount % 2 == 0) ? ',' : ':'); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else - RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); - } + void Prefix(Type type) { + (void)type; + if (level_stack_.GetSize() != 0) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + stream_.Put(','); // add comma if it is not the first element in array + else // in object + stream_.Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else + RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); + } - Stream& stream_; - internal::Stack level_stack_; + Stream& stream_; + internal::Stack level_stack_; private: - // Prohibit assignment for VC C4512 warning - Writer& operator=(const Writer& w); + // Prohibit assignment for VC C4512 warning + Writer& operator=(const Writer& w); }; } // namespace rapidjson diff --git a/include/rapidjson/rapidjson_include.h b/include/rapidjson/rapidjson_include.h index 4cd1ff71..94007df5 100644 --- a/include/rapidjson/rapidjson_include.h +++ b/include/rapidjson/rapidjson_include.h @@ -13,8 +13,8 @@ typedef unsigned int UINT32; #include "rapidjson/rapidjson.h" #include "rapidjson/document.h" -#include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output -#include "rapidjson/prettywriter.h" // for stringify JSON +#include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output +#include "rapidjson/prettywriter.h" // for stringify JSON #include "rapidjson/stringbuffer.h" // for string buffer #include @@ -42,7 +42,7 @@ namespace cpjson i.isstring = v.IsString(); return i; }; - + inline std::string json2string(rapidjson::Value &v) { rapidjson::StringBuffer buffer; @@ -52,178 +52,178 @@ namespace cpjson return buffer.GetString(); } /// A convenience function to get a double from a JSON value, including error checking - inline int get_integer(rapidjson::Value &v, std::string m) - { - if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } - rapidjson::Value &el = v[m.c_str()]; + inline int get_integer(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + rapidjson::Value &el = v[m.c_str()]; if (!el.IsInt()){ throw CoolProp::ValueError(format("Member [%s] is not an integer",m.c_str())); } - else - { + else + { return el.GetInt(); - } - }; - /// A convenience function to get a double from a JSON value, including error checking - inline double get_double(rapidjson::Value &v, std::string m) - { - if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } - rapidjson::Value &el = v[m.c_str()]; - if (!el.IsNumber()){ throw CoolProp::ValueError(format("Member [%s] is not a number",m.c_str())); } - else - { - return el.GetDouble(); - } - }; + } + }; + /// A convenience function to get a double from a JSON value, including error checking + inline double get_double(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + rapidjson::Value &el = v[m.c_str()]; + if (!el.IsNumber()){ throw CoolProp::ValueError(format("Member [%s] is not a number",m.c_str())); } + else + { + return el.GetDouble(); + } + }; /// A convenience function to get a bool from a JSON value, including error checking - inline bool get_bool(rapidjson::Value &v, std::string m) - { - if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } - rapidjson::Value &el = v[m.c_str()]; + inline bool get_bool(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + rapidjson::Value &el = v[m.c_str()]; if (!el.IsBool()){ throw CoolProp::ValueError(format("Member [%s] is not a boolean",m.c_str())); } - else - { + else + { return el.GetBool(); - } - }; + } + }; /// A convenience function to get a string from a JSON value, including error checking - inline std::string get_string(rapidjson::Value &v, std::string m) - { - if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } - rapidjson::Value &el = v[m.c_str()]; + inline std::string get_string(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + rapidjson::Value &el = v[m.c_str()]; if (!el.IsString()){ throw CoolProp::ValueError(format("Member [%s] is not a string",m.c_str())); } - else - { + else + { return el.GetString(); - } - }; + } + }; - /// A convenience function to get a double array compactly - inline std::vector get_double_array(rapidjson::Value &v) - { - std::vector out; - if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) - { - if (!itr->IsNumber()){throw CoolProp::ValueError("input is not a number");} - out.push_back(itr->GetDouble()); - } - return out; - }; - /// A convenience function to get a double array compactly - inline std::vector get_double_array(rapidjson::Value &v, std::string m) - { + inline std::vector get_double_array(rapidjson::Value &v) + { + std::vector out; + if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) + { + if (!itr->IsNumber()){throw CoolProp::ValueError("input is not a number");} + out.push_back(itr->GetDouble()); + } + return out; + }; + + /// A convenience function to get a double array compactly + inline std::vector get_double_array(rapidjson::Value &v, std::string m) + { if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } else{ return get_double_array(v[m.c_str()]); } - }; + }; /// A convenience function to get a long double array compactly - inline std::vector get_long_double_array(rapidjson::Value &v) - { - std::vector out; - if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) - { + inline std::vector get_long_double_array(rapidjson::Value &v) + { + std::vector out; + if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) + { if (!itr->IsNumber()){throw CoolProp::ValueError("input is not a number");} - out.push_back(itr->GetDouble()); - } - return out; - }; + out.push_back(itr->GetDouble()); + } + return out; + }; - /// A convenience function to get a 2D double array compactly - inline std::vector< std::vector > get_double_array2D(rapidjson::Value &v) - { - std::vector< std::vector > out; - std::vector tmp; - if (!v.IsArray()) {throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) - { - // This is here for debugging purposes - // cpjson::value_information vi = cpjson::get_information((*itr)); - if (!(itr->IsArray())) { + /// A convenience function to get a 2D double array compactly + inline std::vector< std::vector > get_double_array2D(rapidjson::Value &v) + { + std::vector< std::vector > out; + std::vector tmp; + if (!v.IsArray()) {throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) + { + // This is here for debugging purposes + // cpjson::value_information vi = cpjson::get_information((*itr)); + if (!(itr->IsArray())) { throw CoolProp::ValueError(format("input \"%s\" is not a 2D array",cpjson::json2string(v).c_str())); } - tmp.clear(); - for (rapidjson::Value::ValueIterator i = itr->Begin(); i != itr->End(); ++i) - { - if (!i->IsNumber()){throw CoolProp::ValueError("input is not a number");} - tmp.push_back(i->GetDouble()); - } - out.push_back(tmp); - } - return out; - }; + tmp.clear(); + for (rapidjson::Value::ValueIterator i = itr->Begin(); i != itr->End(); ++i) + { + if (!i->IsNumber()){throw CoolProp::ValueError("input is not a number");} + tmp.push_back(i->GetDouble()); + } + out.push_back(tmp); + } + return out; + }; /// A convenience function to get a 2D long double array compactly - inline std::vector< std::vector > get_long_double_array2D(rapidjson::Value &v) - { - std::vector< std::vector > out; - std::vector tmp; - if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) - { - if (!itr->IsArray()) { throw CoolProp::ValueError("input is not a 2D array"); } - tmp.clear(); - for (rapidjson::Value::ValueIterator i = itr->Begin(); i != itr->End(); ++i) - { - if (!i->IsNumber()){throw CoolProp::ValueError("input is not a number");} - tmp.push_back(i->GetDouble()); - } - out.push_back(tmp); - } - return out; - }; + inline std::vector< std::vector > get_long_double_array2D(rapidjson::Value &v) + { + std::vector< std::vector > out; + std::vector tmp; + if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) + { + if (!itr->IsArray()) { throw CoolProp::ValueError("input is not a 2D array"); } + tmp.clear(); + for (rapidjson::Value::ValueIterator i = itr->Begin(); i != itr->End(); ++i) + { + if (!i->IsNumber()){throw CoolProp::ValueError("input is not a number");} + tmp.push_back(i->GetDouble()); + } + out.push_back(tmp); + } + return out; + }; - /// A convenience function to get a long double array compactly - inline std::vector get_long_double_array(rapidjson::Value &v, std::string name) - { - std::vector out; + /// A convenience function to get a long double array compactly + inline std::vector get_long_double_array(rapidjson::Value &v, std::string name) + { + std::vector out; if (!v.HasMember(name.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",name.c_str())); } - if (!v[name.c_str()].IsArray()) { throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v[name.c_str()].Begin(); itr != v[name.c_str()].End(); ++itr) - { + if (!v[name.c_str()].IsArray()) { throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v[name.c_str()].Begin(); itr != v[name.c_str()].End(); ++itr) + { if (!itr->IsNumber()){throw CoolProp::ValueError("input is not a number");} - out.push_back(itr->GetDouble()); - } - return out; - }; + out.push_back(itr->GetDouble()); + } + return out; + }; - /// A convenience function to get a string array compactly - inline std::vector get_string_array(rapidjson::Value &v) - { - std::vector out; - if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } - for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) - { - out.push_back(itr->GetString()); - } - return out; - }; + /// A convenience function to get a string array compactly + inline std::vector get_string_array(rapidjson::Value &v) + { + std::vector out; + if (!v.IsArray()) { throw CoolProp::ValueError("input is not an array"); } + for (rapidjson::Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr) + { + out.push_back(itr->GetString()); + } + return out; + }; /// A convenience function to get a double array compactly - inline std::vector get_string_array(rapidjson::Value &v, std::string m) - { + inline std::vector get_string_array(rapidjson::Value &v, std::string m) + { if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } else{ return get_string_array(v[m.c_str()]); } - }; + }; - /// A convenience function to get a std::string from a JSON value - inline std::string to_string(rapidjson::Value &v) - { - rapidjson::StringBuffer buffer; - rapidjson::PrettyWriter writer(buffer); - v.Accept(writer); - return buffer.GetString(); - }; + /// A convenience function to get a std::string from a JSON value + inline std::string to_string(rapidjson::Value &v) + { + rapidjson::StringBuffer buffer; + rapidjson::PrettyWriter writer(buffer); + v.Accept(writer); + return buffer.GetString(); + }; // /// A convenience function to set an array compactly -// template +// template // inline void set_array(const char *key, const std::vector &vec, rapidjson::Value &value, rapidjson::Document &doc) // { // rapidjson::Value _v(rapidjson::kArrayType); @@ -235,17 +235,17 @@ namespace cpjson // }; // // /// A convenience function to set an array compactly -// template +// template // inline void set_array2D(const char *key, const std::vector< std::vector > &vec, rapidjson::Value &value, rapidjson::Document &doc) // { // rapidjson::Value _i(rapidjson::kArrayType); // rapidjson::Value _j; // for (unsigned int i = 0; i < vec.size(); ++i) { -// _j = rapidjson::Value(rapidjson::kArrayType); -// for (unsigned int j = 0; j < vec[i].size(); ++j) { -// _j.PushBack(vec[j],doc.GetAllocator()); -// } -// _i.PushBack(_j,doc.GetAllocator()); +// _j = rapidjson::Value(rapidjson::kArrayType); +// for (unsigned int j = 0; j < vec[i].size(); ++j) { +// _j.PushBack(vec[j],doc.GetAllocator()); +// } +// _i.PushBack(_j,doc.GetAllocator()); // } // value.AddMember(key, _i, doc.GetAllocator()); // }; diff --git a/src/AbstractState.cpp b/src/AbstractState.cpp index 3fb6d72a..93febc6e 100644 --- a/src/AbstractState.cpp +++ b/src/AbstractState.cpp @@ -45,13 +45,13 @@ AbstractState * AbstractState::factory(const std::string &backend, const std::st } else if (!backend.compare("INCOMP")) { - return new IncompressibleBackend(fluid_string); + return new IncompressibleBackend(fluid_string); } else if (backend.find("TTSE&") == 0) { // Will throw if there is a problem with this backend shared_ptr AS(factory(backend.substr(5), fluid_string)); - return new TTSEBackend(*AS.get()); + return new TTSEBackend(*AS.get()); } else if (!backend.compare("TREND")) { @@ -159,19 +159,19 @@ bool AbstractState::clear() { } double AbstractState::trivial_keyed_output(int key) { - if (get_debug_level()>=50) std::cout << format("AbstractState: keyed_output called for %s ",get_parameter_information(key,"short").c_str()) << std::endl; + if (get_debug_level()>=50) std::cout << format("AbstractState: keyed_output called for %s ",get_parameter_information(key,"short").c_str()) << std::endl; switch (key) { - case imolar_mass: + case imolar_mass: return molar_mass(); - case iT_min: + case iT_min: return Tmin(); - case iT_triple: + case iT_triple: return Ttriple(); - case iT_max: + case iT_max: return Tmax(); - case iP_max: - return pmax(); + case iP_max: + return pmax(); case iP_min: case iP_triple: return this->p_triple(); @@ -179,7 +179,7 @@ double AbstractState::trivial_keyed_output(int key) return get_reducing_state().T; case irhomolar_reducing: return get_reducing_state().rhomolar; - case iP_critical: + case iP_critical: return this->p_critical(); case iT_critical: return this->T_critical(); @@ -188,13 +188,13 @@ double AbstractState::trivial_keyed_output(int key) case irhomass_critical: return this->rhomolar_critical()*molar_mass(); - default: - throw ValueError(format("This input [%d: \"%s\"] is not valid for trivial_keyed_output",key,get_parameter_information(key,"short").c_str())); - } + default: + throw ValueError(format("This input [%d: \"%s\"] is not valid for trivial_keyed_output",key,get_parameter_information(key,"short").c_str())); + } } double AbstractState::keyed_output(int key) { - if (get_debug_level()>=50) std::cout << format("AbstractState: keyed_output called for %s ",get_parameter_information(key,"short").c_str()) << std::endl; + if (get_debug_level()>=50) std::cout << format("AbstractState: keyed_output called for %s ",get_parameter_information(key,"short").c_str()) << std::endl; // Handle trivial inputs if (is_trivial_parameter(key)) { @@ -366,25 +366,25 @@ void AbstractState::build_phase_envelope(const std::string &type) calc_phase_envelope(type); } double AbstractState::isothermal_compressibility(void){ - return 1.0/_rhomolar*first_partial_deriv(iDmolar, iP, iT); + return 1.0/_rhomolar*first_partial_deriv(iDmolar, iP, iT); } double AbstractState::isobaric_expansion_coefficient(void){ - return -1.0/pow(_rhomolar,2)*first_partial_deriv(iDmolar, iT, iP); + return -1.0/pow(_rhomolar,2)*first_partial_deriv(iDmolar, iT, iP); } double AbstractState::Bvirial(void){ return calc_Bvirial(); } double AbstractState::Cvirial(void){ return calc_Cvirial(); } double AbstractState::dBvirial_dT(void){ return calc_dBvirial_dT(); } double AbstractState::dCvirial_dT(void){ return calc_dCvirial_dT(); } -// // ---------------------------------------- -// // Smoothing functions for density -// // ---------------------------------------- -// /// A smoothed version of the derivative using a spline curve in the region of x=0 to x=xend -// virtual double AbstractState::drhodh_constp_smoothed(double xend); -// /// A smoothed version of the derivative using a spline curve in the region of x=0 to x=xend -// virtual double AbstractState::drhodp_consth_smoothed(double xend); -// /// Density corresponding to the smoothed derivatives in the region of x=0 to x=xend -// virtual void AbstractState::rho_smoothed(double xend, double *rho_spline, double *dsplinedh, double *dsplinedp); +// // ---------------------------------------- +// // Smoothing functions for density +// // ---------------------------------------- +// /// A smoothed version of the derivative using a spline curve in the region of x=0 to x=xend +// virtual double AbstractState::drhodh_constp_smoothed(double xend); +// /// A smoothed version of the derivative using a spline curve in the region of x=0 to x=xend +// virtual double AbstractState::drhodp_consth_smoothed(double xend); +// /// Density corresponding to the smoothed derivatives in the region of x=0 to x=xend +// virtual void AbstractState::rho_smoothed(double xend, double *rho_spline, double *dsplinedh, double *dsplinedp); } /* namespace CoolProp */ @@ -399,19 +399,19 @@ TEST_CASE("Check AbstractState","[AbstractState]") { CHECK_THROWS(shared_ptr Water(CoolProp::AbstractState::factory("DEFINITELY_A_BAD_BACKEND", "Water"))); } - SECTION("good backend - bad fluid") + SECTION("good backend - bad fluid") { CHECK_THROWS(shared_ptr Water(CoolProp::AbstractState::factory("HEOS", "DEFINITELY_A_BAD_FLUID"))); } - SECTION("good backend - helmholtz") + SECTION("good backend - helmholtz") { CHECK_NOTHROW(shared_ptr Water(CoolProp::AbstractState::factory("HEOS", "Water"))); } - SECTION("good backend - incomp") + SECTION("good backend - incomp") { CHECK_NOTHROW(shared_ptr Water(CoolProp::AbstractState::factory("INCOMP", "DEB"))); } - SECTION("good backend - REFPROP") + SECTION("good backend - REFPROP") { CHECK_NOTHROW(shared_ptr Water(CoolProp::AbstractState::factory("REFPROP", "Water"))); } diff --git a/src/Backends/Helmholtz/ExcessHEFunction.h b/src/Backends/Helmholtz/ExcessHEFunction.h index 4025dc07..2ad04534 100644 --- a/src/Backends/Helmholtz/ExcessHEFunction.h +++ b/src/Backends/Helmholtz/ExcessHEFunction.h @@ -18,17 +18,17 @@ typedef std::vector > STLMatrix; class DepartureFunction { public: - DepartureFunction(){}; - virtual ~DepartureFunction(){}; + DepartureFunction(){}; + virtual ~DepartureFunction(){}; - /// The excess Helmholtz energy of the binary pair - /// Pure-virtual function (must be implemented in derived class - virtual double alphar(double tau, double delta) = 0; - virtual double dalphar_dDelta(double tau, double delta) = 0; - virtual double d2alphar_dDelta2(double tau, double delta) = 0; - virtual double d2alphar_dDelta_dTau(double tau, double delta) = 0; - virtual double dalphar_dTau(double tau, double delta) = 0; - virtual double d2alphar_dTau2(double tau, double delta) = 0; + /// The excess Helmholtz energy of the binary pair + /// Pure-virtual function (must be implemented in derived class + virtual double alphar(double tau, double delta) = 0; + virtual double dalphar_dDelta(double tau, double delta) = 0; + virtual double d2alphar_dDelta2(double tau, double delta) = 0; + virtual double d2alphar_dDelta_dTau(double tau, double delta) = 0; + virtual double dalphar_dTau(double tau, double delta) = 0; + virtual double d2alphar_dTau2(double tau, double delta) = 0; }; /** \brief The departure function used by the GERG-2008 formulation @@ -42,10 +42,10 @@ public: class GERG2008DepartureFunction : public DepartureFunction { protected: - bool using_gaussian; - ResidualHelmholtzGeneralizedExponential phi; + bool using_gaussian; + ResidualHelmholtzGeneralizedExponential phi; public: - GERG2008DepartureFunction(){}; + GERG2008DepartureFunction(){}; GERG2008DepartureFunction(const std::vector &n,const std::vector &d,const std::vector &t, const std::vector &eta,const std::vector &epsilon,const std::vector &beta, const std::vector &gamma, std::size_t Npower) @@ -75,14 +75,14 @@ public: phi.add_GERG2008Gaussian(_n, _d, _t, _eta, _epsilon, _beta, _gamma); } }; - ~GERG2008DepartureFunction(){}; + ~GERG2008DepartureFunction(){}; double alphar(double tau, double delta){return phi.base(tau, delta);}; - double dalphar_dDelta(double tau, double delta){return phi.dDelta(tau, delta);}; - double d2alphar_dDelta_dTau(double tau, double delta){return phi.dDelta_dTau(tau, delta);}; - double dalphar_dTau(double tau, double delta){return phi.dTau(tau, delta);}; - double d2alphar_dDelta2(double tau, double delta){return phi.dDelta2(tau, delta);}; - double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; + double dalphar_dDelta(double tau, double delta){return phi.dDelta(tau, delta);}; + double d2alphar_dDelta_dTau(double tau, double delta){return phi.dDelta_dTau(tau, delta);}; + double dalphar_dTau(double tau, double delta){return phi.dTau(tau, delta);}; + double d2alphar_dDelta2(double tau, double delta){return phi.dDelta2(tau, delta);}; + double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; }; /** \brief A polynomial/exponential departure function @@ -96,9 +96,9 @@ public: class ExponentialDepartureFunction : public DepartureFunction { protected: - ResidualHelmholtzGeneralizedExponential phi; + ResidualHelmholtzGeneralizedExponential phi; public: - ExponentialDepartureFunction(){}; + ExponentialDepartureFunction(){}; ExponentialDepartureFunction(const std::vector &n, const std::vector &d, const std::vector &t, const std::vector &l) { @@ -108,14 +108,14 @@ public: std::vector _l(l.begin(), l.begin()+l.size()); phi.add_Power(_n, _d, _t, _l); }; - ~ExponentialDepartureFunction(){}; + ~ExponentialDepartureFunction(){}; double alphar(double tau, double delta){return phi.base(tau, delta);}; - double dalphar_dDelta(double tau, double delta){return phi.dDelta(tau, delta);}; - double d2alphar_dDelta_dTau(double tau, double delta){return phi.dDelta_dTau(tau, delta);}; - double dalphar_dTau(double tau, double delta){return phi.dTau(tau, delta);}; - double d2alphar_dDelta2(double tau, double delta){return phi.dDelta2(tau, delta);}; - double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; + double dalphar_dDelta(double tau, double delta){return phi.dDelta(tau, delta);}; + double d2alphar_dDelta_dTau(double tau, double delta){return phi.dDelta_dTau(tau, delta);}; + double dalphar_dTau(double tau, double delta){return phi.dTau(tau, delta);}; + double d2alphar_dDelta2(double tau, double delta){return phi.dDelta2(tau, delta);}; + double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; }; typedef shared_ptr DepartureFunctionPointer; @@ -123,12 +123,12 @@ typedef shared_ptr DepartureFunctionPointer; class ExcessTerm { public: - std::size_t N; - std::vector > DepartureFunctionMatrix; - std::vector > F; + std::size_t N; + std::vector > DepartureFunctionMatrix; + std::vector > F; ExcessTerm(){}; - ~ExcessTerm(){}; + ~ExcessTerm(){}; /// Resize the parts of this term void resize(std::size_t N){ @@ -137,127 +137,127 @@ public: DepartureFunctionMatrix.resize(N); for (std::size_t i = 0; i < N; ++i){ DepartureFunctionMatrix[i].resize(N); - } + } }; - double alphar(double tau, double delta, const std::vector &x) - { - double summer = 0; - for (std::size_t i = 0; i < N-1; i++) - { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->alphar(tau,delta); - } - } - return summer; - } - double dalphar_dDelta(double tau, double delta, const std::vector &x) - { - double summer = 0; - for (std::size_t i = 0; i < N-1; i++) - { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->dalphar_dDelta(tau,delta); - } - } - return summer; - } - double d2alphar_dDelta2(double tau, double delta, const std::vector &x) + double alphar(double tau, double delta, const std::vector &x) { double summer = 0; for (std::size_t i = 0; i < N-1; i++) { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dDelta2(tau,delta); - } + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->alphar(tau,delta); + } } return summer; - }; - double d2alphar_dDelta_dTau(double tau, double delta, const std::vector &x) + } + double dalphar_dDelta(double tau, double delta, const std::vector &x) { double summer = 0; for (std::size_t i = 0; i < N-1; i++) { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dDelta_dTau(tau,delta); - } + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->dalphar_dDelta(tau,delta); + } } return summer; } - double dalphar_dTau(double tau, double delta, const std::vector &x) + double d2alphar_dDelta2(double tau, double delta, const std::vector &x) { double summer = 0; - for (std::size_t i = 0; i < N-1; i++) - { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->dalphar_dTau(tau,delta); - } - } - return summer; + for (std::size_t i = 0; i < N-1; i++) + { + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dDelta2(tau,delta); + } + } + return summer; }; - double d2alphar_dTau2(double tau, double delta, const std::vector &x) + double d2alphar_dDelta_dTau(double tau, double delta, const std::vector &x) { double summer = 0; - for (std::size_t i = 0; i < N-1; i++) - { - for (std::size_t j = i + 1; j < N; j++) - { - summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dTau2(tau,delta); - } - } - return summer; + for (std::size_t i = 0; i < N-1; i++) + { + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dDelta_dTau(tau,delta); + } + } + return summer; + } + double dalphar_dTau(double tau, double delta, const std::vector &x) + { + double summer = 0; + for (std::size_t i = 0; i < N-1; i++) + { + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->dalphar_dTau(tau,delta); + } + } + return summer; }; - double dalphar_dxi(double tau, double delta, const std::vector &x, std::size_t i) + double d2alphar_dTau2(double tau, double delta, const std::vector &x) { double summer = 0; - for (std::size_t k = 0; k < N; k++) - { - if (i != k) - { - summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->alphar(tau,delta); - } - } - return summer; + for (std::size_t i = 0; i < N-1; i++) + { + for (std::size_t j = i + 1; j < N; j++) + { + summer += x[i]*x[j]*F[i][j]*DepartureFunctionMatrix[i][j]->d2alphar_dTau2(tau,delta); + } + } + return summer; + }; + double dalphar_dxi(double tau, double delta, const std::vector &x, std::size_t i) + { + double summer = 0; + for (std::size_t k = 0; k < N; k++) + { + if (i != k) + { + summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->alphar(tau,delta); + } + } + return summer; }; double d2alphardxidxj(double tau, double delta, const std::vector &x, std::size_t i, std::size_t j) { if (i != j) - { - return F[i][j]*DepartureFunctionMatrix[i][j]->alphar(tau,delta); - } - else - { - return 0; - } + { + return F[i][j]*DepartureFunctionMatrix[i][j]->alphar(tau,delta); + } + else + { + return 0; + } }; - double d2alphar_dxi_dTau(double tau, double delta, const std::vector &x, std::size_t i) + double d2alphar_dxi_dTau(double tau, double delta, const std::vector &x, std::size_t i) { double summer = 0; - for (std::size_t k = 0; k < N; k++) - { - if (i != k) - { - summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->dalphar_dTau(tau,delta); - } - } - return summer; + for (std::size_t k = 0; k < N; k++) + { + if (i != k) + { + summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->dalphar_dTau(tau,delta); + } + } + return summer; }; - double d2alphar_dxi_dDelta(double tau, double delta, const std::vector &x, std::size_t i) + double d2alphar_dxi_dDelta(double tau, double delta, const std::vector &x, std::size_t i) { double summer = 0; - for (std::size_t k = 0; k < N; k++) - { - if (i != k) - { - summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->dalphar_dDelta(tau,delta); - } - } - return summer; + for (std::size_t k = 0; k < N; k++) + { + if (i != k) + { + summer += x[k]*F[i][k]*DepartureFunctionMatrix[i][k]->dalphar_dDelta(tau,delta); + } + } + return summer; }; }; diff --git a/src/Backends/Helmholtz/FlashRoutines.cpp b/src/Backends/Helmholtz/FlashRoutines.cpp index e676bdf1..6148fd62 100644 --- a/src/Backends/Helmholtz/FlashRoutines.cpp +++ b/src/Backends/Helmholtz/FlashRoutines.cpp @@ -8,25 +8,25 @@ namespace CoolProp{ template T g_RachfordRice(const std::vector &z, const std::vector &lnK, T beta) { - // g function from Rachford-Rice - T summer = 0; - for (std::size_t i = 0; i < z.size(); i++) - { - T Ki = exp(lnK[i]); - summer += z[i]*(Ki-1)/(1-beta+beta*Ki); - } - return summer; + // g function from Rachford-Rice + T summer = 0; + for (std::size_t i = 0; i < z.size(); i++) + { + T Ki = exp(lnK[i]); + summer += z[i]*(Ki-1)/(1-beta+beta*Ki); + } + return summer; } template T dgdbeta_RachfordRice(const std::vector &z, const std::vector &lnK, T beta) { - // derivative of g function from Rachford-Rice with respect to beta - T summer = 0; - for (std::size_t i = 0; i < z.size(); i++) - { - T Ki = exp(lnK[i]); - summer += -z[i]*pow((Ki-1)/(1-beta+beta*Ki),2); - } - return summer; + // derivative of g function from Rachford-Rice with respect to beta + T summer = 0; + for (std::size_t i = 0; i < z.size(); i++) + { + T Ki = exp(lnK[i]); + summer += -z[i]*pow((Ki-1)/(1-beta+beta*Ki),2); + } + return summer; } void FlashRoutines::PT_flash_mixtures(HelmholtzEOSMixtureBackend &HEOS) @@ -104,8 +104,8 @@ void FlashRoutines::PT_flash_mixtures(HelmholtzEOSMixtureBackend &HEOS) } void FlashRoutines::PT_flash(HelmholtzEOSMixtureBackend &HEOS) { - if (HEOS.imposed_phase_index == iphase_not_imposed) // If no phase index is imposed (see set_components function) - { + if (HEOS.imposed_phase_index == iphase_not_imposed) // If no phase index is imposed (see set_components function) + { if (HEOS.is_pure_or_pseudopure) { // At very low temperature (near the triple point temp), the isotherms are VERY steep @@ -127,14 +127,14 @@ void FlashRoutines::PT_flash(HelmholtzEOSMixtureBackend &HEOS) throw ValueError("twophase not implemented yet"); } } - else{ + else{ PT_flash_mixtures(HEOS); } - } - - // Find density - HEOS._rhomolar = HEOS.solver_rho_Tp(HEOS._T, HEOS._p); - HEOS._Q = -1; + } + + // Find density + HEOS._rhomolar = HEOS.solver_rho_Tp(HEOS._T, HEOS._p); + HEOS._Q = -1; } void FlashRoutines::HQ_flash(HelmholtzEOSMixtureBackend &HEOS, long double Tguess) { @@ -212,15 +212,15 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS) long double T = HEOS._T; if (HEOS.is_pure_or_pseudopure) { - // The maximum possible saturation temperature - // Critical point for pure fluids, slightly different for pseudo-pure, very different for mixtures - long double Tmax_sat = HEOS.calc_Tmax_sat() + 1e-13; - - // Check what the minimum limits for the equation of state are - long double Tmin_satL, Tmin_satV, Tmin_sat; - HEOS.calc_Tmin_sat(Tmin_satL, Tmin_satV); - Tmin_sat = std::max(Tmin_satL, Tmin_satV) - 1e-13; - + // The maximum possible saturation temperature + // Critical point for pure fluids, slightly different for pseudo-pure, very different for mixtures + long double Tmax_sat = HEOS.calc_Tmax_sat() + 1e-13; + + // Check what the minimum limits for the equation of state are + long double Tmin_satL, Tmin_satV, Tmin_sat; + HEOS.calc_Tmin_sat(Tmin_satL, Tmin_satV); + Tmin_sat = std::max(Tmin_satL, Tmin_satV) - 1e-13; + // Get a reference to keep the code a bit cleaner CriticalRegionSplines &splines = HEOS.components[0]->pEOS->critical_region_splines; @@ -232,8 +232,8 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS) HEOS._p = HEOS.SatL->p(); } else if (!is_in_closed_range(Tmin_sat, Tmax_sat, T)){ - throw ValueError(format("Temperature to QT_flash [%0.8Lg K] must be in range [%0.8Lg K, %0.8Lg K]", T, Tmin_sat, Tmax_sat)); - } + throw ValueError(format("Temperature to QT_flash [%0.8Lg K] must be in range [%0.8Lg K, %0.8Lg K]", T, Tmin_sat, Tmax_sat)); + } else if (get_config_bool(CRITICAL_SPLINES_ENABLED) && splines.enabled && HEOS._T > splines.T_min){ double rhoL = _HUGE, rhoV = _HUGE; // Use critical region spline if it has it and temperature is in its range @@ -248,7 +248,7 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS) // Set some imput options SaturationSolvers::saturation_T_pure_options options; options.use_guesses = false; - double increment = 0.2; + double increment = 0.2; try{ for (double omega = 1.0; omega > 0; omega -= increment){ try{ @@ -401,8 +401,8 @@ void FlashRoutines::PQ_flash(HelmholtzEOSMixtureBackend &HEOS) options.specified_variable = SaturationSolvers::saturation_PHSU_pure_options::IMPOSED_PL; // Use logarithm of delta as independent variables options.use_logdelta = false; - - double increment = 0.4; + + double increment = 0.4; try{ for (double omega = 1.0; omega > 0; omega -= increment){ @@ -929,7 +929,7 @@ void FlashRoutines::HSU_P_flash_singlephase_Brent(HelmholtzEOSMixtureBackend &HE { if (!ValidNumber(HEOS._p)){throw ValueError("value for p in HSU_P_flash_singlephase_Brent is invalid");}; if (!ValidNumber(value)){throw ValueError("value for other in HSU_P_flash_singlephase_Brent is invalid");}; - class solver_resid : public FuncWrapper1D + class solver_resid : public FuncWrapper1D { public: @@ -949,20 +949,20 @@ void FlashRoutines::HSU_P_flash_singlephase_Brent(HelmholtzEOSMixtureBackend &HE }; double call(double T){ - this->T = T; + this->T = T; - // Run the solver with T,P as inputs; - HEOS->update(PT_INPUTS, p, T); - + // Run the solver with T,P as inputs; + HEOS->update(PT_INPUTS, p, T); + rhomolar = HEOS->rhomolar(); HEOS->update(DmolarT_INPUTS, rhomolar, T); - // Get the value of the desired variable - eos = HEOS->keyed_output(other); + // Get the value of the desired variable + eos = HEOS->keyed_output(other); pp = HEOS->p(); - // Difference between the two is to be driven to zero + // Difference between the two is to be driven to zero r = eos - value; - + // Store values for later use if there are errors if (iter == 0){ r0 = r; T0 = T; eos0 = eos; @@ -979,9 +979,9 @@ void FlashRoutines::HSU_P_flash_singlephase_Brent(HelmholtzEOSMixtureBackend &HE return r; }; }; - solver_resid resid(&HEOS, HEOS._p, value, other); - - std::string errstr; + solver_resid resid(&HEOS, HEOS._p, value, other); + + std::string errstr; try{ Brent(resid, Tmin, Tmax, DBL_EPSILON, 1e-12, 100, errstr); // Un-specify the phase of the fluid @@ -1036,8 +1036,8 @@ void FlashRoutines::HSU_P_flash(HelmholtzEOSMixtureBackend &HEOS, parameters oth // Find the phase, while updating all internal variables possible HEOS.p_phase_determination_pure_or_pseudopure(other, value, saturation_called); - if (HEOS.isHomogeneousPhase()) - { + if (HEOS.isHomogeneousPhase()) + { // Now we use the single-phase solver to find T,rho given P,Y using a // bounded 1D solver by adjusting T and using given value of p long double Tmin, Tmax; @@ -1052,14 +1052,14 @@ void FlashRoutines::HSU_P_flash(HelmholtzEOSMixtureBackend &HEOS, parameters oth case iphase_liquid: { if (saturation_called){ Tmax = HEOS.SatL->T();}else{Tmax = HEOS._TLanc.pt();} - + // Sometimes the minimum pressure for the melting line is a bit above the triple point pressure - if (HEOS.has_melting_line() && HEOS._p > HEOS.calc_melting_line(iP_min, -1, -1)){ + if (HEOS.has_melting_line() && HEOS._p > HEOS.calc_melting_line(iP_min, -1, -1)){ Tmin = HEOS.calc_melting_line(iT, iP, HEOS._p)-1e-3; - } - else{ - Tmin = HEOS.Tmin()-1e-3; - } + } + else{ + Tmin = HEOS.Tmin()-1e-3; + } break; } case iphase_supercritical_liquid: @@ -1069,11 +1069,11 @@ void FlashRoutines::HSU_P_flash(HelmholtzEOSMixtureBackend &HEOS, parameters oth Tmax = 1.5*HEOS.Tmax(); // Sometimes the minimum pressure for the melting line is a bit above the triple point pressure if (HEOS.has_melting_line() && HEOS._p > HEOS.calc_melting_line(iP_min, -1, -1)){ - Tmin = HEOS.calc_melting_line(iT, iP, HEOS._p)-1e-3; - } - else{ - Tmin = HEOS.Tmin()-1e-3; - } + Tmin = HEOS.calc_melting_line(iT, iP, HEOS._p)-1e-3; + } + else{ + Tmin = HEOS.Tmin()-1e-3; + } break; } default: @@ -1085,8 +1085,8 @@ void FlashRoutines::HSU_P_flash(HelmholtzEOSMixtureBackend &HEOS, parameters oth catch(std::exception &e){ throw ValueError(format("unable to solve 1phase PY flash with Tmin=%Lg, Tmax=%Lg due to error: %s",Tmin, Tmax, e.what())); } - HEOS._Q = -1; - } + HEOS._Q = -1; + } } else { diff --git a/src/Backends/Helmholtz/FlashRoutines.h b/src/Backends/Helmholtz/FlashRoutines.h index 2b53eb7c..c1cdc088 100644 --- a/src/Backends/Helmholtz/FlashRoutines.h +++ b/src/Backends/Helmholtz/FlashRoutines.h @@ -75,8 +75,8 @@ public: /// @param T0 The initial guess value for the temperature [K] /// @param rhomolar0 The initial guess value for the density [mol/m^3] static void HSU_P_flash_singlephase_Newton(HelmholtzEOSMixtureBackend &HEOS, parameters other, long double T0, long double rhomolar0); - - /// The single-phase flash routine for the pairs (P,H), (P,S), and (P,U). Similar analysis is needed + + /// The single-phase flash routine for the pairs (P,H), (P,S), and (P,U). Similar analysis is needed /// @param HEOS The HelmholtzEOSMixtureBackend to be used /// @param other The index for the other input from CoolProp::parameters; allowed values are iHmolar, iSmolar, iUmolar /// @param value The value of the other input diff --git a/src/Backends/Helmholtz/Fluids/Ancillaries.cpp b/src/Backends/Helmholtz/Fluids/Ancillaries.cpp index 683f2df1..cd7b6690 100644 --- a/src/Backends/Helmholtz/Fluids/Ancillaries.cpp +++ b/src/Backends/Helmholtz/Fluids/Ancillaries.cpp @@ -13,12 +13,12 @@ namespace CoolProp{ SaturationAncillaryFunction::SaturationAncillaryFunction(rapidjson::Value &json_code) { - std::string type = cpjson::get_string(json_code,"type"); - if (!type.compare("rational_polynomial")) - { - num_coeffs = vec_to_eigen(cpjson::get_double_array(json_code["A"])); - den_coeffs = vec_to_eigen(cpjson::get_double_array(json_code["B"])); - max_abs_error = cpjson::get_double(json_code,"max_abs_error"); + std::string type = cpjson::get_string(json_code,"type"); + if (!type.compare("rational_polynomial")) + { + num_coeffs = vec_to_eigen(cpjson::get_double_array(json_code["A"])); + den_coeffs = vec_to_eigen(cpjson::get_double_array(json_code["B"])); + max_abs_error = cpjson::get_double(json_code,"max_abs_error"); try{ Tmin = cpjson::get_double(json_code,"Tmin"); Tmax = cpjson::get_double(json_code,"Tmax"); @@ -27,103 +27,103 @@ SaturationAncillaryFunction::SaturationAncillaryFunction(rapidjson::Value &json_ Tmin = _HUGE; Tmax = _HUGE; } - } - else - { - n = cpjson::get_double_array(json_code["n"]); - t = cpjson::get_double_array(json_code["t"]); - Tmin = cpjson::get_double(json_code,"Tmin"); - Tmax = cpjson::get_double(json_code,"Tmax"); - reducing_value = cpjson::get_double(json_code,"reducing_value"); - using_tau_r = cpjson::get_bool(json_code,"using_tau_r"); - T_r = cpjson::get_double(json_code,"T_r"); - } - - if (!type.compare("rational_polynomial")) - this->type = TYPE_RATIONAL_POLYNOMIAL; - else if (!type.compare("rhoLnoexp")) - this->type = TYPE_NOT_EXPONENTIAL; - else - this->type = TYPE_EXPONENTIAL; - this->N = n.size(); - s = n; + } + else + { + n = cpjson::get_double_array(json_code["n"]); + t = cpjson::get_double_array(json_code["t"]); + Tmin = cpjson::get_double(json_code,"Tmin"); + Tmax = cpjson::get_double(json_code,"Tmax"); + reducing_value = cpjson::get_double(json_code,"reducing_value"); + using_tau_r = cpjson::get_bool(json_code,"using_tau_r"); + T_r = cpjson::get_double(json_code,"T_r"); + } + + if (!type.compare("rational_polynomial")) + this->type = TYPE_RATIONAL_POLYNOMIAL; + else if (!type.compare("rhoLnoexp")) + this->type = TYPE_NOT_EXPONENTIAL; + else + this->type = TYPE_EXPONENTIAL; + this->N = n.size(); + s = n; }; double SaturationAncillaryFunction::evaluate(double T) { - if (type == TYPE_NOT_SET) - { - throw ValueError(format("type not set")); - } - else if (type == TYPE_RATIONAL_POLYNOMIAL) - { - Polynomial2D poly; - return poly.evaluate(num_coeffs, T)/poly.evaluate(den_coeffs, T); - } - else - { - double THETA = 1-T/T_r; + if (type == TYPE_NOT_SET) + { + throw ValueError(format("type not set")); + } + else if (type == TYPE_RATIONAL_POLYNOMIAL) + { + Polynomial2D poly; + return poly.evaluate(num_coeffs, T)/poly.evaluate(den_coeffs, T); + } + else + { + double THETA = 1-T/T_r; - for (std::size_t i = 0; i < N; ++i) - { - s[i] = n[i]*pow(THETA, t[i]); - } - double summer = std::accumulate(s.begin(), s.end(), 0.0); + for (std::size_t i = 0; i < N; ++i) + { + s[i] = n[i]*pow(THETA, t[i]); + } + double summer = std::accumulate(s.begin(), s.end(), 0.0); - if (type == TYPE_NOT_EXPONENTIAL) - { - return reducing_value*(1+summer); - } - else - { - double tau_r_value; - if (using_tau_r) - tau_r_value = T_r/T; - else - tau_r_value = 1.0; - return reducing_value*exp(tau_r_value*summer); - } - } + if (type == TYPE_NOT_EXPONENTIAL) + { + return reducing_value*(1+summer); + } + else + { + double tau_r_value; + if (using_tau_r) + tau_r_value = T_r/T; + else + tau_r_value = 1.0; + return reducing_value*exp(tau_r_value*summer); + } + } } double SaturationAncillaryFunction::invert(double value, double min_bound, double max_bound) { - // Invert the ancillary curve to get the temperature as a function of the output variable - // Define the residual to be driven to zero - class solver_resid : public FuncWrapper1D - { - public: - int other; - SaturationAncillaryFunction *anc; - long double T, value, r, current_value; + // Invert the ancillary curve to get the temperature as a function of the output variable + // Define the residual to be driven to zero + class solver_resid : public FuncWrapper1D + { + public: + int other; + SaturationAncillaryFunction *anc; + long double T, value, r, current_value; - solver_resid(SaturationAncillaryFunction *anc, long double value) : anc(anc), value(value){}; + solver_resid(SaturationAncillaryFunction *anc, long double value) : anc(anc), value(value){}; - double call(double T){ - this->T = T; - current_value = anc->evaluate(T); - r = current_value - value; - return r; - }; - }; - solver_resid resid(this, value); - std::string errstring; + double call(double T){ + this->T = T; + current_value = anc->evaluate(T); + r = current_value - value; + return r; + }; + }; + solver_resid resid(this, value); + std::string errstring; if (min_bound < 0){ min_bound = Tmin-0.01;} if (max_bound < 0){ max_bound = Tmax;} - try{ + try{ // Safe to expand the domain a little bit to lower temperature, absolutely cannot exceed Tmax // because then you get (negative number)^(double) which is undefined. - return Brent(resid,min_bound,max_bound,DBL_EPSILON,1e-10,100,errstring); - } - catch(std::exception &e){ - return Secant(resid,max_bound, -0.01, 1e-12, 100, errstring); - } + return Brent(resid,min_bound,max_bound,DBL_EPSILON,1e-10,100,errstring); + } + catch(std::exception &e){ + return Secant(resid,max_bound, -0.01, 1e-12, 100, errstring); + } } void MeltingLineVariables::set_limits(void) { - if (type == MELTING_LINE_SIMON_TYPE){ - + if (type == MELTING_LINE_SIMON_TYPE){ + // Fill in the min and max pressures for each part for (std::size_t i = 0; i < simon.parts.size(); ++i){ MeltingLinePiecewiseSimonSegment &part = simon.parts[i]; @@ -131,11 +131,11 @@ void MeltingLineVariables::set_limits(void) part.p_max = part.p_0 + part.a*(pow(part.T_max/part.T_0,part.c)-1); } pmin = simon.parts.front().p_min; - pmax = simon.parts.back().p_max; + pmax = simon.parts.back().p_max; Tmin = simon.parts.front().T_min; - Tmax = simon.parts.back().T_max; - } - else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE){ + Tmax = simon.parts.back().T_max; + } + else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE){ // Fill in the min and max pressures for each part for (std::size_t i = 0; i < polynomial_in_Tr.parts.size(); ++i){ MeltingLinePiecewisePolynomialInTrSegment &part = polynomial_in_Tr.parts[i]; @@ -144,10 +144,10 @@ void MeltingLineVariables::set_limits(void) } Tmin = polynomial_in_Tr.parts.front().T_min; pmin = polynomial_in_Tr.parts.front().p_min; - Tmax = polynomial_in_Tr.parts.back().T_max; + Tmax = polynomial_in_Tr.parts.back().T_max; pmax = polynomial_in_Tr.parts.back().p_max; - } - else if (type == MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE){ + } + else if (type == MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE){ // Fill in the min and max pressures for each part for (std::size_t i = 0; i < polynomial_in_Theta.parts.size(); ++i){ MeltingLinePiecewisePolynomialInThetaSegment &part = polynomial_in_Theta.parts[i]; @@ -156,90 +156,90 @@ void MeltingLineVariables::set_limits(void) } Tmin = polynomial_in_Theta.parts.front().T_min; pmin = polynomial_in_Theta.parts.front().p_min; - Tmax = polynomial_in_Theta.parts.back().T_max; + Tmax = polynomial_in_Theta.parts.back().T_max; pmax = polynomial_in_Theta.parts.back().p_max; - } - else{ - throw ValueError("only Simon supported now"); - } + } + else{ + throw ValueError("only Simon supported now"); + } } long double MeltingLineVariables::evaluate(int OF, int GIVEN, long double value) { - if (type == MELTING_LINE_NOT_SET){throw ValueError("Melting line curve not set");} + if (type == MELTING_LINE_NOT_SET){throw ValueError("Melting line curve not set");} if (OF == iP_max){ return pmax;} else if (OF == iP_min){ return pmin;} else if (OF == iT_max){ return Tmax;} else if (OF == iT_min){ return Tmin;} - else if (OF == iP && GIVEN == iT){ - long double T = value; - if (type == MELTING_LINE_SIMON_TYPE){ - // Need to find the right segment - for (std::size_t i = 0; i < simon.parts.size(); ++i){ - MeltingLinePiecewiseSimonSegment &part = simon.parts[i]; - if (is_in_closed_range(part.T_min, part.T_max, T)){ - return part.p_0 + part.a*(pow(T/part.T_0,part.c)-1); - } - } - throw ValueError("unable to calculate melting line (p,T) for Simon curve"); - } - else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE){ - // Need to find the right segment - for (std::size_t i = 0; i < polynomial_in_Tr.parts.size(); ++i){ - MeltingLinePiecewisePolynomialInTrSegment &part = polynomial_in_Tr.parts[i]; - if (is_in_closed_range(part.T_min, part.T_max, T)){ - return part.evaluate(T); - } - } - throw ValueError("unable to calculate melting line (p,T) for polynomial_in_Tr curve"); - } - else if (type == MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE){ - // Need to find the right segment - for (std::size_t i = 0; i < polynomial_in_Theta.parts.size(); ++i){ - MeltingLinePiecewisePolynomialInThetaSegment &part = polynomial_in_Theta.parts[i]; - if (is_in_closed_range(part.T_min, part.T_max, T)){ - return part.evaluate(T); - } - } - throw ValueError("unable to calculate melting line (p,T) for polynomial_in_Theta curve"); - } - else{ - throw ValueError(format("Invalid melting line type [%d]",type)); - } - } - else{ - if (type == MELTING_LINE_SIMON_TYPE){ - // Need to find the right segment - for (std::size_t i = 0; i < simon.parts.size(); ++i){ - MeltingLinePiecewiseSimonSegment &part = simon.parts[i]; - // p = part.p_0 + part.a*(pow(T/part.T_0,part.c)-1); - long double T = pow((value-part.p_0)/part.a+1,1/part.c)*part.T_0; - if (T >= part.T_0 && T <= part.T_max){ - return T; - } - } - throw ValueError(format("unable to calculate melting line T(p) for Simon curve for p=%Lg; bounds are %Lg,%Lg Pa", value, pmin, pmax)); - } - else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE) - { + else if (OF == iP && GIVEN == iT){ + long double T = value; + if (type == MELTING_LINE_SIMON_TYPE){ + // Need to find the right segment + for (std::size_t i = 0; i < simon.parts.size(); ++i){ + MeltingLinePiecewiseSimonSegment &part = simon.parts[i]; + if (is_in_closed_range(part.T_min, part.T_max, T)){ + return part.p_0 + part.a*(pow(T/part.T_0,part.c)-1); + } + } + throw ValueError("unable to calculate melting line (p,T) for Simon curve"); + } + else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE){ + // Need to find the right segment + for (std::size_t i = 0; i < polynomial_in_Tr.parts.size(); ++i){ + MeltingLinePiecewisePolynomialInTrSegment &part = polynomial_in_Tr.parts[i]; + if (is_in_closed_range(part.T_min, part.T_max, T)){ + return part.evaluate(T); + } + } + throw ValueError("unable to calculate melting line (p,T) for polynomial_in_Tr curve"); + } + else if (type == MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE){ + // Need to find the right segment + for (std::size_t i = 0; i < polynomial_in_Theta.parts.size(); ++i){ + MeltingLinePiecewisePolynomialInThetaSegment &part = polynomial_in_Theta.parts[i]; + if (is_in_closed_range(part.T_min, part.T_max, T)){ + return part.evaluate(T); + } + } + throw ValueError("unable to calculate melting line (p,T) for polynomial_in_Theta curve"); + } + else{ + throw ValueError(format("Invalid melting line type [%d]",type)); + } + } + else{ + if (type == MELTING_LINE_SIMON_TYPE){ + // Need to find the right segment + for (std::size_t i = 0; i < simon.parts.size(); ++i){ + MeltingLinePiecewiseSimonSegment &part = simon.parts[i]; + // p = part.p_0 + part.a*(pow(T/part.T_0,part.c)-1); + long double T = pow((value-part.p_0)/part.a+1,1/part.c)*part.T_0; + if (T >= part.T_0 && T <= part.T_max){ + return T; + } + } + throw ValueError(format("unable to calculate melting line T(p) for Simon curve for p=%Lg; bounds are %Lg,%Lg Pa", value, pmin, pmax)); + } + else if (type == MELTING_LINE_POLYNOMIAL_IN_TR_TYPE) + { class solver_resid : public FuncWrapper1D - { - public: - MeltingLinePiecewisePolynomialInTrSegment *part; - long double r, given_p, calc_p, T; - solver_resid(MeltingLinePiecewisePolynomialInTrSegment *part, long double p) : part(part), given_p(p){}; - double call(double T){ + { + public: + MeltingLinePiecewisePolynomialInTrSegment *part; + long double r, given_p, calc_p, T; + solver_resid(MeltingLinePiecewisePolynomialInTrSegment *part, long double p) : part(part), given_p(p){}; + double call(double T){ - this->T = T; + this->T = T; - calc_p = part->evaluate(T); + calc_p = part->evaluate(T); - // Difference between the two is to be driven to zero - r = given_p - calc_p; + // Difference between the two is to be driven to zero + r = given_p - calc_p; - return r; - }; - }; + return r; + }; + }; // Need to find the right segment for (std::size_t i = 0; i < polynomial_in_Tr.parts.size(); ++i){ @@ -257,23 +257,23 @@ long double MeltingLineVariables::evaluate(int OF, int GIVEN, long double value) { class solver_resid : public FuncWrapper1D - { - public: - MeltingLinePiecewisePolynomialInThetaSegment *part; - long double r, given_p, calc_p, T; - solver_resid(MeltingLinePiecewisePolynomialInThetaSegment *part, long double p) : part(part), given_p(p){}; - double call(double T){ + { + public: + MeltingLinePiecewisePolynomialInThetaSegment *part; + long double r, given_p, calc_p, T; + solver_resid(MeltingLinePiecewisePolynomialInThetaSegment *part, long double p) : part(part), given_p(p){}; + double call(double T){ - this->T = T; + this->T = T; - calc_p = part->evaluate(T); + calc_p = part->evaluate(T); - // Difference between the two is to be driven to zero - r = given_p - calc_p; + // Difference between the two is to be driven to zero + r = given_p - calc_p; - return r; - }; - }; + return r; + }; + }; // Need to find the right segment for (std::size_t i = 0; i < polynomial_in_Theta.parts.size(); ++i){ @@ -287,11 +287,11 @@ long double MeltingLineVariables::evaluate(int OF, int GIVEN, long double value) } throw ValueError(format("unable to calculate melting line T(p) for polynomial_in_Theta curve for p=%Lg; bounds are %Lg,%Lg Pa", value, pmin, pmax)); - } - else{ - throw ValueError(format("Invalid melting line type T(p) [%d]",type)); - } - } + } + else{ + throw ValueError(format("Invalid melting line type T(p) [%d]",type)); + } + } } }; /* namespace CoolProp */ @@ -303,7 +303,7 @@ TEST_CASE("Water melting line", "[melting]") int iT = CoolProp::iT, iP = CoolProp::iP; SECTION("Ice Ih-liquid") { - double actual = AS->melting_line(iT, iP, 138.268e6); + double actual = AS->melting_line(iT, iP, 138.268e6); double expected = 260.0; CAPTURE(actual); CAPTURE(expected); @@ -311,7 +311,7 @@ TEST_CASE("Water melting line", "[melting]") } SECTION("Ice III-liquid") { - double actual = AS->melting_line(iT, iP, 268.685e6); + double actual = AS->melting_line(iT, iP, 268.685e6); double expected = 254; CAPTURE(actual); CAPTURE(expected); @@ -319,7 +319,7 @@ TEST_CASE("Water melting line", "[melting]") } SECTION("Ice V-liquid") { - double actual = AS->melting_line(iT, iP, 479.640e6); + double actual = AS->melting_line(iT, iP, 479.640e6); double expected = 265; CAPTURE(actual); CAPTURE(expected); @@ -327,7 +327,7 @@ TEST_CASE("Water melting line", "[melting]") } SECTION("Ice VI-liquid") { - double actual = AS->melting_line(iT, iP, 1356.76e6); + double actual = AS->melting_line(iT, iP, 1356.76e6); double expected = 320; CAPTURE(actual); CAPTURE(expected); diff --git a/src/Backends/Helmholtz/Fluids/FluidLibrary.cpp b/src/Backends/Helmholtz/Fluids/FluidLibrary.cpp index 9ddda4d3..481324ea 100644 --- a/src/Backends/Helmholtz/Fluids/FluidLibrary.cpp +++ b/src/Backends/Helmholtz/Fluids/FluidLibrary.cpp @@ -8,10 +8,10 @@ static JSONFluidLibrary library; void load() { - rapidjson::Document dd; + rapidjson::Document dd; // This json formatted string comes from the all_fluids_JSON.h header which is a C++-escaped version of the JSON file dd.Parse<0>(all_fluids_JSON.c_str()); - if (dd.HasParseError()){ + if (dd.HasParseError()){ throw ValueError("Unable to load all_fluids.json"); } else{ try{library.add_many(dd);}catch(std::exception &e){std::cout << e.what() << std::endl;} @@ -19,8 +19,8 @@ void load() } JSONFluidLibrary & get_library(void){ - if (library.is_empty()){ load(); } - return library; + if (library.is_empty()){ load(); } + return library; } CoolPropFluid& get_fluid(std::string fluid_string){ diff --git a/src/Backends/Helmholtz/Fluids/FluidLibrary.h b/src/Backends/Helmholtz/Fluids/FluidLibrary.h index f61871f4..8569332b 100644 --- a/src/Backends/Helmholtz/Fluids/FluidLibrary.h +++ b/src/Backends/Helmholtz/Fluids/FluidLibrary.h @@ -886,7 +886,7 @@ protected: if (!type.compare("Simon")) { rapidjson::Value &parts = melting_line["parts"]; - fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_SIMON_TYPE; + fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_SIMON_TYPE; for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) { MeltingLinePiecewiseSimonSegment data; @@ -902,7 +902,7 @@ protected: else if (!type.compare("polynomial_in_Tr")) { rapidjson::Value &parts = melting_line["parts"]; - fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_TR_TYPE; + fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_TR_TYPE; for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) { MeltingLinePiecewisePolynomialInTrSegment data; @@ -918,7 +918,7 @@ protected: else if (!type.compare("polynomial_in_Theta")) { rapidjson::Value &parts = melting_line["parts"]; - fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE; + fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE; for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr) { MeltingLinePiecewisePolynomialInThetaSegment data; @@ -934,8 +934,8 @@ protected: else{ throw ValueError(format("melting line type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str())); } - // Set the limits for the melting line curve - fluid.ancillaries.melting_line.set_limits(); + // Set the limits for the melting line curve + fluid.ancillaries.melting_line.set_limits(); } else{ throw ValueError(format("melting line does not have \"type\" for fluid %s", fluid.name.c_str())); @@ -1151,9 +1151,9 @@ public: for (std::size_t i = 0; i < fluid.aliases.size(); ++i) { string_to_index_map[fluid.aliases[i]] = index; - - // Add uppercase alias for EES compatibility - string_to_index_map[upper(fluid.aliases[i])] = index; + + // Add uppercase alias for EES compatibility + string_to_index_map[upper(fluid.aliases[i])] = index; } if (get_debug_level() > 5){ std::cout << format("Loaded.\n"); } diff --git a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp index 13eeba91..9126fa20 100644 --- a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp +++ b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp @@ -555,65 +555,65 @@ long double HelmholtzEOSMixtureBackend::calc_rhomolar_critical(void) } long double HelmholtzEOSMixtureBackend::calc_pmax_sat(void) { - if (is_pure_or_pseudopure) - { - if (components[0]->pEOS->pseudo_pure) - { - return components[0]->pEOS->max_sat_p.p; - } - else{ - return p_critical(); - } - } - else{ - throw ValueError("calc_pmax_sat not yet defined for mixtures"); - } + if (is_pure_or_pseudopure) + { + if (components[0]->pEOS->pseudo_pure) + { + return components[0]->pEOS->max_sat_p.p; + } + else{ + return p_critical(); + } + } + else{ + throw ValueError("calc_pmax_sat not yet defined for mixtures"); + } } long double HelmholtzEOSMixtureBackend::calc_Tmax_sat(void) { - if (is_pure_or_pseudopure) - { - if (components[0]->pEOS->pseudo_pure) - { - return components[0]->pEOS->max_sat_T.T; - } - else{ - return T_critical(); - } - } - else{ - throw ValueError("calc_Tmax_sat not yet defined for mixtures"); - } + if (is_pure_or_pseudopure) + { + if (components[0]->pEOS->pseudo_pure) + { + return components[0]->pEOS->max_sat_T.T; + } + else{ + return T_critical(); + } + } + else{ + throw ValueError("calc_Tmax_sat not yet defined for mixtures"); + } } void HelmholtzEOSMixtureBackend::calc_Tmin_sat(long double &Tmin_satL, long double &Tmin_satV) { - if (is_pure_or_pseudopure) - { - Tmin_satL = components[0]->pEOS->sat_min_liquid.T; - Tmin_satV = components[0]->pEOS->sat_min_vapor.T; - return; - } - else{ - throw ValueError("calc_Tmin_sat not yet defined for mixtures"); - } + if (is_pure_or_pseudopure) + { + Tmin_satL = components[0]->pEOS->sat_min_liquid.T; + Tmin_satV = components[0]->pEOS->sat_min_vapor.T; + return; + } + else{ + throw ValueError("calc_Tmin_sat not yet defined for mixtures"); + } } void HelmholtzEOSMixtureBackend::calc_pmin_sat(long double &pmin_satL, long double &pmin_satV) { - if (is_pure_or_pseudopure) - { - pmin_satL = components[0]->pEOS->sat_min_liquid.p; - pmin_satV = components[0]->pEOS->sat_min_vapor.p; - return; - } - else{ - throw ValueError("calc_pmin_sat not yet defined for mixtures"); - } + if (is_pure_or_pseudopure) + { + pmin_satL = components[0]->pEOS->sat_min_liquid.p; + pmin_satV = components[0]->pEOS->sat_min_vapor.p; + return; + } + else{ + throw ValueError("calc_pmin_sat not yet defined for mixtures"); + } } // Minimum allowed saturation temperature the maximum of the saturation temperatures of liquid and vapor - // For pure fluids, both values are the same, for pseudo-pure they are probably the same, for mixtures they are definitely not the same + // For pure fluids, both values are the same, for pseudo-pure they are probably the same, for mixtures they are definitely not the same long double HelmholtzEOSMixtureBackend::calc_Tmax(void) { @@ -991,26 +991,26 @@ void HelmholtzEOSMixtureBackend::p_phase_determination_pure_or_pseudopure(int ot this->_phase = iphase_liquid; _Q = 1000; return; } else if (value > s_liq + s_liq_error_band && value < s_vap - s_vap_error_band){ definitely_two_phase = true;} - break; + break; } case iUmolar: { if (!component.ancillaries.hL.enabled()){break;} - // u = h-p/rho + // u = h-p/rho - // Ancillaries are h-h_anchor, so add back h_anchor + // Ancillaries are h-h_anchor, so add back h_anchor long double h_liq = component.ancillaries.hL.evaluate(_TLanc) + component.EOSVector[0].hs_anchor.hmolar; long double h_liq_error_band = component.ancillaries.hL.get_max_abs_error(); long double h_vap = h_liq + component.ancillaries.hLV.evaluate(_TLanc); long double h_vap_error_band = h_liq_error_band + component.ancillaries.hLV.get_max_abs_error(); - long double rho_vap = component.ancillaries.rhoV.evaluate(_TVanc); - long double rho_liq = component.ancillaries.rhoL.evaluate(_TLanc); - long double u_liq = h_liq-_p/rho_liq; - long double u_vap = h_vap-_p/rho_vap; - long double u_liq_error_band = 1.5*h_liq_error_band; // Most of error is in enthalpy - long double u_vap_error_band = 1.5*h_vap_error_band; // Most of error is in enthalpy - - // Check if in range given the accuracy of the fit + long double rho_vap = component.ancillaries.rhoV.evaluate(_TVanc); + long double rho_liq = component.ancillaries.rhoL.evaluate(_TLanc); + long double u_liq = h_liq-_p/rho_liq; + long double u_vap = h_vap-_p/rho_vap; + long double u_liq_error_band = 1.5*h_liq_error_band; // Most of error is in enthalpy + long double u_vap_error_band = 1.5*h_vap_error_band; // Most of error is in enthalpy + + // Check if in range given the accuracy of the fit if (value > u_vap + u_vap_error_band){ this->_phase = iphase_gas; _Q = -1000; return; } @@ -1018,7 +1018,7 @@ void HelmholtzEOSMixtureBackend::p_phase_determination_pure_or_pseudopure(int ot this->_phase = iphase_liquid; _Q = 1000; return; } else if (value > u_liq + u_liq_error_band && value < u_vap - u_vap_error_band){ definitely_two_phase = true;} - break; + break; } default: @@ -1907,16 +1907,16 @@ long double HelmholtzEOSMixtureBackend::solver_rho_Tp(long double T, long double } catch(std::exception &) { - try{ + try{ // Next we try with a Brent method bounded solver since the function is 1-1 double rhomolar = Brent(resid, 0.1*rhomolar_guess, 2*rhomolar_guess,DBL_EPSILON,1e-8,100,errstring); if (!ValidNumber(rhomolar)){throw ValueError();} return rhomolar; - } - catch(...){ - - throw ValueError(format("solver_rho_Tp was unable to find a solution for T=%10Lg, p=%10Lg, with guess value %10Lg",T,p,rhomolar_guess)); - } + } + catch(...){ + + throw ValueError(format("solver_rho_Tp was unable to find a solution for T=%10Lg, p=%10Lg, with guess value %10Lg",T,p,rhomolar_guess)); + } return _HUGE; } } @@ -2113,27 +2113,27 @@ long double HelmholtzEOSMixtureBackend::calc_umolar_nocache(long double T, long } long double HelmholtzEOSMixtureBackend::calc_umolar(void) { - if (isTwoPhase()) + if (isTwoPhase()) { _umolar = _Q*SatV->umolar() + (1 - _Q)*SatL->umolar(); return static_cast(_umolar); } else if (isHomogeneousPhase()) { - // Calculate the reducing parameters - _delta = _rhomolar/_reducing.rhomolar; - _tau = _reducing.T/_T; + // Calculate the reducing parameters + _delta = _rhomolar/_reducing.rhomolar; + _tau = _reducing.T/_T; - // Calculate derivatives if needed, or just use cached values - long double da0_dTau = dalpha0_dTau(); - long double dar_dTau = dalphar_dTau(); - long double R_u = gas_constant(); + // Calculate derivatives if needed, or just use cached values + long double da0_dTau = dalpha0_dTau(); + long double dar_dTau = dalphar_dTau(); + long double R_u = gas_constant(); - // Get molar internal energy - _umolar = R_u*_T*_tau.pt()*(da0_dTau+dar_dTau); + // Get molar internal energy + _umolar = R_u*_T*_tau.pt()*(da0_dTau+dar_dTau); - return static_cast(_umolar); - } + return static_cast(_umolar); + } else{ throw ValueError(format("phase is invalid in calc_umolar")); } diff --git a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h index 99ab02e2..d3f0bdf9 100644 --- a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h +++ b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h @@ -54,10 +54,10 @@ public: bool using_mole_fractions(){return true;} bool using_mass_fractions(){return false;} bool using_volu_fractions(){return false;} - - bool has_melting_line(){ return is_pure_or_pseudopure && components[0]->ancillaries.melting_line.enabled();}; - long double calc_melting_line(int param, int given, long double value); - phases calc_phase(void){return _phase;}; + + bool has_melting_line(){ return is_pure_or_pseudopure && components[0]->ancillaries.melting_line.enabled();}; + long double calc_melting_line(int param, int given, long double value); + phases calc_phase(void){return _phase;}; void calc_specify_phase(phases phase){ specify_phase(phase); } void calc_unspecify_phase(){ unspecify_phase(); } long double calc_saturation_ancillary(parameters param, int Q, parameters given, double value); @@ -145,11 +145,11 @@ public: long double calc_cpmolar_idealgas(void); long double calc_pressure_nocache(long double T, long double rhomolar); long double calc_smolar(void); - long double calc_smolar_nocache(long double T, long double rhomolar); + long double calc_smolar_nocache(long double T, long double rhomolar); + + long double calc_hmolar(void); + long double calc_hmolar_nocache(long double T, long double rhomolar); - long double calc_hmolar(void); - long double calc_hmolar_nocache(long double T, long double rhomolar); - long double calc_umolar_nocache(long double T, long double rhomolar); long double calc_umolar(void); long double calc_speed_sound(void); @@ -191,13 +191,13 @@ public: long double calc_conductivity_background(void); long double calc_Tmin(void); - long double calc_Tmax(void); + long double calc_Tmax(void); long double calc_pmax(void); long double calc_Ttriple(void); long double calc_p_triple(void); - long double calc_pmax_sat(void); - long double calc_Tmax_sat(void); - void calc_Tmin_sat(long double &Tmin_satL, long double &Tmin_satV); + long double calc_pmax_sat(void); + long double calc_Tmax_sat(void); + void calc_Tmin_sat(long double &Tmin_satL, long double &Tmin_satV); void calc_pmin_sat(long double &pmin_satL, long double &pmin_satV); long double calc_T_critical(void); diff --git a/src/Backends/Helmholtz/MixtureDerivatives.h b/src/Backends/Helmholtz/MixtureDerivatives.h index 17426faf..61cdcd9a 100644 --- a/src/Backends/Helmholtz/MixtureDerivatives.h +++ b/src/Backends/Helmholtz/MixtureDerivatives.h @@ -32,22 +32,22 @@ class MixtureDerivatives{ /** \brief GERG 2004 Monograph equation 7.62 * * The derivative term - * \f[ - * n\left(\frac{\partial p}{\partial V} \right)_{T,\bar n} = -\rho^2 RT(1+2\delta \alpha_{\delta}^r+\delta^2\alpha^r_{\delta\delta}) - * \f] + * \f[ + * n\left(\frac{\partial p}{\partial V} \right)_{T,\bar n} = -\rho^2 RT(1+2\delta \alpha_{\delta}^r+\delta^2\alpha^r_{\delta\delta}) + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used - */ - static long double ndpdV__constT_n(HelmholtzEOSMixtureBackend &HEOS); + */ + static long double ndpdV__constT_n(HelmholtzEOSMixtureBackend &HEOS); /** \brief GERG 2004 Monograph equation 7.61 * * The derivative term - * \f[ - * \left(\frac{\partial p}{\partial T} \right)_{V,\bar n} = \rho R(1+\delta \alpha_{\delta}^r-\delta \tau \alpha^r_{\delta\tau}) - * \f] - * @param HEOS The HelmholtzEOSMixtureBackend to be used - */ - static long double dpdT__constV_n(HelmholtzEOSMixtureBackend &HEOS); + * \f[ + * \left(\frac{\partial p}{\partial T} \right)_{V,\bar n} = \rho R(1+\delta \alpha_{\delta}^r-\delta \tau \alpha^r_{\delta\tau}) + * \f] + * @param HEOS The HelmholtzEOSMixtureBackend to be used + */ + static long double dpdT__constV_n(HelmholtzEOSMixtureBackend &HEOS); static long double dpdrho__constT_n(HelmholtzEOSMixtureBackend &HEOS); @@ -56,31 +56,31 @@ class MixtureDerivatives{ static long double d2alphar_dxi_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); static long double d2alphardxidxj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - + - /** \brief GERG 2004 Monograph equation 7.63 + /** \brief GERG 2004 Monograph equation 7.63 * * The derivative term - * \f[ - * n\left(\frac{\partial p}{\partial n_i} \right)_{T,V,n_j} = \rho RT\left[1+\delta\alpha_{\delta}^r\left[2- \frac{1}{\rho_r}\cdot n\left( \frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] +\delta\cdot n\left(\frac{\partial\alpha_{\delta}^r}{\partial n_i}\right)_{T,V,n_j}\right] - * \f] - * @param HEOS The HelmholtzEOSMixtureBackend to be used + * \f[ + * n\left(\frac{\partial p}{\partial n_i} \right)_{T,V,n_j} = \rho RT\left[1+\delta\alpha_{\delta}^r\left[2- \frac{1}{\rho_r}\cdot n\left( \frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] +\delta\cdot n\left(\frac{\partial\alpha_{\delta}^r}{\partial n_i}\right)_{T,V,n_j}\right] + * \f] + * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double ndpdni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double ndpdni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief GERG 2004 monograph Eqn. 7.32 * * The partial molar volume * \f[ * \hat v_i = \left( \frac{\partial V}{\partial n_i}\right)_{T,p,n_j} = \frac{-\left(\dfrac{\partial p}{\partial n_i}\right)_{T,V,n_j}}{\left(\dfrac{\partial p}{\partial V}\right)_{T,\bar n}} - * \f] + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double partial_molar_volume(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double partial_molar_volume(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief Fugacity of the i-th component * @@ -96,10 +96,10 @@ class MixtureDerivatives{ * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ + */ static long double ln_fugacity_coefficient(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief Derivative of the natural logarithm of the fugacity with respect to T + /** \brief Derivative of the natural logarithm of the fugacity with respect to T * * From Witzke, Eqn. 3.14 * \f[ @@ -108,10 +108,10 @@ class MixtureDerivatives{ * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double dln_fugacity_i_dT__constrho_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double dln_fugacity_i_dT__constrho_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief Derivative of the natural logarithm of the fugacity with respect to T + /** \brief Derivative of the natural logarithm of the fugacity with respect to T * * From Witzke, Eqn. 3.15 * \f[ @@ -120,21 +120,21 @@ class MixtureDerivatives{ * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double dln_fugacity_i_drho__constT_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double dln_fugacity_i_drho__constT_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief GERG 2004 Monograph Eqn. 7.29 * - * The derivative term + * The derivative term * * \f[ - * \left(\frac{\partial \ln \phi_i}{\partial T} \right)_{p,\bar n} = \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} + \frac{1}{T}-\frac{\hat v}{RT}\left(\frac{\partial p}{\partial T}\right)_{V,\bar n} + * \left(\frac{\partial \ln \phi_i}{\partial T} \right)_{p,\bar n} = \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} + \frac{1}{T}-\frac{\hat v}{RT}\left(\frac{\partial p}{\partial T}\right)_{V,\bar n} * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double dln_fugacity_coefficient_dT__constp_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double dln_fugacity_coefficient_dT__constp_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); static long double dln_fugacity_i_dT__constp_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); static long double dln_fugacity_i_dp__constT_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); @@ -148,217 +148,217 @@ class MixtureDerivatives{ * The derivative term * \f[ * n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} - * \f] - * which is equal to - * \f{eqnarray*}{ - * n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} &=& \delta \phi^r_{\delta}\left[ 1-\frac{1}{\rho_r}\left[\left(\frac{\partial \rho_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial \rho_r}{\partial x_k}\right)_{x_j} \right]\right]\\ - * && +\tau \phi^r_{\tau}\frac{1}{T_r}\left[\left(\frac{\partial T_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial T_r}{\partial x_k}\right)_{x_j} \right]\\ - * && +\phi^r_{x_i}-\sum_{k=1}^{N}x_k\phi^r_{x_k} - * \f} + * \f] + * which is equal to + * \f{eqnarray*}{ + * n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} &=& \delta \phi^r_{\delta}\left[ 1-\frac{1}{\rho_r}\left[\left(\frac{\partial \rho_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial \rho_r}{\partial x_k}\right)_{x_j} \right]\right]\\ + * && +\tau \phi^r_{\tau}\frac{1}{T_r}\left[\left(\frac{\partial T_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial T_r}{\partial x_k}\right)_{x_j} \right]\\ + * && +\phi^r_{x_i}-\sum_{k=1}^{N}x_k\phi^r_{x_k} + * \f} * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double ndalphar_dni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double ndalphar_dni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /// GERG Equation 7.42 - static long double dnalphar_dni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + /// GERG Equation 7.42 + static long double dnalphar_dni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief GERG 2004 Monograph Eqn. 7.30 * * The derivative term - * \f[ - * \left(\frac{\partial \ln \phi_i}{\partial p} \right)_{T,\bar n} = \frac{\hat v_i}{RT}-\frac{1}{p} - * \f] + * \f[ + * \left(\frac{\partial \ln \phi_i}{\partial p} \right)_{T,\bar n} = \frac{\hat v_i}{RT}-\frac{1}{p} + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double dln_fugacity_coefficient_dp__constT_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double dln_fugacity_coefficient_dp__constT_n(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief GERG 2004 Monograph Equation 7.31 + /** \brief GERG 2004 Monograph Equation 7.31 * * The derivative term - * \f[ - * n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1+\frac{n}{RT}\frac{\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\left(\frac{\partial p}{\partial n_i}\right)_{T,V,n_j}}{\left(\frac{\partial p}{\partial V}\right)_{T,\bar n}} - * \f] - * which is also equal to - * \f[ - * n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1-\frac{\hat v_i}{RT}\left[n\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\right] - * \f] + * \f[ + * n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1+\frac{n}{RT}\frac{\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\left(\frac{\partial p}{\partial n_i}\right)_{T,V,n_j}}{\left(\frac{\partial p}{\partial V}\right)_{T,\bar n}} + * \f] + * which is also equal to + * \f[ + * n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1-\frac{\hat v_i}{RT}\left[n\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\right] + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param j The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double ndln_fugacity_coefficient_dnj__constT_p(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + */ + static long double ndln_fugacity_coefficient_dnj__constT_p(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - /** \brief Gernert Equation 3.115 + /** \brief Gernert Equation 3.115 * * The derivative term - * \f[ - * \left(\frac{\partial \ln \phi_i}{\partial x_j}\right)_{T,p,x_{k\neq j}} = \left(\frac{\partial^2n\alpha^r}{\partial x_j \partial n_i} \right)_{T,V}+\frac{1}{RT}\frac{\left(\frac{\partial p}{\partial n_i}\right)_{T,V,n_{k\neq i}}\left(\frac{\partial p}{\partial x_j}\right)_{T,V,x_{k\neq j}}}{\left(\frac{\partial p}{\partial V}\right)_{T,\bar n}} - * \f] + * \f[ + * \left(\frac{\partial \ln \phi_i}{\partial x_j}\right)_{T,p,x_{k\neq j}} = \left(\frac{\partial^2n\alpha^r}{\partial x_j \partial n_i} \right)_{T,V}+\frac{1}{RT}\frac{\left(\frac{\partial p}{\partial n_i}\right)_{T,V,n_{k\neq i}}\left(\frac{\partial p}{\partial x_j}\right)_{T,V,x_{k\neq j}}}{\left(\frac{\partial p}{\partial V}\right)_{T,\bar n}} + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The first index of interest * @param j The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 * - */ - static long double dln_fugacity_coefficient_dxj__constT_p_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + */ + static long double dln_fugacity_coefficient_dxj__constT_p_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - /** \brief Gernert Equation 3.130 + /** \brief Gernert Equation 3.130 * * The derivative term - * \f[ + * \f[ * \left(\frac{\partial p}{\partial x_j} \right)_{T,V,x_{k\neq j}} = \rho RT\left(-\frac{1}{\rho_r}\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_{k\neq j}} \delta\alpha_{\delta}^r + \delta\left(\frac{\partial}{\partial x_j}\left(\left( \frac{\partial \alpha^r}{\partial \delta}\right)_{\tau,\bar x}\right)\right)_{T,V,x_{k\neq j}}\right) - * \f] + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param j The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 */ - static long double dpdxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); + static long double dpdxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); - /** \brief Gernert Equation 3.117 + /** \brief Gernert Equation 3.117 * * The derivative term - * \f[ + * \f[ * \left(\frac{\partial^2n\alpha^r}{\partial x_j\partial n_i} \right)_{T,V} = \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_{j\neq i}}\right)\right)_{T,V,x_{k\neq j}} +\left(\frac{\partial \alpha^r}{\partial x_j}\right)_{T,V,x_{k\neq j}} - * \f] + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param j The first index of interest * @param i The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ + */ static long double d2nalphar_dxj_dni__constT_V(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, std::size_t i, x_N_dependency_flag xN_flag){ return MixtureDerivatives::d_ndalphardni_dxj__constT_V_xi(HEOS, i, j, xN_flag) + MixtureDerivatives::dalphar_dxj__constT_V_xi(HEOS, j, xN_flag);}; - /// Gernert Equation 3.119 - /// Catch test provided - static long double dalphar_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); + /// Gernert Equation 3.119 + /// Catch test provided + static long double dalphar_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); - /// Gernert Equation 3.118 - /// Catch test provided - static long double d_ndalphardni_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + /// Gernert Equation 3.118 + /// Catch test provided + static long double d_ndalphardni_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - /// Gernert Equation 3.134 - /// Catch test provided - static long double d_dalpharddelta_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); + /// Gernert Equation 3.134 + /// Catch test provided + static long double d_dalpharddelta_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); - /// Gernert Equation 3.121 - /// Catch test provided - static long double ddelta_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); + /// Gernert Equation 3.121 + /// Catch test provided + static long double ddelta_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); - /// Gernert Equation 3.122 - /// Catch test provided - static long double dtau_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); + /// Gernert Equation 3.122 + /// Catch test provided + static long double dtau_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag); - /** \brief GERG 2004 Monograph, equations 7.44 and 7.51 + /** \brief GERG 2004 Monograph, equations 7.44 and 7.51 * * The derivative term - * \f[ - * \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} = \left( \frac{\partial}{\partial T}\left(\frac{\partial n \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right)_{V,\bar n} - * \f] - * \f[ - * \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} = -\frac{\tau}{T}\left[\alpha_{\tau}^r +\left( \frac{\partial}{\partial \tau}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\bar x}\right] - * \f] + * \f[ + * \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} = \left( \frac{\partial}{\partial T}\left(\frac{\partial n \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right)_{V,\bar n} + * \f] + * \f[ + * \left(\frac{\partial^2n\alpha^r}{\partial T\partial n_i} \right)_{V,n_j} = -\frac{\tau}{T}\left[\alpha_{\tau}^r +\left( \frac{\partial}{\partial \tau}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\bar x}\right] + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double d2nalphar_dni_dT(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double d2nalphar_dni_dT(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief GERG 2004 Monograph Equation 7.51 and Table B4, Kunz, JCED, 2012 + /** \brief GERG 2004 Monograph Equation 7.51 and Table B4, Kunz, JCED, 2012 * * The derivative term - * \f{eqnarray*}{ - * \frac{\partial }{\partial \tau} \left( n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} \right) &=& \delta \phi^r_{\delta\tau}\left[ 1-\frac{1}{\rho_r}\left[\left(\frac{\partial \rho_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial \rho_r}{\partial x_k}\right)_{x_j} \right]\right]\\ - * && +(\tau \phi^r_{\tau\tau}+\phi^r_{\tau})\frac{1}{T_r}\left[\left(\frac{\partial T_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial T_r}{\partial x_k}\right)_{x_j} \right]\\ - * && +\phi^r_{x_i\tau}-\sum_{k=1}^{N}x_k\phi^r_{x_k\tau} - * \f} + * \f{eqnarray*}{ + * \frac{\partial }{\partial \tau} \left( n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} \right) &=& \delta \phi^r_{\delta\tau}\left[ 1-\frac{1}{\rho_r}\left[\left(\frac{\partial \rho_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial \rho_r}{\partial x_k}\right)_{x_j} \right]\right]\\ + * && +(\tau \phi^r_{\tau\tau}+\phi^r_{\tau})\frac{1}{T_r}\left[\left(\frac{\partial T_r}{\partial x_i}\right)_{x_j} - \sum_{k=1}^N x_k\left(\frac{\partial T_r}{\partial x_k}\right)_{x_j} \right]\\ + * && +\phi^r_{x_i\tau}-\sum_{k=1}^{N}x_k\phi^r_{x_k\tau} + * \f} * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double d_ndalphardni_dTau(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double d_ndalphardni_dTau(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief GERG 2004 Monograph Equation 7.50 and Table B4, Kunz, JCED, 2012 + /** \brief GERG 2004 Monograph Equation 7.50 and Table B4, Kunz, JCED, 2012 * * The derivative term - * \f{eqnarray*}{ - * \left(\frac{\partial }{\partial \delta} \left( n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} \right)\right)_{\tau,\bar x} &=& (\alpha_{\delta}^r+\delta\alpha_{\delta\delta}^r)\left[1-\frac{1}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j} \right] \\ - * &+&\tau\alpha^r_{\delta\tau}\frac{1}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\\ - * &+&\phi^r_{\delta x_i}-\sum_{k=1}^{N}x_k\phi^r_{\delta x_k} - * \f} + * \f{eqnarray*}{ + * \left(\frac{\partial }{\partial \delta} \left( n\left(\frac{\partial \phi^r}{\partial n_i} \right)_{T,V,n_j} \right)\right)_{\tau,\bar x} &=& (\alpha_{\delta}^r+\delta\alpha_{\delta\delta}^r)\left[1-\frac{1}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j} \right] \\ + * &+&\tau\alpha^r_{\delta\tau}\frac{1}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\\ + * &+&\phi^r_{\delta x_i}-\sum_{k=1}^{N}x_k\phi^r_{\delta x_k} + * \f} * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double d_ndalphardni_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double d_ndalphardni_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief GERG 2004 Monograph equation 7.41 + /** \brief GERG 2004 Monograph equation 7.41 * * The derivative term - * \f[ - * n\left(\frac{\partial^2n\alpha^r}{\partial n_i \partial n_j} \right)_{T,V} = n\left( \frac{\partial}{\partial n_j}\left(\frac{\partial n\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)_{T,V,n_i} - * \f] - * and - * GERG 2004 Monograph equation 7.46: - * \f[ - * n\left( \frac{\partial}{\partial n_j}\left(\frac{\partial n\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)_{T,V,n_i} = n\left( \frac{\partial \alpha^r}{\partial n_j}\right)_{T,V,n_i} + n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} - * \f] - * GERG 2004 Monograph equation 7.47: - * \f{eqnarray*}{ - * n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} &=& \left( \frac{\partial}{\partial \delta}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\delta}{\partial n_j}\right)_{T,V,n_i}\\ - * &+& \left( \frac{\partial}{\partial \tau}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\tau}{\partial n_j}\right)_{T,V,n_i}\\ - * &+& \left( \frac{\partial}{\partial x_j}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}-\sum_{k=1}^{N}x_k \left( \frac{\partial}{\partial x_k}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}\\ - * \f} + * \f[ + * n\left(\frac{\partial^2n\alpha^r}{\partial n_i \partial n_j} \right)_{T,V} = n\left( \frac{\partial}{\partial n_j}\left(\frac{\partial n\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)_{T,V,n_i} + * \f] + * and + * GERG 2004 Monograph equation 7.46: + * \f[ + * n\left( \frac{\partial}{\partial n_j}\left(\frac{\partial n\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)_{T,V,n_i} = n\left( \frac{\partial \alpha^r}{\partial n_j}\right)_{T,V,n_i} + n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} + * \f] + * GERG 2004 Monograph equation 7.47: + * \f{eqnarray*}{ + * n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} &=& \left( \frac{\partial}{\partial \delta}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\delta}{\partial n_j}\right)_{T,V,n_i}\\ + * &+& \left( \frac{\partial}{\partial \tau}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\tau}{\partial n_j}\right)_{T,V,n_i}\\ + * &+& \left( \frac{\partial}{\partial x_j}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}-\sum_{k=1}^{N}x_k \left( \frac{\partial}{\partial x_k}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}\\ + * \f} * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param j The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double nd2nalphardnidnj__constT_V(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + */ + static long double nd2nalphardnidnj__constT_V(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); /** \brief GERG 2004 Monograph equation 7.48 * * The derivative term - * \f[ - * n\left(\frac{\partial \delta}{\partial n_i} \right)_{T,V,n_j} = \delta - \frac{\delta}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j} - * \f] + * \f[ + * n\left(\frac{\partial \delta}{\partial n_i} \right)_{T,V,n_j} = \delta - \frac{\delta}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j} + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double nddeltadni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double nddeltadni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief GERG 2004 Monograph equation 7.49 * * The derivative term - * \f[ - * n\left(\frac{\partial \tau}{\partial n_i} \right)_{T,V,n_j} = \frac{\tau}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j} - * \f] + * \f[ + * n\left(\frac{\partial \tau}{\partial n_i} \right)_{T,V,n_j} = \frac{\tau}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j} + * \f] * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double ndtaudni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); + */ + static long double ndtaudni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag); /** \brief GERG 2004 Monograph equation 7.52 * - * The derivative term - * \f{eqnarray*}{ - * \left( \frac{\partial}{\partial x_j}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i} &=& \delta\alpha_{\delta x_j}^{r}\left[ 1-\frac{1}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] \\ - * &-& \delta\alpha_{\delta}^{r}\frac{1}{\rho_r}\left[ \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right)\right)_{x_i}-\frac{1}{\rho_r}\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] \\ - * &+& \tau\alpha_{\tau x_j}^r\frac{1}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\\ - * &+& \tau\alpha_{\tau}^{r}\frac{1}{T_r}\left[ \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\right)\right)_{x_i}-\frac{1}{T_r}\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\right] \\ - * &+& \alpha_{x_ix_j}^r-\alpha_{x_j}^r-\sum_{m=1}^Nx_m\alpha_{x_jx_m}^r - * \f} + * The derivative term + * \f{eqnarray*}{ + * \left( \frac{\partial}{\partial x_j}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i} &=& \delta\alpha_{\delta x_j}^{r}\left[ 1-\frac{1}{\rho_r}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] \\ + * &-& \delta\alpha_{\delta}^{r}\frac{1}{\rho_r}\left[ \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right)\right)_{x_i}-\frac{1}{\rho_r}\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}\cdot n\left(\frac{\partial \rho_r}{\partial n_i}\right)_{n_j}\right] \\ + * &+& \tau\alpha_{\tau x_j}^r\frac{1}{T_r}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\\ + * &+& \tau\alpha_{\tau}^{r}\frac{1}{T_r}\left[ \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\right)\right)_{x_i}-\frac{1}{T_r}\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}\cdot n\left(\frac{\partial T_r}{\partial n_i}\right)_{n_j}\right] \\ + * &+& \alpha_{x_ix_j}^r-\alpha_{x_j}^r-\sum_{m=1}^Nx_m\alpha_{x_jx_m}^r + * \f} * @param HEOS The HelmholtzEOSMixtureBackend to be used * @param i The index of interest * @param j The second index of interest * @param xN_flag A flag specifying whether the all mole fractions are independent or only the first N-1 - */ - static long double d_ndalphardni_dxj__constdelta_tau_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + */ + static long double d_ndalphardni_dxj__constdelta_tau_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); }; /* class MixtureDerivatives */ diff --git a/src/Backends/Helmholtz/MixtureParameters.cpp b/src/Backends/Helmholtz/MixtureParameters.cpp index 34ec830e..2813be2a 100644 --- a/src/Backends/Helmholtz/MixtureParameters.cpp +++ b/src/Backends/Helmholtz/MixtureParameters.cpp @@ -278,9 +278,9 @@ void MixtureParameters::set_mixture_parameters(HelmholtzEOSMixtureBackend &HEOS) STLMatrix beta_v, gamma_v, beta_T, gamma_T; beta_v.resize(N, std::vector(N, 0)); - gamma_v.resize(N, std::vector(N, 0)); - beta_T.resize(N, std::vector(N, 0)); - gamma_T.resize(N, std::vector(N, 0)); + gamma_v.resize(N, std::vector(N, 0)); + beta_T.resize(N, std::vector(N, 0)); + gamma_T.resize(N, std::vector(N, 0)); HEOS.Excess.resize(N); diff --git a/src/Backends/Helmholtz/ReducingFunctions.cpp b/src/Backends/Helmholtz/ReducingFunctions.cpp index a0f33d05..0a8306e5 100644 --- a/src/Backends/Helmholtz/ReducingFunctions.cpp +++ b/src/Backends/Helmholtz/ReducingFunctions.cpp @@ -29,12 +29,12 @@ long double ReducingFunction::d_ndTrdni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { - long double s = 0; - for (std::size_t k = 0; k < N; k++) - { - s += x[k]*d2rhormolardxidxj(x,j,k, xN_flag); - } - return d2rhormolardxidxj(x,j,i, xN_flag)-drhormolardxi__constxj(x,j, xN_flag)-s; + long double s = 0; + for (std::size_t k = 0; k < N; k++) + { + s += x[k]*d2rhormolardxidxj(x,j,k, xN_flag); + } + return d2rhormolardxidxj(x,j,i, xN_flag)-drhormolardxi__constxj(x,j, xN_flag)-s; } long double ReducingFunction::ndrhorbardni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { @@ -88,23 +88,23 @@ long double GERG2008ReducingFunction::Tr(const std::vector &x) } long double GERG2008ReducingFunction::dTrdxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { - return dYrdxi__constxj(x, i, beta_T, gamma_T, T_c, Yc_T, xN_flag); + return dYrdxi__constxj(x, i, beta_T, gamma_T, T_c, Yc_T, xN_flag); } long double GERG2008ReducingFunction::d2Trdxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { - return d2Yrdxi2__constxj(x, i, beta_T, gamma_T, T_c, Yc_T, xN_flag); + return d2Yrdxi2__constxj(x, i, beta_T, gamma_T, T_c, Yc_T, xN_flag); } long double GERG2008ReducingFunction::d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { - return d2Yrdxidxj(x, i, j, beta_T, gamma_T, T_c, Yc_T, xN_flag); + return d2Yrdxidxj(x, i, j, beta_T, gamma_T, T_c, Yc_T, xN_flag); } long double GERG2008ReducingFunction::rhormolar(const std::vector &x) { - return 1/Yr(x, beta_v, gamma_v, v_c, Yc_v); + return 1/Yr(x, beta_v, gamma_v, v_c, Yc_v); } long double GERG2008ReducingFunction::drhormolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { - return -pow(rhormolar(x),2)*dvrmolardxi__constxj(x, i, xN_flag); + return -pow(rhormolar(x),2)*dvrmolardxi__constxj(x, i, xN_flag); } long double GERG2008ReducingFunction::dvrmolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { @@ -120,21 +120,21 @@ long double GERG2008ReducingFunction::d2vrmolardxidxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { - long double rhor = this->rhormolar(x); - long double dvrbardxi = this->dvrmolardxi__constxj(x,i, xN_flag); - return 2*pow(rhor,3)*pow(dvrbardxi,2)-pow(rhor,2)*this->d2vrmolardxi2__constxj(x,i, xN_flag); + long double rhor = this->rhormolar(x); + long double dvrbardxi = this->dvrmolardxi__constxj(x,i, xN_flag); + return 2*pow(rhor,3)*pow(dvrbardxi,2)-pow(rhor,2)*this->d2vrmolardxi2__constxj(x,i, xN_flag); } long double GERG2008ReducingFunction::d2rhormolardxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { - double rhor = this->rhormolar(x); - double dvrbardxi = this->dvrmolardxi__constxj(x,i, xN_flag); - double dvrbardxj = this->dvrmolardxi__constxj(x,j, xN_flag); - return 2*pow(rhor,3)*dvrbardxi*dvrbardxj-pow(rhor,2)*this->d2vrmolardxidxj(x,i,j, xN_flag); + double rhor = this->rhormolar(x); + double dvrbardxi = this->dvrmolardxi__constxj(x,i, xN_flag); + double dvrbardxj = this->dvrmolardxi__constxj(x,j, xN_flag); + return 2*pow(rhor,3)*dvrbardxi*dvrbardxj-pow(rhor,2)*this->d2vrmolardxidxj(x,i,j, xN_flag); } long double GERG2008ReducingFunction::Yr(const std::vector &x, const STLMatrix &beta, const STLMatrix &gamma, const STLMatrix &Y_c_ij, const std::vector &Yc) { - long double Yr = 0; + long double Yr = 0; for (std::size_t i = 0; i < N; i++) { double xi = x[i]; @@ -148,7 +148,7 @@ long double GERG2008ReducingFunction::Yr(const std::vector &x, cons Yr += c_Y_ij(i, j, beta, gamma, Y_c_ij)*f_Y_ij(x, i, j, beta); } } - return Yr; + return Yr; } long double GERG2008ReducingFunction::dYrdxi__constxj(const std::vector &x, std::size_t i, const STLMatrix &beta, const STLMatrix &gamma, const STLMatrix &Y_c_ij, const std::vector &Yc, x_N_dependency_flag xN_flag) { @@ -275,39 +275,39 @@ long double GERG2008ReducingFunction::d2Yrdxidxj(const std::vector long double GERG2008ReducingFunction::dfYkidxi__constxk(const std::vector &x, std::size_t k, std::size_t i, const STLMatrix &beta) { - double xk = x[k], xi = x[i], beta_Y = beta[k][i]; - return xk*(xk+xi)/(beta_Y*beta_Y*xk+xi)+xk*xi/(beta_Y*beta_Y*xk+xi)*(1-(xk+xi)/(beta_Y*beta_Y*xk+xi)); + double xk = x[k], xi = x[i], beta_Y = beta[k][i]; + return xk*(xk+xi)/(beta_Y*beta_Y*xk+xi)+xk*xi/(beta_Y*beta_Y*xk+xi)*(1-(xk+xi)/(beta_Y*beta_Y*xk+xi)); } long double GERG2008ReducingFunction::dfYikdxi__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta) { - double xk = x[k], xi = x[i], beta_Y = beta[i][k]; - return xk*(xi+xk)/(beta_Y*beta_Y*xi+xk)+xi*xk/(beta_Y*beta_Y*xi+xk)*(1-beta_Y*beta_Y*(xi+xk)/(beta_Y*beta_Y*xi+xk)); + double xk = x[k], xi = x[i], beta_Y = beta[i][k]; + return xk*(xi+xk)/(beta_Y*beta_Y*xi+xk)+xi*xk/(beta_Y*beta_Y*xi+xk)*(1-beta_Y*beta_Y*(xi+xk)/(beta_Y*beta_Y*xi+xk)); } long double GERG2008ReducingFunction::c_Y_ij(std::size_t i, std::size_t j, const STLMatrix &beta, const STLMatrix &gamma, const STLMatrix &Y_c) { - return 2*beta[i][j]*gamma[i][j]*Y_c[i][j]; + return 2*beta[i][j]*gamma[i][j]*Y_c[i][j]; } long double GERG2008ReducingFunction::f_Y_ij(const std::vector &x, std::size_t i, std::size_t j, const STLMatrix &beta) { - double xi = x[i], xj = x[j], beta_Y = beta[i][j]; - return xi*xj*(xi+xj)/(beta_Y*beta_Y*xi+xj); + double xi = x[i], xj = x[j], beta_Y = beta[i][j]; + return xi*xj*(xi+xj)/(beta_Y*beta_Y*xi+xj); } long double GERG2008ReducingFunction::d2fYikdxi2__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta) { - double xi = x[i], xk = x[k], beta_Y = beta[i][k]; - return 1/(beta_Y*beta_Y*xi+xk)*(1-beta_Y*beta_Y*(xi+xk)/(beta_Y*beta_Y*xi+xk))*(2*xk-xi*xk*2*beta_Y*beta_Y/(beta_Y*beta_Y*xi+xk)); + double xi = x[i], xk = x[k], beta_Y = beta[i][k]; + return 1/(beta_Y*beta_Y*xi+xk)*(1-beta_Y*beta_Y*(xi+xk)/(beta_Y*beta_Y*xi+xk))*(2*xk-xi*xk*2*beta_Y*beta_Y/(beta_Y*beta_Y*xi+xk)); } long double GERG2008ReducingFunction::d2fYkidxi2__constxk(const std::vector &x, std::size_t k, std::size_t i, const STLMatrix &beta) { - double xi = x[i], xk = x[k], beta_Y = beta[k][i]; - return 1/(beta_Y*beta_Y*xk+xi)*(1-(xk+xi)/(beta_Y*beta_Y*xk+xi))*(2*xk-xk*xi*2/(beta_Y*beta_Y*xk+xi)); + double xi = x[i], xk = x[k], beta_Y = beta[k][i]; + return 1/(beta_Y*beta_Y*xk+xi)*(1-(xk+xi)/(beta_Y*beta_Y*xk+xi))*(2*xk-xk*xi*2/(beta_Y*beta_Y*xk+xi)); } long double GERG2008ReducingFunction::d2fYijdxidxj(const std::vector &x, std::size_t i, std::size_t j, const STLMatrix &beta) { - double xi = x[i], xj = x[j], beta_Y = beta[i][j], beta_Y2 = beta_Y*beta_Y; - return (xi+xj)/(beta_Y2*xi+xj) + xj/(beta_Y2*xi+xj)*(1-(xi+xj)/(beta_Y2*xi+xj)) - +xi/(beta_Y2*xi+xj)*(1-beta_Y2*(xi+xj)/(beta_Y2*xi+xj)) - -xi*xj/pow(beta_Y2*xi+xj,2)*(1+beta_Y2-2*beta_Y2*(xi+xj)/(beta_Y2*xi+xj)); + double xi = x[i], xj = x[j], beta_Y = beta[i][j], beta_Y2 = beta_Y*beta_Y; + return (xi+xj)/(beta_Y2*xi+xj) + xj/(beta_Y2*xi+xj)*(1-(xi+xj)/(beta_Y2*xi+xj)) + +xi/(beta_Y2*xi+xj)*(1-beta_Y2*(xi+xj)/(beta_Y2*xi+xj)) + -xi*xj/pow(beta_Y2*xi+xj,2)*(1+beta_Y2-2*beta_Y2*(xi+xj)/(beta_Y2*xi+xj)); } } /* namespace CoolProp */ diff --git a/src/Backends/Helmholtz/ReducingFunctions.h b/src/Backends/Helmholtz/ReducingFunctions.h index 9817ad56..3b529b83 100644 --- a/src/Backends/Helmholtz/ReducingFunctions.h +++ b/src/Backends/Helmholtz/ReducingFunctions.h @@ -29,57 +29,57 @@ std::string get_reducing_function_name(std::string CAS1, std::string CAS2); class ReducingFunction { protected: - std::size_t N; + std::size_t N; public: - ReducingFunction(){}; - virtual ~ReducingFunction(){}; + ReducingFunction(){}; + virtual ~ReducingFunction(){}; /// A factory function to generate the requiredreducing function static shared_ptr factory(const std::vector &components, std::vector< std::vector< long double> > &F); - /// The reduced temperature - virtual long double Tr(const std::vector &x) = 0; - /// The derivative of reduced temperature with respect to component i mole fraction - virtual long double dTrdxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; - /// The molar reducing density - virtual long double rhormolar(const std::vector &x) = 0; - ///Derivative of the molar reducing density with respect to component i mole fraction - virtual long double drhormolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; + /// The reduced temperature + virtual long double Tr(const std::vector &x) = 0; + /// The derivative of reduced temperature with respect to component i mole fraction + virtual long double dTrdxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; + /// The molar reducing density + virtual long double rhormolar(const std::vector &x) = 0; + ///Derivative of the molar reducing density with respect to component i mole fraction + virtual long double drhormolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; - virtual long double d2rhormolardxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; - virtual long double d2rhormolardxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) = 0; - virtual long double d2Trdxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; - virtual long double d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) = 0; + virtual long double d2rhormolardxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; + virtual long double d2rhormolardxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) = 0; + virtual long double d2Trdxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; + virtual long double d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) = 0; - /** \brief GERG 2004 Monograph equation 7.56: + /** \brief GERG 2004 Monograph equation 7.56: * * If the \f$x_i\f$ are all independent - * \f[ - * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) - * \f] + * \f[ + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) + * \f] * If \f$x_N = 1-\sum x_i\f$: - * \f[ - * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) - * \f] - */ - long double d_ndTrdni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - /** \brief + * \f[ + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) + * \f] + */ + long double d_ndTrdni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + /** \brief * * GERG 2004 Monograph equation 7.55: * If the \f$x_i\f$ are all independent - * \f[ - * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) - * \f] + * \f[ + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-1}x_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) + * \f] * Gernert, JPCRD, 2014, A28 * If \f$x_N = 1-\sum x_i\f$: * \f[ - * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-2}x_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) - * \f] - */ - long double d_ndrhorbardni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=0}^{N-2}x_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) + * \f] + */ + long double d_ndrhorbardni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - long double ndrhorbardni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); - long double ndTrdni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); + long double ndrhorbardni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); + long double ndTrdni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); }; /** \brief The reducing function model of GERG-2008 @@ -92,53 +92,53 @@ class GERG2008ReducingFunction : public ReducingFunction private: GERG2008ReducingFunction(const GERG2008ReducingFunction& that); // No copying protected: - STLMatrix v_c; ///< \f$ v_{c,ij} = \frac{1}{8}\left(v_{c,i}^{1/3}+v_{c,j}^{1/3}\right)^{3}\f$ from GERG-2008 - STLMatrix T_c; ///< \f$ T_{c,ij} = \sqrt{T_{c,i}T_{c,j}} \f$ from GERG=2008 - STLMatrix beta_v; ///< \f$ \beta_{v,ij} \f$ from GERG-2008 - STLMatrix gamma_v; ///< \f$ \gamma_{v,ij} \f$ from GERG-2008 - STLMatrix beta_T; ///< \f$ \beta_{T,ij} \f$ from GERG-2008 - STLMatrix gamma_T; ///< \f$ \gamma_{T,ij} \f$ from GERG-2008 + STLMatrix v_c; ///< \f$ v_{c,ij} = \frac{1}{8}\left(v_{c,i}^{1/3}+v_{c,j}^{1/3}\right)^{3}\f$ from GERG-2008 + STLMatrix T_c; ///< \f$ T_{c,ij} = \sqrt{T_{c,i}T_{c,j}} \f$ from GERG=2008 + STLMatrix beta_v; ///< \f$ \beta_{v,ij} \f$ from GERG-2008 + STLMatrix gamma_v; ///< \f$ \gamma_{v,ij} \f$ from GERG-2008 + STLMatrix beta_T; ///< \f$ \beta_{T,ij} \f$ from GERG-2008 + STLMatrix gamma_T; ///< \f$ \gamma_{T,ij} \f$ from GERG-2008 std::vector Yc_T; ///< Vector of critical temperatures for all components std::vector Yc_v; ///< Vector of critical molar volumes for all components - std::vector pFluids; ///< List of pointer to fluids + std::vector pFluids; ///< List of pointer to fluids public: - GERG2008ReducingFunction(std::vector pFluids, STLMatrix beta_v, STLMatrix gamma_v, STLMatrix beta_T, STLMatrix gamma_T) - { - this->pFluids = pFluids; - this->beta_v = beta_v; - this->gamma_v = gamma_v; - this->beta_T = beta_T; - this->gamma_T = gamma_T; - this->N = pFluids.size(); - T_c.resize(N,std::vector(N,0)); - v_c.resize(N,std::vector(N,0)); + GERG2008ReducingFunction(std::vector pFluids, STLMatrix beta_v, STLMatrix gamma_v, STLMatrix beta_T, STLMatrix gamma_T) + { + this->pFluids = pFluids; + this->beta_v = beta_v; + this->gamma_v = gamma_v; + this->beta_T = beta_T; + this->gamma_T = gamma_T; + this->N = pFluids.size(); + T_c.resize(N,std::vector(N,0)); + v_c.resize(N,std::vector(N,0)); Yc_T.resize(N); Yc_v.resize(N); - for (std::size_t i = 0; i < N; ++i) - { - for (std::size_t j = 0; j < N; j++) - { - T_c[i][j] = sqrt(pFluids[i]->pEOS->reduce.T*pFluids[j]->pEOS->reduce.T); - v_c[i][j] = 1.0/8.0*pow(pow(pFluids[i]->pEOS->reduce.rhomolar, -1.0/3.0)+pow(pFluids[j]->pEOS->reduce.rhomolar, -1.0/3.0),3); - } + for (std::size_t i = 0; i < N; ++i) + { + for (std::size_t j = 0; j < N; j++) + { + T_c[i][j] = sqrt(pFluids[i]->pEOS->reduce.T*pFluids[j]->pEOS->reduce.T); + v_c[i][j] = 1.0/8.0*pow(pow(pFluids[i]->pEOS->reduce.rhomolar, -1.0/3.0)+pow(pFluids[j]->pEOS->reduce.rhomolar, -1.0/3.0),3); + } Yc_T[i] = pFluids[i]->pEOS->reduce.T; Yc_v[i] = 1/pFluids[i]->pEOS->reduce.rhomolar; - } - }; + } + }; - /// Default destructor - ~GERG2008ReducingFunction(){}; - /** \brief The reducing temperature + /// Default destructor + ~GERG2008ReducingFunction(){}; + /** \brief The reducing temperature * Calculated from \ref Yr with \f$T = Y\f$ */ - long double Tr(const std::vector &x); - /** \brief The derivative of reducing temperature with respect to component i mole fraction + long double Tr(const std::vector &x); + /** \brief The derivative of reducing temperature with respect to component i mole fraction * * Calculated from \ref dYrdxi__constxj with \f$T = Y\f$ */ - long double dTrdxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief The second derivative of reducing temperature with respect to component i mole fraction + long double dTrdxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); + /** \brief The second derivative of reducing temperature with respect to component i mole fraction * * Calculated from \ref d2Yrdxi2__constxj with \f$T = Y\f$ */ @@ -147,7 +147,7 @@ public: * * Calculated from \ref d2Yrdxidxj with \f$T = Y\f$ */ - long double d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + long double d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); /** \brief The derivative of reducing molar volume with respect to component i mole fraction * @@ -168,7 +168,7 @@ public: * * Given by \f$ \rho_r = 1/v_r \f$ */ - long double rhormolar(const std::vector &x); + long double rhormolar(const std::vector &x); /** \brief Derivative of the molar reducing density with respect to component i mole fraction * * See also GERG 2004, Eqn. 7.57 @@ -176,8 +176,8 @@ public: * \left(\frac{\partial \rho_r}{\partial x_i}\right)_{x_{i\neq j}} = -\rho_r^2\left(\frac{\partial v_r}{\partial x_i}\right)_{x_{i\neq j}} * \f] */ - long double drhormolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); - /** \brief Derivative of the molar reducing density with respect to component i mole fraction + long double drhormolardxi__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); + /** \brief Derivative of the molar reducing density with respect to component i mole fraction * * See also GERG 2004, Eqn. 7.58 * \f[ @@ -192,8 +192,8 @@ public: * \left(\frac{\partial^2 \rho_r}{\partial x_i\partial x_j}\right) = 2\rho_r^3\left(\left(\frac{\partial v_r}{\partial x_i}\right)_{x_{i\neq j}}\right)\left(\left(\frac{\partial v_r}{\partial x_j}\right)_{x_{i\neq j}}\right)-\rho_r^2\left(\left(\frac{\partial v_r}{\partial x_i\partial x_j}\right)\right) * \f] */ - long double d2rhormolardxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - + long double d2rhormolardxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); + /** \brief Generalized reducing term \f$Y_r\f$ * * \f[ @@ -253,28 +253,28 @@ public: * c_{Y,ij} = 2\beta_{Y,ij}\gamma_{Y,ij}Y_{c,ij} * \f] */ - long double c_Y_ij(std::size_t i, std::size_t j, const STLMatrix &beta, const STLMatrix &gamma, const STLMatrix &Y_c); + long double c_Y_ij(std::size_t i, std::size_t j, const STLMatrix &beta, const STLMatrix &gamma, const STLMatrix &Y_c); /** \brief The function \f$ f_{Y,ij}(x_i,x_j) \f$ * * \f[ f_{Y,ij}(x_i,x_j) = x_ix_j\frac{x_i+x_j}{\beta_{Y,ij}^2x_i+x_j} \f] */ - long double f_Y_ij(const std::vector &x, std::size_t i, std::size_t j, const STLMatrix &beta); + long double f_Y_ij(const std::vector &x, std::size_t i, std::size_t j, const STLMatrix &beta); /** * * \f[ * \left(\frac{\partial f_{Y,ki}(x_k, x_i)}{\partial x_i}\right)_{x_{k\neq i}} = x_k\frac{x_k+x_i}{\beta_{Y,ki}^2x_k+x_i} + \frac{x_kx_i}{\beta_{Y,ki}^2x_k+x_i}\left(1-\frac{x_k+x_i}{\beta_{Y,ki}^2x_k+x_i}\right) * \f] */ - long double dfYkidxi__constxk(const std::vector &x, std::size_t k, std::size_t i, const STLMatrix &beta); + long double dfYkidxi__constxk(const std::vector &x, std::size_t k, std::size_t i, const STLMatrix &beta); /** * * \f[ * \left(\frac{\partial f_{Y,ik}(x_i, x_k)}{\partial x_i}\right)_{x_k} = x_k\frac{x_i+x_k}{\beta_{Y,ik}^2x_i+x_k} + \frac{x_ix_k}{\beta_{Y,ik}^2x_i+x_k}\left(1-\beta_{Y,ik}^2\frac{x_i+x_k}{\beta_{Y,ik}^2x_i+x_k}\right) * \f] */ - long double dfYikdxi__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta); - /** + long double dfYikdxi__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta); + /** * \f[ * \left(\frac{\partial^2 f_{Y,ki}(x_k, x_i)}{\partial x_i^2}\right)_{x_{k\neq i}} = \frac{1}{\beta_{Y,ki}^2x_k+x_i}\left(1-\frac{x_k+x_i}{\beta_{Y,ki}^2x_k+x_i}\right)\left(2x_k-\frac{2x_kx_i}{\beta_{Y,ki}^2x_k+x_i}\right) * \f] @@ -285,8 +285,8 @@ public: * \left(\frac{\partial^2 f_{Y,ik}(x_i, x_k)}{\partial x_i^2}\right)_{x_{k}} = \frac{1}{\beta_{Y,ik}^2x_i+x_k}\left(1-\beta_{Y,ik}^2\frac{x_i+x_k}{\beta_{Y,ik}^2x_i+x_k}\right)\left(2x_k-\frac{2x_ix_k\beta_{Y,ik}^2}{\beta_{Y,ik}^2x_i+x_k}\right) * \f] */ - long double d2fYikdxi2__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta); - /** + long double d2fYikdxi2__constxk(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta); + /** * \f{eqnarray*}{ * \left(\frac{\partial^2 f_{Y,ki}(x_k, x_i)}{\partial x_i\partial x_j}\right)_{x_{k\neq j\neq i}} &=& \frac{x_i+x_j}{\beta_{Y,ij}^2x_i+x_j} + \frac{x_j}{\beta_{Y,ij}^2x_i+x_j}\left(1-\frac{x_i+x_j}{\beta_{Y,ij}^2x_i+x_j}\right) \\ * &+& \frac{x_i}{\beta_{Y,ij}^2x_i+x_j}\left(1-\beta_{Y,ij}^2\frac{x_i+x_j}{\beta_{Y,ij}^2x_i+x_j}\right) - \frac{x_ix_j}{(\beta_{Y,ij}^2x_i+x_j)^2}\left(1+\beta_{Y,ij}^2-2\beta_{Y,ij}^2\frac{x_i+x_j}{\beta_{Y,ij}^2x_i+x_j}\right) @@ -323,18 +323,18 @@ class LemmonAirHFCReducingFunction protected: LemmonAirHFCReducingFunction(const LemmonAirHFCReducingFunction &); public: - /// Set the coefficients based on reducing parameters loaded from JSON - static void convert_to_GERG(const std::vector &pFluids, std::size_t i, std::size_t j, Dictionary d, long double &beta_T, long double &beta_v, long double &gamma_T, long double &gamma_v) + /// Set the coefficients based on reducing parameters loaded from JSON + static void convert_to_GERG(const std::vector &pFluids, std::size_t i, std::size_t j, Dictionary d, long double &beta_T, long double &beta_v, long double &gamma_T, long double &gamma_v) { long double xi_ij = d.get_number("xi"); long double zeta_ij = d.get_number("zeta"); - beta_T = 1; - beta_v = 1; - gamma_T = (pFluids[i]->pEOS->reduce.T + pFluids[j]->pEOS->reduce.T + xi_ij)/(2*sqrt(pFluids[i]->pEOS->reduce.T*pFluids[j]->pEOS->reduce.T)); - long double v_i = 1/pFluids[i]->pEOS->reduce.rhomolar; - long double v_j = 1/pFluids[j]->pEOS->reduce.rhomolar; - long double one_third = 1.0/3.0; - gamma_v = (v_i + v_j + zeta_ij)/(0.25*pow(pow(v_i, one_third)+pow(v_j, one_third),3)); + beta_T = 1; + beta_v = 1; + gamma_T = (pFluids[i]->pEOS->reduce.T + pFluids[j]->pEOS->reduce.T + xi_ij)/(2*sqrt(pFluids[i]->pEOS->reduce.T*pFluids[j]->pEOS->reduce.T)); + long double v_i = 1/pFluids[i]->pEOS->reduce.rhomolar; + long double v_j = 1/pFluids[j]->pEOS->reduce.rhomolar; + long double one_third = 1.0/3.0; + gamma_v = (v_i + v_j + zeta_ij)/(0.25*pow(pow(v_i, one_third)+pow(v_j, one_third),3)); }; }; diff --git a/src/Backends/Helmholtz/TransportRoutines.cpp b/src/Backends/Helmholtz/TransportRoutines.cpp index 7744df45..2928c4da 100644 --- a/src/Backends/Helmholtz/TransportRoutines.cpp +++ b/src/Backends/Helmholtz/TransportRoutines.cpp @@ -187,113 +187,113 @@ long double TransportRoutines::viscosity_initial_density_dependence_empirical(He static void visc_Helper(double Tbar, double rhobar, double *mubar_0, double *mubar_1) { - std::vector > H(6,std::vector(7,0)); + std::vector > H(6,std::vector(7,0)); double sum; - int i,j; + int i,j; - // Dilute-gas component - *mubar_0=100.0*sqrt(Tbar)/(1.67752+2.20462/Tbar+0.6366564/powInt(Tbar,2)-0.241605/powInt(Tbar,3)); + // Dilute-gas component + *mubar_0=100.0*sqrt(Tbar)/(1.67752+2.20462/Tbar+0.6366564/powInt(Tbar,2)-0.241605/powInt(Tbar,3)); - //Fill in zeros in H - for (i=0;i<=5;i++) - { - for (j=0;j<=6;j++) - { - H[i][j]=0; - } - } + //Fill in zeros in H + for (i=0;i<=5;i++) + { + for (j=0;j<=6;j++) + { + H[i][j]=0; + } + } - //Set non-zero parameters of H - H[0][0]=5.20094e-1; - H[1][0]=8.50895e-2; - H[2][0]=-1.08374; - H[3][0]=-2.89555e-1; + //Set non-zero parameters of H + H[0][0]=5.20094e-1; + H[1][0]=8.50895e-2; + H[2][0]=-1.08374; + H[3][0]=-2.89555e-1; - H[0][1]=2.22531e-1; - H[1][1]=9.99115e-1; - H[2][1]=1.88797; - H[3][1]=1.26613; - H[5][1]=1.20573e-1; + H[0][1]=2.22531e-1; + H[1][1]=9.99115e-1; + H[2][1]=1.88797; + H[3][1]=1.26613; + H[5][1]=1.20573e-1; - H[0][2]=-2.81378e-1; - H[1][2]=-9.06851e-1; - H[2][2]=-7.72479e-1; - H[3][2]=-4.89837e-1; - H[4][2]=-2.57040e-1; + H[0][2]=-2.81378e-1; + H[1][2]=-9.06851e-1; + H[2][2]=-7.72479e-1; + H[3][2]=-4.89837e-1; + H[4][2]=-2.57040e-1; - H[0][3]=1.61913e-1; - H[1][3]=2.57399e-1; + H[0][3]=1.61913e-1; + H[1][3]=2.57399e-1; - H[0][4]=-3.25372e-2; - H[3][4]=6.98452e-2; + H[0][4]=-3.25372e-2; + H[3][4]=6.98452e-2; - H[4][5]=8.72102e-3; + H[4][5]=8.72102e-3; - H[3][6]=-4.35673e-3; - H[5][6]=-5.93264e-4; + H[3][6]=-4.35673e-3; + H[5][6]=-5.93264e-4; - // Finite density component - sum=0; - for (i=0;i<=5;i++) - { - for (j=0;j<=6;j++) - { - sum+=powInt(1/Tbar-1,i)*(H[i][j]*powInt(rhobar-1,j)); - } - } - *mubar_1=exp(rhobar*sum); + // Finite density component + sum=0; + for (i=0;i<=5;i++) + { + for (j=0;j<=6;j++) + { + sum+=powInt(1/Tbar-1,i)*(H[i][j]*powInt(rhobar-1,j)); + } + } + *mubar_1=exp(rhobar*sum); } long double TransportRoutines::viscosity_water_hardcoded(HelmholtzEOSMixtureBackend &HEOS) { - double x_mu=0.068,qc=1/1.9,qd=1/1.1,nu=0.630,gamma=1.239,zeta_0=0.13,LAMBDA_0=0.06,Tbar_R=1.5, pstar, Tstar, rhostar; - double delta,tau,mubar_0,mubar_1,mubar_2,drhodp,drhodp_R,DeltaChibar,zeta,w,L,Y,psi_D,Tbar,rhobar; - double drhobar_dpbar,drhobar_dpbar_R,R_Water; + double x_mu=0.068,qc=1/1.9,qd=1/1.1,nu=0.630,gamma=1.239,zeta_0=0.13,LAMBDA_0=0.06,Tbar_R=1.5, pstar, Tstar, rhostar; + double delta,tau,mubar_0,mubar_1,mubar_2,drhodp,drhodp_R,DeltaChibar,zeta,w,L,Y,psi_D,Tbar,rhobar; + double drhobar_dpbar,drhobar_dpbar_R,R_Water; pstar = 22.064e6; // [Pa] Tstar = 647.096; // [K] rhostar = 322; // [kg/m^3] - Tbar = HEOS.T()/Tstar; + Tbar = HEOS.T()/Tstar; rhobar = HEOS.rhomass()/rhostar; R_Water = HEOS.gas_constant()/HEOS.molar_mass(); // [J/kg/K] - // Dilute and finite gas portions - visc_Helper(Tbar, rhobar, &mubar_0, &mubar_1); + // Dilute and finite gas portions + visc_Helper(Tbar, rhobar, &mubar_0, &mubar_1); // ********************************************************************** - // ************************ Critical Enhancement ************************ + // ************************ Critical Enhancement ************************ // ********************************************************************** - delta=rhobar; - // "Normal" calculation - tau=1/Tbar; - drhodp=1/(R_Water*HEOS.T()*(1+2*delta*HEOS.dalphar_dDelta()+delta*delta*HEOS.d2alphar_dDelta2())); - drhobar_dpbar = pstar/rhostar*drhodp; - // "Reducing" calculation - tau=1/Tbar_R; - drhodp_R=1/(R_Water*Tbar_R*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,tau,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,tau, delta))); - drhobar_dpbar_R = pstar/rhostar*drhodp_R; + delta=rhobar; + // "Normal" calculation + tau=1/Tbar; + drhodp=1/(R_Water*HEOS.T()*(1+2*delta*HEOS.dalphar_dDelta()+delta*delta*HEOS.d2alphar_dDelta2())); + drhobar_dpbar = pstar/rhostar*drhodp; + // "Reducing" calculation + tau=1/Tbar_R; + drhodp_R=1/(R_Water*Tbar_R*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,tau,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,tau, delta))); + drhobar_dpbar_R = pstar/rhostar*drhodp_R; - DeltaChibar=rhobar*(drhobar_dpbar-drhobar_dpbar_R*Tbar_R/Tbar); - if (DeltaChibar<0) - DeltaChibar=0; - zeta=zeta_0*pow(DeltaChibar/LAMBDA_0,nu/gamma); - if (zeta<0.3817016416){ - Y=1.0/5.0*qc*zeta*powInt(qd*zeta,5)*(1-qc*zeta+powInt(qc*zeta,2)-765.0/504.0*powInt(qd*zeta,2)); - } - else - { - psi_D=acos(pow(1+powInt(qd*zeta,2),-1.0/2.0)); - w=sqrt(std::abs((qc*zeta-1)/(qc*zeta+1)))*tan(psi_D/2.0); - if (qc*zeta>1){ - L=log((1+w)/(1-w)); - } - else{ - L=2*atan(std::abs(w)); - } - Y=1.0/12.0*sin(3*psi_D)-1/(4*qc*zeta)*sin(2*psi_D)+1.0/powInt(qc*zeta,2)*(1-5.0/4.0*powInt(qc*zeta,2))*sin(psi_D)-1.0/powInt(qc*zeta,3)*((1-3.0/2.0*powInt(qc*zeta,2))*psi_D-pow(std::abs(powInt(qc*zeta,2)-1),3.0/2.0)*L); - } - mubar_2=exp(x_mu*Y); + DeltaChibar=rhobar*(drhobar_dpbar-drhobar_dpbar_R*Tbar_R/Tbar); + if (DeltaChibar<0) + DeltaChibar=0; + zeta=zeta_0*pow(DeltaChibar/LAMBDA_0,nu/gamma); + if (zeta<0.3817016416){ + Y=1.0/5.0*qc*zeta*powInt(qd*zeta,5)*(1-qc*zeta+powInt(qc*zeta,2)-765.0/504.0*powInt(qd*zeta,2)); + } + else + { + psi_D=acos(pow(1+powInt(qd*zeta,2),-1.0/2.0)); + w=sqrt(std::abs((qc*zeta-1)/(qc*zeta+1)))*tan(psi_D/2.0); + if (qc*zeta>1){ + L=log((1+w)/(1-w)); + } + else{ + L=2*atan(std::abs(w)); + } + Y=1.0/12.0*sin(3*psi_D)-1/(4*qc*zeta)*sin(2*psi_D)+1.0/powInt(qc*zeta,2)*(1-5.0/4.0*powInt(qc*zeta,2))*sin(psi_D)-1.0/powInt(qc*zeta,3)*((1-3.0/2.0*powInt(qc*zeta,2))*psi_D-pow(std::abs(powInt(qc*zeta,2)-1),3.0/2.0)*L); + } + mubar_2=exp(x_mu*Y); - return (mubar_0*mubar_1*mubar_2)/1e6; + return (mubar_0*mubar_1*mubar_2)/1e6; } long double TransportRoutines::viscosity_hydrogen_higher_order_hardcoded(HelmholtzEOSMixtureBackend &HEOS) { @@ -314,7 +314,7 @@ long double TransportRoutines::viscosity_hexane_higher_order_hardcoded(Helmholtz // Output is in Pa-s double c[] = {2.53402335/1e6, -9.724061002/1e6, 0.469437316, 158.5571631, 72.42916856/1e6, 10.60751253, 8.628373915, -6.61346441, -2.212724566}; - return pow(rhor,static_cast(2.0/3.0))*sqrt(Tr)*(c[0]/Tr+c[1]/(c[2]+Tr+c[3]*rhor*rhor)+c[4]*(1+rhor)/(c[5]+c[6]*Tr+c[7]*rhor+rhor*rhor+c[8]*rhor*Tr)); + return pow(rhor,static_cast(2.0/3.0))*sqrt(Tr)*(c[0]/Tr+c[1]/(c[2]+Tr+c[3]*rhor*rhor)+c[4]*(1+rhor)/(c[5]+c[6]*Tr+c[7]*rhor+rhor*rhor+c[8]*rhor*Tr)); } long double TransportRoutines::viscosity_heptane_higher_order_hardcoded(HelmholtzEOSMixtureBackend &HEOS) @@ -324,7 +324,7 @@ long double TransportRoutines::viscosity_heptane_higher_order_hardcoded(Helmholt // Output is in Pa-s double c[] = {0, 22.15000/1e6, -15.00870/1e6, 3.71791/1e6, 77.72818/1e6, 9.73449, 9.51900, -6.34076, -2.51909}; - return pow(rhor,2.0L/3.0L)*sqrt(Tr)*(c[1]*rhor+c[2]*pow(rhor,2)+c[3]*pow(rhor,3)+c[4]*rhor/(c[5]+c[6]*Tr+c[7]*rhor+rhor*rhor+c[8]*rhor*Tr)); + return pow(rhor,2.0L/3.0L)*sqrt(Tr)*(c[1]*rhor+c[2]*pow(rhor,2)+c[3]*pow(rhor,3)+c[4]*rhor/(c[5]+c[6]*Tr+c[7]*rhor+rhor*rhor+c[8]*rhor*Tr)); } long double TransportRoutines::viscosity_higher_order_friction_theory(HelmholtzEOSMixtureBackend &HEOS) @@ -336,26 +336,26 @@ long double TransportRoutines::viscosity_higher_order_friction_theory(HelmholtzE long double tau = F.T_reduce/HEOS.T(), kii, krrr, kaaa, krr, kdrdr; double psi1 = exp(tau)-F.c1; - double psi2 = exp(pow(tau,2))-F.c2; + double psi2 = exp(pow(tau,2))-F.c2; - double ki = (F.Ai[0] + F.Ai[1]*psi1 + F.Ai[2]*psi2)*tau; + double ki = (F.Ai[0] + F.Ai[1]*psi1 + F.Ai[2]*psi2)*tau; double ka = (F.Aa[0] + F.Aa[1]*psi1 + F.Aa[2]*psi2)*pow(tau, F.Na); - double kr = (F.Ar[0] + F.Ar[1]*psi1 + F.Ar[2]*psi2)*pow(tau, F.Nr); - double kaa = (F.Aaa[0] + F.Aaa[1]*psi1 + F.Aaa[2]*psi2)*pow(tau, F.Naa); + double kr = (F.Ar[0] + F.Ar[1]*psi1 + F.Ar[2]*psi2)*pow(tau, F.Nr); + double kaa = (F.Aaa[0] + F.Aaa[1]*psi1 + F.Aaa[2]*psi2)*pow(tau, F.Naa); if (F.Arr.empty()){ krr = 0; kdrdr = (F.Adrdr[0] + F.Adrdr[1]*psi1 + F.Adrdr[2]*psi2)*pow(tau, F.Nrr); } else{ - krr = (F.Arr[0] + F.Arr[1]*psi1 + F.Arr[2]*psi2)*pow(tau, F.Nrr); + krr = (F.Arr[0] + F.Arr[1]*psi1 + F.Arr[2]*psi2)*pow(tau, F.Nrr); kdrdr = 0; } if (!F.Aii.empty() && !F.Arrr.empty() && !F.Aaaa.empty()){ - kii = (F.Aii[0] + F.Aii[1]*psi1 + F.Aii[2]*psi2)*pow(tau, F.Nii); - krrr = (F.Arrr[0] + F.Arrr[1]*psi1 + F.Arrr[2]*psi2)*pow(tau, F.Nrrr); - kaaa = (F.Aaaa[0] + F.Aaaa[1]*psi1 + F.Aaaa[2]*psi2)*pow(tau, F.Naaa); + kii = (F.Aii[0] + F.Aii[1]*psi1 + F.Aii[2]*psi2)*pow(tau, F.Nii); + krrr = (F.Arrr[0] + F.Arrr[1]*psi1 + F.Arrr[2]*psi2)*pow(tau, F.Nrrr); + kaaa = (F.Aaaa[0] + F.Aaaa[1]*psi1 + F.Aaaa[2]*psi2)*pow(tau, F.Naaa); } else{ kii = 0; @@ -364,12 +364,12 @@ long double TransportRoutines::viscosity_higher_order_friction_theory(HelmholtzE } double p = HEOS.p()/1e5; // [bar]; 1e5 for conversion from Pa -> bar - double pr = HEOS.T()*HEOS.first_partial_deriv(CoolProp::iP, CoolProp::iT, CoolProp::iDmolar)/1e5; // [bar/K]; 1e5 for conversion from Pa -> bar - double pa = p - pr; //[bar] + double pr = HEOS.T()*HEOS.first_partial_deriv(CoolProp::iP, CoolProp::iT, CoolProp::iDmolar)/1e5; // [bar/K]; 1e5 for conversion from Pa -> bar + double pa = p - pr; //[bar] double pid = HEOS.rhomolar() * HEOS.gas_constant() * HEOS.T() / 1e5; // [bar]; 1e5 for conversion from Pa -> bar - double deltapr = pr - pid; + double deltapr = pr - pid; - double eta_f = ka*pa + kr*deltapr + ki*pid + kaa*pa*pa + kdrdr*deltapr*deltapr + krr*pr*pr + kii*pid*pid + krrr*pr*pr*pr + kaaa*pa*pa*pa; + double eta_f = ka*pa + kr*deltapr + ki*pid + kaa*pa*pa + kdrdr*deltapr*deltapr + krr*pr*pr + kii*pid*pid + krrr*pr*pr*pr + kaaa*pa*pa*pa; return eta_f; //[Pa-s] } @@ -381,43 +381,43 @@ long double TransportRoutines::viscosity_higher_order_friction_theory(HelmholtzE long double TransportRoutines::viscosity_helium_hardcoded(HelmholtzEOSMixtureBackend &HEOS) { double eta_0,eta_0_slash, eta_E_slash, B,C,D,ln_eta,x; - // - // Arp, V.D., McCarty, R.D., and Friend, D.G., - // "Thermophysical Properties of Helium-4 from 0.8 to 1500 K with Pressures to 2000 MPa", - // NIST Technical Note 1334 (revised), 1998. - // - // Using Arp NIST report - // Report is not clear on viscosity, referring to REFPROP source code for clarity + // + // Arp, V.D., McCarty, R.D., and Friend, D.G., + // "Thermophysical Properties of Helium-4 from 0.8 to 1500 K with Pressures to 2000 MPa", + // NIST Technical Note 1334 (revised), 1998. + // + // Using Arp NIST report + // Report is not clear on viscosity, referring to REFPROP source code for clarity - // Correlation wants density in g/cm^3; kg/m^3 --> g/cm^3, divide by 1000 + // Correlation wants density in g/cm^3; kg/m^3 --> g/cm^3, divide by 1000 long double rho = HEOS.keyed_output(CoolProp::iDmass)/1000.0, T = HEOS.T(); if (T <= 300){ - x = log(T); - } - else{ - x = log(300.0); - } - // Evaluate the terms B,C,D - B = -47.5295259/x+87.6799309-42.0741589*x+8.33128289*x*x-0.589252385*x*x*x; - C = 547.309267/x-904.870586+431.404928*x-81.4504854*x*x+5.37008433*x*x*x; - D = -1684.39324/x+3331.08630-1632.19172*x+308.804413*x*x-20.2936367*x*x*x; - eta_0_slash = -0.135311743/x+1.00347841+1.20654649*x-0.149564551*x*x+0.012520841*x*x*x; - eta_E_slash = rho*B+rho*rho*C+rho*rho*rho*D; + x = log(T); + } + else{ + x = log(300.0); + } + // Evaluate the terms B,C,D + B = -47.5295259/x+87.6799309-42.0741589*x+8.33128289*x*x-0.589252385*x*x*x; + C = 547.309267/x-904.870586+431.404928*x-81.4504854*x*x+5.37008433*x*x*x; + D = -1684.39324/x+3331.08630-1632.19172*x+308.804413*x*x-20.2936367*x*x*x; + eta_0_slash = -0.135311743/x+1.00347841+1.20654649*x-0.149564551*x*x+0.012520841*x*x*x; + eta_E_slash = rho*B+rho*rho*C+rho*rho*rho*D; if (T<=100) - { - ln_eta = eta_0_slash + eta_E_slash; + { + ln_eta = eta_0_slash + eta_E_slash; // Correlation yields viscosity in micro g/(cm-s); to get Pa-s, divide by 10 to get micro Pa-s, then another 1e6 to get Pa-s - return exp(ln_eta)/10.0/1e6; - } - else - { - ln_eta = eta_0_slash + eta_E_slash; - eta_0 = 196*pow(T,static_cast(0.71938))*exp(12.451/T-295.67/T/T-4.1249); + return exp(ln_eta)/10.0/1e6; + } + else + { + ln_eta = eta_0_slash + eta_E_slash; + eta_0 = 196*pow(T,static_cast(0.71938))*exp(12.451/T-295.67/T/T-4.1249); // Correlation yields viscosity in micro g/(cm-s); to get Pa-s, divide by 10 to get micro Pa-s, then another 1e6 to get Pa-s - return (exp(ln_eta)+eta_0-exp(eta_0_slash))/10.0/1e6; - } + return (exp(ln_eta)+eta_0-exp(eta_0_slash))/10.0/1e6; + } } long double TransportRoutines::viscosity_methanol_hardcoded(HelmholtzEOSMixtureBackend &HEOS) @@ -484,68 +484,68 @@ long double TransportRoutines::viscosity_methanol_hardcoded(HelmholtzEOSMixtureB long double TransportRoutines::viscosity_R23_hardcoded(HelmholtzEOSMixtureBackend &HEOS) { double C1 = 1.3163, // - C2 = 0.1832, - DeltaGstar = 771.23, - rhoL = 32.174, - rhocbar = 7.5114, + C2 = 0.1832, + DeltaGstar = 771.23, + rhoL = 32.174, + rhocbar = 7.5114, Tc = 299.2793, - DELTAeta_max = 3.967, - Ru = 8.31451, + DELTAeta_max = 3.967, + Ru = 8.31451, molar_mass = 70.014; - double a[] = {0.4425728, -0.5138403, 0.1547566, -0.02821844, 0.001578286}; - double e_k = 243.91, sigma = 0.4278; - double Tstar = HEOS.T()/e_k; - double logTstar = log(Tstar); - double Omega = exp(a[0]+a[1]*logTstar+a[2]*pow(logTstar,2)+a[3]*pow(logTstar,3)+a[4]*pow(logTstar,4)); + double a[] = {0.4425728, -0.5138403, 0.1547566, -0.02821844, 0.001578286}; + double e_k = 243.91, sigma = 0.4278; + double Tstar = HEOS.T()/e_k; + double logTstar = log(Tstar); + double Omega = exp(a[0]+a[1]*logTstar+a[2]*pow(logTstar,2)+a[3]*pow(logTstar,3)+a[4]*pow(logTstar,4)); double eta_DG = 1.25*0.021357*sqrt(molar_mass*HEOS.T())/(sigma*sigma*Omega); // uPa-s - double rhobar = HEOS.rhomolar()/1000; // [mol/L] - double eta_L = C2*(rhoL*rhoL)/(rhoL-rhobar)*sqrt(HEOS.T())*exp(rhobar/(rhoL-rhobar)*DeltaGstar/(Ru*HEOS.T())); + double rhobar = HEOS.rhomolar()/1000; // [mol/L] + double eta_L = C2*(rhoL*rhoL)/(rhoL-rhobar)*sqrt(HEOS.T())*exp(rhobar/(rhoL-rhobar)*DeltaGstar/(Ru*HEOS.T())); - double chi = rhobar - rhocbar; - double tau = HEOS.T() - Tc; + double chi = rhobar - rhocbar; + double tau = HEOS.T() - Tc; - double DELTAeta_c = 4*DELTAeta_max/((exp(chi)+exp(-chi))*(exp(tau)+exp(-tau))); + double DELTAeta_c = 4*DELTAeta_max/((exp(chi)+exp(-chi))*(exp(tau)+exp(-tau))); - return (pow((rhoL-rhobar)/rhoL,C1)*eta_DG+pow(rhobar/rhoL,C1)*eta_L+DELTAeta_c)/1e6; + return (pow((rhoL-rhobar)/rhoL,C1)*eta_DG+pow(rhobar/rhoL,C1)*eta_L+DELTAeta_c)/1e6; } long double TransportRoutines::viscosity_dilute_ethane(HelmholtzEOSMixtureBackend &HEOS) { double C[] = {0, -3.0328138281, 16.918880086, -37.189364917, 41.288861858, -24.615921140, 8.9488430959, -1.8739245042, 0.20966101390, -9.6570437074e-3}; - double OMEGA_2_2 = 0, e_k = 245, Tstar; + double OMEGA_2_2 = 0, e_k = 245, Tstar; - Tstar = HEOS.T()/e_k; - for (int i = 1; i<= 9; i++) - { - OMEGA_2_2 += C[i]*pow(Tstar,(i-1)/3.0-1); - } + Tstar = HEOS.T()/e_k; + for (int i = 1; i<= 9; i++) + { + OMEGA_2_2 += C[i]*pow(Tstar,(i-1)/3.0-1); + } - return 12.0085*sqrt(Tstar)*OMEGA_2_2/1e6; //[Pa-s] + return 12.0085*sqrt(Tstar)*OMEGA_2_2/1e6; //[Pa-s] } long double TransportRoutines::viscosity_dilute_cyclohexane(HelmholtzEOSMixtureBackend &HEOS) { // From Tariq, JPCRD, 2014 long double T = HEOS.T(); long double S_eta = exp(-1.5093 + 364.87/T - 39537/pow(T, 2)); //[nm^2] - return 0.19592*sqrt(T)/S_eta/1e6; //[Pa-s] + return 0.19592*sqrt(T)/S_eta/1e6; //[Pa-s] } long double TransportRoutines::viscosity_ethane_higher_order_hardcoded(HelmholtzEOSMixtureBackend &HEOS) { - double r[] = {0,1,1,2,2,2,3,3,4,4,1,1}; - double s[] = {0,0,1,0,1,1.5,0,2,0,1,0,1}; - double g[] = {0, 0.47177003, -0.23950311, 0.39808301, -0.27343335, 0.35192260, -0.21101308, -0.00478579, 0.07378129, -0.030435255, -0.30435286, 0.001215675}; + double r[] = {0,1,1,2,2,2,3,3,4,4,1,1}; + double s[] = {0,0,1,0,1,1.5,0,2,0,1,0,1}; + double g[] = {0, 0.47177003, -0.23950311, 0.39808301, -0.27343335, 0.35192260, -0.21101308, -0.00478579, 0.07378129, -0.030435255, -0.30435286, 0.001215675}; - double sum1 = 0, sum2 = 0, tau = 305.33/HEOS.T(), delta = HEOS.rhomolar()/6870; + double sum1 = 0, sum2 = 0, tau = 305.33/HEOS.T(), delta = HEOS.rhomolar()/6870; - for (int i = 1; i<= 9; ++i){ - sum1 += g[i]*pow(delta,r[i])*pow(tau,s[i]); - } - for (int i = 10; i<= 11; ++i){ - sum2 += g[i]*pow(delta,r[i])*pow(tau,s[i]); - } - return 15.977*sum1/(1+sum2)/1e6; + for (int i = 1; i<= 9; ++i){ + sum1 += g[i]*pow(delta,r[i])*pow(tau,s[i]); + } + for (int i = 10; i<= 11; ++i){ + sum2 += g[i]*pow(delta,r[i])*pow(tau,s[i]); + } + return 15.977*sum1/(1+sum2)/1e6; } long double TransportRoutines::conductivity_dilute_ratio_polynomials(HelmholtzEOSMixtureBackend &HEOS){ @@ -615,9 +615,9 @@ long double TransportRoutines::conductivity_critical_simplified_Olchowy_Sengers( // Retrieve values from the state class CoolProp::ConductivityCriticalSimplifiedOlchowySengersData &data = HEOS.components[0]->transport.conductivity_critical.Olchowy_Sengers; - double k = data.k, - R0 = data.R0, - nu = data.nu, + double k = data.k, + R0 = data.R0, + nu = data.nu, gamma = data.gamma, GAMMA = data.GAMMA, zeta0 = data.zeta0, @@ -625,8 +625,8 @@ long double TransportRoutines::conductivity_critical_simplified_Olchowy_Sengers( Tc = HEOS.get_reducing_state().T, // [K] rhoc = HEOS.get_reducing_state().rhomolar, // [mol/m^3] Pcrit = HEOS.get_reducing_state().p, // [Pa] - Tref, // [K] - cp,cv,delta,num,zeta,mu,pi=M_PI, + Tref, // [K] + cp,cv,delta,num,zeta,mu,pi=M_PI, OMEGA_tilde,OMEGA_tilde0; if (ValidNumber(data.T_ref)) @@ -634,32 +634,32 @@ long double TransportRoutines::conductivity_critical_simplified_Olchowy_Sengers( else Tref = 1.5*Tc; - delta = HEOS.delta(); + delta = HEOS.delta(); double dp_drho = HEOS.gas_constant()*HEOS.T()*(1+2*delta*HEOS.dalphar_dDelta()+delta*delta*HEOS.d2alphar_dDelta2()); - double X = Pcrit/pow(rhoc,2)*HEOS.rhomolar()/dp_drho; + double X = Pcrit/pow(rhoc,2)*HEOS.rhomolar()/dp_drho; - double tau_ref = Tc/Tref; + double tau_ref = Tc/Tref; double dp_drho_ref = HEOS.gas_constant()*Tref*(1+2*delta*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,tau_ref,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,tau_ref,delta)); - double Xref = Pcrit/pow(rhoc, 2)*HEOS.rhomolar()/dp_drho_ref*Tref/HEOS.T(); - num = X - Xref; + double Xref = Pcrit/pow(rhoc, 2)*HEOS.rhomolar()/dp_drho_ref*Tref/HEOS.T(); + num = X - Xref; - // No critical enhancement if numerator is negative, zero, or just a tiny bit positive due to roundoff + // No critical enhancement if numerator is negative, zero, or just a tiny bit positive due to roundoff // See also Lemmon, IJT, 2004, page 27 - if (num < DBL_EPSILON*10) - return 0.0; - else - zeta = zeta0*pow(num/GAMMA, nu/gamma); //[m] + if (num < DBL_EPSILON*10) + return 0.0; + else + zeta = zeta0*pow(num/GAMMA, nu/gamma); //[m] cp = HEOS.cpmolar(); //[J/mol/K] - cv = HEOS.cvmolar(); //[J/mol/K] - mu = HEOS.viscosity(); //[Pa-s] + cv = HEOS.cvmolar(); //[J/mol/K] + mu = HEOS.viscosity(); //[Pa-s] - OMEGA_tilde = 2.0/pi*((cp-cv)/cp*atan(zeta*qD)+cv/cp*(zeta*qD)); //[-] - OMEGA_tilde0 = 2.0/pi*(1.0-exp(-1.0/(1.0/(qD*zeta)+1.0/3.0*(zeta*qD)*(zeta*qD)/delta/delta))); //[-] + OMEGA_tilde = 2.0/pi*((cp-cv)/cp*atan(zeta*qD)+cv/cp*(zeta*qD)); //[-] + OMEGA_tilde0 = 2.0/pi*(1.0-exp(-1.0/(1.0/(qD*zeta)+1.0/3.0*(zeta*qD)*(zeta*qD)/delta/delta))); //[-] - double lambda = HEOS.rhomolar()*cp*R0*k*HEOS.T()/(6*pi*mu*zeta)*(OMEGA_tilde - OMEGA_tilde0); //[W/m/K] - return lambda; //[W/m/K] + double lambda = HEOS.rhomolar()*cp*R0*k*HEOS.T()/(6*pi*mu*zeta)*(OMEGA_tilde - OMEGA_tilde0); //[W/m/K] + return lambda; //[W/m/K] } else{ throw NotImplementedError("TransportRoutines::conductivity_critical_simplified_Olchowy_Sengers is only for pure and pseudo-pure"); @@ -688,31 +688,31 @@ long double TransportRoutines::conductivity_critical_hardcoded_CO2_ScalabrinJPCR long double TransportRoutines::conductivity_dilute_hardcoded_CO2(HelmholtzEOSMixtureBackend &HEOS){ double e_k = 251.196, Tstar; - double b[] = {0.4226159, 0.6280115, -0.5387661, 0.6735941, 0, 0, -0.4362677, 0.2255388}; - double c[] = {0, 2.387869e-2, 4.350794, -10.33404, 7.981590, -1.940558}; + double b[] = {0.4226159, 0.6280115, -0.5387661, 0.6735941, 0, 0, -0.4362677, 0.2255388}; + double c[] = {0, 2.387869e-2, 4.350794, -10.33404, 7.981590, -1.940558}; - //Vesovic Eq. 31 [no units] - double summer = 0; - for (int i=1; i<=5; i++) - summer += c[i]*pow(HEOS.T()/100.0, 2-i); - double cint_k = 1.0 + exp(-183.5/HEOS.T())*summer; + //Vesovic Eq. 31 [no units] + double summer = 0; + for (int i=1; i<=5; i++) + summer += c[i]*pow(HEOS.T()/100.0, 2-i); + double cint_k = 1.0 + exp(-183.5/HEOS.T())*summer; - //Vesovic Eq. 12 [no units] - double r = sqrt(2.0/5.0*cint_k); + //Vesovic Eq. 12 [no units] + double r = sqrt(2.0/5.0*cint_k); // According to REFPROP, 1+r^2 = cp-2.5R. This is unclear to me but seems to suggest that cint/k is the difference // between the ideal gas specific heat and a monatomic specific heat of 5/2*R. Using the form of cint/k from Vesovic // does not yield exactly the correct values - Tstar = HEOS.T()/e_k; - //Vesovic Eq. 30 [no units] - summer = 0; - for (int i=0; i<=7; i++) - summer += b[i]/pow(Tstar, i); - double Gstar_lambda = summer; + Tstar = HEOS.T()/e_k; + //Vesovic Eq. 30 [no units] + summer = 0; + for (int i=0; i<=7; i++) + summer += b[i]/pow(Tstar, i); + double Gstar_lambda = summer; - //Vesovic Eq. 29 [W/m/K] - double lambda_0 = 0.475598e-3*sqrt(HEOS.T())*(1+r*r)/Gstar_lambda; + //Vesovic Eq. 29 [W/m/K] + double lambda_0 = 0.475598e-3*sqrt(HEOS.T())*(1+r*r)/Gstar_lambda; return lambda_0; } @@ -720,8 +720,8 @@ long double TransportRoutines::conductivity_dilute_hardcoded_CO2(HelmholtzEOSMix long double TransportRoutines::conductivity_dilute_hardcoded_ethane(HelmholtzEOSMixtureBackend &HEOS){ double e_k = 245.0; - double tau = 305.33/HEOS.T(), Tstar = HEOS.T()/e_k; - double fint = 1.7104147-0.6936482/Tstar; + double tau = 305.33/HEOS.T(), Tstar = HEOS.T()/e_k; + double fint = 1.7104147-0.6936482/Tstar; double lambda_0 = 0.276505e-3*(HEOS.calc_viscosity_dilute()*1e6)*(3.75-fint*(tau*tau*HEOS.d2alpha0_dTau2()+1.5)); //[W/m/K] return lambda_0; @@ -735,9 +735,9 @@ long double TransportRoutines::conductivity_dilute_eta0_and_poly(HelmholtzEOSMix double eta0_uPas = HEOS.calc_viscosity_dilute()*1e6; // [uPa-s] double summer = E.A[0]*eta0_uPas; - for (std::size_t i=1; i < E.A.size(); ++i) - summer += E.A[i]*pow(static_cast(HEOS.tau()), E.t[i]); - return summer; + for (std::size_t i=1; i < E.A.size(); ++i) + summer += E.A[i]*pow(static_cast(HEOS.tau()), E.t[i]); + return summer; } else{ throw NotImplementedError("TransportRoutines::conductivity_dilute_eta0_and_poly is only for pure and pseudo-pure"); @@ -747,146 +747,146 @@ long double TransportRoutines::conductivity_dilute_eta0_and_poly(HelmholtzEOSMix long double TransportRoutines::conductivity_hardcoded_water(HelmholtzEOSMixtureBackend &HEOS){ double L[5][6] = {{1.60397357,-0.646013523,0.111443906,0.102997357,-0.0504123634,0.00609859258}, - {2.33771842,-2.78843778,1.53616167,-0.463045512,0.0832827019,-0.00719201245}, - {2.19650529,-4.54580785,3.55777244,-1.40944978,0.275418278,-0.0205938816}, - {-1.21051378,1.60812989,-0.621178141,0.0716373224,0,0}, - {-2.7203370,4.57586331,-3.18369245,1.1168348,-0.19268305,0.012913842}}; + {2.33771842,-2.78843778,1.53616167,-0.463045512,0.0832827019,-0.00719201245}, + {2.19650529,-4.54580785,3.55777244,-1.40944978,0.275418278,-0.0205938816}, + {-1.21051378,1.60812989,-0.621178141,0.0716373224,0,0}, + {-2.7203370,4.57586331,-3.18369245,1.1168348,-0.19268305,0.012913842}}; - double lambdabar_0,lambdabar_1,lambdabar_2,rhobar,Tbar,sum; - double Tstar=647.096,rhostar=322,pstar=22064000,lambdastar=1e-3,mustar=1e-6; - double xi; - int i,j; + double lambdabar_0,lambdabar_1,lambdabar_2,rhobar,Tbar,sum; + double Tstar=647.096,rhostar=322,pstar=22064000,lambdastar=1e-3,mustar=1e-6; + double xi; + int i,j; double R = 461.51805; //[J/kg/K] - Tbar = HEOS.T()/Tstar; - rhobar = HEOS.keyed_output(CoolProp::iDmass)/rhostar; + Tbar = HEOS.T()/Tstar; + rhobar = HEOS.keyed_output(CoolProp::iDmass)/rhostar; double rho = HEOS.keyed_output(CoolProp::iDmass); - // Dilute gas contribution - lambdabar_0 = sqrt(Tbar)/(2.443221e-3+1.323095e-2/Tbar+6.770357e-3/pow(Tbar,2)-3.454586e-3/pow(Tbar,3)+4.096266e-4/pow(Tbar,4)); + // Dilute gas contribution + lambdabar_0 = sqrt(Tbar)/(2.443221e-3+1.323095e-2/Tbar+6.770357e-3/pow(Tbar,2)-3.454586e-3/pow(Tbar,3)+4.096266e-4/pow(Tbar,4)); - sum=0; - for (i=0;i<=4;i++){ - for (j=0;j<=5;j++){ - sum+=L[i][j]*powInt(1.0/Tbar-1.0,i)*powInt(rhobar-1,j); - } - } - // Finite density contribution - lambdabar_1=exp(rhobar*sum); + sum=0; + for (i=0;i<=4;i++){ + for (j=0;j<=5;j++){ + sum+=L[i][j]*powInt(1.0/Tbar-1.0,i)*powInt(rhobar-1,j); + } + } + // Finite density contribution + lambdabar_1=exp(rhobar*sum); - double nu=0.630,GAMMA =177.8514,gamma=1.239,xi_0=0.13,Lambda_0=0.06,Tr_bar=1.5, + double nu=0.630,GAMMA =177.8514,gamma=1.239,xi_0=0.13,Lambda_0=0.06,Tr_bar=1.5, qd_bar=1/0.4,pi=3.141592654, delta = HEOS.delta(); - double drhodp = 1/(R*HEOS.T()*(1+2*rhobar*HEOS.dalphar_dDelta()+rhobar*rhobar*HEOS.d2alphar_dDelta2())); - double drhobar_dpbar = pstar/rhostar*drhodp; - double drhodp_Trbar = 1/(R*Tr_bar*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,1/Tr_bar,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,1/Tr_bar,delta))); - double drhobar_dpbar_Trbar = pstar/rhostar*drhodp_Trbar; + double drhodp = 1/(R*HEOS.T()*(1+2*rhobar*HEOS.dalphar_dDelta()+rhobar*rhobar*HEOS.d2alphar_dDelta2())); + double drhobar_dpbar = pstar/rhostar*drhodp; + double drhodp_Trbar = 1/(R*Tr_bar*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,1/Tr_bar,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,1/Tr_bar,delta))); + double drhobar_dpbar_Trbar = pstar/rhostar*drhodp_Trbar; double cp = HEOS.cpmass(); // [J/kg/K] - double cv = HEOS.cvmass(); // [J/kg/K] - double cpbar = cp/R; //[-] - double mubar = HEOS.viscosity()/mustar; - double DELTAchibar_T = rhobar*(drhobar_dpbar-drhobar_dpbar_Trbar*Tr_bar/Tbar); - if (DELTAchibar_T<0) - xi = 0; - else - xi = xi_0*pow(DELTAchibar_T/Lambda_0,nu/gamma); - double y = qd_bar*xi; + double cv = HEOS.cvmass(); // [J/kg/K] + double cpbar = cp/R; //[-] + double mubar = HEOS.viscosity()/mustar; + double DELTAchibar_T = rhobar*(drhobar_dpbar-drhobar_dpbar_Trbar*Tr_bar/Tbar); + if (DELTAchibar_T<0) + xi = 0; + else + xi = xi_0*pow(DELTAchibar_T/Lambda_0,nu/gamma); + double y = qd_bar*xi; - double Z; - double kappa = cp/cv; - if (y < 1.2e-7) - Z = 0; - else - Z = 2/(pi*y)*(((1-1/kappa)*atan(y)+y/kappa)-(1-exp(-1/(1/y+y*y/3/rhobar/rhobar)))); + double Z; + double kappa = cp/cv; + if (y < 1.2e-7) + Z = 0; + else + Z = 2/(pi*y)*(((1-1/kappa)*atan(y)+y/kappa)-(1-exp(-1/(1/y+y*y/3/rhobar/rhobar)))); - lambdabar_2 = GAMMA*rhobar*cpbar*Tbar/mubar*Z; + lambdabar_2 = GAMMA*rhobar*cpbar*Tbar/mubar*Z; - return (lambdabar_0*lambdabar_1+lambdabar_2)*lambdastar; + return (lambdabar_0*lambdabar_1+lambdabar_2)*lambdastar; } long double TransportRoutines::conductivity_hardcoded_R23(HelmholtzEOSMixtureBackend &HEOS){ double B1 = -2.5370, // [mW/m/K] - B2 = 0.05366, // [mW/m/K^2] - C1 = 0.94215, // [-] - C2 = 0.14914, // [mW/m/K^2] - DeltaGstar = 2508.58, //[J/mol] - rhoL = 68.345, // [mol/dm^3] = [mol/L] - rhocbar = 7.5114, // [mol/dm^3] - DELTAlambda_max = 25, //[mW/m/K] - Ru = 8.31451, // [J/mol/K] + B2 = 0.05366, // [mW/m/K^2] + C1 = 0.94215, // [-] + C2 = 0.14914, // [mW/m/K^2] + DeltaGstar = 2508.58, //[J/mol] + rhoL = 68.345, // [mol/dm^3] = [mol/L] + rhocbar = 7.5114, // [mol/dm^3] + DELTAlambda_max = 25, //[mW/m/K] + Ru = 8.31451, // [J/mol/K] Tc = 299.2793, //[K] T = HEOS.T(); //[K] - double lambda_DG = B1 + B2*T; + double lambda_DG = B1 + B2*T; - double rhobar = HEOS.rhomolar()/1000; // [mol/L] - double lambda_L = C2*(rhoL*rhoL)/(rhoL-rhobar)*sqrt(T)*exp(rhobar/(rhoL-rhobar)*DeltaGstar/(Ru*T)); + double rhobar = HEOS.rhomolar()/1000; // [mol/L] + double lambda_L = C2*(rhoL*rhoL)/(rhoL-rhobar)*sqrt(T)*exp(rhobar/(rhoL-rhobar)*DeltaGstar/(Ru*T)); - double chi = rhobar - rhocbar; - double tau = T - Tc; + double chi = rhobar - rhocbar; + double tau = T - Tc; - double DELTAlambda_c = 4*DELTAlambda_max/((exp(chi)+exp(-chi))*(exp(tau)+exp(-tau))); + double DELTAlambda_c = 4*DELTAlambda_max/((exp(chi)+exp(-chi))*(exp(tau)+exp(-tau))); - return (pow((rhoL-rhobar)/rhoL,C1)*lambda_DG+pow(rhobar/rhoL,C1)*lambda_L+DELTAlambda_c)/1e3; + return (pow((rhoL-rhobar)/rhoL,C1)*lambda_DG+pow(rhobar/rhoL,C1)*lambda_L+DELTAlambda_c)/1e3; } long double TransportRoutines::conductivity_critical_hardcoded_ammonia(HelmholtzEOSMixtureBackend &HEOS){ /* - From "Thermal Conductivity of Ammonia in a Large - Temperature and Pressure Range Including the Critical Region" - by R. Tufeu, D.Y. Ivanov, Y. Garrabos, B. Le Neindre, - Bereicht der Bunsengesellschaft Phys. Chem. 88 (1984) 422-427 - */ + From "Thermal Conductivity of Ammonia in a Large + Temperature and Pressure Range Including the Critical Region" + by R. Tufeu, D.Y. Ivanov, Y. Garrabos, B. Le Neindre, + Bereicht der Bunsengesellschaft Phys. Chem. 88 (1984) 422-427 + */ double T = HEOS.T(), Tc = 405.4, rhoc = 235, rho; - double LAMBDA=1.2, nu=0.63, gamma =1.24, DELTA=0.50,t,zeta_0_plus=1.34e-10,a_zeta=1,GAMMA_0_plus=0.423e-8; - double pi=3.141592654,a_chi,k_B=1.3806504e-23,X_T,DELTA_lambda,dPdT,eta_B,DELTA_lambda_id,DELTA_lambda_i; + double LAMBDA=1.2, nu=0.63, gamma =1.24, DELTA=0.50,t,zeta_0_plus=1.34e-10,a_zeta=1,GAMMA_0_plus=0.423e-8; + double pi=3.141592654,a_chi,k_B=1.3806504e-23,X_T,DELTA_lambda,dPdT,eta_B,DELTA_lambda_id,DELTA_lambda_i; rho = HEOS.keyed_output(CoolProp::iDmass); - t = std::abs((T-Tc)/Tc); - a_chi = a_zeta/0.7; - eta_B = (2.60+1.6*t)*1e-5; - dPdT = (2.18-0.12/exp(17.8*t))*1e5; // [Pa-K] - X_T = 0.61*rhoc+16.5*log(t); - // Along the critical isochore (only a function of temperature) (Eq. 9) - DELTA_lambda_i = LAMBDA*(k_B*T*T)/(6*pi*eta_B*(zeta_0_plus*pow(t,-nu)*(1+a_zeta*pow(t,DELTA))))*dPdT*dPdT*GAMMA_0_plus*pow(t,-gamma)*(1+a_chi*pow(t,DELTA)); - DELTA_lambda_id = DELTA_lambda_i*exp(-36*t*t); - if (rho < 0.6*rhoc) - { - DELTA_lambda = DELTA_lambda_id*(X_T*X_T)/(X_T*X_T+powInt(0.6*rhoc-0.96*rhoc,2))*powInt(rho,2)/powInt(0.6*rhoc,2); - } - else - { - DELTA_lambda = DELTA_lambda_id*(X_T*X_T)/(X_T*X_T+powInt(rho-0.96*rhoc,2)); - } + t = std::abs((T-Tc)/Tc); + a_chi = a_zeta/0.7; + eta_B = (2.60+1.6*t)*1e-5; + dPdT = (2.18-0.12/exp(17.8*t))*1e5; // [Pa-K] + X_T = 0.61*rhoc+16.5*log(t); + // Along the critical isochore (only a function of temperature) (Eq. 9) + DELTA_lambda_i = LAMBDA*(k_B*T*T)/(6*pi*eta_B*(zeta_0_plus*pow(t,-nu)*(1+a_zeta*pow(t,DELTA))))*dPdT*dPdT*GAMMA_0_plus*pow(t,-gamma)*(1+a_chi*pow(t,DELTA)); + DELTA_lambda_id = DELTA_lambda_i*exp(-36*t*t); + if (rho < 0.6*rhoc) + { + DELTA_lambda = DELTA_lambda_id*(X_T*X_T)/(X_T*X_T+powInt(0.6*rhoc-0.96*rhoc,2))*powInt(rho,2)/powInt(0.6*rhoc,2); + } + else + { + DELTA_lambda = DELTA_lambda_id*(X_T*X_T)/(X_T*X_T+powInt(rho-0.96*rhoc,2)); + } - return DELTA_lambda; + return DELTA_lambda; } long double TransportRoutines::conductivity_hardcoded_helium(HelmholtzEOSMixtureBackend &HEOS){ /* - What an incredibly annoying formulation! Implied coefficients?? Not cool. - */ + What an incredibly annoying formulation! Implied coefficients?? Not cool. + */ double rhoc = 68.0, lambda_e, lambda_c, T = HEOS.T(), rho = HEOS.rhomass(); - double summer = 3.739232544/T-2.620316969e1/T/T+5.982252246e1/T/T/T-4.926397634e1/T/T/T/T; - double lambda_0 = 2.7870034e-3*pow(T, 7.034007057e-1)*exp(summer); - double c[]={ 1.862970530e-4, - -7.275964435e-7, - -1.427549651e-4, - 3.290833592e-5, - -5.213335363e-8, - 4.492659933e-8, - -5.924416513e-9, - 7.087321137e-6, - -6.013335678e-6, - 8.067145814e-7, - 3.995125013e-7}; - // Equation 17 - lambda_e = (c[0]+c[1]*T+c[2]*pow(T,1/3.0)+c[3]*pow(T,2.0/3.0))*rho - +(c[4]+c[5]*pow(T,1.0/3.0)+c[6]*pow(T,2.0/3.0))*rho*rho*rho - +(c[7]+c[8]*pow(T,1.0/3.0)+c[9]*pow(T,2.0/3.0)+c[10]/T)*rho*rho*log(rho/rhoc); + double summer = 3.739232544/T-2.620316969e1/T/T+5.982252246e1/T/T/T-4.926397634e1/T/T/T/T; + double lambda_0 = 2.7870034e-3*pow(T, 7.034007057e-1)*exp(summer); + double c[]={ 1.862970530e-4, + -7.275964435e-7, + -1.427549651e-4, + 3.290833592e-5, + -5.213335363e-8, + 4.492659933e-8, + -5.924416513e-9, + 7.087321137e-6, + -6.013335678e-6, + 8.067145814e-7, + 3.995125013e-7}; + // Equation 17 + lambda_e = (c[0]+c[1]*T+c[2]*pow(T,1/3.0)+c[3]*pow(T,2.0/3.0))*rho + +(c[4]+c[5]*pow(T,1.0/3.0)+c[6]*pow(T,2.0/3.0))*rho*rho*rho + +(c[7]+c[8]*pow(T,1.0/3.0)+c[9]*pow(T,2.0/3.0)+c[10]/T)*rho*rho*log(rho/rhoc); // Critical component lambda_c = 0.0; @@ -928,9 +928,9 @@ long double TransportRoutines::conductivity_hardcoded_helium(HelmholtzEOSMixture // 3.4685233d-17 and 3.726229668d0 are "magical" coefficients that are present in the REFPROP source to yield the right values. Not clear why these values are needed. // Also, the form of the critical term in REFPROP does not agree with Hands paper. EL and MH from NIST are not sure where these coefficients come from. - lambda_c = 3.4685233e-17*3.726229668*sqrt(K_Tbar)*pow(T,2)/rho/eta*pow(dpdT,2)*exp(-18.66*pow(DeltaT,2)-4.25*pow(DeltaRho,4)); + lambda_c = 3.4685233e-17*3.726229668*sqrt(K_Tbar)*pow(T,2)/rho/eta*pow(dpdT,2)*exp(-18.66*pow(DeltaT,2)-4.25*pow(DeltaRho,4)); } - return lambda_0+lambda_e+lambda_c; + return lambda_0+lambda_e+lambda_c; } long double TransportRoutines::viscosity_ECS(HelmholtzEOSMixtureBackend &HEOS, HelmholtzEOSMixtureBackend &HEOS_Reference) @@ -962,7 +962,7 @@ long double TransportRoutines::viscosity_ECS(HelmholtzEOSMixtureBackend &HEOS, H // The equivalent substance reducing ratios long double f = Tc/Tc0*theta; - long double h = rhocmolar0/rhocmolar*phi; // Must be the ratio of MOLAR densities!! + long double h = rhocmolar0/rhocmolar*phi; // Must be the ratio of MOLAR densities!! // To be solved for long double T0 = HEOS.T()/f; @@ -975,10 +975,10 @@ long double TransportRoutines::viscosity_ECS(HelmholtzEOSMixtureBackend &HEOS, H long double eta_resid = HEOS_Reference.calc_viscosity_background(); // The F factor - long double F_eta = sqrt(f)*pow(h, static_cast(-2.0/3.0))*sqrt(M/M0); + long double F_eta = sqrt(f)*pow(h, static_cast(-2.0/3.0))*sqrt(M/M0); // The total viscosity considering the contributions of the fluid of interest and the reference fluid [Pa-s] - long double eta = eta_dilute + eta_resid*F_eta; + long double eta = eta_dilute + eta_resid*F_eta; return eta; } @@ -1031,7 +1031,7 @@ long double TransportRoutines::conductivity_ECS(HelmholtzEOSMixtureBackend &HEOS // The equivalent substance reducing ratios long double f = Tc/Tc0*theta; - long double h = rhocmolar0/rhocmolar*phi; // Must be the ratio of MOLAR densities!! + long double h = rhocmolar0/rhocmolar*phi; // Must be the ratio of MOLAR densities!! // To be solved for long double T0 = HEOS.T()/f; @@ -1044,13 +1044,13 @@ long double TransportRoutines::conductivity_ECS(HelmholtzEOSMixtureBackend &HEOS long double lambda_resid = HEOS_Reference.calc_conductivity_background(); // The F factor - long double F_lambda = sqrt(f)*pow(h, static_cast(-2.0/3.0))*sqrt(M0/M); + long double F_lambda = sqrt(f)*pow(h, static_cast(-2.0/3.0))*sqrt(M0/M); // The critical contribution from the fluid of interest [W/m/K] long double lambda_critical = conductivity_critical_simplified_Olchowy_Sengers(HEOS); // The total thermal conductivity considering the contributions of the fluid of interest and the reference fluid [Pa-s] - long double lambda = lambda_int + lambda_dilute + lambda_resid*F_lambda + lambda_critical; + long double lambda = lambda_int + lambda_dilute + lambda_resid*F_lambda + lambda_critical; return lambda; } diff --git a/src/Backends/Helmholtz/VLERoutines.cpp b/src/Backends/Helmholtz/VLERoutines.cpp index 8ca296a8..fb9eea70 100644 --- a/src/Backends/Helmholtz/VLERoutines.cpp +++ b/src/Backends/Helmholtz/VLERoutines.cpp @@ -193,22 +193,22 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l { // Invert liquid density ancillary to get temperature // TODO: fit inverse ancillaries too - try{ - T = HEOS.get_components()[0]->ancillaries.pL.invert(specified_value); - } - catch(std::exception &e) - { - throw ValueError("Unable to invert ancillary equation"); - } + try{ + T = HEOS.get_components()[0]->ancillaries.pL.invert(specified_value); + } + catch(std::exception &e) + { + throw ValueError("Unable to invert ancillary equation"); + } } else if (options.specified_variable == saturation_PHSU_pure_options::IMPOSED_HL) { CoolProp::SimpleState hs_anchor = HEOS.get_state("hs_anchor"); // Ancillary is deltah = h - hs_anchor.h try{ T = HEOS.get_components()[0]->ancillaries.hL.invert(specified_value - hs_anchor.hmolar); } - catch(std::exception &e){ - throw ValueError("Unable to invert ancillary equation for hL"); - } + catch(std::exception &e){ + throw ValueError("Unable to invert ancillary equation for hL"); + } } else if (options.specified_variable == saturation_PHSU_pure_options::IMPOSED_HV) { @@ -235,12 +235,12 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l double Tmin = Tmin_satL; double Tmax = HEOS.calc_Tmax_sat(); try{ T = Brent(resid, Tmin-3, Tmax + 1, DBL_EPSILON, 1e-10, 50, errstr); } - catch(std::exception &e){ + catch(std::exception &e){ shared_ptr HEOS_copy(new HelmholtzEOSMixtureBackend(HEOS.get_components())); HEOS_copy->update(QT_INPUTS, 1, Tmin); double hTmin = HEOS_copy->hmolar(); HEOS_copy->update(QT_INPUTS, 1, Tmax); double hTmax = HEOS_copy->hmolar(); T = (Tmax-Tmin)/(hTmax-hTmin)*(HEOS.hmolar()-hTmin) + Tmin; - } + } } else if (options.specified_variable == saturation_PHSU_pure_options::IMPOSED_SL) { @@ -457,7 +457,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l } // dr_3/ddelta'' (liquid pressure not a function of vapor density) J[2][2] = 0; - specified_parameter = CoolProp::iP; + specified_parameter = CoolProp::iP; break; case saturation_PHSU_pure_options::IMPOSED_PV: // dr_3/dtau @@ -472,7 +472,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l // dr_3/ddelta'' J[2][2] = SatV->first_partial_deriv(iP,iDelta,iTau)/specified_value; } - specified_parameter = CoolProp::iP; + specified_parameter = CoolProp::iP; break; case saturation_PHSU_pure_options::IMPOSED_HL: // dr_3/dtau @@ -482,7 +482,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l if (options.use_logdelta){ J[2][1]*=deltaL;} // dr_3/ddelta'' J[2][2] = 0; //(liquid enthalpy not a function of vapor density) - specified_parameter = CoolProp::iHmolar; + specified_parameter = CoolProp::iHmolar; break; case saturation_PHSU_pure_options::IMPOSED_HV: // dr_3/dtau @@ -492,7 +492,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l // dr_3/ddelta'' J[2][2] = SatV->first_partial_deriv(iHmolar,iDelta,iTau); if (options.use_logdelta){ J[2][2]*=deltaV;} - specified_parameter = CoolProp::iHmolar; + specified_parameter = CoolProp::iHmolar; break; case saturation_PHSU_pure_options::IMPOSED_SL: // dr_3/dtau @@ -502,7 +502,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l if (options.use_logdelta){ J[2][1] *= deltaL; } // dr_3/ddelta'' J[2][2] = 0; //(liquid entropy not a function of vapor density) - specified_parameter = CoolProp::iSmolar; + specified_parameter = CoolProp::iSmolar; break; case saturation_PHSU_pure_options::IMPOSED_SV: // dr_3/dtau @@ -512,7 +512,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l // dr_3/ddelta'' J[2][2] = SatV->first_partial_deriv(iSmolar,iDelta,iTau); if (options.use_logdelta){ J[2][2]*=deltaV;} - specified_parameter = CoolProp::iSmolar; + specified_parameter = CoolProp::iSmolar; break; default: throw ValueError(format("options.specified_variable to saturation_PHSU_pure [%d] is invalid",options.specified_variable)); @@ -557,7 +557,7 @@ void SaturationSolvers::saturation_PHSU_pure(HelmholtzEOSMixtureBackend &HEOS, l // Set values back into the options structure for use in next solver options.rhoL = rhoL; options.rhoV = rhoV; options.T = T; // Error out - std::string info = get_parameter_information(specified_parameter, "short"); + std::string info = get_parameter_information(specified_parameter, "short"); throw SolutionError(format("saturation_PHSU_pure solver did not converge after 50 iterations for %s=%Lg current error is %Lg", info.c_str(), specified_value, error)); } } @@ -704,8 +704,8 @@ void SaturationSolvers::saturation_D_pure(HelmholtzEOSMixtureBackend &HEOS, long rhoL = deltaL*reduce.rhomolar; rhoV = deltaV*reduce.rhomolar; T = reduce.T/tau; - - p_error = (pL-pV)/pL; + + p_error = (pL-pV)/pL; error = sqrt(pow(r[0], 2)+pow(r[1], 2)); iter++; @@ -718,10 +718,10 @@ void SaturationSolvers::saturation_D_pure(HelmholtzEOSMixtureBackend &HEOS, long } } while (error > 1e-9); - long double p_error_limit = 1e-3; - if (std::abs(p_error) > p_error_limit){ - throw SolutionError(format("saturation_D_pure solver abs error on p [%Lg] > limit [%Lg]", p_error, p_error_limit)); - } + long double p_error_limit = 1e-3; + if (std::abs(p_error) > p_error_limit){ + throw SolutionError(format("saturation_D_pure solver abs error on p [%Lg] > limit [%Lg]", p_error, p_error_limit)); + } } void SaturationSolvers::saturation_T_pure(HelmholtzEOSMixtureBackend &HEOS, long double T, saturation_T_pure_options &options) { @@ -783,8 +783,8 @@ void SaturationSolvers::saturation_T_pure_Akasaka(HelmholtzEOSMixtureBackend &HE } else { - // Use the density ancillary function as the starting point for the solver - + // Use the density ancillary function as the starting point for the solver + // If very close to the critical temp, evaluate the ancillaries for a slightly lower temperature if (T > 0.99*HEOS.get_reducing_state().T){ rhoL = HEOS.get_components()[0]->ancillaries.rhoL.evaluate(T-0.1); @@ -793,13 +793,13 @@ void SaturationSolvers::saturation_T_pure_Akasaka(HelmholtzEOSMixtureBackend &HE else{ rhoL = HEOS.get_components()[0]->ancillaries.rhoL.evaluate(T); rhoV = HEOS.get_components()[0]->ancillaries.rhoV.evaluate(T); - - // Apply a single step of Newton's method to improve guess value for liquid - // based on the error between the gas pressure (which is usually very close already) - // and the liquid pressure, which can sometimes (especially at low pressure), - // be way off, and often times negative - SatL->update(DmolarT_INPUTS, rhoL, T); - SatV->update(DmolarT_INPUTS, rhoV, T); + + // Apply a single step of Newton's method to improve guess value for liquid + // based on the error between the gas pressure (which is usually very close already) + // and the liquid pressure, which can sometimes (especially at low pressure), + // be way off, and often times negative + SatL->update(DmolarT_INPUTS, rhoL, T); + SatV->update(DmolarT_INPUTS, rhoV, T); // Update the guess for liquid density using density solver with vapor pressure // and liquid density guess from ancillaries @@ -827,8 +827,8 @@ void SaturationSolvers::saturation_T_pure_Akasaka(HelmholtzEOSMixtureBackend &HE //tau = reduce.T/T; } //if (get_debug_level()>5){ - // std::cout << format("%s:%d: Akasaka guess values deltaL = %g deltaV = %g tau = %g\n",__FILE__,__LINE__,deltaL, deltaV, tau).c_str(); - // } + // std::cout << format("%s:%d: Akasaka guess values deltaL = %g deltaV = %g tau = %g\n",__FILE__,__LINE__,deltaL, deltaV, tau).c_str(); + // } do{ /*if (get_debug_level()>8){ @@ -888,16 +888,16 @@ void SaturationSolvers::saturation_T_pure_Akasaka(HelmholtzEOSMixtureBackend &HE } } while (error > 1e-10 && std::abs(stepL) > 10*DBL_EPSILON*std::abs(stepL) && std::abs(stepV) > 10*DBL_EPSILON*std::abs(stepV)); - - long double p_error_limit = 1e-3; - long double p_error = (PL - PV)/PL; - if (std::abs(p_error) > p_error_limit){ + + long double p_error_limit = 1e-3; + long double p_error = (PL - PV)/PL; + if (std::abs(p_error) > p_error_limit){ options.pL = PL; options.pV = PV; options.rhoL = rhoL; options.rhoV = rhoV; - throw SolutionError(format("saturation_T_pure_Akasaka solver abs error on p [%g] > limit [%g]", std::abs(p_error), p_error_limit)); - } + throw SolutionError(format("saturation_T_pure_Akasaka solver abs error on p [%g] > limit [%g]", std::abs(p_error), p_error_limit)); + } } long double sign(long double x) @@ -936,8 +936,8 @@ void SaturationSolvers::saturation_T_pure_Maxwell(HelmholtzEOSMixtureBackend &HE } else { - // Use the density ancillary function as the starting point for the solver - + // Use the density ancillary function as the starting point for the solver + // If very close to the critical temp, evaluate the ancillaries for a slightly lower temperature if (T > 0.9999*HEOS.get_reducing_state().T){ rhoL = HEOS.get_components()[0]->ancillaries.rhoL.evaluate(T-0.1); @@ -946,13 +946,13 @@ void SaturationSolvers::saturation_T_pure_Maxwell(HelmholtzEOSMixtureBackend &HE else{ rhoL = HEOS.get_components()[0]->ancillaries.rhoL.evaluate(T); rhoV = HEOS.get_components()[0]->ancillaries.rhoV.evaluate(T); - - // Apply a single step of Newton's method to improve guess value for liquid - // based on the error between the gas pressure (which is usually very close already) - // and the liquid pressure, which can sometimes (especially at low pressure), - // be way off, and often times negative - SatL->update(DmolarT_INPUTS, rhoL, T); - SatV->update(DmolarT_INPUTS, rhoV, T); + + // Apply a single step of Newton's method to improve guess value for liquid + // based on the error between the gas pressure (which is usually very close already) + // and the liquid pressure, which can sometimes (especially at low pressure), + // be way off, and often times negative + SatL->update(DmolarT_INPUTS, rhoL, T); + SatV->update(DmolarT_INPUTS, rhoV, T); // Update the guess for liquid density using density solver with vapor pressure // and liquid density guess from ancillaries, but only if the pressures are not diff --git a/src/Backends/Helmholtz/VLERoutines.h b/src/Backends/Helmholtz/VLERoutines.h index f00d5027..36c6f60a 100644 --- a/src/Backends/Helmholtz/VLERoutines.h +++ b/src/Backends/Helmholtz/VLERoutines.h @@ -37,15 +37,15 @@ namespace SaturationSolvers }; /*! Returns the natural logarithm of K for component i using the method from Wilson as in - \f[ - \ln K_i = \ln\left(\frac{p_{c,i}}{p}\right)+5.373(1+\omega_i)\left(1-\frac{T_{c,i}}{T}\right) - \f] + \f[ + \ln K_i = \ln\left(\frac{p_{c,i}}{p}\right)+5.373(1+\omega_i)\left(1-\frac{T_{c,i}}{T}\right) + \f] @param HEOS The Helmholtz EOS mixture backend - @param T Temperature [K] - @param p Pressure [Pa] - @param i Index of component [-] - */ - static long double Wilson_lnK_factor(HelmholtzEOSMixtureBackend &HEOS, long double T, long double p, int i){ + @param T Temperature [K] + @param p Pressure [Pa] + @param i Index of component [-] + */ + static long double Wilson_lnK_factor(HelmholtzEOSMixtureBackend &HEOS, long double T, long double p, int i){ EquationOfState *EOS = (HEOS.get_components())[i]->pEOS; return log(EOS->reduce.p/p)+5.373*(1 + EOS->accentric)*(1-EOS->reduce.T/T); }; @@ -130,12 +130,12 @@ namespace SaturationSolvers { public: int input_type; - double T, p, beta; - const std::vector *z; + double T, p, beta; + const std::vector *z; std::vector *K; - HelmholtzEOSMixtureBackend *HEOS; + HelmholtzEOSMixtureBackend *HEOS; - WilsonK_resid(HelmholtzEOSMixtureBackend &HEOS, double beta, double imposed_value, int input_type, const std::vector &z, std::vector &K){ + WilsonK_resid(HelmholtzEOSMixtureBackend &HEOS, double beta, double imposed_value, int input_type, const std::vector &z, std::vector &K){ this->z = &z; this->K = &K; this->HEOS = &HEOS; this->beta = beta; this->input_type = input_type; if (input_type == imposed_T){ this->T = imposed_value; @@ -143,35 +143,35 @@ namespace SaturationSolvers else{ this->p = imposed_value; } - }; - double call(double input_value){ - double summer = 0; + }; + double call(double input_value){ + double summer = 0; if (input_type == imposed_T){ p = input_value; // Iterate on pressure } else{ T = input_value; // Iterate on temperature, pressure imposed } - for (unsigned int i = 0; i< (*z).size(); i++) { - (*K)[i] = exp(Wilson_lnK_factor(*HEOS,T,p,i)); - summer += (*z)[i]*((*K)[i]-1)/(1-beta+beta*(*K)[i]); - } - return summer; - }; + for (unsigned int i = 0; i< (*z).size(); i++) { + (*K)[i] = exp(Wilson_lnK_factor(*HEOS,T,p,i)); + summer += (*z)[i]*((*K)[i]-1)/(1-beta+beta*(*K)[i]); + } + return summer; + }; }; inline double saturation_preconditioner(HelmholtzEOSMixtureBackend &HEOS, double input_value, int input_type, const std::vector &z) { - double ptriple = 0, pcrit = 0, Ttriple = 0, Tcrit = 0; - - for (unsigned int i = 0; i < z.size(); i++) - { + double ptriple = 0, pcrit = 0, Ttriple = 0, Tcrit = 0; + + for (unsigned int i = 0; i < z.size(); i++) + { EquationOfState *EOS = (HEOS.get_components())[i]->pEOS; - ptriple += EOS->sat_min_liquid.p*z[i]; + ptriple += EOS->sat_min_liquid.p*z[i]; pcrit += EOS->reduce.p*z[i]; - Ttriple += EOS->sat_min_liquid.T*z[i]; - Tcrit += EOS->reduce.T*z[i]; - } + Ttriple += EOS->sat_min_liquid.T*z[i]; + Tcrit += EOS->reduce.T*z[i]; + } if (input_type == imposed_T) { @@ -185,16 +185,16 @@ namespace SaturationSolvers } inline double saturation_Wilson(HelmholtzEOSMixtureBackend &HEOS, double beta, double input_value, int input_type, const std::vector &z, double guess) { - double T; + double T; - std::string errstr; + std::string errstr; - // Find first guess for T using Wilson K-factors + // Find first guess for T using Wilson K-factors WilsonK_resid Resid(HEOS, beta, input_value, input_type, z, HEOS.get_K()); - T = Secant(Resid, guess, 0.001, 1e-10, 100, errstr); - - if (!ValidNumber(T)){throw ValueError("saturation_p_Wilson failed to get good T");} - return T; + T = Secant(Resid, guess, 0.001, 1e-10, 100, errstr); + + if (!ValidNumber(T)){throw ValueError("saturation_p_Wilson failed to get good T");} + return T; } struct SuccessiveSubstitutionStep { @@ -245,41 +245,41 @@ namespace SaturationSolvers { public: newton_raphson_twophase_options::imposed_variable_options imposed_variable; - long double error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change, beta; - unsigned int N; - bool logging; - int Nsteps; - STLMatrix J; + long double error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change, beta; + unsigned int N; + bool logging; + int Nsteps; + STLMatrix J; HelmholtzEOSMixtureBackend *HEOS; - std::vector K, x, y, z, r, negative_r, err_rel; - std::vector step_logger; + std::vector K, x, y, z, r, negative_r, err_rel; + std::vector step_logger; - newton_raphson_twophase(){}; + newton_raphson_twophase(){}; - void resize(unsigned int N); - - // Reset the state of all the internal variables - void pre_call() - { - K.clear(); x.clear(); y.clear(); step_logger.clear(); error_rms = 1e99; Nsteps = 0; - rhomolar_liq = _HUGE; rhomolar_vap = _HUGE; T = _HUGE; p = _HUGE; - }; + void resize(unsigned int N); + + // Reset the state of all the internal variables + void pre_call() + { + K.clear(); x.clear(); y.clear(); step_logger.clear(); error_rms = 1e99; Nsteps = 0; + rhomolar_liq = _HUGE; rhomolar_vap = _HUGE; T = _HUGE; p = _HUGE; + }; - /** \brief Call the Newton-Raphson VLE Solver + /** \brief Call the Newton-Raphson VLE Solver * - * This solver must be passed reasonable guess values for the mole fractions, - * densities, etc. You may want to take a few steps of successive substitution - * before you start with Newton Raphson. + * This solver must be passed reasonable guess values for the mole fractions, + * densities, etc. You may want to take a few steps of successive substitution + * before you start with Newton Raphson. * - * @param HEOS HelmholtzEOSMixtureBackend instance + * @param HEOS HelmholtzEOSMixtureBackend instance * @param IO The input/output data structure - */ - void call(HelmholtzEOSMixtureBackend &HEOS, newton_raphson_twophase_options &IO); + */ + void call(HelmholtzEOSMixtureBackend &HEOS, newton_raphson_twophase_options &IO); - /* \brief Build the arrays for the Newton-Raphson solve + /* \brief Build the arrays for the Newton-Raphson solve * - */ - void build_arrays(); + */ + void build_arrays(); }; @@ -325,48 +325,48 @@ namespace SaturationSolvers { public: newton_raphson_saturation_options::imposed_variable_options imposed_variable; - long double error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change; - unsigned int N; - bool logging; + long double error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change; + unsigned int N; + bool logging; bool bubble_point; - int Nsteps; - STLMatrix J; + int Nsteps; + STLMatrix J; HelmholtzEOSMixtureBackend *HEOS; long double dTsat_dPsat, dPsat_dTsat; - std::vector K, x, y, r, negative_r, err_rel; - std::vector step_logger; + std::vector K, x, y, r, negative_r, err_rel; + std::vector step_logger; - newton_raphson_saturation(){}; + newton_raphson_saturation(){}; - void resize(unsigned int N); - - // Reset the state of all the internal variables - void pre_call() - { - K.clear(); x.clear(); y.clear(); + void resize(unsigned int N); + + // Reset the state of all the internal variables + void pre_call() + { + K.clear(); x.clear(); y.clear(); step_logger.clear(); error_rms = 1e99; Nsteps = 0; - rhomolar_liq = _HUGE; rhomolar_vap = _HUGE; T = _HUGE; p = _HUGE; - }; + rhomolar_liq = _HUGE; rhomolar_vap = _HUGE; T = _HUGE; p = _HUGE; + }; - /** \brief Call the Newton-Raphson VLE Solver + /** \brief Call the Newton-Raphson VLE Solver * - * This solver must be passed reasonable guess values for the mole fractions, - * densities, etc. You may want to take a few steps of successive substitution - * before you start with Newton Raphson. + * This solver must be passed reasonable guess values for the mole fractions, + * densities, etc. You may want to take a few steps of successive substitution + * before you start with Newton Raphson. * - * @param HEOS HelmholtzEOSMixtureBackend instance - * @param z Bulk mole fractions [-] - * @param z_incipient Initial guesses for the mole fractions of the incipient phase [-] + * @param HEOS HelmholtzEOSMixtureBackend instance + * @param z Bulk mole fractions [-] + * @param z_incipient Initial guesses for the mole fractions of the incipient phase [-] * @param IO The input/output data structure - */ - void call(HelmholtzEOSMixtureBackend &HEOS, const std::vector &z, std::vector &z_incipient, newton_raphson_saturation_options &IO); + */ + void call(HelmholtzEOSMixtureBackend &HEOS, const std::vector &z, std::vector &z_incipient, newton_raphson_saturation_options &IO); - /** \brief Build the arrays for the Newton-Raphson solve + /** \brief Build the arrays for the Newton-Raphson solve * - * This method builds the Jacobian matrix, the sensitivity matrix, etc. + * This method builds the Jacobian matrix, the sensitivity matrix, etc. * - */ - void build_arrays(); + */ + void build_arrays(); /** \brief Check the derivatives in the Jacobian using numerical derivatives. */ diff --git a/src/Backends/Incompressible/IncompressibleBackend.cpp b/src/Backends/Incompressible/IncompressibleBackend.cpp index d81d510b..4a44d3cd 100644 --- a/src/Backends/Incompressible/IncompressibleBackend.cpp +++ b/src/Backends/Incompressible/IncompressibleBackend.cpp @@ -24,17 +24,17 @@ IncompressibleBackend::IncompressibleBackend() { } IncompressibleBackend::IncompressibleBackend(IncompressibleFluid* fluid) { - //this->_fractions_id = fluid->getxid(); + //this->_fractions_id = fluid->getxid(); this->fluid = fluid; } IncompressibleBackend::IncompressibleBackend(const std::string &fluid_name) { - this->fluid = &get_incompressible_fluid(fluid_name); + this->fluid = &get_incompressible_fluid(fluid_name); //this->_fractions_id = this->fluid->getxid(); } IncompressibleBackend::IncompressibleBackend(const std::vector &component_names) { - throw NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids"); + throw NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids"); } void IncompressibleBackend::update(CoolProp::input_pairs input_pair, double value1, double value2) { @@ -42,62 +42,62 @@ void IncompressibleBackend::update(CoolProp::input_pairs input_pair, double valu // throw ValueError("mass fractions have not been set"); //} - if (get_debug_level()>=10) { - //throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for the solver, %d is not valid. ",__FILE__,__LINE__,axis)); - std::cout << format("Incompressible backend: Called update with %d and %f, %f ",input_pair, value1, value2) << std::endl; - } + if (get_debug_level()>=10) { + //throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for the solver, %d is not valid. ",__FILE__,__LINE__,axis)); + std::cout << format("Incompressible backend: Called update with %d and %f, %f ",input_pair, value1, value2) << std::endl; + } - clear(); + clear(); - if (get_debug_level()>=50) std::cout << format("Incompressible backend: _fractions are %s ",vec_to_string(_fractions).c_str()) << std::endl; - if (fluid->is_pure()){ - this->_fluid_type = FLUID_TYPE_INCOMPRESSIBLE_LIQUID; - if (get_debug_level()>=50) std::cout << format("Incompressible backend: Fluid type is %d ",this->_fluid_type) << std::endl; - if ((_fractions.size()!=1) || (_fractions[0]!=0.0)){ - throw ValueError(format("%s is a pure fluid. The composition has to be set to a vector with one entry equal to 0.0 or nothing. %s is not valid.",this->name().c_str(),vec_to_string(_fractions).c_str())); - } - } else { - this->_fluid_type = FLUID_TYPE_INCOMPRESSIBLE_SOLUTION; - if (get_debug_level()>=50) std::cout << format("Incompressible backend: Fluid type is %d ",this->_fluid_type) << std::endl; - if (_fractions.size()!=1 || ((_fractions[0]<0.0) || (_fractions[0]>1.0)) ){ - throw ValueError(format("%s is a solution or brine. Mass fractions must be set to a vector with one entry between 0 and 1. %s is not valid.",this->name().c_str(),vec_to_string(_fractions).c_str())); - } - } + if (get_debug_level()>=50) std::cout << format("Incompressible backend: _fractions are %s ",vec_to_string(_fractions).c_str()) << std::endl; + if (fluid->is_pure()){ + this->_fluid_type = FLUID_TYPE_INCOMPRESSIBLE_LIQUID; + if (get_debug_level()>=50) std::cout << format("Incompressible backend: Fluid type is %d ",this->_fluid_type) << std::endl; + if ((_fractions.size()!=1) || (_fractions[0]!=0.0)){ + throw ValueError(format("%s is a pure fluid. The composition has to be set to a vector with one entry equal to 0.0 or nothing. %s is not valid.",this->name().c_str(),vec_to_string(_fractions).c_str())); + } + } else { + this->_fluid_type = FLUID_TYPE_INCOMPRESSIBLE_SOLUTION; + if (get_debug_level()>=50) std::cout << format("Incompressible backend: Fluid type is %d ",this->_fluid_type) << std::endl; + if (_fractions.size()!=1 || ((_fractions[0]<0.0) || (_fractions[0]>1.0)) ){ + throw ValueError(format("%s is a solution or brine. Mass fractions must be set to a vector with one entry between 0 and 1. %s is not valid.",this->name().c_str(),vec_to_string(_fractions).c_str())); + } + } - this->_phase = iphase_liquid; - if (get_debug_level()>=50) std::cout << format("Incompressible backend: Phase type is %d ",this->_phase) << std::endl; + this->_phase = iphase_liquid; + if (get_debug_level()>=50) std::cout << format("Incompressible backend: Phase type is %d ",this->_phase) << std::endl; - switch (input_pair) - { + switch (input_pair) + { case PT_INPUTS: { _p = value1; _T = value2; break; } case DmassP_INPUTS: { - _p = value2; - _T = this->DmassP_flash(value1,value2); - break; + _p = value2; + _T = this->DmassP_flash(value1,value2); + break; } case PUmass_INPUTS: { - _p = value1; - _T = this->PUmass_flash(value1, value2); + _p = value1; + _T = this->PUmass_flash(value1, value2); break; } case PSmass_INPUTS: { - _p = value1; - _T = this->PSmass_flash(value1, value2); + _p = value1; + _T = this->PSmass_flash(value1, value2); break; } case HmassP_INPUTS: { - _p = value2; - _T = this->HmassP_flash(value1, value2); + _p = value2; + _T = this->HmassP_flash(value1, value2); break; } case QT_INPUTS: { - if (value1!=0) {throw ValueError("Incompressible fluids can only handle saturated liquid, Q=0.");} - _T = value2; - _p = fluid->psat(value2, _fractions[0]); + if (value1!=0) {throw ValueError("Incompressible fluids can only handle saturated liquid, Q=0.");} + _T = value2; + _p = fluid->psat(value2, _fractions[0]); break; } default: { @@ -105,8 +105,8 @@ void IncompressibleBackend::update(CoolProp::input_pairs input_pair, double valu format("This pair of inputs [%s] is not yet supported", get_input_pair_short_desc(input_pair).c_str())); } - } - if (_p < 0){ throw ValueError("p is less than zero");} + } + if (_p < 0){ throw ValueError("p is less than zero");} if (!ValidNumber(_p)){ throw ValueError("p is not a valid number");} if (_T < 0){ throw ValueError("T is less than zero");} if (!ValidNumber(_T)){ throw ValueError("T is not a valid number");} @@ -119,14 +119,14 @@ void IncompressibleBackend::update(CoolProp::input_pairs input_pair, double valu @param fractions The vector of fractions of the components converted to the correct input */ void IncompressibleBackend::set_fractions(const std::vector &fractions){ - if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_fractions with %s ",vec_to_string(fractions).c_str()) << std::endl; - if (fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the fraction vector and not %d.",fractions.size())); - if ( ( this->_fractions.size()!=1 ) || - ( this->_fractions[0]!=fractions[0] ) ) { // Change it! - if (get_debug_level()>=20) std::cout << format("Incompressible backend: Updating the fractions triggered a change in reference state %s -> %s",vec_to_string(this->_fractions).c_str(),vec_to_string(fractions).c_str()) << std::endl; - this->_fractions = fractions; - fluid->set_reference_state(fluid->getTref(), fluid->getpref(), this->_fractions[0], fluid->gethref(), fluid->getsref()); - } + if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_fractions with %s ",vec_to_string(fractions).c_str()) << std::endl; + if (fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the fraction vector and not %d.",fractions.size())); + if ( ( this->_fractions.size()!=1 ) || + ( this->_fractions[0]!=fractions[0] ) ) { // Change it! + if (get_debug_level()>=20) std::cout << format("Incompressible backend: Updating the fractions triggered a change in reference state %s -> %s",vec_to_string(this->_fractions).c_str(),vec_to_string(fractions).c_str()) << std::endl; + this->_fractions = fractions; + fluid->set_reference_state(fluid->getTref(), fluid->getpref(), this->_fractions[0], fluid->gethref(), fluid->getsref()); + } } /// Set the mole fractions @@ -134,20 +134,20 @@ void IncompressibleBackend::set_fractions(const std::vector &fracti @param mole_fractions The vector of mole fractions of the components */ void IncompressibleBackend::set_mole_fractions(const std::vector &mole_fractions){ - if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_mole_fractions with %s ",vec_to_string(mole_fractions).c_str()) << std::endl; - if (mole_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the mole fraction vector and not %d.",mole_fractions.size())); - if (fluid->getxid()==IFRAC_PURE) { - this->set_fractions(std::vector(1,0)); - if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(mole_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; - } else if (fluid->getxid()==IFRAC_MOLE) { - this->set_fractions(mole_fractions); - } else { - std::vector tmp_fractions; - for (std::size_t i = 0; i < mole_fractions.size(); i++) { - tmp_fractions.push_back((long double) fluid->inputFromMole(0.0, mole_fractions[i])); - } - this->set_fractions(tmp_fractions); - } + if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_mole_fractions with %s ",vec_to_string(mole_fractions).c_str()) << std::endl; + if (mole_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the mole fraction vector and not %d.",mole_fractions.size())); + if (fluid->getxid()==IFRAC_PURE) { + this->set_fractions(std::vector(1,0)); + if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(mole_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; + } else if (fluid->getxid()==IFRAC_MOLE) { + this->set_fractions(mole_fractions); + } else { + std::vector tmp_fractions; + for (std::size_t i = 0; i < mole_fractions.size(); i++) { + tmp_fractions.push_back((long double) fluid->inputFromMole(0.0, mole_fractions[i])); + } + this->set_fractions(tmp_fractions); + } } /// Set the mass fractions @@ -155,20 +155,20 @@ void IncompressibleBackend::set_mole_fractions(const std::vector &m @param mass_fractions The vector of mass fractions of the components */ void IncompressibleBackend::set_mass_fractions(const std::vector &mass_fractions){ - if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_mass_fractions with %s ",vec_to_string(mass_fractions).c_str()) << std::endl; - if (mass_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the mass fraction vector and not %d.",mass_fractions.size())); - if (fluid->getxid()==IFRAC_PURE) { - this->set_fractions(std::vector(1,0)); - if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(mass_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; - } else if (fluid->getxid()==IFRAC_MASS) { - this->set_fractions(mass_fractions); - } else { - std::vector tmp_fractions; - for (std::size_t i = 0; i < mass_fractions.size(); i++) { - tmp_fractions.push_back((long double) fluid->inputFromMass(0.0, mass_fractions[i])); - } - this->set_fractions(tmp_fractions); - } + if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_mass_fractions with %s ",vec_to_string(mass_fractions).c_str()) << std::endl; + if (mass_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the mass fraction vector and not %d.",mass_fractions.size())); + if (fluid->getxid()==IFRAC_PURE) { + this->set_fractions(std::vector(1,0)); + if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(mass_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; + } else if (fluid->getxid()==IFRAC_MASS) { + this->set_fractions(mass_fractions); + } else { + std::vector tmp_fractions; + for (std::size_t i = 0; i < mass_fractions.size(); i++) { + tmp_fractions.push_back((long double) fluid->inputFromMass(0.0, mass_fractions[i])); + } + this->set_fractions(tmp_fractions); + } } /// Set the volume fractions @@ -176,25 +176,25 @@ void IncompressibleBackend::set_mass_fractions(const std::vector &m @param volu_fractions The vector of volume fractions of the components */ void IncompressibleBackend::set_volu_fractions(const std::vector &volu_fractions){ - if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_volu_fractions with %s ",vec_to_string(volu_fractions).c_str()) << std::endl; - if (volu_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the volume fraction vector and not %d.",volu_fractions.size())); - if (fluid->getxid()==IFRAC_PURE) { - this->set_fractions(std::vector(1,0)); - if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(volu_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; - } else if (fluid->getxid()==IFRAC_VOLUME) { - this->set_fractions(volu_fractions); - } else { - std::vector tmp_fractions; - for (std::size_t i = 0; i < volu_fractions.size(); i++) { - tmp_fractions.push_back((long double) fluid->inputFromVolume(0.0, volu_fractions[i])); - } - this->set_fractions(tmp_fractions); - } + if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_volu_fractions with %s ",vec_to_string(volu_fractions).c_str()) << std::endl; + if (volu_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the volume fraction vector and not %d.",volu_fractions.size())); + if (fluid->getxid()==IFRAC_PURE) { + this->set_fractions(std::vector(1,0)); + if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(volu_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl; + } else if (fluid->getxid()==IFRAC_VOLUME) { + this->set_fractions(volu_fractions); + } else { + std::vector tmp_fractions; + for (std::size_t i = 0; i < volu_fractions.size(); i++) { + tmp_fractions.push_back((long double) fluid->inputFromVolume(0.0, volu_fractions[i])); + } + this->set_fractions(tmp_fractions); + } } /// Check if the mole fractions have been set, etc. void IncompressibleBackend::check_status() { - throw NotImplementedError("Cannot check status for incompressible fluid"); + throw NotImplementedError("Cannot check status for incompressible fluid"); } /// Calculate T given pressure and density @@ -204,7 +204,7 @@ void IncompressibleBackend::check_status() { @returns T The temperature in K */ long double IncompressibleBackend::DmassP_flash(long double rhomass, long double p){ - return fluid->T_rho(rhomass, p, _fractions[0]); + return fluid->T_rho(rhomass, p, _fractions[0]); } /// Calculate T given pressure and enthalpy /** @@ -214,37 +214,37 @@ long double IncompressibleBackend::DmassP_flash(long double rhomass, long double */ long double IncompressibleBackend::HmassP_flash(long double hmass, long double p){ - class HmassP_residual : public FuncWrapper1D { - protected: - double p,x,h_in; - IncompressibleFluid* fluid; - protected: + class HmassP_residual : public FuncWrapper1D { + protected: + double p,x,h_in; + IncompressibleFluid* fluid; + protected: HmassP_residual(){}; - public: - HmassP_residual(IncompressibleFluid* fluid, const double &p, const double &x, const double &h_in){ - this->p = p; - this->x = x; - this->h_in = h_in; - this->fluid = fluid; - } - virtual ~HmassP_residual(){}; - double call(double target){ - return fluid->h(target,p,x) - h_in; //fluid.u(target,p,x)+ p / fluid.rho(target,p,x) - h_in; - } - //double deriv(double target); - }; + public: + HmassP_residual(IncompressibleFluid* fluid, const double &p, const double &x, const double &h_in){ + this->p = p; + this->x = x; + this->h_in = h_in; + this->fluid = fluid; + } + virtual ~HmassP_residual(){}; + double call(double target){ + return fluid->h(target,p,x) - h_in; //fluid.u(target,p,x)+ p / fluid.rho(target,p,x) - h_in; + } + //double deriv(double target); + }; - //double T_tmp = this->PUmass_flash(p, hmass); // guess value from u=h + //double T_tmp = this->PUmass_flash(p, hmass); // guess value from u=h - HmassP_residual res = HmassP_residual(fluid, p, _fractions[0], hmass); + HmassP_residual res = HmassP_residual(fluid, p, _fractions[0], hmass); - std::string errstring; - double macheps = DBL_EPSILON; - double tol = DBL_EPSILON*1e3; - int maxiter = 10; - double result = Brent(&res, fluid->getTmin(), fluid->getTmax(), macheps, tol, maxiter, errstring); - //if (this->do_debug()) std::cout << "Brent solver message: " << errstring << std::endl; - return result; + std::string errstring; + double macheps = DBL_EPSILON; + double tol = DBL_EPSILON*1e3; + int maxiter = 10; + double result = Brent(&res, fluid->getTmin(), fluid->getTmax(), macheps, tol, maxiter, errstring); + //if (this->do_debug()) std::cout << "Brent solver message: " << errstring << std::endl; + return result; } /// Calculate T given pressure and entropy /** @@ -253,7 +253,7 @@ long double IncompressibleBackend::HmassP_flash(long double hmass, long double p @returns T The temperature in K */ long double IncompressibleBackend::PSmass_flash(long double p, long double smass){ - return fluid->T_s(smass, p, _fractions[0]); + return fluid->T_s(smass, p, _fractions[0]); } /// Calculate T given pressure and internal energy @@ -263,7 +263,7 @@ long double IncompressibleBackend::PSmass_flash(long double p, long double smass @returns T The temperature in K */ long double IncompressibleBackend::PUmass_flash(long double p, long double umass){ - return fluid->T_u(umass, p, _fractions[0]); + return fluid->T_u(umass, p, _fractions[0]); } @@ -284,428 +284,428 @@ long double IncompressibleBackend::PUmass_flash(long double p, long double umass TEST_CASE("Internal consistency checks and example use cases for the incompressible backend","[IncompressibleBackend]") { - CoolProp::IncompressibleFluid fluid = CoolPropTesting::incompressibleFluidObject(); - CoolProp::IncompressibleBackend backend = CoolProp::IncompressibleBackend(&fluid); + CoolProp::IncompressibleFluid fluid = CoolPropTesting::incompressibleFluidObject(); + CoolProp::IncompressibleBackend backend = CoolProp::IncompressibleBackend(&fluid); - SECTION("Test case for Methanol from SecCool") { + SECTION("Test case for Methanol from SecCool") { - // Some basic functions - // has to return false - CHECK( backend.using_mole_fractions()==false ); + // Some basic functions + // has to return false + CHECK( backend.using_mole_fractions()==false ); - //void update(long input_pair, double value1, double value2); + //void update(long input_pair, double value1, double value2); - std::vector fractions; - fractions.push_back(0.4); - CHECK_THROWS( backend.set_mole_fractions(fractions) ); - CHECK_NOTHROW( backend.set_mass_fractions(fractions) ); - fractions.push_back(0.4); - CHECK_THROWS( backend.set_mass_fractions(fractions) ); - CHECK_THROWS( backend.check_status() ); + std::vector fractions; + fractions.push_back(0.4); + CHECK_THROWS( backend.set_mole_fractions(fractions) ); + CHECK_NOTHROW( backend.set_mass_fractions(fractions) ); + fractions.push_back(0.4); + CHECK_THROWS( backend.set_mass_fractions(fractions) ); + CHECK_THROWS( backend.check_status() ); - // Prepare the results and compare them to the calculated values - double acc = 0.0001; - double T = 273.15+10; - double p = 10e5; - double x = 0.25; - backend.set_mass_fractions(std::vector(1,x)); - double val = 0; - double res = 0; + // Prepare the results and compare them to the calculated values + double acc = 0.0001; + double T = 273.15+10; + double p = 10e5; + double x = 0.25; + backend.set_mass_fractions(std::vector(1,x)); + double val = 0; + double res = 0; - //CoolProp::set_debug_level(100); + //CoolProp::set_debug_level(100); - // Compare density flash - val = fluid.rho(T,p,x); - res = backend.DmassP_flash(val, p); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(T,res,acc) ); - } + // Compare density flash + val = fluid.rho(T,p,x); + res = backend.DmassP_flash(val, p); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(T,res,acc) ); + } - // Compare h - val = fluid.h(T, p, x); - res = backend.HmassP_flash(val, p); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(T,res,acc) ); - } + // Compare h + val = fluid.h(T, p, x); + res = backend.HmassP_flash(val, p); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(T,res,acc) ); + } - // Compare s - val = fluid.s(T, p, x); - res = backend.PSmass_flash(p, val); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(T,res,acc) ); - } + // Compare s + val = fluid.s(T, p, x); + res = backend.PSmass_flash(p, val); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(T,res,acc) ); + } - // Compare u - val = fluid.u(T, p, x); - res = backend.PUmass_flash(p, val); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(T,res,acc) ); - } + // Compare u + val = fluid.u(T, p, x); + res = backend.PUmass_flash(p, val); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(T,res,acc) ); + } - // call the update function to set internal variables, - // concentration has been set before. - CHECK_THROWS( backend.update( CoolProp::DmassT_INPUTS, val, T ) ); // First with wrong parameters - CHECK_NOTHROW( backend.update( CoolProp::PT_INPUTS, p, T ) ); // ... and then with the correct ones. + // call the update function to set internal variables, + // concentration has been set before. + CHECK_THROWS( backend.update( CoolProp::DmassT_INPUTS, val, T ) ); // First with wrong parameters + CHECK_NOTHROW( backend.update( CoolProp::PT_INPUTS, p, T ) ); // ... and then with the correct ones. - /// Get the viscosity [Pa-s] - val = fluid.visc(T, p, x); - res = backend.calc_viscosity(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + /// Get the viscosity [Pa-s] + val = fluid.visc(T, p, x); + res = backend.calc_viscosity(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - /// Get the thermal conductivity [W/m/K] (based on the temperature and pressure in the state class) - val = fluid.cond(T, p, x); - res = backend.calc_conductivity(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + /// Get the thermal conductivity [W/m/K] (based on the temperature and pressure in the state class) + val = fluid.cond(T, p, x); + res = backend.calc_conductivity(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = fluid.rho(T, p, x); - res = backend.calc_rhomass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + val = fluid.rho(T, p, x); + res = backend.calc_rhomass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = fluid.h(T, p, x); - res = backend.calc_hmass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + val = fluid.h(T, p, x); + res = backend.calc_hmass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = fluid.s(T, p, x); - res = backend.calc_smass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + val = fluid.s(T, p, x); + res = backend.calc_smass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = fluid.u(T, p, x); - res = backend.calc_umass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + val = fluid.u(T, p, x); + res = backend.calc_umass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = fluid.c(T, p, x); - res = backend.calc_cpmass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + val = fluid.c(T, p, x); + res = backend.calc_cpmass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - res = backend.calc_cvmass(); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + res = backend.calc_cvmass(); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - // Compare Tfreeze - val = fluid.Tfreeze(p, x);//-20.02+273.15;// 253.1293105454671; - res = -20.02+273.15; - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare Tfreeze + val = fluid.Tfreeze(p, x);//-20.02+273.15;// 253.1293105454671; + res = -20.02+273.15; + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - } + } - SECTION("Tests for the full implementation using PropsSI") { + SECTION("Tests for the full implementation using PropsSI") { - // Prepare the results and compare them to the calculated values - std::string fluid("INCOMP::ExampleMelinder"); - double acc = 0.0001; - double T = -5 + 273.15; - double p = 10e5; - double x = 0.3; - double expected = 0; - double actual = 0; + // Prepare the results and compare them to the calculated values + std::string fluid("INCOMP::ExampleMelinder"); + double acc = 0.0001; + double T = -5 + 273.15; + double p = 10e5; + double x = 0.3; + double expected = 0; + double actual = 0; - // Compare different inputs - // ... as vector - expected = 9.6212e+02; - actual = CoolProp::PropsSI("D","T",T,"P",p,fluid,std::vector(1,x)); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } - // ... as % - actual = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("-%f%s",x*100.0,"%")); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } - // ... as mass fraction - actual = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("[%f]",x)); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string name = fluid+format("[%f]",x); - CAPTURE(name); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare different inputs + // ... as vector + expected = 9.6212e+02; + actual = CoolProp::PropsSI("D","T",T,"P",p,fluid,std::vector(1,x)); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } + // ... as % + actual = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("-%f%s",x*100.0,"%")); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } + // ... as mass fraction + actual = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("[%f]",x)); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string name = fluid+format("[%f]",x); + CAPTURE(name); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - fluid = std::string("INCOMP::ExampleSecCool"); - T = -5 + 273.15; - p = 10e5; - x = 0.4; - std::vector x_vec = std::vector(1,x); + fluid = std::string("INCOMP::ExampleSecCool"); + T = -5 + 273.15; + p = 10e5; + x = 0.4; + std::vector x_vec = std::vector(1,x); - // Compare d - expected = 9.4844e+02; - actual = CoolProp::PropsSI("D","T",T,"P",p,fluid,x_vec); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare d + expected = 9.4844e+02; + actual = CoolProp::PropsSI("D","T",T,"P",p,fluid,x_vec); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare cp - expected = 3.6304e+03; - actual = CoolProp::PropsSI("C","T",T,"P",p,fluid,x_vec); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare cp + expected = 3.6304e+03; + actual = CoolProp::PropsSI("C","T",T,"P",p,fluid,x_vec); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - fluid = std::string("INCOMP::ExamplePure"); - T = +55 + 273.15; - p = 10e5; + fluid = std::string("INCOMP::ExamplePure"); + T = +55 + 273.15; + p = 10e5; - // Compare d - expected = 7.3646e+02; - actual = CoolProp::PropsSI("D","T",T,"P",p,fluid); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare d + expected = 7.3646e+02; + actual = CoolProp::PropsSI("D","T",T,"P",p,fluid); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare cp - expected = 2.2580e+03; - actual = CoolProp::PropsSI("C","T",T,"P",p,fluid); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } - } + // Compare cp + expected = 2.2580e+03; + actual = CoolProp::PropsSI("C","T",T,"P",p,fluid); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } + } - //std::string name("INCOMP::TCO"); - double T = 50 + 273.15; - double p = 10e5; - double x = 0.3; + //std::string name("INCOMP::TCO"); + double T = 50 + 273.15; + double p = 10e5; + double x = 0.3; -// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::TCO",std::vector(1,x)) << std::endl; -// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::LiBr",std::vector(1,x)) << std::endl; -// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::NaK",std::vector(1,x)) << std::endl; +// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::TCO",std::vector(1,x)) << std::endl; +// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::LiBr",std::vector(1,x)) << std::endl; +// std::cout << CoolProp::PropsSI("D","T",T,"P",p,"INCOMP::NaK",std::vector(1,x)) << std::endl; -// SECTION("Tests for the hardcoded fluids") { +// SECTION("Tests for the hardcoded fluids") { // -// // Prepare the results and compare them to the calculated values -// std::string fluid("INCOMP::LiBr"); -// double acc = 0.0001; -// double T = 50 + 273.15; -// double p = 10e5; -// double x = 0.3; -// double val = 0; -// double res = 0; +// // Prepare the results and compare them to the calculated values +// std::string fluid("INCOMP::LiBr"); +// double acc = 0.0001; +// double T = 50 + 273.15; +// double p = 10e5; +// double x = 0.3; +// double val = 0; +// double res = 0; // -// // Compare different inputs -// // ... as vector -// val = 9.6212e+02; -// res = CoolProp::PropsSI("D","T",T,"P",p,fluid,std::vector(1,x)); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } -// // ... as % -// res = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("-%f%s",x*100.0,"%")); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } -// // ... as mass fraction -// res = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("[%f]",x)); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } +// // Compare different inputs +// // ... as vector +// val = 9.6212e+02; +// res = CoolProp::PropsSI("D","T",T,"P",p,fluid,std::vector(1,x)); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } +// // ... as % +// res = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("-%f%s",x*100.0,"%")); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } +// // ... as mass fraction +// res = CoolProp::PropsSI("D","T",T,"P",p,fluid+format("[%f]",x)); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } // // -// fluid = std::string("INCOMP::ExampleSecCool"); -// T = -5 + 273.15; -// p = 10e5; -// x = 0.4; -// std::vector x_vec = std::vector(1,x); +// fluid = std::string("INCOMP::ExampleSecCool"); +// T = -5 + 273.15; +// p = 10e5; +// x = 0.4; +// std::vector x_vec = std::vector(1,x); // -// // Compare d -// val = 9.4844e+02; -// res = CoolProp::PropsSI("D","T",T,"P",p,fluid,x_vec); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } +// // Compare d +// val = 9.4844e+02; +// res = CoolProp::PropsSI("D","T",T,"P",p,fluid,x_vec); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } // -// // Compare cp -// val = 3.6304e+03; -// res = CoolProp::PropsSI("C","T",T,"P",p,fluid,x_vec); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } +// // Compare cp +// val = 3.6304e+03; +// res = CoolProp::PropsSI("C","T",T,"P",p,fluid,x_vec); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } // -// fluid = std::string("INCOMP::ExamplePure"); -// T = +55 + 273.15; -// p = 10e5; +// fluid = std::string("INCOMP::ExamplePure"); +// T = +55 + 273.15; +// p = 10e5; // -// // Compare d -// val = 7.3646e+02; -// res = CoolProp::PropsSI("D","T",T,"P",p,fluid); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } +// // Compare d +// val = 7.3646e+02; +// res = CoolProp::PropsSI("D","T",T,"P",p,fluid); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } // -// // Compare cp -// val = 2.2580e+03; -// res = CoolProp::PropsSI("C","T",T,"P",p,fluid); -// { -// CAPTURE(T); -// CAPTURE(p); -// CAPTURE(x); -// CAPTURE(val); -// CAPTURE(res); -// CHECK( check_abs(val,res,acc) ); -// } -// } +// // Compare cp +// val = 2.2580e+03; +// res = CoolProp::PropsSI("C","T",T,"P",p,fluid); +// { +// CAPTURE(T); +// CAPTURE(p); +// CAPTURE(x); +// CAPTURE(val); +// CAPTURE(res); +// CHECK( check_abs(val,res,acc) ); +// } +// } } #endif /* ENABLE_CATCH */ diff --git a/src/Backends/Incompressible/IncompressibleBackend.h b/src/Backends/Incompressible/IncompressibleBackend.h index b2174eed..2e268e9a 100644 --- a/src/Backends/Incompressible/IncompressibleBackend.h +++ b/src/Backends/Incompressible/IncompressibleBackend.h @@ -36,8 +36,8 @@ public: /// @param fluid_name the string with the fluid name IncompressibleBackend(const std::string &fluid_name); /// The instantiator - /// @param component_names The vector of strings of the fluid components, without file ending - IncompressibleBackend(const std::vector &component_names); + /// @param component_names The vector of strings of the fluid components, without file ending + IncompressibleBackend(const std::vector &component_names); // Incompressible backend uses different compositions bool using_mole_fractions(void){return this->fluid->getxid()==IFRAC_MOLE;}; @@ -117,8 +117,8 @@ public: long double calc_umass(void){return fluid->u(_T, _p, _fractions[0]);}; long double calc_cpmass(void){return fluid->cp(_T, _p, _fractions[0]);}; long double calc_cvmass(void){return fluid->cv(_T, _p, _fractions[0]);}; - long double calc_Tmax(void){return fluid->getTmax();}; - long double calc_Tmin(void){return fluid->getTmin();}; + long double calc_Tmax(void){return fluid->getTmax();}; + long double calc_Tmin(void){return fluid->getTmin();}; }; } /* namespace CoolProp */ diff --git a/src/Backends/Incompressible/IncompressibleFluid.cpp b/src/Backends/Incompressible/IncompressibleFluid.cpp index 48886828..9c7a85ee 100644 --- a/src/Backends/Incompressible/IncompressibleFluid.cpp +++ b/src/Backends/Incompressible/IncompressibleFluid.cpp @@ -16,144 +16,144 @@ This fluid instance is populated using an entry from a JSON file //IncompressibleFluid::IncompressibleFluid(); void IncompressibleFluid::set_reference_state(double T0, double p0, double x0, double h0, double s0){ - this->Tref = T0; - this->rhoref = rho(T0,p0,x0); - this->pref = p0; - this->uref = h0 - p0/rhoref; - this->uref = u(T0,p0,x0); - this->href = h0; // set new reference value - this->sref = s0; // set new reference value - this->href = h(T0,p0,x0); // adjust offset to fit to equations - this->sref = s(T0,p0,x0); // adjust offset to fit to equations + this->Tref = T0; + this->rhoref = rho(T0,p0,x0); + this->pref = p0; + this->uref = h0 - p0/rhoref; + this->uref = u(T0,p0,x0); + this->href = h0; // set new reference value + this->sref = s0; // set new reference value + this->href = h(T0,p0,x0); // adjust offset to fit to equations + this->sref = s(T0,p0,x0); // adjust offset to fit to equations } void IncompressibleFluid::validate(){ - return; - // TODO: Implement validation function + return; + // TODO: Implement validation function - // u and s have to be of the polynomial type! - throw NotImplementedError("TODO"); + // u and s have to be of the polynomial type! + throw NotImplementedError("TODO"); } bool IncompressibleFluid::is_pure() { - if (density.coeffs.cols()==1) return true; - return false; + if (density.coeffs.cols()==1) return true; + return false; } /// Base exponential function double IncompressibleFluid::baseExponential(IncompressibleData data, double y, double ybase){ - Eigen::VectorXd coeffs = makeVector(data.coeffs); - size_t r=coeffs.rows(),c=coeffs.cols(); - if (strict && (r!=3 || c!=1) ) throw ValueError(format("%s (%d): You have to provide a 3,1 matrix of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); - return exp( (double) (coeffs[0] / ( (y-ybase)+coeffs[1] ) - coeffs[2] ) ); + Eigen::VectorXd coeffs = makeVector(data.coeffs); + size_t r=coeffs.rows(),c=coeffs.cols(); + if (strict && (r!=3 || c!=1) ) throw ValueError(format("%s (%d): You have to provide a 3,1 matrix of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); + return exp( (double) (coeffs[0] / ( (y-ybase)+coeffs[1] ) - coeffs[2] ) ); } /// Base exponential function with logarithmic term double IncompressibleFluid::baseLogexponential(IncompressibleData data, double y, double ybase){ - Eigen::VectorXd coeffs = makeVector(data.coeffs); - size_t r=coeffs.rows(),c=coeffs.cols(); - if (strict && (r!=3 || c!=1) ) throw ValueError(format("%s (%d): You have to provide a 3,1 matrix of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); - return exp( (double) ( log( (double) (1.0/((y-ybase)+coeffs[0]) + 1.0/((y-ybase)+coeffs[0])/((y-ybase)+coeffs[0]) ) ) *coeffs[1]+coeffs[2] ) ); + Eigen::VectorXd coeffs = makeVector(data.coeffs); + size_t r=coeffs.rows(),c=coeffs.cols(); + if (strict && (r!=3 || c!=1) ) throw ValueError(format("%s (%d): You have to provide a 3,1 matrix of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); + return exp( (double) ( log( (double) (1.0/((y-ybase)+coeffs[0]) + 1.0/((y-ybase)+coeffs[0])/((y-ybase)+coeffs[0]) ) ) *coeffs[1]+coeffs[2] ) ); } double IncompressibleFluid::basePolyOffset(IncompressibleData data, double y, double z){ - size_t r=data.coeffs.rows(),c=data.coeffs.cols(); - double offset = 0.0; - double in = 0.0; - Eigen::MatrixXd coeffs; - if (r>0 && c>0) { - offset = data.coeffs(0,0); - if (r==1 && c>1) { // row vector -> function of z - coeffs = Eigen::MatrixXd(data.coeffs.block(0,1,r,c-1)); - in = z; - } else if (r>1 && c==1) { // column vector -> function of y - coeffs = Eigen::MatrixXd(data.coeffs.block(1,0,r-1,c)); - in = y; - } else { - throw ValueError(format("%s (%d): You have to provide a vector (1D matrix) of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); - } - return poly.evaluate(coeffs, in, 0, offset); - } - throw ValueError(format("%s (%d): You have to provide a vector (1D matrix) of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); - return _HUGE; + size_t r=data.coeffs.rows(),c=data.coeffs.cols(); + double offset = 0.0; + double in = 0.0; + Eigen::MatrixXd coeffs; + if (r>0 && c>0) { + offset = data.coeffs(0,0); + if (r==1 && c>1) { // row vector -> function of z + coeffs = Eigen::MatrixXd(data.coeffs.block(0,1,r,c-1)); + in = z; + } else if (r>1 && c==1) { // column vector -> function of y + coeffs = Eigen::MatrixXd(data.coeffs.block(1,0,r-1,c)); + in = y; + } else { + throw ValueError(format("%s (%d): You have to provide a vector (1D matrix) of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); + } + return poly.evaluate(coeffs, in, 0, offset); + } + throw ValueError(format("%s (%d): You have to provide a vector (1D matrix) of coefficients, not (%d,%d).",__FILE__,__LINE__,r,c)); + return _HUGE; } /// Density as a function of temperature, pressure and composition. double IncompressibleFluid::rho (double T, double p, double x){ - switch (density.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(density.coeffs, T, x, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(density, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(density, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(density.coeffs, T, x, 0, 0, Tbase, xbase)); - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(density, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,density.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,density.type)); - break; - } - return _HUGE; + switch (density.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(density.coeffs, T, x, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(density, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(density, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(density.coeffs, T, x, 0, 0, Tbase, xbase)); + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(density, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,density.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,density.type)); + break; + } + return _HUGE; } /// Heat capacities as a function of temperature, pressure and composition. double IncompressibleFluid::c (double T, double p, double x){ - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - //throw NotImplementedError("Here you should implement the polynomial."); - return poly.evaluate(specific_heat.coeffs, T, x, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for specific heat.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + //throw NotImplementedError("Here you should implement the polynomial."); + return poly.evaluate(specific_heat.coeffs, T, x, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for specific heat.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Entropy as a function of temperature, pressure and composition. double IncompressibleFluid::s (double T, double p, double x){ - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - //throw NotImplementedError("Here you should implement the polynomial."); - return poly.integral(specific_heat.coeffs, T, x, 0, -1, 0, Tbase, xbase) - sref; - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for entropy.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + //throw NotImplementedError("Here you should implement the polynomial."); + return poly.integral(specific_heat.coeffs, T, x, 0, -1, 0, Tbase, xbase) - sref; + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for entropy.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Internal energy as a function of temperature, pressure and composition. double IncompressibleFluid::u (double T, double p, double x){ - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - //throw NotImplementedError("Here you should implement the polynomial."); - return poly.integral(specific_heat.coeffs, T, x, 0, 0, 0, Tbase, xbase) - uref; - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for internal energy.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + //throw NotImplementedError("Here you should implement the polynomial."); + return poly.integral(specific_heat.coeffs, T, x, 0, 0, 0, Tbase, xbase) - uref; + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for internal energy.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Enthalpy as a function of temperature, pressure and composition. @@ -161,223 +161,223 @@ double IncompressibleFluid::h (double T, double p, double x){return h_u(T,p,x) /// Viscosity as a function of temperature, pressure and composition. double IncompressibleFluid::visc(double T, double p, double x){ - switch (viscosity.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(viscosity.coeffs, T, x, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(viscosity, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(viscosity, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(viscosity.coeffs, T, x, 0, 0, Tbase, xbase)); - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(viscosity, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,viscosity.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,viscosity.type)); - break; - } - return _HUGE; + switch (viscosity.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(viscosity.coeffs, T, x, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(viscosity, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(viscosity, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(viscosity.coeffs, T, x, 0, 0, Tbase, xbase)); + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(viscosity, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,viscosity.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,viscosity.type)); + break; + } + return _HUGE; } /// Thermal conductivity as a function of temperature, pressure and composition. double IncompressibleFluid::cond(double T, double p, double x){ - switch (conductivity.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(conductivity.coeffs, T, x, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(conductivity, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(conductivity, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(conductivity.coeffs, T, x, 0, 0, Tbase, xbase)); - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(conductivity, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,conductivity.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,conductivity.type)); - break; - } - return _HUGE; + switch (conductivity.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(conductivity.coeffs, T, x, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(conductivity, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(conductivity, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(conductivity.coeffs, T, x, 0, 0, Tbase, xbase)); + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(conductivity, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,conductivity.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,conductivity.type)); + break; + } + return _HUGE; } /// Saturation pressure as a function of temperature and composition. double IncompressibleFluid::psat(double T, double x){ - if (T<=this->TminPsat) return 0.0; - switch (p_sat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(p_sat.coeffs, T, x, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(p_sat, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(p_sat, T, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(p_sat.coeffs, T, x, 0, 0, Tbase, xbase)); - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(p_sat, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,p_sat.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,p_sat.type)); - break; - } - return _HUGE; + if (T<=this->TminPsat) return 0.0; + switch (p_sat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(p_sat.coeffs, T, x, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(p_sat, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(p_sat, T, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(p_sat.coeffs, T, x, 0, 0, Tbase, xbase)); + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(p_sat, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,p_sat.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,p_sat.type)); + break; + } + return _HUGE; } /// Freezing temperature as a function of pressure and composition. double IncompressibleFluid::Tfreeze( double p, double x){ - switch (T_freeze.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(T_freeze.coeffs, p, x, 0, 0, 0.0, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(T_freeze, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(T_freeze, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(T_freeze.coeffs, p, x, 0, 0, 0.0, xbase)); - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(T_freeze, p, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,T_freeze.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,T_freeze.type)); - break; - } - return _HUGE; + switch (T_freeze.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(T_freeze.coeffs, p, x, 0, 0, 0.0, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(T_freeze, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(T_freeze, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(T_freeze.coeffs, p, x, 0, 0, 0.0, xbase)); + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(T_freeze, p, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,T_freeze.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,T_freeze.type)); + break; + } + return _HUGE; } /// Mass fraction conversion function /** If the fluid type is mass-based, it does not do anything. Otherwise, * it converts the mass fraction to the required input. */ double IncompressibleFluid::inputFromMass (double T, double x){ - if (this->xid==IFRAC_PURE) { - return _HUGE; - } else if (this->xid==IFRAC_MASS) { - return x; - } else { - throw NotImplementedError("Mass composition conversion has not been implemented."); - switch (mass2input.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(mass2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(mass2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(mass2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(mass2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(mass2input, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,mass2input.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,mass2input.type)); - break; - } - return _HUGE; - } + if (this->xid==IFRAC_PURE) { + return _HUGE; + } else if (this->xid==IFRAC_MASS) { + return x; + } else { + throw NotImplementedError("Mass composition conversion has not been implemented."); + switch (mass2input.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(mass2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(mass2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(mass2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(mass2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(mass2input, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,mass2input.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,mass2input.type)); + break; + } + return _HUGE; + } } /// Volume fraction conversion function /** If the fluid type is volume-based, it does not do anything. Otherwise, * it converts the volume fraction to the required input. */ double IncompressibleFluid::inputFromVolume (double T, double x){ - if (this->xid==IFRAC_PURE) { - return _HUGE; - } else if (this->xid==IFRAC_VOLUME) { - return x; - } else { - throw NotImplementedError("Volume composition conversion has not been implemented."); - switch (volume2input.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(volume2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(volume2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(volume2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(volume2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(volume2input, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,volume2input.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,volume2input.type)); - break; - } - return _HUGE; - } + if (this->xid==IFRAC_PURE) { + return _HUGE; + } else if (this->xid==IFRAC_VOLUME) { + return x; + } else { + throw NotImplementedError("Volume composition conversion has not been implemented."); + switch (volume2input.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(volume2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(volume2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(volume2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(volume2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(volume2input, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,volume2input.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,volume2input.type)); + break; + } + return _HUGE; + } } /// Mole fraction conversion function /** If the fluid type is mole-based, it does not do anything. Otherwise, * it converts the mole fraction to the required input. */ double IncompressibleFluid::inputFromMole (double T, double x){ - if (this->xid==IFRAC_PURE) { - return _HUGE; - } else if (this->xid==IFRAC_MOLE) { - return x; - } else { - throw NotImplementedError("Mole composition conversion has not been implemented."); - switch (mole2input.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.evaluate(mole2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: - return baseExponential(mole2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: - return baseLogexponential(mole2input, x, 0.0); - break; - case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: - return exp(poly.evaluate(mole2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way - break; - case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: - return basePolyOffset(mole2input, T, x); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,mole2input.type)); - break; - default: - throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,mole2input.type)); - break; - } - return _HUGE; - } + if (this->xid==IFRAC_PURE) { + return _HUGE; + } else if (this->xid==IFRAC_MOLE) { + return x; + } else { + throw NotImplementedError("Mole composition conversion has not been implemented."); + switch (mole2input.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.evaluate(mole2input.coeffs, T, x, 0, 0, 0.0, 0.0); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL: + return baseExponential(mole2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL: + return baseLogexponential(mole2input, x, 0.0); + break; + case IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL: + return exp(poly.evaluate(mole2input.coeffs, T, x, 0, 0, 0.0, 0.0)); // TODO: make sure Tbase and xbase is defined in the correct way + break; + case IncompressibleData::INCOMPRESSIBLE_POLYOFFSET: + return basePolyOffset(mole2input, T, x); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,mole2input.type)); + break; + default: + throw ValueError(format("%s (%d): Your function type \"[%d]\" is unknown.",__FILE__,__LINE__,mole2input.type)); + break; + } + return _HUGE; + } } /* Some functions can be inverted directly, those are listed @@ -387,67 +387,67 @@ double IncompressibleFluid::inputFromMole (double T, double x){ */ /// Temperature as a function of density, pressure and composition. double IncompressibleFluid::T_rho (double Dmass, double p, double x){ - double d_raw = Dmass; // No changes needed, no reference values... - switch (density.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.solve_limits(density.coeffs, x, d_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse density.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + double d_raw = Dmass; // No changes needed, no reference values... + switch (density.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.solve_limits(density.coeffs, x, d_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse density.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Temperature as a function of heat capacities as a function of temperature, pressure and composition. double IncompressibleFluid::T_c (double Cmass, double p, double x){ - double c_raw = Cmass; // No changes needed, no reference values... - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.solve_limits(specific_heat.coeffs, x, c_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse specific heat.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + double c_raw = Cmass; // No changes needed, no reference values... + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.solve_limits(specific_heat.coeffs, x, c_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse specific heat.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Temperature as a function of entropy as a function of temperature, pressure and composition. double IncompressibleFluid::T_s (double Smass, double p, double x){ - double s_raw = Smass + sref; - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.solve_limitsInt(specific_heat.coeffs, x, s_raw, Tmin, Tmax, 0, -1, 0, Tbase, xbase, 0); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse entropy.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + double s_raw = Smass + sref; + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.solve_limitsInt(specific_heat.coeffs, x, s_raw, Tmin, Tmax, 0, -1, 0, Tbase, xbase, 0); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse entropy.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } /// Temperature as a function of internal energy as a function of temperature, pressure and composition. double IncompressibleFluid::T_u (double Umass, double p, double x){ - double u_raw = Umass + uref; - switch (specific_heat.type) { - case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: - return poly.solve_limitsInt(specific_heat.coeffs, x, u_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase, 0); - break; - case IncompressibleData::INCOMPRESSIBLE_NOT_SET: - throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); - break; - default: - throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse entropy.",__FILE__,__LINE__,specific_heat.type)); - break; - } - return _HUGE; + double u_raw = Umass + uref; + switch (specific_heat.type) { + case IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL: + return poly.solve_limitsInt(specific_heat.coeffs, x, u_raw, Tmin, Tmax, 0, 0, 0, Tbase, xbase, 0); + break; + case IncompressibleData::INCOMPRESSIBLE_NOT_SET: + throw ValueError(format("%s (%d): The function type is not specified (\"[%d]\"), are you sure the coefficients have been set?",__FILE__,__LINE__,specific_heat.type)); + break; + default: + throw ValueError(format("%s (%d): There is no predefined way to use this function type \"[%d]\" for inverse entropy.",__FILE__,__LINE__,specific_heat.type)); + break; + } + return _HUGE; } ///// Temperature as a function of enthalpy, pressure and composition. //double IncompressibleFluid::T_h (double Hmass, double p, double x){throw NotImplementedError(format("%s (%d): T from enthalpy is not implemented in the fluid, use the backend.",__FILE__,__LINE__));} @@ -472,13 +472,13 @@ double IncompressibleFluid::T_u (double Umass, double p, double x){ * freezing point calculation. This is not necessarily * defined for all fluids, default values do not cause errors. */ bool IncompressibleFluid::checkT(double T, double p, double x) { - if (Tmin <= 0.) throw ValueError("Please specify the minimum temperature."); - if (Tmax <= 0.) throw ValueError("Please specify the maximum temperature."); - if ((Tmin > T) || (T > Tmax)) throw ValueError(format("Your temperature %f is not between %f and %f.", T, Tmin, Tmax)); - double TF = 0.0; - if (T_freeze.type!=IncompressibleData::INCOMPRESSIBLE_NOT_SET) TF = Tfreeze(p, x); - if ( T T) || (T > Tmax)) throw ValueError(format("Your temperature %f is not between %f and %f.", T, Tmin, Tmax)); + double TF = 0.0; + if (T_freeze.type!=IncompressibleData::INCOMPRESSIBLE_NOT_SET) TF = Tfreeze(p, x); + if ( T 0.0 && p < ps) throw ValueError(format("Equations are valid for liquid phase only: %f < %f (psat). ", p, ps)); - return true; + double ps = 0.0; + if (p_sat.type!=IncompressibleData::INCOMPRESSIBLE_NOT_SET) ps = psat(T, x); + if (p < 0.0) throw ValueError(format("You cannot use negative pressures: %f < %f. ", p, 0.0)); + if (ps> 0.0 && p < ps) throw ValueError(format("Equations are valid for liquid phase only: %f < %f (psat). ", p, ps)); + return true; } /// Check validity of composition input. @@ -501,10 +501,10 @@ bool IncompressibleFluid::checkP(double T, double p, double x) { * maximum value. Enforces the redefinition of xmin and * xmax since the default values cause an error. */ bool IncompressibleFluid::checkX(double x){ - if (xmin < 0.0 || xmin > 1.0) throw ValueError("Please specify the minimum concentration between 0 and 1."); - if (xmax < 0.0 || xmax > 1.0) throw ValueError("Please specify the maximum concentration between 0 and 1."); - if ((xmin > x) || (x > xmax)) throw ValueError(format("Your composition %f is not between %f and %f.", x, xmin, xmax)); - return true; + if (xmin < 0.0 || xmin > 1.0) throw ValueError("Please specify the minimum concentration between 0 and 1."); + if (xmax < 0.0 || xmax > 1.0) throw ValueError("Please specify the maximum concentration between 0 and 1."); + if ((xmin > x) || (x > xmax)) throw ValueError(format("Your composition %f is not between %f and %f.", x, xmin, xmax)); + return true; } } /* namespace CoolProp */ @@ -524,407 +524,407 @@ bool IncompressibleFluid::checkX(double x){ Eigen::MatrixXd makeMatrix(const std::vector &coefficients){ - //IncompressibleClass::checkCoefficients(coefficients,18); - std::vector< std::vector > matrix; - std::vector tmpVector; + //IncompressibleClass::checkCoefficients(coefficients,18); + std::vector< std::vector > matrix; + std::vector tmpVector; - tmpVector.clear(); - tmpVector.push_back(coefficients[0]); - tmpVector.push_back(coefficients[6]); - tmpVector.push_back(coefficients[11]); - tmpVector.push_back(coefficients[15]); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[0]); + tmpVector.push_back(coefficients[6]); + tmpVector.push_back(coefficients[11]); + tmpVector.push_back(coefficients[15]); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[1]*100.0); - tmpVector.push_back(coefficients[7]*100.0); - tmpVector.push_back(coefficients[12]*100.0); - tmpVector.push_back(coefficients[16]*100.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[1]*100.0); + tmpVector.push_back(coefficients[7]*100.0); + tmpVector.push_back(coefficients[12]*100.0); + tmpVector.push_back(coefficients[16]*100.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[2]*100.0*100.0); - tmpVector.push_back(coefficients[8]*100.0*100.0); - tmpVector.push_back(coefficients[13]*100.0*100.0); - tmpVector.push_back(coefficients[17]*100.0*100.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[2]*100.0*100.0); + tmpVector.push_back(coefficients[8]*100.0*100.0); + tmpVector.push_back(coefficients[13]*100.0*100.0); + tmpVector.push_back(coefficients[17]*100.0*100.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[3]*100.0*100.0*100.0); - tmpVector.push_back(coefficients[9]*100.0*100.0*100.0); - tmpVector.push_back(coefficients[14]*100.0*100.0*100.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[3]*100.0*100.0*100.0); + tmpVector.push_back(coefficients[9]*100.0*100.0*100.0); + tmpVector.push_back(coefficients[14]*100.0*100.0*100.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[4]*100.0*100.0*100.0*100.0); - tmpVector.push_back(coefficients[10]*100.0*100.0*100.0*100.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[4]*100.0*100.0*100.0*100.0); + tmpVector.push_back(coefficients[10]*100.0*100.0*100.0*100.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[5]*100.0*100.0*100.0*100.0*100.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[5]*100.0*100.0*100.0*100.0*100.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - return CoolProp::vec_to_eigen(matrix).transpose(); + tmpVector.clear(); + return CoolProp::vec_to_eigen(matrix).transpose(); } TEST_CASE("Internal consistency checks and example use cases for the incompressible fluids","[IncompressibleFluids]") { - bool PRINT = false; - std::string tmpStr; - std::vector tmpVector; - std::vector< std::vector > tmpMatrix; + bool PRINT = false; + std::string tmpStr; + std::vector tmpVector; + std::vector< std::vector > tmpMatrix; - SECTION("Test case for \"SylthermXLT\" by Dow Chemicals") { + SECTION("Test case for \"SylthermXLT\" by Dow Chemicals") { - std::vector cRho; - cRho.push_back(+1.1563685145E+03); - cRho.push_back(-1.0269048032E+00); - cRho.push_back(-9.3506079577E-07); - cRho.push_back(+1.0368116627E-09); - CoolProp::IncompressibleData density; - density.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - density.coeffs = CoolProp::vec_to_eigen(cRho); + std::vector cRho; + cRho.push_back(+1.1563685145E+03); + cRho.push_back(-1.0269048032E+00); + cRho.push_back(-9.3506079577E-07); + cRho.push_back(+1.0368116627E-09); + CoolProp::IncompressibleData density; + density.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + density.coeffs = CoolProp::vec_to_eigen(cRho); - std::vector cHeat; - cHeat.push_back(+1.1562261074E+03); - cHeat.push_back(+2.0994549103E+00); - cHeat.push_back(+7.7175381057E-07); - cHeat.push_back(-3.7008444051E-20); - CoolProp::IncompressibleData specific_heat; - specific_heat.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - specific_heat.coeffs = CoolProp::vec_to_eigen(cHeat); + std::vector cHeat; + cHeat.push_back(+1.1562261074E+03); + cHeat.push_back(+2.0994549103E+00); + cHeat.push_back(+7.7175381057E-07); + cHeat.push_back(-3.7008444051E-20); + CoolProp::IncompressibleData specific_heat; + specific_heat.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + specific_heat.coeffs = CoolProp::vec_to_eigen(cHeat); - std::vector cCond; - cCond.push_back(+1.6121957379E-01); - cCond.push_back(-1.3023781944E-04); - cCond.push_back(-1.4395238766E-07); - CoolProp::IncompressibleData conductivity; - conductivity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - conductivity.coeffs = CoolProp::vec_to_eigen(cCond); + std::vector cCond; + cCond.push_back(+1.6121957379E-01); + cCond.push_back(-1.3023781944E-04); + cCond.push_back(-1.4395238766E-07); + CoolProp::IncompressibleData conductivity; + conductivity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + conductivity.coeffs = CoolProp::vec_to_eigen(cCond); - std::vector cVisc; - cVisc.push_back(+1.0337654989E+03); - cVisc.push_back(-4.3322764383E+01); - cVisc.push_back(+1.0715062356E+01); - CoolProp::IncompressibleData viscosity; - viscosity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL; - viscosity.coeffs = CoolProp::vec_to_eigen(cVisc); + std::vector cVisc; + cVisc.push_back(+1.0337654989E+03); + cVisc.push_back(-4.3322764383E+01); + cVisc.push_back(+1.0715062356E+01); + CoolProp::IncompressibleData viscosity; + viscosity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL; + viscosity.coeffs = CoolProp::vec_to_eigen(cVisc); - CoolProp::IncompressibleFluid XLT; - XLT.setName("XLT"); - XLT.setDescription("SylthermXLT"); - XLT.setReference("Dow Chemicals data sheet"); - XLT.setTmax(533.15); - XLT.setTmin(173.15); - XLT.setxmax(0.0); - XLT.setxmin(0.0); - XLT.setTminPsat(533.15); + CoolProp::IncompressibleFluid XLT; + XLT.setName("XLT"); + XLT.setDescription("SylthermXLT"); + XLT.setReference("Dow Chemicals data sheet"); + XLT.setTmax(533.15); + XLT.setTmin(173.15); + XLT.setxmax(0.0); + XLT.setxmin(0.0); + XLT.setTminPsat(533.15); - XLT.setTbase(0.0); - XLT.setxbase(0.0); + XLT.setTbase(0.0); + XLT.setxbase(0.0); - /// Setters for the coefficients - XLT.setDensity(density); - XLT.setSpecificHeat(specific_heat); - XLT.setViscosity(viscosity); - XLT.setConductivity(conductivity); - //XLT.setPsat(parse_coefficients(fluid_json, "saturation_pressure", false)); - //XLT.setTfreeze(parse_coefficients(fluid_json, "T_freeze", false)); - //XLT.setVolToMass(parse_coefficients(fluid_json, "volume2mass", false)); - //XLT.setMassToMole(parse_coefficients(fluid_json, "mass2mole", false)); + /// Setters for the coefficients + XLT.setDensity(density); + XLT.setSpecificHeat(specific_heat); + XLT.setViscosity(viscosity); + XLT.setConductivity(conductivity); + //XLT.setPsat(parse_coefficients(fluid_json, "saturation_pressure", false)); + //XLT.setTfreeze(parse_coefficients(fluid_json, "T_freeze", false)); + //XLT.setVolToMass(parse_coefficients(fluid_json, "volume2mass", false)); + //XLT.setMassToMole(parse_coefficients(fluid_json, "mass2mole", false)); - //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); - double Tref = 25+273.15; - double pref = 0.0; - double xref = 0.0; - double href = 0.0; - double sref = 0.0; - XLT.set_reference_state(Tref, pref, xref, href, sref); + //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); + double Tref = 25+273.15; + double pref = 0.0; + double xref = 0.0; + double href = 0.0; + double sref = 0.0; + XLT.set_reference_state(Tref, pref, xref, href, sref); - /// A function to check coefficients and equation types. - //XLT.validate(); + /// A function to check coefficients and equation types. + //XLT.validate(); - // Prepare the results and compare them to the calculated values - double acc = 0.0001; - double T = 273.15+50; - double p = 10e5; - double x = xref; - double val = 0; - double res = 0; + // Prepare the results and compare them to the calculated values + double acc = 0.0001; + double T = 273.15+50; + double p = 10e5; + double x = xref; + double val = 0; + double res = 0; - // Compare density - val = 824.4615702148608; - res = XLT.rho(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare density + val = 824.4615702148608; + res = XLT.rho(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - // Compare cp - val = 1834.7455527670554; - res = XLT.c(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare cp + val = 1834.7455527670554; + res = XLT.c(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - // Compare s - val = 145.59157247249246; - res = XLT.s(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare s + val = 145.59157247249246; + res = XLT.s(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = 0.0; - res = XLT.s(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( val==res ); - } + val = 0.0; + res = XLT.s(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( val==res ); + } - // Compare u - val = 45212.407309106304; - res = XLT.u(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare u + val = 45212.407309106304; + res = XLT.u(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = href - pref/XLT.rho(Tref,pref,xref); - res = XLT.u(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( val==res ); - } + val = href - pref/XLT.rho(Tref,pref,xref); + res = XLT.u(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( val==res ); + } - // Compare h - val = 46425.32011926845; - res = XLT.h(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare h + val = 46425.32011926845; + res = XLT.h(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - val = 0.0; - res = XLT.h(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( val==res ); - } + val = 0.0; + res = XLT.h(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( val==res ); + } - // Compare v - val = 0.0008931435169681835; - res = XLT.visc(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } + // Compare v + val = 0.0008931435169681835; + res = XLT.visc(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } - // Compare l - val = 0.10410086156049088; - res = XLT.cond(T,p,x); - { - CAPTURE(T); - CAPTURE(val); - CAPTURE(res); - CHECK( check_abs(val,res,acc) ); - } - } + // Compare l + val = 0.10410086156049088; + res = XLT.cond(T,p,x); + { + CAPTURE(T); + CAPTURE(val); + CAPTURE(res); + CHECK( check_abs(val,res,acc) ); + } + } - SECTION("Test case for Methanol from SecCool") { + SECTION("Test case for Methanol from SecCool") { - CoolProp::IncompressibleFluid CH3OH = CoolPropTesting::incompressibleFluidObject(); + CoolProp::IncompressibleFluid CH3OH = CoolPropTesting::incompressibleFluidObject(); - //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); - double Tref = 25+273.15; - double pref = 0.0; - double xref = 0.25; - double href = 0.0; - double sref = 0.0; - CH3OH.set_reference_state(Tref, pref, xref, href, sref); + //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); + double Tref = 25+273.15; + double pref = 0.0; + double xref = 0.25; + double href = 0.0; + double sref = 0.0; + CH3OH.set_reference_state(Tref, pref, xref, href, sref); - /// A function to check coefficients and equation types. - //CH3OH.validate(); + /// A function to check coefficients and equation types. + //CH3OH.validate(); - // Prepare the results and compare them to the calculated values - double acc = 0.0001; - double T = 273.15+10; - double p = 10e5; - double x = 0.25; - double expected = 0; - double actual = 0; + // Prepare the results and compare them to the calculated values + double acc = 0.0001; + double T = 273.15+10; + double p = 10e5; + double x = 0.25; + double expected = 0; + double actual = 0; - // Compare density - expected = 963.2886528091547; - actual = CH3OH.rho(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare density + expected = 963.2886528091547; + actual = CH3OH.rho(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare cp - expected = 3993.9748117022423; - actual = CH3OH.c(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare cp + expected = 3993.9748117022423; + actual = CH3OH.c(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare s - expected = -206.62646783739274; - actual = CH3OH.s(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare s + expected = -206.62646783739274; + actual = CH3OH.s(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } - expected = 0.0; - actual = CH3OH.s(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( expected==actual ); - } + expected = 0.0; + actual = CH3OH.s(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( expected==actual ); + } - // Compare u - expected = -60043.78429641827; - actual = CH3OH.u(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare u + expected = -60043.78429641827; + actual = CH3OH.u(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } - expected = href - pref/CH3OH.rho(Tref,pref,xref); - actual = CH3OH.u(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( expected==actual ); - } + expected = href - pref/CH3OH.rho(Tref,pref,xref); + actual = CH3OH.u(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( expected==actual ); + } - // Compare h - expected = -59005.67386390795; - actual = CH3OH.h(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare h + expected = -59005.67386390795; + actual = CH3OH.h(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + CHECK( check_abs(expected,actual,acc) ); + } - expected = 0.0; - actual = CH3OH.h(Tref,pref,xref); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( expected==actual ); - } + expected = 0.0; + actual = CH3OH.h(Tref,pref,xref); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( expected==actual ); + } - // Compare v - expected = 0.0023970245009602097; - actual = CH3OH.visc(T,p,x)/1e3; - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare v + expected = 0.0023970245009602097; + actual = CH3OH.visc(T,p,x)/1e3; + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare conductivity - expected = 0.44791148414693727; - actual = CH3OH.cond(T,p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare conductivity + expected = 0.44791148414693727; + actual = CH3OH.cond(T,p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - // Compare Tfreeze - expected = -20.02+273.15;// 253.1293105454671; - actual = CH3OH.Tfreeze(p,x); - { - CAPTURE(T); - CAPTURE(p); - CAPTURE(x); - CAPTURE(expected); - CAPTURE(actual); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); - CHECK( check_abs(expected,actual,acc) ); - } + // Compare Tfreeze + expected = -20.02+273.15;// 253.1293105454671; + actual = CH3OH.Tfreeze(p,x); + { + CAPTURE(T); + CAPTURE(p); + CAPTURE(x); + CAPTURE(expected); + CAPTURE(actual); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); + CHECK( check_abs(expected,actual,acc) ); + } - } + } } diff --git a/src/Backends/Incompressible/IncompressibleLibrary.cpp b/src/Backends/Incompressible/IncompressibleLibrary.cpp index 2e23fc71..b4ae37e9 100644 --- a/src/Backends/Incompressible/IncompressibleLibrary.cpp +++ b/src/Backends/Incompressible/IncompressibleLibrary.cpp @@ -35,217 +35,217 @@ double const LiBrSolution::cpt_H2O = 76.0226; /* J/(mol.K), molar isobaric heat double LiBrSolution::ps_mix(double T, double x) /* Equation (1) */ { - static double m[8] = { 3.0, 4.0, 4.0, 8.0, 1.0, 1.0, 4.0, 6.0 }; - static double n[8] = { 0.0, 5.0, 6.0, 3.0, 0.0, 2.0, 6.0, 0.0 }; - static double t[8] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 }; - static double a[8] = { -2.41303e2, 1.91750e7, -1.75521e8, 3.25430e7, - 3.92571e2, -2.12626e3, 1.85127e8, 1.91216e3 }; - double tau, suma = 0.0; - int i; + static double m[8] = { 3.0, 4.0, 4.0, 8.0, 1.0, 1.0, 4.0, 6.0 }; + static double n[8] = { 0.0, 5.0, 6.0, 3.0, 0.0, 2.0, 6.0, 0.0 }; + static double t[8] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 }; + static double a[8] = { -2.41303e2, 1.91750e7, -1.75521e8, 3.25430e7, + 3.92571e2, -2.12626e3, 1.85127e8, 1.91216e3 }; + double tau, suma = 0.0; + int i; - tau = T / Tc_H2O; - for (i = 0; i <= 7; i++) - suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); - return (ps_H2O(T - suma)); + tau = T / Tc_H2O; + for (i = 0; i <= 7; i++) + suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); + return (ps_H2O(T - suma)); } /* end function ps_mix */ double LiBrSolution::rho_mix(double T, double x) /* Equation (2) */ { - static double m[2] = { 1.0, 1.0 }; - static double n[2] = { 0.0, 6.0 }; - static double a[2] = { 1.746, 4.709 }; + static double m[2] = { 1.0, 1.0 }; + static double n[2] = { 0.0, 6.0 }; + static double a[2] = { 1.746, 4.709 }; - double tau, suma = 0.0; - int i; + double tau, suma = 0.0; + int i; - tau = T / Tc_H2O; - for (i = 0; i <= 1; i++) - suma += a[i] * pow(x, m[i]) * pow(tau, n[i]); + tau = T / Tc_H2O; + for (i = 0; i <= 1; i++) + suma += a[i] * pow(x, m[i]) * pow(tau, n[i]); - return ((1.0 - x) * rho_H2O(T) + rhoc_H2O * suma); + return ((1.0 - x) * rho_H2O(T) + rhoc_H2O * suma); } /* end function rho_mix */ double LiBrSolution::cp_mix(double T, double x) /* Equation (3) */ { - static double m[8] = { 2.0, 3.0, 3.0, 3.0, 3.0, 2.0, 1.0, 1.0 }; - static double n[8] = { 0.0, 0.0, 1.0, 2.0, 3.0, 0.0, 3.0, 2.0 }; - static double t[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 3.0, 4.0 }; - static double a[8] = { -1.42094e1, 4.04943e1, 1.11135e2, 2.29980e2, - 1.34526e3, -1.41010e-2, 1.24977e-2, -6.83209e-4 }; + static double m[8] = { 2.0, 3.0, 3.0, 3.0, 3.0, 2.0, 1.0, 1.0 }; + static double n[8] = { 0.0, 0.0, 1.0, 2.0, 3.0, 0.0, 3.0, 2.0 }; + static double t[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 3.0, 4.0 }; + static double a[8] = { -1.42094e1, 4.04943e1, 1.11135e2, 2.29980e2, + 1.34526e3, -1.41010e-2, 1.24977e-2, -6.83209e-4 }; - double tau, suma = 0.0; - int i; + double tau, suma = 0.0; + int i; - tau = Tc_H2O / (T - T0); - for (i = 0; i <= 7; i++) - suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); + tau = Tc_H2O / (T - T0); + for (i = 0; i <= 7; i++) + suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); - return ((1.0 - x) * cp_H2O(T) + cpt_H2O * suma); + return ((1.0 - x) * cp_H2O(T) + cpt_H2O * suma); } /* end function cp_mix */ double LiBrSolution::h_mix(double T, double x) /* Equation (4) */ { - static double m[30] = { 1.0, 1.0, 2.0, 3.0, 6.0, 1.0, 3.0, 5.0, 4.0, - 5.0, 5.0, 6.0, 6.0, 1.0, 2.0, 2.0, 2.0, 5.0, 6.0, 7.0, 1.0, 1.0, - 2.0, 2.0, 2.0, 3.0, 1.0, 1.0, 1.0, 1.0 }; + static double m[30] = { 1.0, 1.0, 2.0, 3.0, 6.0, 1.0, 3.0, 5.0, 4.0, + 5.0, 5.0, 6.0, 6.0, 1.0, 2.0, 2.0, 2.0, 5.0, 6.0, 7.0, 1.0, 1.0, + 2.0, 2.0, 2.0, 3.0, 1.0, 1.0, 1.0, 1.0 }; - static double n[30] = { 0.0, 1.0, 6.0, 6.0, 2.0, 0.0, 0.0, 4.0, 0.0, - 4.0, 5.0, 5.0, 6.0, 0.0, 3.0, 5.0, 7.0, 0.0, 3.0, 1.0, 0.0, 4.0, - 2.0, 6.0, 7.0, 0.0, 0.0, 1.0, 2.0, 3.0 }; + static double n[30] = { 0.0, 1.0, 6.0, 6.0, 2.0, 0.0, 0.0, 4.0, 0.0, + 4.0, 5.0, 5.0, 6.0, 0.0, 3.0, 5.0, 7.0, 0.0, 3.0, 1.0, 0.0, 4.0, + 2.0, 6.0, 7.0, 0.0, 0.0, 1.0, 2.0, 3.0 }; - static double t[30] = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, - 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, - 4.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0 }; + static double t[30] = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, + 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, + 4.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0 }; - static double a[30] = { 2.27431, -7.99511, 3.85239e2, -1.63940e4, - -4.22562e2, 1.13314e-1, -8.33474, -1.73833e4, 6.49763, - 3.24552e3, -1.34643e4, 3.99322e4, -2.58877e5, -1.93046e-3, - 2.80616, -4.04479e1, 1.45342e2, -2.74873, -4.49743e2, - -1.21794e1, -5.83739e-3, 2.33910e-1, 3.41888e-1, 8.85259, - -1.78731e1, 7.35179e-2, -1.79430e-4, 1.84261e-3, -6.24282e-3, - 6.84765e-3 }; + static double a[30] = { 2.27431, -7.99511, 3.85239e2, -1.63940e4, + -4.22562e2, 1.13314e-1, -8.33474, -1.73833e4, 6.49763, + 3.24552e3, -1.34643e4, 3.99322e4, -2.58877e5, -1.93046e-3, + 2.80616, -4.04479e1, 1.45342e2, -2.74873, -4.49743e2, + -1.21794e1, -5.83739e-3, 2.33910e-1, 3.41888e-1, 8.85259, + -1.78731e1, 7.35179e-2, -1.79430e-4, 1.84261e-3, -6.24282e-3, + 6.84765e-3 }; - double tau, suma = 0.0; - int i; + double tau, suma = 0.0; + int i; - tau = Tc_H2O / (T - T0); - for (i = 0; i <= 29; i++) - suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); + tau = Tc_H2O / (T - T0); + for (i = 0; i <= 29; i++) + suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); - return ((1.0 - x) * h_H2O(T) + hc_H2O * suma); + return ((1.0 - x) * h_H2O(T) + hc_H2O * suma); } /* end function h_mix */ double LiBrSolution::s_mix(double T, double x) /* Equation (5) */ { - static double m[29] = { 1.0, 1.0, 2.0, 3.0, 6.0, 1.0, 3.0, 5.0, 1.0, - 2.0, 2.0, 4.0, 5.0, 5.0, 6.0, 6.0, 1.0, 3.0, 5.0, 7.0, 1.0, 1.0, - 1.0, 2.0, 3.0, 1.0, 1.0, 1.0, 1.0 }; + static double m[29] = { 1.0, 1.0, 2.0, 3.0, 6.0, 1.0, 3.0, 5.0, 1.0, + 2.0, 2.0, 4.0, 5.0, 5.0, 6.0, 6.0, 1.0, 3.0, 5.0, 7.0, 1.0, 1.0, + 1.0, 2.0, 3.0, 1.0, 1.0, 1.0, 1.0 }; - static double n[29] = { 0.0, 1.0, 6.0, 6.0, 2.0, 0.0, 0.0, 4.0, 0.0, - 0.0, 4.0, 0.0, 4.0, 5.0, 2.0, 5.0, 0.0, 4.0, 0.0, 1.0, 0.0, 2.0, - 4.0, 7.0, 1.0, 0.0, 1.0, 2.0, 3.0 }; + static double n[29] = { 0.0, 1.0, 6.0, 6.0, 2.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 4.0, 0.0, 4.0, 5.0, 2.0, 5.0, 0.0, 4.0, 0.0, 1.0, 0.0, 2.0, + 4.0, 7.0, 1.0, 0.0, 1.0, 2.0, 3.0 }; - static double t[29] = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, - 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, - 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0 }; + static double t[29] = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, + 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, + 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0 }; - static double a[29] = { 1.53091, -4.52564, 6.98302e+2, -2.16664e+4, - -1.47533e+3, 8.47012e-2, -6.59523, -2.95331e+4, 9.56314e-3, - -1.88679e-1, 9.31752, 5.78104, 1.38931e+4, -1.71762e+4, - 4.15108e+2, -5.55647e+4, -4.23409e-3, 3.05242e+1, -1.67620, - 1.48283e+1, 3.03055e-3, -4.01810e-2, 1.49252e-1, 2.59240, - -1.77421e-1, -6.99650e-5, 6.05007e-4, -1.65228e-3, 1.22966e-3 }; + static double a[29] = { 1.53091, -4.52564, 6.98302e+2, -2.16664e+4, + -1.47533e+3, 8.47012e-2, -6.59523, -2.95331e+4, 9.56314e-3, + -1.88679e-1, 9.31752, 5.78104, 1.38931e+4, -1.71762e+4, + 4.15108e+2, -5.55647e+4, -4.23409e-3, 3.05242e+1, -1.67620, + 1.48283e+1, 3.03055e-3, -4.01810e-2, 1.49252e-1, 2.59240, + -1.77421e-1, -6.99650e-5, 6.05007e-4, -1.65228e-3, 1.22966e-3 }; - double tau, suma = 0.0; - int i; + double tau, suma = 0.0; + int i; - tau = Tc_H2O / (T - T0); - for (i = 0; i <= 28; i++) - suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); + tau = Tc_H2O / (T - T0); + for (i = 0; i <= 28; i++) + suma += a[i] * pow(x, m[i]) * pow(0.4 - x, n[i]) * pow(tau, t[i]); - return ((1.0 - x) * s_H2O(T) + sc_H2O * suma); + return ((1.0 - x) * s_H2O(T) + sc_H2O * suma); } /* end function s_mix */ double LiBrSolution::ps_H2O(double T) /* Equation (28) */ { - static double a[7] = { 0.0, -7.85951783, 1.84408259, -11.7866497, - 22.6807411, -15.9618719, 1.80122502 }; + static double a[7] = { 0.0, -7.85951783, 1.84408259, -11.7866497, + 22.6807411, -15.9618719, 1.80122502 }; - double tau, ps; + double tau, ps; - tau = 1 - T / Tc_H2O; + tau = 1 - T / Tc_H2O; - ps = pc_H2O - * exp( - Tc_H2O / T - * (a[1] * tau + a[2] * pow(tau, 1.5) - + a[3] * pow(tau, 3.0) - + a[4] * pow(tau, 3.5) - + a[5] * pow(tau, 4.0) - + a[6] * pow(tau, 7.5))); + ps = pc_H2O + * exp( + Tc_H2O / T + * (a[1] * tau + a[2] * pow(tau, 1.5) + + a[3] * pow(tau, 3.0) + + a[4] * pow(tau, 3.5) + + a[5] * pow(tau, 4.0) + + a[6] * pow(tau, 7.5))); - return (ps * 1.0e6); + return (ps * 1.0e6); } /* end function ps_H2O */ double LiBrSolution::rho_H2O(double T) /* Equation (29) */ { - static double b[7] = { 0.0, 1.99274064, 1.09965342, -0.510839303, - -1.75493479, -45.5170352, -6.7469445e5 }; - double theta, rho; + static double b[7] = { 0.0, 1.99274064, 1.09965342, -0.510839303, + -1.75493479, -45.5170352, -6.7469445e5 }; + double theta, rho; - theta = 1.0 - T / Tc_H2O; + theta = 1.0 - T / Tc_H2O; - rho = rhoc_H2O - * (1.0 + b[1] * pow(theta, 1.0 / 3.0) - + b[2] * pow(theta, 2.0 / 3.0) - + b[3] * pow(theta, 5.0 / 3.0) - + b[4] * pow(theta, 16.0 / 3.0) - + b[5] * pow(theta, 43.0 / 3.0) - + b[6] * pow(theta, 110.0 / 3.0)); + rho = rhoc_H2O + * (1.0 + b[1] * pow(theta, 1.0 / 3.0) + + b[2] * pow(theta, 2.0 / 3.0) + + b[3] * pow(theta, 5.0 / 3.0) + + b[4] * pow(theta, 16.0 / 3.0) + + b[5] * pow(theta, 43.0 / 3.0) + + b[6] * pow(theta, 110.0 / 3.0)); - return (rho); + return (rho); } /* end function rho_H2O */ double LiBrSolution::cp_H2O(double T) /* Equation (30) */ { - static double a[5] = - { 1.38801, -2.95318, 3.18721, -0.645473, 9.18946e5 }; - static double b[5] = { 0.0, 2.0, 3.0, 6.0, 34.0 }; - static double c[5] = { 0.0, 2.0, 3.0, 5.0, 0.0 }; + static double a[5] = + { 1.38801, -2.95318, 3.18721, -0.645473, 9.18946e5 }; + static double b[5] = { 0.0, 2.0, 3.0, 6.0, 34.0 }; + static double c[5] = { 0.0, 2.0, 3.0, 5.0, 0.0 }; - double suma = 0.0; - int i; + double suma = 0.0; + int i; - for (i = 0; i <= 4; i++) - suma += a[i] * exp(b[i] * log(1.0 - T / Tc_H2O)) - * exp(c[i] * log(T / Tt_H2O)); + for (i = 0; i <= 4; i++) + suma += a[i] * exp(b[i] * log(1.0 - T / Tc_H2O)) + * exp(c[i] * log(T / Tt_H2O)); - return (cpt_H2O * suma); + return (cpt_H2O * suma); } /* end function cp_H2O */ double LiBrSolution::h_H2O(double T) /* Equation (31) */ { - static double a[4] = { -4.37196e-1, 3.03440e-1, -1.29582, -1.76410e-1 }; - static double alpha[4] = { 1.0 / 3.0, 2.0 / 3.0, 5.0 / 6.0, 21.0 / 6.0 }; + static double a[4] = { -4.37196e-1, 3.03440e-1, -1.29582, -1.76410e-1 }; + static double alpha[4] = { 1.0 / 3.0, 2.0 / 3.0, 5.0 / 6.0, 21.0 / 6.0 }; - double suma = 0.0; - int i; + double suma = 0.0; + int i; - for (i = 0; i <= 3; i++) - suma += a[i] * exp(alpha[i] * log(1.0 - T / Tc_H2O)); + for (i = 0; i <= 3; i++) + suma += a[i] * exp(alpha[i] * log(1.0 - T / Tc_H2O)); - return (hc_H2O * (1.0 + suma)); + return (hc_H2O * (1.0 + suma)); } /* end function h_H2O */ double LiBrSolution::s_H2O(double T) /* Equation (32) */ { - static double a[4] = { -3.34112e-1, -8.47987e-1, -9.11980e-1, -1.64046 }; - static double alpha[4] = { 1.0 / 3.0, 3.0 / 3.0, 8.0 / 3.0, 24.0 / 3.0 }; + static double a[4] = { -3.34112e-1, -8.47987e-1, -9.11980e-1, -1.64046 }; + static double alpha[4] = { 1.0 / 3.0, 3.0 / 3.0, 8.0 / 3.0, 24.0 / 3.0 }; - double suma = 0.0; - int i; + double suma = 0.0; + int i; - for (i = 0; i <= 3; i++) - suma += a[i] * exp(alpha[i] * log(1.0 - T / Tc_H2O)); + for (i = 0; i <= 3; i++) + suma += a[i] * exp(alpha[i] * log(1.0 - T / Tc_H2O)); - return (sc_H2O * (1.0 + suma)); + return (sc_H2O * (1.0 + suma)); } /* end function s_H2O */ @@ -255,16 +255,16 @@ double LiBrSolution::s_H2O(double T) double LiBrSolution::massToMole(double w) /* Equation (7) */ { - return (w/M_LiBr)/(w/M_LiBr+(1.-w)/M_H2O); - //return (w*M_LiBr)/(w*M_LiBr+(1.-w)*M_H2O); + return (w/M_LiBr)/(w/M_LiBr+(1.-w)/M_H2O); + //return (w*M_LiBr)/(w*M_LiBr+(1.-w)*M_H2O); } double LiBrSolution::molarToSpecific(double w, double value) /* Equation (7,8) */ { - double x = massToMole(w); - //return w/(x*M_LiBr) * value; - return 1. / ( x*M_LiBr + (1.-x)*M_H2O ) * value; + double x = massToMole(w); + //return w/(x*M_LiBr) * value; + return 1. / ( x*M_LiBr + (1.-x)*M_H2O ) * value; } bool const LiBrSolution::debug = false; @@ -272,68 +272,68 @@ bool const LiBrSolution::debug = false; LiBrSolution::LiBrSolution():IncompressibleFluid(){ - name = std::string("LiBr"); - description = std::string("Lithium-Bromide solution from Patek2006"); - reference = std::string("Patek2006"); + name = std::string("LiBr"); + description = std::string("Lithium-Bromide solution from Patek2006"); + reference = std::string("Patek2006"); - Tmin = 273.00; - Tmax = 500.00; - TminPsat = Tmin; + Tmin = 273.00; + Tmax = 500.00; + TminPsat = Tmin; - xmin = 0.0; - xmax = 1.0; + xmin = 0.0; + xmax = 1.0; - xref = 0.0; - Tref = 0.0; - pref = 0.0; - href = 0.0; - sref = 0.0; - uref = 0.0; - rhoref = 0.0; - xbase = 0.0; - Tbase = 0.0; + xref = 0.0; + Tref = 0.0; + pref = 0.0; + href = 0.0; + sref = 0.0; + uref = 0.0; + rhoref = 0.0; + xbase = 0.0; + Tbase = 0.0; }; double LiBrSolution::rho(double T, double p, double x){ - checkTPX(T, p, x); - return 1./molarToSpecific(x, 1./rho_mix(T,massToMole(x))); + checkTPX(T, p, x); + return 1./molarToSpecific(x, 1./rho_mix(T,massToMole(x))); } double LiBrSolution::c(double T, double p, double x){ - checkTPX(T, p, x); - return molarToSpecific(x, cp_mix(T,massToMole(x))); + checkTPX(T, p, x); + return molarToSpecific(x, cp_mix(T,massToMole(x))); } //double h(double T, double p, double x){ -// return h_u(T,p,x); +// return h_u(T,p,x); //} double LiBrSolution::s(double T, double p, double x){ - checkTPX(T, p, x); - return molarToSpecific(x, s_mix(T,massToMole(x))); + checkTPX(T, p, x); + return molarToSpecific(x, s_mix(T,massToMole(x))); } double LiBrSolution::visc(double T, double p, double x){ - throw ValueError("Viscosity is not defined for LiBr-solutions."); + throw ValueError("Viscosity is not defined for LiBr-solutions."); } double LiBrSolution::cond(double T, double p, double x){ - throw ValueError("Thermal conductivity is not defined for LiBr-solutions."); + throw ValueError("Thermal conductivity is not defined for LiBr-solutions."); } double LiBrSolution::u(double T, double p, double x){ - checkTPX(T, p, x); - return molarToSpecific(x, h_mix(T,massToMole(x))); + checkTPX(T, p, x); + return molarToSpecific(x, h_mix(T,massToMole(x))); } double LiBrSolution::psat(double T, double x){ - //checkT(T,p,x); - if (debug) throw ValueError(format("Your concentration is %f in kg/kg and %f in mol/mol.",x,massToMole(x))); - return ps_mix(T,massToMole(x)); + //checkT(T,p,x); + if (debug) throw ValueError(format("Your concentration is %f in kg/kg and %f in mol/mol.",x,massToMole(x))); + return ps_mix(T,massToMole(x)); }; double LiBrSolution::Tfreeze(double p, double x){ - if (debug) throw ValueError(format("No freezing point data available for Lithium-Bromide: p=%f, x=%f",p,x)); - return Tmin; + if (debug) throw ValueError(format("No freezing point data available for Lithium-Bromide: p=%f, x=%f",p,x)); + return Tmin; } /// Default constructor JSONIncompressibleLibrary::JSONIncompressibleLibrary(){ - _is_empty = true; + _is_empty = true; // fluid_map.clear(); // name_vector.clear(); // string_to_index_map.clear(); @@ -344,168 +344,168 @@ JSONIncompressibleLibrary::JSONIncompressibleLibrary(){ /// Default destructor JSONIncompressibleLibrary::~JSONIncompressibleLibrary(){ -// freeClear(fluid_map); -// fluid_map.clear(); +// freeClear(fluid_map); +// fluid_map.clear(); // name_vector.clear(); // string_to_index_map.clear(); }; /// A general function to parse the json files that hold the coefficient matrices IncompressibleData JSONIncompressibleLibrary::parse_coefficients(rapidjson::Value &obj, std::string id, bool vital){ - IncompressibleData fluidData; - if (obj.HasMember(id.c_str())) { - //rapidjson::Value value = obj[id.c_str()]; - if (obj[id.c_str()].HasMember("type")){ - if (obj[id.c_str()].HasMember("coeffs")){ - std::string type = cpjson::get_string(obj[id.c_str()], "type"); - if (!type.compare("polynomial")){ - fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - fluidData.coeffs = vec_to_eigen(cpjson::get_double_array2D(obj[id.c_str()]["coeffs"])); - return fluidData; - } - else if (!type.compare("exponential")){ - fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL; - fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); - return fluidData; - } - else if (!type.compare("logexponential")){ - fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL; - fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); - return fluidData; - } - else if (!type.compare("exppolynomial")){ - fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL; - fluidData.coeffs = vec_to_eigen(cpjson::get_double_array2D(obj[id.c_str()]["coeffs"])); - return fluidData; - } - else if (!type.compare("polyoffset")){ - fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYOFFSET; - fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); - return fluidData; - } - else if (vital){ - throw ValueError(format("The type [%s] is not understood for [%s] of incompressible fluids. Please check your JSON file.", type.c_str(), id.c_str())); - } - else{ + IncompressibleData fluidData; + if (obj.HasMember(id.c_str())) { + //rapidjson::Value value = obj[id.c_str()]; + if (obj[id.c_str()].HasMember("type")){ + if (obj[id.c_str()].HasMember("coeffs")){ + std::string type = cpjson::get_string(obj[id.c_str()], "type"); + if (!type.compare("polynomial")){ + fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + fluidData.coeffs = vec_to_eigen(cpjson::get_double_array2D(obj[id.c_str()]["coeffs"])); + return fluidData; + } + else if (!type.compare("exponential")){ + fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPONENTIAL; + fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); + return fluidData; + } + else if (!type.compare("logexponential")){ + fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_LOGEXPONENTIAL; + fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); + return fluidData; + } + else if (!type.compare("exppolynomial")){ + fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL; + fluidData.coeffs = vec_to_eigen(cpjson::get_double_array2D(obj[id.c_str()]["coeffs"])); + return fluidData; + } + else if (!type.compare("polyoffset")){ + fluidData.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYOFFSET; + fluidData.coeffs = vec_to_eigen(cpjson::get_double_array(obj[id.c_str()]["coeffs"])); + return fluidData; + } + else if (vital){ + throw ValueError(format("The type [%s] is not understood for [%s] of incompressible fluids. Please check your JSON file.", type.c_str(), id.c_str())); + } + else{ //std::cout << format("The type [%s] is not understood for [%s] of incompressible fluids. Please check your JSON file.\n", type.c_str(), id.c_str()); - } - } - else{ - throw ValueError(format("Your file does not have an entry for \"coeffs\" in [%s], which is vital for this function.", id.c_str())); - } - } - else{ - throw ValueError(format("Your file does not have an entry for \"type\" in [%s], which is vital for this function.", id.c_str())); - } - } - else{ - if (vital) { - throw ValueError(format("Your file does not have information for [%s], which is vital for an incompressible fluid.", id.c_str())); - } - } - return fluidData; + } + } + else{ + throw ValueError(format("Your file does not have an entry for \"coeffs\" in [%s], which is vital for this function.", id.c_str())); + } + } + else{ + throw ValueError(format("Your file does not have an entry for \"type\" in [%s], which is vital for this function.", id.c_str())); + } + } + else{ + if (vital) { + throw ValueError(format("Your file does not have information for [%s], which is vital for an incompressible fluid.", id.c_str())); + } + } + return fluidData; } /// Get a double from the JSON storage if it is defined, otherwise return def double JSONIncompressibleLibrary::parse_value(rapidjson::Value &obj, std::string id, bool vital, double def=0.0){ - if (obj.HasMember(id.c_str())) { + if (obj.HasMember(id.c_str())) { return cpjson::get_double(obj, id); } - else{ - if (vital) { - throw ValueError(format("Your file does not have information for [%s], which is vital for an incompressible fluid.", id.c_str())); - } - else{ - return def; - } - } + else{ + if (vital) { + throw ValueError(format("Your file does not have information for [%s], which is vital for an incompressible fluid.", id.c_str())); + } + else{ + return def; + } + } } /// Get an integer from the JSON storage to identify the composition composition_types JSONIncompressibleLibrary::parse_ifrac(rapidjson::Value &obj, std::string id){ - std::string res = cpjson::get_string(obj, id); - if (!res.compare("mass")) return IFRAC_MASS; - if (!res.compare("mole")) return IFRAC_MOLE; - if (!res.compare("volume")) return IFRAC_VOLUME; - if (!res.compare("not defined")) return IFRAC_UNDEFINED; - if (!res.compare("pure")) return IFRAC_PURE; + std::string res = cpjson::get_string(obj, id); + if (!res.compare("mass")) return IFRAC_MASS; + if (!res.compare("mole")) return IFRAC_MOLE; + if (!res.compare("volume")) return IFRAC_VOLUME; + if (!res.compare("not defined")) return IFRAC_UNDEFINED; + if (!res.compare("pure")) return IFRAC_PURE; - throw ValueError(format("Cannot recognise the entry for [%s], [%s] is unknown for incompressible fluids.", id.c_str(), res.c_str())); - return IFRAC_UNDEFINED; + throw ValueError(format("Cannot recognise the entry for [%s], [%s] is unknown for incompressible fluids.", id.c_str(), res.c_str())); + return IFRAC_UNDEFINED; } /// Add all the fluid entries in the rapidjson::Value instance passed in void JSONIncompressibleLibrary::add_many(rapidjson::Value &listing) { - for (rapidjson::Value::ValueIterator itr = listing.Begin(); - itr != listing.End(); ++itr) { - add_one(*itr); - } + for (rapidjson::Value::ValueIterator itr = listing.Begin(); + itr != listing.End(); ++itr) { + add_one(*itr); + } }; void JSONIncompressibleLibrary::add_one(rapidjson::Value &fluid_json) { - _is_empty = false; + _is_empty = false; - // Get the next index for this fluid - std::size_t index = fluid_map.size(); + // Get the next index for this fluid + std::size_t index = fluid_map.size(); - // Add index->fluid mapping - fluid_map[index] = IncompressibleFluid(); - //fluid_map[index].reset(new IncompressibleFluid()); - //fluid_map[index].reset(new IncompressibleFluid()); + // Add index->fluid mapping + fluid_map[index] = IncompressibleFluid(); + //fluid_map[index].reset(new IncompressibleFluid()); + //fluid_map[index].reset(new IncompressibleFluid()); - // Create an instance of the fluid - IncompressibleFluid &fluid = fluid_map[index]; - fluid.setName("unloaded"); + // Create an instance of the fluid + IncompressibleFluid &fluid = fluid_map[index]; + fluid.setName("unloaded"); try { - fluid.setName(cpjson::get_string(fluid_json, "name")); - if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading base values for %s ",fluid.getName().c_str()) << std::endl; - fluid.setDescription(cpjson::get_string(fluid_json, "description")); - fluid.setReference(cpjson::get_string(fluid_json, "reference")); - fluid.setTmax( parse_value(fluid_json, "Tmax", true, 0.0)); - fluid.setTmin( parse_value(fluid_json, "Tmin", true, 0.0)); - fluid.setxmax( parse_value(fluid_json, "xmax", false, 1.0)); - fluid.setxmin( parse_value(fluid_json, "xmin", false, 0.0)); - fluid.setxid( parse_ifrac(fluid_json, "xid") ); - fluid.setTminPsat(parse_value(fluid_json, "TminPsat", false, 0.0)); + fluid.setName(cpjson::get_string(fluid_json, "name")); + if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading base values for %s ",fluid.getName().c_str()) << std::endl; + fluid.setDescription(cpjson::get_string(fluid_json, "description")); + fluid.setReference(cpjson::get_string(fluid_json, "reference")); + fluid.setTmax( parse_value(fluid_json, "Tmax", true, 0.0)); + fluid.setTmin( parse_value(fluid_json, "Tmin", true, 0.0)); + fluid.setxmax( parse_value(fluid_json, "xmax", false, 1.0)); + fluid.setxmin( parse_value(fluid_json, "xmin", false, 0.0)); + fluid.setxid( parse_ifrac(fluid_json, "xid") ); + fluid.setTminPsat(parse_value(fluid_json, "TminPsat", false, 0.0)); - fluid.setTbase(parse_value(fluid_json, "Tbase", false, 0.0)); - fluid.setxbase(parse_value(fluid_json, "xbase", false, 0.0)); + fluid.setTbase(parse_value(fluid_json, "Tbase", false, 0.0)); + fluid.setxbase(parse_value(fluid_json, "xbase", false, 0.0)); - /// Setters for the coefficients - if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading coefficients for %s ",fluid.getName().c_str()) << std::endl; - fluid.setDensity(parse_coefficients(fluid_json, "density", true)); - fluid.setSpecificHeat(parse_coefficients(fluid_json, "specific_heat", true)); - fluid.setViscosity(parse_coefficients(fluid_json, "viscosity", false)); - fluid.setConductivity(parse_coefficients(fluid_json, "conductivity", false)); - fluid.setPsat(parse_coefficients(fluid_json, "saturation_pressure", false)); - fluid.setTfreeze(parse_coefficients(fluid_json, "T_freeze", false)); - fluid.setMass2input(parse_coefficients(fluid_json, "mass2input", false)); - fluid.setVolume2input(parse_coefficients(fluid_json, "volume2input", false)); - fluid.setMole2input(parse_coefficients(fluid_json, "mole2input", false)); + /// Setters for the coefficients + if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading coefficients for %s ",fluid.getName().c_str()) << std::endl; + fluid.setDensity(parse_coefficients(fluid_json, "density", true)); + fluid.setSpecificHeat(parse_coefficients(fluid_json, "specific_heat", true)); + fluid.setViscosity(parse_coefficients(fluid_json, "viscosity", false)); + fluid.setConductivity(parse_coefficients(fluid_json, "conductivity", false)); + fluid.setPsat(parse_coefficients(fluid_json, "saturation_pressure", false)); + fluid.setTfreeze(parse_coefficients(fluid_json, "T_freeze", false)); + fluid.setMass2input(parse_coefficients(fluid_json, "mass2input", false)); + fluid.setVolume2input(parse_coefficients(fluid_json, "volume2input", false)); + fluid.setMole2input(parse_coefficients(fluid_json, "mole2input", false)); - if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading reference state for %s ",fluid.getName().c_str()) << std::endl; - fluid.set_reference_state( - parse_value(fluid_json, "Tref", false, 20+273.15) , - parse_value(fluid_json, "pref", false, 1.01325e5) , - parse_value(fluid_json, "xref", false, 0.0) , - parse_value(fluid_json, "href", false, 0.0) , - parse_value(fluid_json, "sref", false, 0.0) - ); + if (get_debug_level()>=20) std::cout << format("Incompressible library: Loading reference state for %s ",fluid.getName().c_str()) << std::endl; + fluid.set_reference_state( + parse_value(fluid_json, "Tref", false, 20+273.15) , + parse_value(fluid_json, "pref", false, 1.01325e5) , + parse_value(fluid_json, "xref", false, 0.0) , + parse_value(fluid_json, "href", false, 0.0) , + parse_value(fluid_json, "sref", false, 0.0) + ); - /// A function to check coefficients and equation types. - fluid.validate(); + /// A function to check coefficients and equation types. + fluid.validate(); - // Add name->index mapping - string_to_index_map[fluid.getName()] = index; + // Add name->index mapping + string_to_index_map[fluid.getName()] = index; // Add name to vector of names - if (fluid.is_pure()){ - this->name_vector_pure.push_back(fluid.getName()); - } - else{ - this->name_vector_solution.push_back(fluid.getName()); - } + if (fluid.is_pure()){ + this->name_vector_pure.push_back(fluid.getName()); + } + else{ + this->name_vector_solution.push_back(fluid.getName()); + } } catch(std::exception &e) { @@ -516,16 +516,16 @@ void JSONIncompressibleLibrary::add_one(rapidjson::Value &fluid_json) { }; void JSONIncompressibleLibrary::add_obj(IncompressibleFluid fluid_obj) { - _is_empty = false; + _is_empty = false; - // Get the next index for this fluid - std::size_t index = fluid_map.size(); + // Get the next index for this fluid + std::size_t index = fluid_map.size(); - // Add index->fluid mapping - fluid_map[index] = fluid_obj; + // Add index->fluid mapping + fluid_map[index] = fluid_obj; - // Create an instance of the fluid - IncompressibleFluid &fluid = fluid_map[index]; + // Create an instance of the fluid + IncompressibleFluid &fluid = fluid_map[index]; /// A function to check coefficients and equation types. fluid.validate(); @@ -536,20 +536,20 @@ void JSONIncompressibleLibrary::add_obj(IncompressibleFluid fluid_obj) { // Get an IncompressibleFluid instance stored in this library IncompressibleFluid& JSONIncompressibleLibrary::get(std::string key) { - std::map::iterator it; - // Try to find it - it = string_to_index_map.find(key); - // If it is found - if (it != string_to_index_map.end()) { - return get(it->second); - } else { - throw ValueError( - format( - "key [%s] was not found in string_to_index_map in JSONIncompressibleLibrary", - key.c_str() - ) - ); - } + std::map::iterator it; + // Try to find it + it = string_to_index_map.find(key); + // If it is found + if (it != string_to_index_map.end()) { + return get(it->second); + } else { + throw ValueError( + format( + "key [%s] was not found in string_to_index_map in JSONIncompressibleLibrary", + key.c_str() + ) + ); + } }; /// Get a IncompressibleFluid instance stored in this library @@ -557,16 +557,16 @@ IncompressibleFluid& JSONIncompressibleLibrary::get(std::string key) { @param key The index of the fluid in the map */ IncompressibleFluid& JSONIncompressibleLibrary::get(std::size_t key) { - std::map::iterator it; - // Try to find it - it = fluid_map.find(key); - // If it is found - if (it != fluid_map.end()) { - return it->second; - } else { - throw ValueError( - format("key [%d] was not found in JSONIncompressibleLibrary",key)); - } + std::map::iterator it; + // Try to find it + it = fluid_map.find(key); + // If it is found + if (it != fluid_map.end()) { + return it->second; + } else { + throw ValueError( + format("key [%d] was not found in JSONIncompressibleLibrary",key)); + } }; @@ -597,21 +597,21 @@ static JSONIncompressibleLibrary library; void load_incompressible_library() { - rapidjson::Document dd; + rapidjson::Document dd; // This json formatted string comes from the all_incompressibles_JSON.h header which is a C++-escaped version of the JSON file dd.Parse<0>(all_incompressibles_JSON.c_str()); - if (dd.HasParseError()){ + if (dd.HasParseError()){ throw ValueError("Unable to load all_incompressibles_JSON.json"); } else{ try{library.add_many(dd);}catch(std::exception &e){std::cout << e.what() << std::endl;} } - // TODO: Implement LiBr in the source code! - //library.add_obj(LiBrSolution()); + // TODO: Implement LiBr in the source code! + //library.add_obj(LiBrSolution()); } JSONIncompressibleLibrary & get_incompressible_library(void){ - if (library.is_empty()){ load_incompressible_library(); } - return library; + if (library.is_empty()){ load_incompressible_library(); } + return library; } IncompressibleFluid& get_incompressible_fluid(std::string fluid_string){ diff --git a/src/Backends/Incompressible/IncompressibleLibrary.h b/src/Backends/Incompressible/IncompressibleLibrary.h index b474e53a..89cfcfb6 100644 --- a/src/Backends/Incompressible/IncompressibleLibrary.h +++ b/src/Backends/Incompressible/IncompressibleLibrary.h @@ -29,101 +29,101 @@ extern int get_debug_level(); class LiBrSolution : public IncompressibleFluid{ protected: - static double const M_H2O; /* kg/mol, molar mass of H2O */ - static double const M_LiBr; /* kg/mol, molar mass of LiBr */ - static double const T0; /* K, constant */ + static double const M_H2O; /* kg/mol, molar mass of H2O */ + static double const M_LiBr; /* kg/mol, molar mass of LiBr */ + static double const T0; /* K, constant */ - /* Critical point of H2O */ - static double const Tc_H2O; /* K, temperature */ - static double const pc_H2O; /* MPa, pressure */ - static double const rhoc_H2O; /* mol/m^3 (322 kg/m^3), molar density */ - static double const hc_H2O; /* J/mol, molar enthalpy */ - static double const sc_H2O; /* J/(mol.K) molar entropy*/ + /* Critical point of H2O */ + static double const Tc_H2O; /* K, temperature */ + static double const pc_H2O; /* MPa, pressure */ + static double const rhoc_H2O; /* mol/m^3 (322 kg/m^3), molar density */ + static double const hc_H2O; /* J/mol, molar enthalpy */ + static double const sc_H2O; /* J/(mol.K) molar entropy*/ - /*Triple point of H2O */ - static double const Tt_H2O; /* K, temperature */ - static double const cpt_H2O; /* J/(mol.K), molar isobaric heat capacity*/ + /*Triple point of H2O */ + static double const Tt_H2O; /* K, temperature */ + static double const cpt_H2O; /* J/(mol.K), molar isobaric heat capacity*/ - double ps_mix(double T, double x); - double rho_mix(double T, double x); - double cp_mix(double T, double x); - double h_mix(double T, double x); - double s_mix(double T, double x); - double ps_H2O(double T); - double rho_H2O(double T); - double cp_H2O(double T); - double h_H2O(double T); - double s_H2O(double T); + double ps_mix(double T, double x); + double rho_mix(double T, double x); + double cp_mix(double T, double x); + double h_mix(double T, double x); + double s_mix(double T, double x); + double ps_H2O(double T); + double rho_H2O(double T); + double cp_H2O(double T); + double h_H2O(double T); + double s_H2O(double T); - /** Finished with the code from the paper. Now we need to - * convert the molar values to mass-based units. */ - double massToMole(double w); - double molarToSpecific(double w, double value); + /** Finished with the code from the paper. Now we need to + * convert the molar values to mass-based units. */ + double massToMole(double w); + double molarToSpecific(double w, double value); - static const bool debug; + static const bool debug; public: - LiBrSolution(); + LiBrSolution(); - double rho(double T, double p, double x); - double c(double T, double p, double x); - //double h(double T_K, double p, double x); - double s(double T, double p, double x); - double visc(double T, double p, double x); - double cond(double T, double p, double x); - double u(double T, double p, double x); - double psat(double T, double x); - double Tfreeze(double p, double x); + double rho(double T, double p, double x); + double c(double T, double p, double x); + //double h(double T_K, double p, double x); + double s(double T, double p, double x); + double visc(double T, double p, double x); + double cond(double T, double p, double x); + double u(double T, double p, double x); + double psat(double T, double x); + double Tfreeze(double p, double x); - /* Some functions can be inverted directly, those are listed - * here. It is also possible to solve for other quantities, but - * that involves some more sophisticated processing and is not - * done here, but in the backend, T(h,p) for example. - */ - /// Temperature as a function of density, pressure and composition. - double T_rho (double Dmass, double p, double x){throw NotImplementedError(format("%s (%d): T from density is not implemented for LiBr.",__FILE__,__LINE__));} - /// Temperature as a function of heat capacities as a function of temperature, pressure and composition. - double T_c (double Cmass, double p, double x){throw NotImplementedError(format("%s (%d): T from heat capacity is not implemented for LiBr.",__FILE__,__LINE__));} - /// Temperature as a function of entropy as a function of temperature, pressure and composition. - double T_s (double Smass, double p, double x){throw NotImplementedError(format("%s (%d): T from entropy is not implemented for LiBr.",__FILE__,__LINE__));} - /// Temperature as a function of internal energy as a function of temperature, pressure and composition. - double T_u (double Umass, double p, double x){throw NotImplementedError(format("%s (%d): T from internal energy is not implemented for LiBr.",__FILE__,__LINE__));} - /// Temperature as a function of enthalpy, pressure and composition. - //double T_h (double Hmass, double p, double x){throw NotImplementedError(format("%s (%d): T from enthalpy is not implemented in the fluid, use the backend.",__FILE__,__LINE__));} - /// Viscosity as a function of temperature, pressure and composition. - double T_visc(double visc, double p, double x){throw NotImplementedError(format("%s (%d): T from viscosity is not implemented.",__FILE__,__LINE__));} - /// Thermal conductivity as a function of temperature, pressure and composition. - double T_cond(double cond, double p, double x){throw NotImplementedError(format("%s (%d): T from conductivity is not implemented.",__FILE__,__LINE__));} - /// Saturation pressure as a function of temperature and composition. - double T_psat(double psat, double x){throw NotImplementedError(format("%s (%d): T from psat is not implemented.",__FILE__,__LINE__));} - /// Composition as a function of freezing temperature and pressure. - double x_Tfreeze( double Tfreeze, double p){throw NotImplementedError(format("%s (%d): x from T_freeze is not implemented.",__FILE__,__LINE__));} + /* Some functions can be inverted directly, those are listed + * here. It is also possible to solve for other quantities, but + * that involves some more sophisticated processing and is not + * done here, but in the backend, T(h,p) for example. + */ + /// Temperature as a function of density, pressure and composition. + double T_rho (double Dmass, double p, double x){throw NotImplementedError(format("%s (%d): T from density is not implemented for LiBr.",__FILE__,__LINE__));} + /// Temperature as a function of heat capacities as a function of temperature, pressure and composition. + double T_c (double Cmass, double p, double x){throw NotImplementedError(format("%s (%d): T from heat capacity is not implemented for LiBr.",__FILE__,__LINE__));} + /// Temperature as a function of entropy as a function of temperature, pressure and composition. + double T_s (double Smass, double p, double x){throw NotImplementedError(format("%s (%d): T from entropy is not implemented for LiBr.",__FILE__,__LINE__));} + /// Temperature as a function of internal energy as a function of temperature, pressure and composition. + double T_u (double Umass, double p, double x){throw NotImplementedError(format("%s (%d): T from internal energy is not implemented for LiBr.",__FILE__,__LINE__));} + /// Temperature as a function of enthalpy, pressure and composition. + //double T_h (double Hmass, double p, double x){throw NotImplementedError(format("%s (%d): T from enthalpy is not implemented in the fluid, use the backend.",__FILE__,__LINE__));} + /// Viscosity as a function of temperature, pressure and composition. + double T_visc(double visc, double p, double x){throw NotImplementedError(format("%s (%d): T from viscosity is not implemented.",__FILE__,__LINE__));} + /// Thermal conductivity as a function of temperature, pressure and composition. + double T_cond(double cond, double p, double x){throw NotImplementedError(format("%s (%d): T from conductivity is not implemented.",__FILE__,__LINE__));} + /// Saturation pressure as a function of temperature and composition. + double T_psat(double psat, double x){throw NotImplementedError(format("%s (%d): T from psat is not implemented.",__FILE__,__LINE__));} + /// Composition as a function of freezing temperature and pressure. + double x_Tfreeze( double Tfreeze, double p){throw NotImplementedError(format("%s (%d): x from T_freeze is not implemented.",__FILE__,__LINE__));} - /// Overwrite some standard functions that cannot be used with LiBr - void setName(std::string name){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setDescription(std::string description){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setReference(std::string reference){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setTmax(double Tmax){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setTmin(double Tmin){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setxmax(double xmax){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setxmin(double xmin){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setTminPsat(double TminPsat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + /// Overwrite some standard functions that cannot be used with LiBr + void setName(std::string name){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setDescription(std::string description){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setReference(std::string reference){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setTmax(double Tmax){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setTmin(double Tmin){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setxmax(double xmax){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setxmin(double xmin){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setTminPsat(double TminPsat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setTbase(double Tbase){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setxbase(double xbase){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setTbase(double Tbase){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setxbase(double xbase){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setDensity(IncompressibleData density){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setSpecificHeat(IncompressibleData specific_heat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setViscosity(IncompressibleData viscosity){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setConductivity(IncompressibleData conductivity){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setPsat(IncompressibleData p_sat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setTfreeze(IncompressibleData T_freeze){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setVolToMass(IncompressibleData volToMass){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - void setMassToMole(IncompressibleData massToMole){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setDensity(IncompressibleData density){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setSpecificHeat(IncompressibleData specific_heat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setViscosity(IncompressibleData viscosity){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setConductivity(IncompressibleData conductivity){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setPsat(IncompressibleData p_sat){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setTfreeze(IncompressibleData T_freeze){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setVolToMass(IncompressibleData volToMass){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} + void setMassToMole(IncompressibleData massToMole){throw ValueError(format("%s (%d): Cannot change property of LiBr class",__FILE__,__LINE__));} - bool is_pure() {return false;}; + bool is_pure() {return false;}; }; @@ -143,8 +143,8 @@ a rapidjson array of fluids to the add_many function. class JSONIncompressibleLibrary { /// Map from CAS code to JSON instance. - /** This is not practical for the incompressibles, the CAS may not be - * defined for blends of heat transfer fluids and solutions. + /** This is not practical for the incompressibles, the CAS may not be + * defined for blends of heat transfer fluids and solutions. */ std::map fluid_map; std::vector name_vector_pure, name_vector_solution; @@ -183,8 +183,8 @@ public: /// Return a comma-separated list of incompressible pure fluid names std::string get_incompressible_list_pure(void){ return strjoin(name_vector_pure, ",");}; - /// Return a comma-separated list of solution names - std::string get_incompressible_list_solution(void){ return strjoin(name_vector_solution, ",");}; + /// Return a comma-separated list of solution names + std::string get_incompressible_list_solution(void){ return strjoin(name_vector_solution, ",");}; }; /// Get a reference to the library instance diff --git a/src/Backends/REFPROP/REFPROPBackend.cpp b/src/Backends/REFPROP/REFPROPBackend.cpp index d57f395a..bee6e03a 100644 --- a/src/Backends/REFPROP/REFPROPBackend.cpp +++ b/src/Backends/REFPROP/REFPROPBackend.cpp @@ -23,21 +23,21 @@ namespace CoolProp { REFPROPBackend::REFPROPBackend(const std::string & fluid_name) { - // Do the REFPROP instantiation for this fluid + // Do the REFPROP instantiation for this fluid - // Try to add this fluid to REFPROP - might want to think about making array of - // components and setting mole fractions if they change a lot. - std::vector component_names(1,fluid_name); - set_REFPROP_fluids(component_names); + // Try to add this fluid to REFPROP - might want to think about making array of + // components and setting mole fractions if they change a lot. + std::vector component_names(1,fluid_name); + set_REFPROP_fluids(component_names); - // Set the mole fraction to 1 in the base class (we can't set the mole fraction in this class, - // otherwise a NotImplementedError will be returned) - std::vector x(1, 1.0); // (one element with value of 1.0) - REFPROPMixtureBackend::set_mole_fractions(x); + // Set the mole fraction to 1 in the base class (we can't set the mole fraction in this class, + // otherwise a NotImplementedError will be returned) + std::vector x(1, 1.0); // (one element with value of 1.0) + REFPROPMixtureBackend::set_mole_fractions(x); } REFPROPBackend::~REFPROPBackend() { - // TODO Auto-generated destructor stub + // TODO Auto-generated destructor stub } } /* namespace CoolProp */ diff --git a/src/Backends/REFPROP/REFPROPBackend.h b/src/Backends/REFPROP/REFPROPBackend.h index 373140b0..8728d04e 100644 --- a/src/Backends/REFPROP/REFPROPBackend.h +++ b/src/Backends/REFPROP/REFPROPBackend.h @@ -20,10 +20,10 @@ and exposes just the pure fluid interface. class REFPROPBackend : public REFPROPMixtureBackend { public: - REFPROPBackend(); - REFPROPBackend(const std::string &fluid_name); - - virtual ~REFPROPBackend(); + REFPROPBackend(); + REFPROPBackend(const std::string &fluid_name); + + virtual ~REFPROPBackend(); }; } /* namespace CoolProp */ diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp index d454c4d9..2862f0cd 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp @@ -71,7 +71,7 @@ surface tension N/m #define filepathlength 255 #define lengthofreference 3 #define errormessagelength 255 -#define ncmax 20 // Note: ncmax is the max number of components +#define ncmax 20 // Note: ncmax is the max number of components #define numparams 72 #define maxcoefs 50 @@ -82,7 +82,7 @@ std::string LoadedREFPROPRef; #define filepathlength 255 #define lengthofreference 3 #define errormessagelength 255 -#define ncmax 20 // Note: ncmax is the max number of components +#define ncmax 20 // Note: ncmax is the max number of components #define numparams 72 #define maxcoefs 50 @@ -318,7 +318,7 @@ double setFunctionPointers() SETMODdll = (SETMODdll_POINTER) getFunctionPointer((char *)SETMODdll_NAME); SETREFdll = (SETREFdll_POINTER) getFunctionPointer((char *)SETREFdll_NAME); SETUPdll = (SETUPdll_POINTER) getFunctionPointer((char *)SETUPdll_NAME); -// SPECGRdll = (SPECGRdll_POINTER) getFunctionPointer((char *)SPECGRdll_NAME); // not in library +// SPECGRdll = (SPECGRdll_POINTER) getFunctionPointer((char *)SPECGRdll_NAME); // not in library SUBLPdll = (SUBLPdll_POINTER) getFunctionPointer((char *)SUBLPdll_NAME); SUBLTdll = (SUBLTdll_POINTER) getFunctionPointer((char *)SUBLTdll_NAME); SURFTdll = (SURFTdll_POINTER) getFunctionPointer((char *)SURFTdll_NAME); @@ -595,81 +595,81 @@ void REFPROPMixtureBackend::check_status(void) void REFPROPMixtureBackend::limits(double &Tmin, double &Tmax, double &rhomolarmax, double &pmax) { - /* - * - subroutine LIMITS (htyp,x,tmin,tmax,Dmax,pmax) - c - c returns limits of a property model as a function of composition - c - c Pure fluid limits are read in from the .fld files; for mixtures, a - c simple mole fraction weighting in reduced variables is used. - c - c inputs: - c htyp--flag indicating which models are to be checked [character*3] - c 'EOS': equation of state for thermodynamic properties - c 'ETA': viscosity - c 'TCX': thermal conductivity - c 'STN': surface tension - c x--composition array [mol frac] - c outputs: - c tmin--minimum temperature for model specified by htyp [K] - c tmax--maximum temperature [K] - c Dmax--maximum density [mol/L] - c pmax--maximum pressure [kPa] - * - */ - double Dmax_mol_L,pmax_kPa; + /* + * + subroutine LIMITS (htyp,x,tmin,tmax,Dmax,pmax) + c + c returns limits of a property model as a function of composition + c + c Pure fluid limits are read in from the .fld files; for mixtures, a + c simple mole fraction weighting in reduced variables is used. + c + c inputs: + c htyp--flag indicating which models are to be checked [character*3] + c 'EOS': equation of state for thermodynamic properties + c 'ETA': viscosity + c 'TCX': thermal conductivity + c 'STN': surface tension + c x--composition array [mol frac] + c outputs: + c tmin--minimum temperature for model specified by htyp [K] + c tmax--maximum temperature [K] + c Dmax--maximum density [mol/L] + c pmax--maximum pressure [kPa] + * + */ + double Dmax_mol_L,pmax_kPa; char htyp[] = "EOS"; - LIMITSdll(htyp, &(mole_fractions[0]), &Tmin, &Tmax, &Dmax_mol_L, &pmax_kPa, 3); - pmax = pmax_kPa*1000; - rhomolarmax = Dmax_mol_L*1000; + LIMITSdll(htyp, &(mole_fractions[0]), &Tmin, &Tmax, &Dmax_mol_L, &pmax_kPa, 3); + pmax = pmax_kPa*1000; + rhomolarmax = Dmax_mol_L*1000; } long double REFPROPMixtureBackend::calc_pmax(void){ - double Tmin, Tmax, rhomolarmax, pmax; - limits(Tmin, Tmax, rhomolarmax, pmax); - return static_cast(pmax); + double Tmin, Tmax, rhomolarmax, pmax; + limits(Tmin, Tmax, rhomolarmax, pmax); + return static_cast(pmax); }; long double REFPROPMixtureBackend::calc_Tmax(void){ - double Tmin, Tmax, rhomolarmax, pmax; - limits(Tmin, Tmax, rhomolarmax, pmax); - return static_cast(Tmax); + double Tmin, Tmax, rhomolarmax, pmax; + limits(Tmin, Tmax, rhomolarmax, pmax); + return static_cast(Tmax); }; long double REFPROPMixtureBackend::calc_T_critical(){ long ierr; char herr[255]; double Tcrit, pcrit_kPa, dcrit_mol_L; CRITPdll(&(mole_fractions[0]),&Tcrit,&pcrit_kPa,&dcrit_mol_L,&ierr,herr,255); if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} - return static_cast(Tcrit); + return static_cast(Tcrit); }; long double REFPROPMixtureBackend::calc_p_critical(){ long ierr; char herr[255]; double Tcrit, pcrit_kPa, dcrit_mol_L; CRITPdll(&(mole_fractions[0]),&Tcrit,&pcrit_kPa,&dcrit_mol_L,&ierr,herr,255); if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} - return static_cast(pcrit_kPa*1000); + return static_cast(pcrit_kPa*1000); }; long double REFPROPMixtureBackend::calc_rhomolar_critical(){ long ierr; char herr[255]; double Tcrit, pcrit_kPa, dcrit_mol_L; CRITPdll(&(mole_fractions[0]),&Tcrit,&pcrit_kPa,&dcrit_mol_L,&ierr,herr,255); if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} - return static_cast(dcrit_mol_L*1000); + return static_cast(dcrit_mol_L*1000); }; long double REFPROPMixtureBackend::calc_Ttriple(){ if (mole_fractions.size() != 1){throw ValueError("calc_Ttriple cannot be evaluated for mixtures");} long icomp = 0; double wmm, ttrp, tnbpt, tc, pc, Dc, Zc, acf, dip, Rgas; INFOdll(&icomp, &wmm, &ttrp, &tnbpt, &tc, &pc, &Dc, &Zc, &acf, &dip, &Rgas); - return static_cast(ttrp); + return static_cast(ttrp); }; long double REFPROPMixtureBackend::calc_molar_mass(void) { double wmm_kg_kmol; WMOLdll(&(mole_fractions[0]), &wmm_kg_kmol); // returns mole mass in kg/kmol _molar_mass = wmm_kg_kmol/1000; // kg/mol - return static_cast(_molar_mass.pt()); + return static_cast(_molar_mass.pt()); }; - + double REFPROPMixtureBackend::calc_melt_Tmax() { long ierr; @@ -687,33 +687,33 @@ double REFPROPMixtureBackend::calc_melt_Tmax() } long double REFPROPMixtureBackend::calc_melting_line(int param, int given, long double value) { - long ierr; + long ierr; char herr[255]; - if (param == iP && given == iT){ - double _T = static_cast(value), p_kPa; - MELTTdll(&_T, &(mole_fractions[0]), + if (param == iP && given == iT){ + double _T = static_cast(value), p_kPa; + MELTTdll(&_T, &(mole_fractions[0]), &p_kPa, &ierr,herr,errormessagelength); // Error message - if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} - return p_kPa*1000; - } - else if (param == iT && given == iP){ - double p_kPa = static_cast(value), _T; - MELTPdll(&p_kPa, &(mole_fractions[0]), + if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} + return p_kPa*1000; + } + else if (param == iT && given == iP){ + double p_kPa = static_cast(value), _T; + MELTPdll(&p_kPa, &(mole_fractions[0]), &_T, &ierr,herr,errormessagelength); // Error message - if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} - return p_kPa*1000; - } - else{ - throw ValueError(format("calc_melting_line(%s,%s,%Lg) is an invalid set of inputs ", - get_parameter_information(param,"short").c_str(), - get_parameter_information(given,"short").c_str(), - value - ) - ); - } + if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } //else if (ierr < 0) {set_warning(format("%s",herr).c_str());} + return p_kPa*1000; + } + else{ + throw ValueError(format("calc_melting_line(%s,%s,%Lg) is an invalid set of inputs ", + get_parameter_information(param,"short").c_str(), + get_parameter_information(given,"short").c_str(), + value + ) + ); + } } @@ -1294,13 +1294,13 @@ void REFPROPMixtureBackend::update(CoolProp::input_pairs input_pair, double valu // Use flash routine to find properties TQFLSHdll(&_T,&_Q,&(mole_fractions[0]),&kq,&p_kPa,&rho_mol_L, - &rhoLmol_L,&rhoVmol_L,&(mole_fractions_liq[0]),&(mole_fractions_vap[0]), // Saturation terms + &rhoLmol_L,&rhoVmol_L,&(mole_fractions_liq[0]),&(mole_fractions_vap[0]), // Saturation terms &emol,&hmol,&smol,&cvmol,&cpmol,&w, // Other thermodynamic terms &ierr,herr,errormessagelength); // Error terms if (ierr > 0) { - throw ValueError(format("TQ(%s): %s",LoadedREFPROPRef.c_str(), herr).c_str()); - }// TODO: else if (ierr < 0) {set_warning(format("%s",herr).c_str()); + throw ValueError(format("TQ(%s): %s",LoadedREFPROPRef.c_str(), herr).c_str()); + }// TODO: else if (ierr < 0) {set_warning(format("%s",herr).c_str()); // Set all cache values that can be set with unit conversion to SI _p = p_kPa*1000; // 1000 for conversion from kPa to Pa diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.h b/src/Backends/REFPROP/REFPROPMixtureBackend.h index 525e15cf..89466b11 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.h +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.h @@ -18,96 +18,96 @@ namespace CoolProp { class REFPROPMixtureBackend : public AbstractState { protected: std::size_t Ncomp; - bool _mole_fractions_set; - static bool _REFPROP_supported; - std::vector mole_fractions, mass_fractions; - std::vector mole_fractions_liq, mole_fractions_vap; + bool _mole_fractions_set; + static bool _REFPROP_supported; + std::vector mole_fractions, mass_fractions; + std::vector mole_fractions_liq, mole_fractions_vap; public: - REFPROPMixtureBackend(){}; + REFPROPMixtureBackend(){}; - /// The instantiator - /// @param fluid_names The vector of strings of the fluid components, without file ending - REFPROPMixtureBackend(const std::vector& fluid_names); - virtual ~REFPROPMixtureBackend(); + /// The instantiator + /// @param fluid_names The vector of strings of the fluid components, without file ending + REFPROPMixtureBackend(const std::vector& fluid_names); + virtual ~REFPROPMixtureBackend(); // REFPROP backend uses mole fractions bool using_mole_fractions(){return true;} bool using_mass_fractions(){return false;} bool using_volu_fractions(){return false;} - /// Updating function for REFPROP - /** - In this function we take a pair of thermodynamic states, those defined in the input_pairs - enumeration and update all the internal variables that we can. REFPROP calculates - a lot of other state variables each time you use a flash routine so we cache all the - outputs that we can, which saves on computational time. + /// Updating function for REFPROP + /** + In this function we take a pair of thermodynamic states, those defined in the input_pairs + enumeration and update all the internal variables that we can. REFPROP calculates + a lot of other state variables each time you use a flash routine so we cache all the + outputs that we can, which saves on computational time. - @param input_pair Integer key from CoolProp::input_pairs to the two inputs that will be passed to the function - @param value1 First input value - @param value2 Second input value - */ - void update(CoolProp::input_pairs, - double value1, - double value2 - ); + @param input_pair Integer key from CoolProp::input_pairs to the two inputs that will be passed to the function + @param value1 First input value + @param value2 Second input value + */ + void update(CoolProp::input_pairs, + double value1, + double value2 + ); long double calc_molar_mass(void); - /// Returns true if REFPROP is supported on this platform - bool REFPROP_supported(void); + /// Returns true if REFPROP is supported on this platform + bool REFPROP_supported(void); long double calc_cpmolar_idealgas(void); long double calc_first_partial_deriv(parameters Of, parameters Wrt, parameters Constant); - /// Set the fluids in REFPROP DLL by calling the SETUPdll function - /** - @param fluid_names The vector of strings of the fluid components, without file ending - */ - void set_REFPROP_fluids(const std::vector &fluid_names); + /// Set the fluids in REFPROP DLL by calling the SETUPdll function + /** + @param fluid_names The vector of strings of the fluid components, without file ending + */ + void set_REFPROP_fluids(const std::vector &fluid_names); - /// Set the mole fractions - /** - @param mole_fractions The vector of mole fractions of the components - */ - void set_mole_fractions(const std::vector &mole_fractions); + /// Set the mole fractions + /** + @param mole_fractions The vector of mole fractions of the components + */ + void set_mole_fractions(const std::vector &mole_fractions); - /// Set the mass fractions - /** - @param mass_fractions The vector of mass fractions of the components - */ - void set_mass_fractions(const std::vector &mass_fractions); + /// Set the mass fractions + /** + @param mass_fractions The vector of mass fractions of the components + */ + void set_mass_fractions(const std::vector &mass_fractions); - void calc_phase_envelope(const std::string &type); + void calc_phase_envelope(const std::string &type); std::vector calc_mole_fractions_liquid(void){return std::vector(mole_fractions_liq.begin(), mole_fractions_liq.end());} std::vector calc_mole_fractions_vapor(void){return std::vector(mole_fractions_vap.begin(), mole_fractions_vap.end());} - /// Check if the mole fractions have been set, etc. - void check_status(); + /// Check if the mole fractions have been set, etc. + void check_status(); - /// Get the viscosity [Pa-s] (based on the temperature and density in the state class) - long double calc_viscosity(void); - /// Get the thermal conductivity [W/m/K] (based on the temperature and density in the state class) - long double calc_conductivity(void); - /// Get the surface tension [N/m] (based on the temperature in the state class). Invalid for temperatures above critical point or below triple point temperature - long double calc_surface_tension(void); + /// Get the viscosity [Pa-s] (based on the temperature and density in the state class) + long double calc_viscosity(void); + /// Get the thermal conductivity [W/m/K] (based on the temperature and density in the state class) + long double calc_conductivity(void); + /// Get the surface tension [N/m] (based on the temperature in the state class). Invalid for temperatures above critical point or below triple point temperature + long double calc_surface_tension(void); long double calc_fugacity_coefficient(int i); - long double calc_melting_line(int param, int given, long double value); + long double calc_melting_line(int param, int given, long double value); bool has_melting_line(){return true;}; double calc_melt_Tmax(); long double calc_T_critical(void); long double calc_p_critical(void); long double calc_rhomolar_critical(void); long double calc_Ttriple(void); - - /// A wrapper function to calculate the limits for the EOS - void limits(double &Tmin, double &Tmax, double &rhomolarmax, double &pmax); - /// Calculate the maximum pressure - long double calc_pmax(void); - /// Calculate the maximum temperature - long double calc_Tmax(void); + + /// A wrapper function to calculate the limits for the EOS + void limits(double &Tmin, double &Tmax, double &rhomolarmax, double &pmax); + /// Calculate the maximum pressure + long double calc_pmax(void); + /// Calculate the maximum temperature + long double calc_Tmax(void); }; } /* namespace CoolProp */ diff --git a/src/CoolProp.cpp b/src/CoolProp.cpp index 6410046d..2bbf4aa3 100644 --- a/src/CoolProp.cpp +++ b/src/CoolProp.cpp @@ -53,60 +53,60 @@ void set_warning_string(std::string warning){ warning_string = warning; } void set_error_string(std::string error){ - error_string = error; + error_string = error; } // //static int IsCoolPropFluid(std::string FluidName) //{ -// // Try to get the fluid from Fluids by name -// try -// { -// pFluid = Fluids.get_fluid(FluidName); -// } -// catch (NotImplementedError &) -// { -// return false; -// } -// // If NULL, didn't find it (or its alias) -// if (pFluid!=NULL) -// { -// return true; -// } -// else -// return false; +// // Try to get the fluid from Fluids by name +// try +// { +// pFluid = Fluids.get_fluid(FluidName); +// } +// catch (NotImplementedError &) +// { +// return false; +// } +// // If NULL, didn't find it (or its alias) +// if (pFluid!=NULL) +// { +// return true; +// } +// else +// return false; //} // //static int IsBrine(const char* Ref) //{ -// // First check whether it is one of the Brines that does -// // not have a pure-fluid equivalent in CoolProp +// // First check whether it is one of the Brines that does +// // not have a pure-fluid equivalent in CoolProp // if ( // strcmp(Ref,"HC-10")==0 || // strncmp(Ref,"PG-",3)==0 || -// strncmp(Ref,"EG-",3)==0 || -// strncmp(Ref,"EA-",3)==0 || -// strncmp(Ref,"MA-",3)==0 || -// strncmp(Ref,"Glycerol-",9)==0 || -// strncmp(Ref,"K2CO3-",6)==0 || -// strncmp(Ref,"CaCl2-",6)==0 || -// strncmp(Ref,"MgCl2-",6)==0 || -// strncmp(Ref,"NaCl-",5)==0 || -// strncmp(Ref,"KAC-",4)==0 || -// strncmp(Ref,"KFO-",4)==0 || -// strncmp(Ref,"LiCl-",4)==0 || +// strncmp(Ref,"EG-",3)==0 || +// strncmp(Ref,"EA-",3)==0 || +// strncmp(Ref,"MA-",3)==0 || +// strncmp(Ref,"Glycerol-",9)==0 || +// strncmp(Ref,"K2CO3-",6)==0 || +// strncmp(Ref,"CaCl2-",6)==0 || +// strncmp(Ref,"MgCl2-",6)==0 || +// strncmp(Ref,"NaCl-",5)==0 || +// strncmp(Ref,"KAC-",4)==0 || +// strncmp(Ref,"KFO-",4)==0 || +// strncmp(Ref,"LiCl-",4)==0 || // strncmp(Ref,"NH3/H2O-",8)==0 // ) // { // return 1; // } -// // Then check for diluants that are also pure fluids in CoolProp -// else if ( (strncmp(Ref,"Methanol-",9)==0 && Ref[8] == '-') || -// (strncmp(Ref,"Ethanol-",8)==0 && Ref[7] == '-') || -// (strncmp(Ref,"NH3-",4)==0 && Ref[3] == '-') -// ) -// { -// return 1; -// } +// // Then check for diluants that are also pure fluids in CoolProp +// else if ( (strncmp(Ref,"Methanol-",9)==0 && Ref[8] == '-') || +// (strncmp(Ref,"Ethanol-",8)==0 && Ref[7] == '-') || +// (strncmp(Ref,"NH3-",4)==0 && Ref[3] == '-') +// ) +// { +// return 1; +// } // else // { // return 0; @@ -114,78 +114,78 @@ void set_error_string(std::string error){ //} // //long getFluidType(std::string FluidName){ -// if (IsREFPROP(FluidName)) { return FLUID_TYPE_REFPROP;} -// else if(IsIncompressibleLiquid(FluidName)){ return FLUID_TYPE_INCOMPRESSIBLE_LIQUID;} -// // TODO SOLUTION: Check if working -// else if(IsIncompressibleSolution(FluidName)){ return FLUID_TYPE_INCOMPRESSIBLE_SOLUTION; } -// else { -// // Try to get the index of the fluid -// long iFluid = get_Fluid_index(FluidName); -// // If iFluid is greater than -1, it is a CoolProp Fluid, otherwise not -// if (iFluid > -1) { -// // Get a pointer to the fluid object -// pFluid = get_fluid(iFluid); -// if (pFluid->pure()) { return FLUID_TYPE_PURE;} -// else { return FLUID_TYPE_PSEUDOPURE; } -// } else { -// throw ValueError(format("Bad Fluid name [%s] - not a CoolProp fluid",FluidName.c_str())); -// } -// } -// return -1; +// if (IsREFPROP(FluidName)) { return FLUID_TYPE_REFPROP;} +// else if(IsIncompressibleLiquid(FluidName)){ return FLUID_TYPE_INCOMPRESSIBLE_LIQUID;} +// // TODO SOLUTION: Check if working +// else if(IsIncompressibleSolution(FluidName)){ return FLUID_TYPE_INCOMPRESSIBLE_SOLUTION; } +// else { +// // Try to get the index of the fluid +// long iFluid = get_Fluid_index(FluidName); +// // If iFluid is greater than -1, it is a CoolProp Fluid, otherwise not +// if (iFluid > -1) { +// // Get a pointer to the fluid object +// pFluid = get_fluid(iFluid); +// if (pFluid->pure()) { return FLUID_TYPE_PURE;} +// else { return FLUID_TYPE_PSEUDOPURE; } +// } else { +// throw ValueError(format("Bad Fluid name [%s] - not a CoolProp fluid",FluidName.c_str())); +// } +// } +// return -1; //} // //EXPORT_CODE int CONVENTION IsFluidType(const char *Ref, const char *Type) //{ -// pFluid = Fluids.get_fluid(Ref); +// pFluid = Fluids.get_fluid(Ref); // -// if (IsBrine(Ref)){ // TODO Solution: Remove this part -// if (!strcmp(Type,"Brine")){ -// return 1; -// } -// else{ -// return 0; -// } -// } -// else if (IsIncompressibleSolution(Ref)){ -// if (!strcmp(Type,"Solution")){ -// return 1; -// } -// else{ -// return 0; -// } -// } -// else if (IsIncompressibleLiquid(Ref)){ -// if (!strcmp(Type,"Liquid")){ -// return 1; -// } -// else{ -// return 0; -// } -// } -// else if (IsREFPROP(Ref)){ -// if (!strcmp(Type,"PureFluid")){ -// return 1; -// } -// else{ -// return 0; -// } -// } -// else if (!pFluid->pure()){ -// if (!strcmp(Type,"PseudoPure") || !strcmp(Type,"PseudoPureFluid")){ -// return 1; -// } -// else{ -// return 0; -// } -// } -// else if (pFluid->pure()){ -// if (!strcmp(Type,"PureFluid")){ -// return 1; -// } -// else{ -// return 0; -// } -// } +// if (IsBrine(Ref)){ // TODO Solution: Remove this part +// if (!strcmp(Type,"Brine")){ +// return 1; +// } +// else{ +// return 0; +// } +// } +// else if (IsIncompressibleSolution(Ref)){ +// if (!strcmp(Type,"Solution")){ +// return 1; +// } +// else{ +// return 0; +// } +// } +// else if (IsIncompressibleLiquid(Ref)){ +// if (!strcmp(Type,"Liquid")){ +// return 1; +// } +// else{ +// return 0; +// } +// } +// else if (IsREFPROP(Ref)){ +// if (!strcmp(Type,"PureFluid")){ +// return 1; +// } +// else{ +// return 0; +// } +// } +// else if (!pFluid->pure()){ +// if (!strcmp(Type,"PseudoPure") || !strcmp(Type,"PseudoPureFluid")){ +// return 1; +// } +// else{ +// return 0; +// } +// } +// else if (pFluid->pure()){ +// if (!strcmp(Type,"PureFluid")){ +// return 1; +// } +// else{ +// return 0; +// } +// } // else // { // return 0; @@ -195,48 +195,48 @@ void set_error_string(std::string error){ // //std::string Phase_Trho(std::string Fluid, double T, double rho) //{ -// try{ -// // Try to load the CoolProp Fluid -// pFluid = Fluids.get_fluid(Fluid); -// double pL,pV,rhoL,rhoV; -// return pFluid->phase_Trho(T,rho, pL, pV, rhoL, rhoV); -// } -// catch(NotImplementedError &){ -// return std::string(""); -// } -// return std::string(""); +// try{ +// // Try to load the CoolProp Fluid +// pFluid = Fluids.get_fluid(Fluid); +// double pL,pV,rhoL,rhoV; +// return pFluid->phase_Trho(T,rho, pL, pV, rhoL, rhoV); +// } +// catch(NotImplementedError &){ +// return std::string(""); +// } +// return std::string(""); //} // //std::string Phase(std::string Fluid, double T, double p) //{ -// try{ -// // Try to load the CoolProp Fluid -// pFluid = Fluids.get_fluid(Fluid); -// double pL,pV,rhoL,rhoV; -// return pFluid->phase_Tp(T, p, pL, pV, rhoL, rhoV); -// } -// catch(NotImplementedError &){ -// return std::string(""); -// } -// return std::string(""); +// try{ +// // Try to load the CoolProp Fluid +// pFluid = Fluids.get_fluid(Fluid); +// double pL,pV,rhoL,rhoV; +// return pFluid->phase_Tp(T, p, pL, pV, rhoL, rhoV); +// } +// catch(NotImplementedError &){ +// return std::string(""); +// } +// return std::string(""); //} // //std::string Phase_Tp(std::string Fluid, double T, double p) //{ -// return Phase(Fluid,T,p); +// return Phase(Fluid,T,p); //} // // Return true if the string has "BACKEND::*" format where * signifies a wildcard bool has_backend_in_string(const std::string &fluid_string, std::size_t &i) { - i = fluid_string.find("::"); + i = fluid_string.find("::"); return i != std::string::npos; } void extract_backend(const std::string &fluid_string, std::string &backend, std::string &fluid) { - std::size_t i; + std::size_t i; std::string _fluid_string = fluid_string; // For backwards compatibility reasons, if "REFPROP-" or "REFPROP-MIX:" start the fluid_string, replace them with "REFPROP::" if (_fluid_string.find("REFPROP-MIX:") == 0) @@ -247,19 +247,19 @@ void extract_backend(const std::string &fluid_string, std::string &backend, std: { _fluid_string.replace(0, 8, "REFPROP::"); } - if (has_backend_in_string(_fluid_string, i)) - { - // Part without the :: - backend = _fluid_string.substr(0, i); - // Fluid name after the :: - fluid = _fluid_string.substr(i+2); - } - else - { - backend = "?"; - fluid = _fluid_string; - } - if (get_debug_level()>10) std::cout << format("%s:%d: backend extracted. backend: %s. fluid: %s\n",__FILE__,__LINE__, backend.c_str(), fluid.c_str()); + if (has_backend_in_string(_fluid_string, i)) + { + // Part without the :: + backend = _fluid_string.substr(0, i); + // Fluid name after the :: + fluid = _fluid_string.substr(i+2); + } + else + { + backend = "?"; + fluid = _fluid_string; + } + if (get_debug_level()>10) std::cout << format("%s:%d: backend extracted. backend: %s. fluid: %s\n",__FILE__,__LINE__, backend.c_str(), fluid.c_str()); } bool has_fractions_in_string(const std::string &fluid_string) @@ -275,71 +275,71 @@ bool has_solution_concentration(const std::string &fluid_string) std::string extract_fractions(const std::string &fluid_string, std::vector &fractions) { - if (has_fractions_in_string(fluid_string)) - { - fractions.clear(); - std::vector names; + if (has_fractions_in_string(fluid_string)) + { + fractions.clear(); + std::vector names; - // Break up into pairs - like "Ethane[0.5]&Methane[0.5]" -> ("Ethane[0.5]","Methane[0.5]") - std::vector pairs = strsplit(fluid_string, '&'); + // Break up into pairs - like "Ethane[0.5]&Methane[0.5]" -> ("Ethane[0.5]","Methane[0.5]") + std::vector pairs = strsplit(fluid_string, '&'); - for (std::size_t i = 0; i < pairs.size(); ++i) - { - std::string fluid = pairs[i]; + for (std::size_t i = 0; i < pairs.size(); ++i) + { + std::string fluid = pairs[i]; - // Must end with ']' - if (fluid[fluid.size()-1] != ']') - throw ValueError(format("Fluid entry [%s] must end with ']' character",pairs[i].c_str())); + // Must end with ']' + if (fluid[fluid.size()-1] != ']') + throw ValueError(format("Fluid entry [%s] must end with ']' character",pairs[i].c_str())); - // Split at '[', but first remove the ']' from the end by taking a substring - std::vector name_fraction = strsplit(fluid.substr(0, fluid.size()-1), '['); + // Split at '[', but first remove the ']' from the end by taking a substring + std::vector name_fraction = strsplit(fluid.substr(0, fluid.size()-1), '['); - if (name_fraction.size() != 2){throw ValueError(format("Could not break [%s] into name/fraction", fluid.substr(0, fluid.size()-1).c_str()));} + if (name_fraction.size() != 2){throw ValueError(format("Could not break [%s] into name/fraction", fluid.substr(0, fluid.size()-1).c_str()));} - // Convert fraction to a double - char *pEnd; - std::string &name = name_fraction[0], &fraction = name_fraction[1]; - double f = strtod(fraction.c_str(), &pEnd); + // Convert fraction to a double + char *pEnd; + std::string &name = name_fraction[0], &fraction = name_fraction[1]; + double f = strtod(fraction.c_str(), &pEnd); - // If pEnd points to the last character in the string, it wasn't able to do the conversion - if (pEnd == &(fraction[fraction.size()-1])){throw ValueError(format("Could not convert [%s] into number", fraction.c_str()));} + // If pEnd points to the last character in the string, it wasn't able to do the conversion + if (pEnd == &(fraction[fraction.size()-1])){throw ValueError(format("Could not convert [%s] into number", fraction.c_str()));} - // And add to vector - fractions.push_back(f); + // And add to vector + fractions.push_back(f); - // Add name - names.push_back(name); - } + // Add name + names.push_back(name); + } - if (get_debug_level()>10) std::cout << format("%s:%d: Detected fractions of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), (strjoin(names, "&")).c_str()); - // Join fluids back together - return strjoin(names, "&"); - } - else if (has_solution_concentration(fluid_string)) - { - fractions.clear(); - double x; + if (get_debug_level()>10) std::cout << format("%s:%d: Detected fractions of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), (strjoin(names, "&")).c_str()); + // Join fluids back together + return strjoin(names, "&"); + } + else if (has_solution_concentration(fluid_string)) + { + fractions.clear(); + double x; - std::vector fluid_parts = strsplit(fluid_string,'-'); - // Check it worked - if (fluid_parts.size() != 2){ - throw ValueError(format("Format of incompressible solution string [%s] is invalid, should be like \"EG-20%\" or \"EG-0.2\" ", fluid_string.c_str()) ); - } + std::vector fluid_parts = strsplit(fluid_string,'-'); + // Check it worked + if (fluid_parts.size() != 2){ + throw ValueError(format("Format of incompressible solution string [%s] is invalid, should be like \"EG-20%\" or \"EG-0.2\" ", fluid_string.c_str()) ); + } - // Convert the concentration into a string - char* pEnd; - x = strtod(fluid_parts[1].c_str(), &pEnd); + // Convert the concentration into a string + char* pEnd; + x = strtod(fluid_parts[1].c_str(), &pEnd); - // Check if per cent or fraction syntax is used - if (!strcmp(pEnd,"%")){ x *= 0.01;} - fractions.push_back(x); - if (get_debug_level()>10) std::cout << format("%s:%d: Detected incompressible concentration of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), fluid_parts[0].c_str()); - return fluid_parts[0]; - } - else - { - return fluid_string; - } + // Check if per cent or fraction syntax is used + if (!strcmp(pEnd,"%")){ x *= 0.01;} + fractions.push_back(x); + if (get_debug_level()>10) std::cout << format("%s:%d: Detected incompressible concentration of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), fluid_parts[0].c_str()); + return fluid_parts[0]; + } + else + { + return fluid_string; + } } // Internal function to do the actual calculations, make this a wrapped function so @@ -351,7 +351,7 @@ double _PropsSI(const std::string &Output, const std::string &Name1, double Prop iOf1 = iundefined_parameter, iWrt1 = iundefined_parameter, iConstant1 = iundefined_parameter, iWrt2 = iundefined_parameter, iConstant2 = iundefined_parameter; double x1, x2; - + if (get_debug_level()>5){ std::cout << format("%s:%d: _PropsSI(%s,%s,%g,%s,%g,%s,%s)\n",__FILE__,__LINE__,Output.c_str(),Name1.c_str(),Prop1,Name2.c_str(),Prop2,backend.c_str(),Ref.c_str(), vec_to_string(z).c_str()).c_str(); } @@ -359,49 +359,49 @@ double _PropsSI(const std::string &Output, const std::string &Name1, double Prop // The state we are going to use shared_ptr State; - // If the fractions of the components have been encoded in the string, extract them - // If they have not, this function does nothing - std::vector fractions; - if (z.empty()) - { - // Make a one-element vector - fractions = std::vector(1, 1); - } - else{ - // Make a copy - fractions = z; - } - - std::string fluid_string = extract_fractions(Ref, fractions); - - // We are going to let the factory function load the state - State.reset(AbstractState::factory(backend, fluid_string)); + // If the fractions of the components have been encoded in the string, extract them + // If they have not, this function does nothing + std::vector fractions; + if (z.empty()) + { + // Make a one-element vector + fractions = std::vector(1, 1); + } + else{ + // Make a copy + fractions = z; + } - // First check if it is a trivial input (critical/max parameters for instance) - if (is_valid_parameter(Output, iOutput) && is_trivial_parameter(iOutput)) - { - double val = State->trivial_keyed_output(iOutput); - return val; - } - - long iName1 = get_parameter_index(Name1); - long iName2 = get_parameter_index(Name2); + std::string fluid_string = extract_fractions(Ref, fractions); + + // We are going to let the factory function load the state + State.reset(AbstractState::factory(backend, fluid_string)); + + // First check if it is a trivial input (critical/max parameters for instance) + if (is_valid_parameter(Output, iOutput) && is_trivial_parameter(iOutput)) + { + double val = State->trivial_keyed_output(iOutput); + return val; + } + + long iName1 = get_parameter_index(Name1); + long iName2 = get_parameter_index(Name2); - if (State->using_mole_fractions()){ - State->set_mole_fractions(fractions); - } else if (State->using_mass_fractions()){ - State->set_mass_fractions(fractions); - } else if (State->using_volu_fractions()){ - State->set_volu_fractions(fractions); - } else { - if (get_debug_level()>50) std::cout << format("%s:%d: _PropsSI, could not set composition to %s, defaulting to mole fraction.\n",__FILE__,__LINE__, vec_to_string(z).c_str()).c_str(); - } + if (State->using_mole_fractions()){ + State->set_mole_fractions(fractions); + } else if (State->using_mass_fractions()){ + State->set_mass_fractions(fractions); + } else if (State->using_volu_fractions()){ + State->set_volu_fractions(fractions); + } else { + if (get_debug_level()>50) std::cout << format("%s:%d: _PropsSI, could not set composition to %s, defaulting to mole fraction.\n",__FILE__,__LINE__, vec_to_string(z).c_str()).c_str(); + } - // Obtain the input pair - CoolProp::input_pairs pair = generate_update_pair(iName1, Prop1, iName2, Prop2, x1, x2); + // Obtain the input pair + CoolProp::input_pairs pair = generate_update_pair(iName1, Prop1, iName2, Prop2, x1, x2); - // Update the state - State->update(pair, x1, x2); + // Update the state + State->update(pair, x1, x2); if (iOutput != iundefined_parameter){ // Get the desired output @@ -430,9 +430,9 @@ double _PropsSI(const std::string &Output, const std::string &Name1, double Prop } double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref, const std::vector &z) { - std::string backend, fluid; - // Fractions are already provided, we just need to parse the Ref string - extract_backend(Ref, backend, fluid); + std::string backend, fluid; + // Fractions are already provided, we just need to parse the Ref string + extract_backend(Ref, backend, fluid); CATCH_ALL_ERRORS_RETURN_HUGE(return _PropsSI(Output,Name1,Prop1,Name2,Prop2,backend, fluid,z);) } double PropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char *FluidName, const std::vector &x) @@ -458,34 +458,34 @@ double Props1SI(const std::string &FluidName, const std::string &Output) } double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref) { - std::string backend, fluid; - #if !defined(PROPSSI_NO_ERROR_CATCH) + std::string backend, fluid; + #if !defined(PROPSSI_NO_ERROR_CATCH) // In this function the error catching happens; try{ - #else - std::cout << "macro is on; error checking disabled in PropsSI" << std::endl; - #endif + #else + std::cout << "macro is on; error checking disabled in PropsSI" << std::endl; + #endif // BEGIN OF TRY - // Here is the real code that is inside the try block - extract_backend(Ref, backend, fluid); - double val = _PropsSI(Output, Name1, Prop1, Name2, Prop2, backend, fluid, std::vector()); - if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; } + // Here is the real code that is inside the try block + extract_backend(Ref, backend, fluid); + double val = _PropsSI(Output, Name1, Prop1, Name2, Prop2, backend, fluid, std::vector()); + if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; } return val; // END OF TRY - #if !defined(PROPSSI_NO_ERROR_CATCH) + #if !defined(PROPSSI_NO_ERROR_CATCH) } catch(const std::exception& e){ - set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str())); - #if defined (PROPSSI_ERROR_STDOUT) - std::cout << e.what() << std::endl; - #endif - if (get_debug_level() > 1){std::cout << e.what() << std::endl;} - return _HUGE; - } + set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str())); + #if defined (PROPSSI_ERROR_STDOUT) + std::cout << e.what() << std::endl; + #endif + if (get_debug_level() > 1){std::cout << e.what() << std::endl;} + return _HUGE; + } catch(...){ - return _HUGE; - } - #endif + return _HUGE; + } + #endif } std::vector PropsSI(const std::string &Output, const std::string &Name1, const std::vector &Prop1, const std::string &Name2, const std::vector Prop2, const std::string &FluidName) { @@ -515,29 +515,29 @@ double Props1SI(std::string FluidName,std::string Output) //{ // Prop1 = convert_from_unit_system_to_SI(iName1, Prop1, get_standard_unit_system()); // Prop2 = convert_from_unit_system_to_SI(iName2, Prop2, get_standard_unit_system()); -// double out = IPropsSI(iOutput,iName1,Prop1,iName2,Prop2,iFluid); +// double out = IPropsSI(iOutput,iName1,Prop1,iName2,Prop2,iFluid); // return convert_from_SI_to_unit_system(iOutput,out,get_standard_unit_system()); //} //double _CoolProp_Fluid_PropsSI(long iOutput, long iName1, double Prop1, long iName2, double Prop2, Fluid *pFluid) //{ -// double val = _HUGE, T = _HUGE; -// // This private method uses the indices directly for speed +// double val = _HUGE, T = _HUGE; +// // This private method uses the indices directly for speed // -// if (get_debug_level()>3){ -// std::cout << format("%s:%d: _CoolProp_Fluid_PropsSI(%d,%d,%g,%d,%g,%s)\n",__FILE__,__LINE__,iOutput,iName1, Prop1, iName2, Prop2, pFluid->get_name().c_str()).c_str(); -// } +// if (get_debug_level()>3){ +// std::cout << format("%s:%d: _CoolProp_Fluid_PropsSI(%d,%d,%g,%d,%g,%s)\n",__FILE__,__LINE__,iOutput,iName1, Prop1, iName2, Prop2, pFluid->get_name().c_str()).c_str(); +// } // if (iName1 == iT){ // T = Prop1;} // else if (iName2 == iT){ // T = Prop2;} // -// // Generate a State instance wrapped around the Fluid instance -// CoolPropStateClassSI CPS(pFluid); +// // Generate a State instance wrapped around the Fluid instance +// CoolPropStateClassSI CPS(pFluid); // -// // Check if it is an output that doesn't require a state input -// // Deal with it and return -// switch (iOutput) -// { +// // Check if it is an output that doesn't require a state input +// // Deal with it and return +// switch (iOutput) +// { // case iI: // { // if (!ValidNumber(T)){throw ValueError(format("T must be provided as an input to use this output").c_str());} @@ -573,188 +573,188 @@ double Props1SI(std::string FluidName,std::string Output) // return CPS.pFluid->psatV(T); // } // } -// case iMM: -// case iPcrit: -// case iTcrit: -// case iTtriple: -// case iPtriple: +// case iMM: +// case iPcrit: +// case iTcrit: +// case iTtriple: +// case iPtriple: // case iPmax: // case iTmax: -// case iRhocrit: -// case iTmin: -// case iAccentric: -// case iPHASE_LIQUID: -// case iPHASE_GAS: -// case iPHASE_SUPERCRITICAL: -// case iPHASE_TWOPHASE: -// case iGWP20: -// case iGWP100: -// case iGWP500: -// case iODP: -// case iCritSplineT: -// case iScrit: -// case iHcrit: -// case iTreduce: -// case iRhoreduce: -// return CPS.keyed_output(iOutput); -// } +// case iRhocrit: +// case iTmin: +// case iAccentric: +// case iPHASE_LIQUID: +// case iPHASE_GAS: +// case iPHASE_SUPERCRITICAL: +// case iPHASE_TWOPHASE: +// case iGWP20: +// case iGWP100: +// case iGWP500: +// case iODP: +// case iCritSplineT: +// case iScrit: +// case iHcrit: +// case iTreduce: +// case iRhoreduce: +// return CPS.keyed_output(iOutput); +// } // -// // Update the class -// CPS.update(iName1,Prop1,iName2,Prop2); +// // Update the class +// CPS.update(iName1,Prop1,iName2,Prop2); // -// // Debug -// if (get_debug_level()>9){std::cout << format("%s:%d: State update successful\n",__FILE__,__LINE__).c_str();} +// // Debug +// if (get_debug_level()>9){std::cout << format("%s:%d: State update successful\n",__FILE__,__LINE__).c_str();} // -// // Get the output -// val = CPS.keyed_output(iOutput); +// // Get the output +// val = CPS.keyed_output(iOutput); // -// // Debug -// if (get_debug_level()>5){std::cout << format("%s:%d: _CoolProp_Fluid_PropsSI returns: %g\n",__FILE__,__LINE__,val).c_str();} +// // Debug +// if (get_debug_level()>5){std::cout << format("%s:%d: _CoolProp_Fluid_PropsSI returns: %g\n",__FILE__,__LINE__,val).c_str();} // -// // Return the value -// return val; +// // Return the value +// return val; //} //EXPORT_CODE double CONVENTION IPropsSI(long iOutput, long iName1, double Prop1, long iName2, double Prop2, long iFluid) //{ -// pFluid = Fluids.get_fluid(iFluid); -// // Didn't work -// if (pFluid == NULL){ -// err_string=std::string("CoolProp error: ").append(format("%d is an invalid fluid index to IProps",iFluid)); -// return _HUGE; -// } -// else{ -// // In this function the error catching happens; -// try{ -// // This is already converted to the right units since we take in SI units -// return _CoolProp_Fluid_PropsSI(iOutput,iName1,Prop1,iName2,Prop2,pFluid); -// } -// catch(std::exception &e){ -// err_string=std::string("CoolProp error: ").append(e.what()); -// return _HUGE; -// } -// catch(...){ -// err_string=std::string("CoolProp error: Indeterminate error"); -// return _HUGE; -// } -// } +// pFluid = Fluids.get_fluid(iFluid); +// // Didn't work +// if (pFluid == NULL){ +// err_string=std::string("CoolProp error: ").append(format("%d is an invalid fluid index to IProps",iFluid)); +// return _HUGE; +// } +// else{ +// // In this function the error catching happens; +// try{ +// // This is already converted to the right units since we take in SI units +// return _CoolProp_Fluid_PropsSI(iOutput,iName1,Prop1,iName2,Prop2,pFluid); +// } +// catch(std::exception &e){ +// err_string=std::string("CoolProp error: ").append(e.what()); +// return _HUGE; +// } +// catch(...){ +// err_string=std::string("CoolProp error: Indeterminate error"); +// return _HUGE; +// } +// } //} ///// Calculate some interesting derivatives //double _CoolProp_Deriv_Terms(long iTerm, double T, double rho, Fluid * pFluid) //{ -// double val = _HUGE; -// // This private method uses the indices directly for speed +// double val = _HUGE; +// // This private method uses the indices directly for speed // -// if (get_debug_level()>3){ -// std::cout<<__FILE__<<" _CoolProp_Deriv_Terms return: "<3){ +// std::cout<<__FILE__<<" _CoolProp_Deriv_Terms return: "<5){ -// std::cout<<__FILE__<<" _CoolProp_Deriv_Terms return: "<5){ +// std::cout<<__FILE__<<" _CoolProp_Deriv_Terms return: "<5){ -// std::cout<<__FILE__<<": "<5){ +// std::cout<<__FILE__<<": "< _comps(1, Ref); HEOS.reset(new CoolProp::HelmholtzEOSMixtureBackend(_comps)); - if (!reference_state.compare("IIR")) - { - HEOS->update(QT_INPUTS, 0, 273.15); + if (!reference_state.compare("IIR")) + { + HEOS->update(QT_INPUTS, 0, 273.15); - // Get current values for the enthalpy and entropy - double deltah = HEOS->hmass() - 200000; // offset from 200000 J/kg enthalpy - double deltas = HEOS->smass() - 1000; // offset from 1000 J/kg/K entropy + // Get current values for the enthalpy and entropy + double deltah = HEOS->hmass() - 200000; // offset from 200000 J/kg enthalpy + double deltas = HEOS->smass() - 1000; // offset from 1000 J/kg/K entropy double delta_a1 = deltas/(8.314472/HEOS->molar_mass()); double delta_a2 = -deltah/(8.314472/HEOS->molar_mass()*HEOS->get_reducing_state().T); HEOS->get_components()[0]->pEOS->alpha0.EnthalpyEntropyOffset.set(delta_a1, delta_a2, "IIR"); HEOS->update_states(); - } - else if (!reference_state.compare("ASHRAE")) - { + } + else if (!reference_state.compare("ASHRAE")) + { HEOS->update(QT_INPUTS, 0, 243.15); - // Get current values for the enthalpy and entropy - double deltah = HEOS->hmass() - 0; // offset from 0 J/kg enthalpy - double deltas = HEOS->smass() - 0; // offset from 0 J/kg/K entropy - double delta_a1 = deltas/(8.314472/HEOS->molar_mass()); + // Get current values for the enthalpy and entropy + double deltah = HEOS->hmass() - 0; // offset from 0 J/kg enthalpy + double deltas = HEOS->smass() - 0; // offset from 0 J/kg/K entropy + double delta_a1 = deltas/(8.314472/HEOS->molar_mass()); double delta_a2 = -deltah/(8.314472/HEOS->molar_mass()*HEOS->get_reducing_state().T); HEOS->get_components()[0]->pEOS->alpha0.EnthalpyEntropyOffset.set(delta_a1, delta_a2, "ASHRAE"); HEOS->update_states(); - } - else if (!reference_state.compare("NBP")) - { - // Saturated liquid boiling point at 1 atmosphere + } + else if (!reference_state.compare("NBP")) + { + // Saturated liquid boiling point at 1 atmosphere HEOS->update(PQ_INPUTS, 101325, 0); - double deltah = HEOS->hmass() - 0; // offset from 0 kJ/kg enthalpy - double deltas = HEOS->smass() - 0; // offset from 0 kJ/kg/K entropy - double delta_a1 = deltas/(8.314472/HEOS->molar_mass()); + double deltah = HEOS->hmass() - 0; // offset from 0 kJ/kg enthalpy + double deltas = HEOS->smass() - 0; // offset from 0 kJ/kg/K entropy + double delta_a1 = deltas/(8.314472/HEOS->molar_mass()); double delta_a2 = -deltah/(8.314472/HEOS->molar_mass()*HEOS->get_reducing_state().T); HEOS->get_components()[0]->pEOS->alpha0.EnthalpyEntropyOffset.set(delta_a1, delta_a2, "NBP"); HEOS->update_states(); - } + } else if (!reference_state.compare("DEF")) { //HEOS->get_components()[0]->pEOS->alpha0.EnthalpyEntropyOffset.set(0,0); @@ -808,10 +808,10 @@ void set_reference_stateS(std::string Ref, std::string reference_state) { HEOS->get_components()[0]->pEOS->alpha0.EnthalpyEntropyOffset.set(0, 0, ""); } - else - { + else + { throw ValueError(format("reference state string is invalid: [%s]",reference_state.c_str())); - } + } } void set_reference_stateD(std::string Ref, double T, double rhomolar, double h0, double s0) { @@ -836,77 +836,77 @@ std::string get_BibTeXKey(std::string Ref, std::string key) HelmholtzEOSMixtureBackend HEOS(names); if (!key.compare("EOS")){ return HEOS.get_components()[0]->pEOS->BibTeX_EOS; } - else if (!key.compare("CP0")){ return HEOS.get_components()[0]->pEOS->BibTeX_CP0; } + else if (!key.compare("CP0")){ return HEOS.get_components()[0]->pEOS->BibTeX_CP0; } else if (!key.compare("VISCOSITY")){ return HEOS.get_components()[0]->transport.BibTeX_viscosity; } - else if (!key.compare("CONDUCTIVITY")){ return HEOS.get_components()[0]->transport.BibTeX_conductivity; } - else if (!key.compare("ECS_LENNARD_JONES")){ throw NotImplementedError(); } - else if (!key.compare("ECS_VISCOSITY_FITS")){ throw NotImplementedError(); } + else if (!key.compare("CONDUCTIVITY")){ return HEOS.get_components()[0]->transport.BibTeX_conductivity; } + else if (!key.compare("ECS_LENNARD_JONES")){ throw NotImplementedError(); } + else if (!key.compare("ECS_VISCOSITY_FITS")){ throw NotImplementedError(); } else if (!key.compare("ECS_CONDUCTIVITY_FITS")){ throw NotImplementedError(); } else if (!key.compare("SURFACE_TENSION")){ return HEOS.get_components()[0]->ancillaries.surface_tension.BibTeX;} - else{ return "Bad key";} + else{ return "Bad key";} } std::string get_global_param_string(std::string ParamName) { - if (!ParamName.compare("version")){ - return version; - } - else if (!ParamName.compare("gitrevision")){ - return gitrevision; - } + if (!ParamName.compare("version")){ + return version; + } + else if (!ParamName.compare("gitrevision")){ + return gitrevision; + } else if (!ParamName.compare("errstring")){ - std::string temp = error_string; - error_string = ""; - return temp; - } - else if (!ParamName.compare("warnstring")){ - std::string temp = warning_string; - warning_string = ""; - return temp; - } - else if (!ParamName.compare("FluidsList") || !ParamName.compare("fluids_list") || !ParamName.compare("fluidslist")){ - return get_fluid_list(); - } - else if (!ParamName.compare("incompressible_list_pure")){ - return get_incompressible_list_pure(); - } - else if (!ParamName.compare("incompressible_list_solution")){ - return get_incompressible_list_solution(); - } + std::string temp = error_string; + error_string = ""; + return temp; + } + else if (!ParamName.compare("warnstring")){ + std::string temp = warning_string; + warning_string = ""; + return temp; + } + else if (!ParamName.compare("FluidsList") || !ParamName.compare("fluids_list") || !ParamName.compare("fluidslist")){ + return get_fluid_list(); + } + else if (!ParamName.compare("incompressible_list_pure")){ + return get_incompressible_list_pure(); + } + else if (!ParamName.compare("incompressible_list_solution")){ + return get_incompressible_list_solution(); + } else if (!ParamName.compare("mixture_binary_pairs_list")){ - return get_csv_mixture_binary_pairs(); - } - else if (!ParamName.compare("parameter_list") ) + return get_csv_mixture_binary_pairs(); + } + else if (!ParamName.compare("parameter_list") ) { return get_csv_parameter_list(); } - else{ - return format("Input value [%s] is invalid",ParamName.c_str()).c_str(); - } + else{ + return format("Input value [%s] is invalid",ParamName.c_str()).c_str(); + } }; std::string get_fluid_param_string(std::string FluidName, std::string ParamName) { - try{ + try{ std::vector comps(1,FluidName); shared_ptr HEOS(new CoolProp::HelmholtzEOSMixtureBackend(comps)); CoolProp::CoolPropFluid *fluid = HEOS->get_components()[0]; - if (!ParamName.compare("aliases")) - { - return strjoin(fluid->aliases, ", "); - } - else if (!ParamName.compare("CAS") || !ParamName.compare("CAS_number")) - { + if (!ParamName.compare("aliases")) + { + return strjoin(fluid->aliases, ", "); + } + else if (!ParamName.compare("CAS") || !ParamName.compare("CAS_number")) + { return fluid->CAS; - } - else if (!ParamName.compare("ASHRAE34")) - { + } + else if (!ParamName.compare("ASHRAE34")) + { return fluid->environment.ASHRAE34; - } - else if (!ParamName.compare("REFPROPName") || !ParamName.compare("REFPROP_name") || !ParamName.compare("REFPROPname")) - { + } + else if (!ParamName.compare("REFPROPName") || !ParamName.compare("REFPROP_name") || !ParamName.compare("REFPROPname")) + { return fluid->REFPROPname; - } + } else if (ParamName.find("BibTeX") == 0) // Starts with "BibTeX" { std::vector parts = strsplit(ParamName,'-'); @@ -934,18 +934,18 @@ std::string get_fluid_param_string(std::string FluidName, std::string ParamName) return format("Could not match BibTeX item: %s", item.c_str()); } } - else - { - return format("Input value [%s] is invalid for Fluid [%s]",ParamName.c_str(),FluidName.c_str()); - } - } - catch(std::exception &e) - { - return(std::string("CoolProp error: ").append(e.what())); - } - catch(...){ - return(std::string("CoolProp error: Indeterminate error")); - } + else + { + return format("Input value [%s] is invalid for Fluid [%s]",ParamName.c_str(),FluidName.c_str()); + } + } + catch(std::exception &e) + { + return(std::string("CoolProp error: ").append(e.what())); + } + catch(...){ + return(std::string("CoolProp error: Indeterminate error")); + } } std::string phase_lookup_string(phases Phase) { diff --git a/src/CoolPropLib.cpp b/src/CoolPropLib.cpp index 44c11e41..690a48da 100644 --- a/src/CoolPropLib.cpp +++ b/src/CoolPropLib.cpp @@ -13,72 +13,72 @@ #include double convert_from_kSI_to_SI(long iInput, double value) { - if (get_debug_level() > 8){ - std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n",__FILE__,__LINE__,iInput,value).c_str(); - } + if (get_debug_level() > 8){ + std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n",__FILE__,__LINE__,iInput,value).c_str(); + } - switch (iInput) - { + switch (iInput) + { case CoolProp::iP: - case CoolProp::iCpmass: - case CoolProp::iCp0mass: - case CoolProp::iSmass: - case CoolProp::iGmass: - case CoolProp::iCvmass: - case CoolProp::iHmass: - case CoolProp::iUmass: - case CoolProp::iconductivity: + case CoolProp::iCpmass: + case CoolProp::iCp0mass: + case CoolProp::iSmass: + case CoolProp::iGmass: + case CoolProp::iCvmass: + case CoolProp::iHmass: + case CoolProp::iUmass: + case CoolProp::iconductivity: return value*1000.0; - case CoolProp::iDmass: - case CoolProp::ispeed_sound: - case CoolProp::iQ: - case CoolProp::iviscosity: - case CoolProp::iT: - case CoolProp::iPrandtl: - case CoolProp::isurface_tension: - return value; - default: - throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI",iInput).c_str()); - break; - } - return _HUGE; + case CoolProp::iDmass: + case CoolProp::ispeed_sound: + case CoolProp::iQ: + case CoolProp::iviscosity: + case CoolProp::iT: + case CoolProp::iPrandtl: + case CoolProp::isurface_tension: + return value; + default: + throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI",iInput).c_str()); + break; + } + return _HUGE; } double convert_from_SI_to_kSI(long iInput, double value) { - if (get_debug_level() > 8){ - std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n",__FILE__,__LINE__,iInput,value).c_str(); - } + if (get_debug_level() > 8){ + std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n",__FILE__,__LINE__,iInput,value).c_str(); + } - switch (iInput) - { + switch (iInput) + { case CoolProp::iP: - case CoolProp::iCpmass: - case CoolProp::iCp0mass: - case CoolProp::iSmass: - case CoolProp::iGmass: - case CoolProp::iCvmass: - case CoolProp::iHmass: - case CoolProp::iUmass: - case CoolProp::iconductivity: + case CoolProp::iCpmass: + case CoolProp::iCp0mass: + case CoolProp::iSmass: + case CoolProp::iGmass: + case CoolProp::iCvmass: + case CoolProp::iHmass: + case CoolProp::iUmass: + case CoolProp::iconductivity: return value/1000.0; - case CoolProp::iDmass: - case CoolProp::iQ: - case CoolProp::ispeed_sound: - case CoolProp::iviscosity: - case CoolProp::iT: - case CoolProp::isurface_tension: - return value; - default: - throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str()); - break; - } - return _HUGE; + case CoolProp::iDmass: + case CoolProp::iQ: + case CoolProp::ispeed_sound: + case CoolProp::iviscosity: + case CoolProp::iT: + case CoolProp::isurface_tension: + return value; + default: + throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str()); + break; + } + return _HUGE; } EXPORT_CODE long CONVENTION redirect_stdout(const char* file){ - freopen(file, "a+", stdout); - return 0; + freopen(file, "a+", stdout); + return 0; } EXPORT_CODE int CONVENTION set_reference_stateS(const char *Ref, const char *reference_state) { @@ -108,8 +108,8 @@ EXPORT_CODE double CONVENTION Props1(const char *FluidName, const char *Output){ return PropsS(Output, "", 0, "", 0, FluidName); } EXPORT_CODE double CONVENTION PropsS(const char *Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char * Ref){ - double val = Props(Output,Name1[0],Prop1,Name2[0],Prop2,Ref); - return val; + double val = Props(Output,Name1[0],Prop1,Name2[0],Prop2,Ref); + return val; } EXPORT_CODE double CONVENTION Props(const char *Output, const char Name1, double Prop1, const char Name2, double Prop2, const char * Ref) { @@ -125,10 +125,10 @@ EXPORT_CODE double CONVENTION Props(const char *Output, const char Name1, double Prop1 = convert_from_kSI_to_SI(iName1, Prop1); Prop2 = convert_from_kSI_to_SI(iName2, Prop2); - // Call the SI function + // Call the SI function double val = PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref); - // Convert back to unit system + // Convert back to unit system return convert_from_SI_to_kSI(iOutput, val); } catch(std::exception &e){CoolProp::set_error_string(e.what()); return _HUGE;} @@ -213,7 +213,7 @@ EXPORT_CODE long CONVENTION get_parameter_information_string(const char *param, } EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char * Output) { - std::string s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param)); + std::string s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param)); if (s.size() < strlen(Output)){ strcpy(Output, s.c_str()); return 1; @@ -225,19 +225,19 @@ EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char EXPORT_CODE double CONVENTION HAPropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3) { std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3; - return HumidAir::HAPropsSI(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3); + return HumidAir::HAPropsSI(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3); } EXPORT_CODE void CONVENTION hapropssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output) { std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3; - *output = HumidAir::HAPropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _Name3, *Prop3); + *output = HumidAir::HAPropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _Name3, *Prop3); } EXPORT_CODE double CONVENTION HAProps(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3) { std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3; - return HumidAir::HAProps(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3); + return HumidAir::HAProps(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3); } EXPORT_CODE void CONVENTION haprops_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output) { - *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3); + *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3); } diff --git a/src/CoolPropTools.cpp b/src/CoolPropTools.cpp index 6c9a099e..f9ef251e 100644 --- a/src/CoolPropTools.cpp +++ b/src/CoolPropTools.cpp @@ -14,12 +14,12 @@ double root_sum_square(std::vector x) { - double sum = 0; - for (unsigned int i=0; i strsplit(std::string s, char del) { - std::size_t iL = 0, iR = 0, N = s.size(); - std::vector v; - // Find the first instance of the delimiter - iR = s.find_first_of(del); - // Delimiter not found, return the same string again - if (iR == std::string::npos){ - v.push_back(s); - return v; - } - while (iR != N-1) - { - v.push_back(s.substr(iL,iR-iL)); - iL = iR; - iR = s.find_first_of(del,iR+1); - // Move the iL to the right to avoid the delimiter - iL += 1; - if (iR == std::string::npos) - { - v.push_back(s.substr(iL,N-iL)); - break; - } - } - return v; + std::size_t iL = 0, iR = 0, N = s.size(); + std::vector v; + // Find the first instance of the delimiter + iR = s.find_first_of(del); + // Delimiter not found, return the same string again + if (iR == std::string::npos){ + v.push_back(s); + return v; + } + while (iR != N-1) + { + v.push_back(s.substr(iL,iR-iL)); + iL = iR; + iR = s.find_first_of(del,iR+1); + // Move the iL to the right to avoid the delimiter + iL += 1; + if (iR == std::string::npos) + { + v.push_back(s.substr(iL,N-iL)); + break; + } + } + return v; } double interp1d(std::vector *x, std::vector *y, double x0) { - std::size_t i,L,R,M; - L=0; - R=(*x).size()-1; - M=(L+R)/2; - // Use interval halving to find the indices which bracket the density of interest - while (R-L>1) - { - if (x0 >= (*x)[M]) - { L=M; M=(L+R)/2; continue;} - if (x0 < (*x)[M]) - { R=M; M=(L+R)/2; continue;} - } - i=L; - if (i<(*x).size()-2) + std::size_t i,L,R,M; + L=0; + R=(*x).size()-1; + M=(L+R)/2; + // Use interval halving to find the indices which bracket the density of interest + while (R-L>1) { - // Go "forwards" with the interpolation range - return QuadInterp((*x)[i],(*x)[i+1],(*x)[i+2],(*y)[i],(*y)[i+1],(*y)[i+2],x0); + if (x0 >= (*x)[M]) + { L=M; M=(L+R)/2; continue;} + if (x0 < (*x)[M]) + { R=M; M=(L+R)/2; continue;} + } + i=L; + if (i<(*x).size()-2) + { + // Go "forwards" with the interpolation range + return QuadInterp((*x)[i],(*x)[i+1],(*x)[i+2],(*y)[i],(*y)[i+1],(*y)[i+2],x0); } else { // Go "backwards" with the interpolation range - return QuadInterp((*x)[i],(*x)[i-1],(*x)[i-2],(*y)[i],(*y)[i-1],(*y)[i-2],x0); + return QuadInterp((*x)[i],(*x)[i-1],(*x)[i-2],(*y)[i],(*y)[i-1],(*y)[i-2],x0); } } double powInt(double x, int y) @@ -133,36 +133,36 @@ double powInt(double x, int y) void MatInv_2(double A[2][2] , double B[2][2]) { - double Det; - //Using Cramer's Rule to solve + double Det; + //Using Cramer's Rule to solve - Det=A[0][0]*A[1][1]-A[1][0]*A[0][1]; - B[0][0]=1.0/Det*A[1][1]; - B[1][1]=1.0/Det*A[0][0]; - B[1][0]=-1.0/Det*A[1][0]; - B[0][1]=-1.0/Det*A[0][1]; + Det=A[0][0]*A[1][1]-A[1][0]*A[0][1]; + B[0][0]=1.0/Det*A[1][1]; + B[1][1]=1.0/Det*A[0][0]; + B[1][0]=-1.0/Det*A[1][0]; + B[0][1]=-1.0/Det*A[0][1]; } std::string get_file_contents(const char *filename) { - std::ifstream in(filename, std::ios::in | std::ios::binary); - if (in) - { - std::string contents; - in.seekg(0, std::ios::end); - contents.resize((unsigned int) in.tellg()); - in.seekg(0, std::ios::beg); - in.read(&contents[0], contents.size()); - in.close(); - return(contents); - } - throw(errno); + std::ifstream in(filename, std::ios::in | std::ios::binary); + if (in) + { + std::string contents; + in.seekg(0, std::ios::end); + contents.resize((unsigned int) in.tellg()); + in.seekg(0, std::ios::beg); + in.read(&contents[0], contents.size()); + in.close(); + return(contents); + } + throw(errno); } void solve_cubic(double a, double b, double c, double d, int &N, double &x0, double &x1, double &x2) { - // 0 = ax^3 + b*x^2 + c*x + d + // 0 = ax^3 + b*x^2 + c*x + d // First check if the "cubic" is actually a second order or first order curve if (std::abs(a) < 10*DBL_EPSILON){ @@ -183,113 +183,113 @@ void solve_cubic(double a, double b, double c, double d, int &N, double &x0, dou // Ok, it is really a cubic - // Discriminant - double DELTA = 18*a*b*c*d-4*b*b*b*d+b*b*c*c-4*a*c*c*c-27*a*a*d*d; - // Coefficients for the depressed cubic t^3+p*t+q = 0 - double p = (3*a*c-b*b)/(3*a*a); - double q = (2*b*b*b-9*a*b*c+27*a*a*d)/(27*a*a*a); + // Discriminant + double DELTA = 18*a*b*c*d-4*b*b*b*d+b*b*c*c-4*a*c*c*c-27*a*a*d*d; + // Coefficients for the depressed cubic t^3+p*t+q = 0 + double p = (3*a*c-b*b)/(3*a*a); + double q = (2*b*b*b-9*a*b*c+27*a*a*d)/(27*a*a*a); - if (DELTA<0) - { - // One real root - double t0; - if (4*p*p*p+27*q*q>0 && p<0) - { - t0 = -2.0*std::abs(q)/q*sqrt(-p/3.0)*cosh(1.0/3.0*acosh(-3.0*std::abs(q)/(2.0*p)*sqrt(-3.0/p))); - } - else - { - t0 = -2.0*sqrt(p/3.0)*sinh(1.0/3.0*asinh(3.0*q/(2.0*p)*sqrt(3.0/p))); - } + if (DELTA<0) + { + // One real root + double t0; + if (4*p*p*p+27*q*q>0 && p<0) + { + t0 = -2.0*std::abs(q)/q*sqrt(-p/3.0)*cosh(1.0/3.0*acosh(-3.0*std::abs(q)/(2.0*p)*sqrt(-3.0/p))); + } + else + { + t0 = -2.0*sqrt(p/3.0)*sinh(1.0/3.0*asinh(3.0*q/(2.0*p)*sqrt(3.0/p))); + } N = 1; - x0 = t0-b/(3*a); - x1 = t0-b/(3*a); - x2 = t0-b/(3*a); - } - else //(DELTA>0) - { - // Three real roots - double t0 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-0*2.0*M_PI/3.0); - double t1 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-1*2.0*M_PI/3.0); - double t2 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-2*2.0*M_PI/3.0); + x0 = t0-b/(3*a); + x1 = t0-b/(3*a); + x2 = t0-b/(3*a); + } + else //(DELTA>0) + { + // Three real roots + double t0 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-0*2.0*M_PI/3.0); + double t1 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-1*2.0*M_PI/3.0); + double t2 = 2.0*sqrt(-p/3.0)*cos(1.0/3.0*acos(3.0*q/(2.0*p)*sqrt(-3.0/p))-2*2.0*M_PI/3.0); N = 3; - x0 = t0-b/(3*a); - x1 = t1-b/(3*a); - x2 = t2-b/(3*a); - } + x0 = t0-b/(3*a); + x1 = t1-b/(3*a); + x2 = t2-b/(3*a); + } } std::string strjoin(std::vector strings, std::string delim) { - // Empty input vector - if (strings.empty()){return "";} + // Empty input vector + if (strings.empty()){return "";} - std::string output = strings[0]; - for (unsigned int i = 1; i < strings.size(); i++) - { - output += format("%s%s",delim.c_str(),strings[i].c_str()); - } - return output; + std::string output = strings[0]; + for (unsigned int i = 1; i < strings.size(); i++) + { + output += format("%s%s",delim.c_str(),strings[i].c_str()); + } + return output; } SplineClass::SplineClass() { - Nconstraints = 0; - A.resize(4, std::vector(4, 0)); - B.resize(4,0); + Nconstraints = 0; + A.resize(4, std::vector(4, 0)); + B.resize(4,0); } bool SplineClass::build() { - if (Nconstraints == 4) - { - std::vector abcd = CoolProp::linsolve(A,B); - a = abcd[0]; - b = abcd[1]; - c = abcd[2]; - d = abcd[3]; + if (Nconstraints == 4) + { + std::vector abcd = CoolProp::linsolve(A,B); + a = abcd[0]; + b = abcd[1]; + c = abcd[2]; + d = abcd[3]; return true; - } - else - { - throw CoolProp::ValueError(format("Number of constraints[%d] is not equal to 4", Nconstraints)); - } + } + else + { + throw CoolProp::ValueError(format("Number of constraints[%d] is not equal to 4", Nconstraints)); + } } bool SplineClass::add_value_constraint(double x, double y) { - int i = Nconstraints; - if (i == 4) - return false; - A[i][0] = x*x*x; - A[i][1] = x*x; - A[i][2] = x; - A[i][3] = 1; - B[i] = y; - Nconstraints++; - return true; + int i = Nconstraints; + if (i == 4) + return false; + A[i][0] = x*x*x; + A[i][1] = x*x; + A[i][2] = x; + A[i][3] = 1; + B[i] = y; + Nconstraints++; + return true; } void SplineClass::add_4value_constraints(double x1, double x2, double x3, double x4, double y1, double y2, double y3, double y4) { - add_value_constraint(x1, y1); - add_value_constraint(x2, y2); - add_value_constraint(x3, y3); - add_value_constraint(x4, y4); + add_value_constraint(x1, y1); + add_value_constraint(x2, y2); + add_value_constraint(x3, y3); + add_value_constraint(x4, y4); } bool SplineClass::add_derivative_constraint(double x, double dydx) { - int i = Nconstraints; - if (i == 4) - return false; - A[i][0] = 3*x*x; - A[i][1] = 2*x; - A[i][2] = 1; - A[i][3] = 0; - B[i] = dydx; - Nconstraints++; - return true; + int i = Nconstraints; + if (i == 4) + return false; + A[i][0] = 3*x*x; + A[i][1] = 2*x; + A[i][2] = 1; + A[i][3] = 0; + B[i] = dydx; + Nconstraints++; + return true; } double SplineClass::evaluate(double x) { - return a*x*x*x+b*x*x+c*x+d; + return a*x*x*x+b*x*x+c*x+d; } \ No newline at end of file diff --git a/src/DataStructures.cpp b/src/DataStructures.cpp index 5ac0944d..3fcaee45 100644 --- a/src/DataStructures.cpp +++ b/src/DataStructures.cpp @@ -8,7 +8,7 @@ namespace CoolProp{ struct parameter_info -{ +{ int key; std::string short_desc, IO, units, description; bool trivial; ///< True if the input is trivial, and can be directly calculated (constants like critical properties, etc.) @@ -55,15 +55,15 @@ parameter_info parameter_info_list[] = { parameter_info(irhomass_reducing, "rhomass_reducing","O","kg/m^3","Mass density at reducing point",true), parameter_info(irhomolar_reducing, "rhomolar_reducing","O","mol/m^3","Molar density at reducing point",true), parameter_info(irhomolar_critical, "rhomolar_critical","O","mol/m^3","Molar density at critical point",true), - parameter_info(irhomass_critical, "rhomass_critical","O","kg/m^3","Mass density at critical point",true), + parameter_info(irhomass_critical, "rhomass_critical","O","kg/m^3","Mass density at critical point",true), parameter_info(iT_reducing, "T_reducing","O","K","Temperature at the reducing point",true), parameter_info(iT_critical, "T_critical","O","K","Temperature at the critical point",true), - parameter_info(iT_triple, "T_triple","O","K","Temperature at the triple point",true), - parameter_info(iT_max, "T_max","O","K","Maximum temperature limit",true), - parameter_info(iT_min, "T_min","O","K","Minimum temperature limit",true), - parameter_info(iP_min, "P_min","O","Pa","Minimum pressure limit",true), + parameter_info(iT_triple, "T_triple","O","K","Temperature at the triple point",true), + parameter_info(iT_max, "T_max","O","K","Maximum temperature limit",true), + parameter_info(iT_min, "T_min","O","K","Minimum temperature limit",true), + parameter_info(iP_min, "P_min","O","Pa","Minimum pressure limit",true), parameter_info(iP_max, "P_max","O","Pa","Maximum pressure limit",true), - parameter_info(iP_critical, "p_critical","O","Pa","Pressure at the critical point",true), + parameter_info(iP_critical, "p_critical","O","Pa","Pressure at the critical point",true), parameter_info(iP_triple, "p_triple","O","Pa","Pressure at the triple point (pure only)",true), parameter_info(ispeed_sound, "speed_of_sound","O","m/s","Speed of sound",false), @@ -93,7 +93,7 @@ class ParameterInformation { public: std::map trivial_map; - std::map short_desc_map, description_map, IO_map, units_map; + std::map short_desc_map, description_map, IO_map, units_map; std::map index_map; ParameterInformation() { @@ -106,7 +106,7 @@ public: units_map.insert(std::pair(el.key, el.units)); description_map.insert(std::pair(el.key, el.description)); index_map.insert(std::pair(el.short_desc, el.key)); - trivial_map.insert(std::pair(el.key, el.trivial)); + trivial_map.insert(std::pair(el.key, el.trivial)); } // Backward compatibility aliases index_map.insert(std::pair("D", iDmass)); @@ -118,14 +118,14 @@ public: index_map.insert(std::pair("O", iCvmass)); index_map.insert(std::pair("V", iviscosity)); index_map.insert(std::pair("L", iconductivity)); - index_map.insert(std::pair("pcrit", iP_critical)); - index_map.insert(std::pair("Tcrit", iT_critical)); - index_map.insert(std::pair("Ttriple", iT_triple)); + index_map.insert(std::pair("pcrit", iP_critical)); + index_map.insert(std::pair("Tcrit", iT_critical)); + index_map.insert(std::pair("Ttriple", iT_triple)); index_map.insert(std::pair("ptriple", iP_triple)); - index_map.insert(std::pair("rhocrit", irhomass_critical)); - index_map.insert(std::pair("Tmin", iT_min)); - index_map.insert(std::pair("Tmax", iT_max)); - index_map.insert(std::pair("pmax", iP_max)); + index_map.insert(std::pair("rhocrit", irhomass_critical)); + index_map.insert(std::pair("Tmin", iT_min)); + index_map.insert(std::pair("Tmax", iT_max)); + index_map.insert(std::pair("pmax", iP_max)); index_map.insert(std::pair("pmin", iP_min)); index_map.insert(std::pair("molemass", imolar_mass)); index_map.insert(std::pair("A", ispeed_sound)); @@ -288,7 +288,7 @@ bool is_valid_second_derivative(const std::string & name, parameters &iOf1, para } struct phase_info -{ +{ phases key; std::string short_desc, long_desc; public: @@ -310,7 +310,7 @@ phase_info phase_info_list[] = { class PhaseInformation { public: - std::map short_desc_map, long_desc_map; + std::map short_desc_map, long_desc_map; std::map index_map; PhaseInformation() { diff --git a/src/HumidAirProp.cpp b/src/HumidAirProp.cpp index 3f817539..e70c467f 100644 --- a/src/HumidAirProp.cpp +++ b/src/HumidAirProp.cpp @@ -1880,8 +1880,8 @@ TEST_CASE_METHOD(HAPropsConsistencyFixture, "ASHRAE RP1485 Tables", "[RP1485]") CAPTURE(out); CAPTURE(actual); CAPTURE(expected); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); CHECK(std::abs(actual/expected-1) < 0.01); } } @@ -1900,8 +1900,8 @@ TEST_CASE_METHOD(HAPropsConsistencyFixture, "ASHRAE RP1485 Tables", "[RP1485]") CAPTURE(out); CAPTURE(actual); CAPTURE(expected); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); CHECK(std::abs(actual/expected-1) < 0.01); } } @@ -1920,8 +1920,8 @@ TEST_CASE_METHOD(HAPropsConsistencyFixture, "ASHRAE RP1485 Tables", "[RP1485]") CAPTURE(out); CAPTURE(actual); CAPTURE(expected); - std::string errmsg = CoolProp::get_global_param_string("errstring"); - CAPTURE(errmsg); + std::string errmsg = CoolProp::get_global_param_string("errstring"); + CAPTURE(errmsg); CHECK(std::abs(actual/expected-1) < 0.01); } } diff --git a/src/Ice.cpp b/src/Ice.cpp index c93f7b87..12b82bf2 100644 --- a/src/Ice.cpp +++ b/src/Ice.cpp @@ -27,118 +27,118 @@ static double s0= -0.332733756492168e4; double IsothermCompress_Ice(double T, double p) { - #ifndef __powerpc__ - // Inputs in K, Pa, Output in 1/Pa - return -dg2_dp2_Ice(T,p)/dg_dp_Ice(T,p); - #else - return 1e99; - #endif + #ifndef __powerpc__ + // Inputs in K, Pa, Output in 1/Pa + return -dg2_dp2_Ice(T,p)/dg_dp_Ice(T,p); + #else + return 1e99; + #endif } double psub_Ice(double T) { - #ifndef __powerpc__ - double a[]={0,-0.212144006e2,0.273203819e2,-0.610598130e1}; - double b[]={0,0.333333333e-2,0.120666667e1,0.170333333e1}; - double summer=0,theta; - theta=T/T_t; - for (int i=1;i<=3;i++) - { - summer+=a[i]*pow(theta,b[i]); - } - return p_t*exp(1/theta*summer); - #else - return 1e99; - #endif + #ifndef __powerpc__ + double a[]={0,-0.212144006e2,0.273203819e2,-0.610598130e1}; + double b[]={0,0.333333333e-2,0.120666667e1,0.170333333e1}; + double summer=0,theta; + theta=T/T_t; + for (int i=1;i<=3;i++) + { + summer+=a[i]*pow(theta,b[i]); + } + return p_t*exp(1/theta*summer); + #else + return 1e99; + #endif } double g_Ice(double T,double p) { - #ifndef __powerpc__ - std::complex r2,term1,term2; - double g0,theta,pi,pi_0; - theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; - g0=g00*pow(pi-pi_0,0.0)+g01*pow(pi-pi_0,1.0)+g02*pow(pi-pi_0,2.0)+g03*pow(pi-pi_0,3.0)+g04*pow(pi-pi_0,4.0); - r2=r20*pow(pi-pi_0,0.0)+r21*pow(pi-pi_0,1.0)+r22*pow(pi-pi_0,2.0); - // The two terms of the summation - term1=r1*((t1-theta)*log(t1-theta)+(t1+theta)*log(t1+theta)-2.0*t1*log(t1)-theta*theta/t1); - term2=r2*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2); - return g0-s0*T_t*theta+T_t*real(term1+term2); - #else - return 1e99; - #endif + #ifndef __powerpc__ + std::complex r2,term1,term2; + double g0,theta,pi,pi_0; + theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; + g0=g00*pow(pi-pi_0,0.0)+g01*pow(pi-pi_0,1.0)+g02*pow(pi-pi_0,2.0)+g03*pow(pi-pi_0,3.0)+g04*pow(pi-pi_0,4.0); + r2=r20*pow(pi-pi_0,0.0)+r21*pow(pi-pi_0,1.0)+r22*pow(pi-pi_0,2.0); + // The two terms of the summation + term1=r1*((t1-theta)*log(t1-theta)+(t1+theta)*log(t1+theta)-2.0*t1*log(t1)-theta*theta/t1); + term2=r2*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2); + return g0-s0*T_t*theta+T_t*real(term1+term2); + #else + return 1e99; + #endif } double dg_dp_Ice(double T, double p) { - #ifndef __powerpc__ - std::complex r2_p; - double g0_p,theta,pi,pi_0; - theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; - g0_p=g01*1.0/p_t*pow(pi-pi_0,1-1.0)+g02*2.0/p_t*pow(pi-pi_0,2-1.0)+g03*3.0/p_t*pow(pi-pi_0,3-1.0)+g04*4.0/p_t*pow(pi-pi_0,4-1.0); - r2_p=r21*1.0/p_t*pow(pi-pi_0,1-1.0)+r22*2.0/p_t*pow(pi-pi_0,2-1.0); - return g0_p+T_t*real(r2_p*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2)); - #else - return 1e99; - #endif + #ifndef __powerpc__ + std::complex r2_p; + double g0_p,theta,pi,pi_0; + theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; + g0_p=g01*1.0/p_t*pow(pi-pi_0,1-1.0)+g02*2.0/p_t*pow(pi-pi_0,2-1.0)+g03*3.0/p_t*pow(pi-pi_0,3-1.0)+g04*4.0/p_t*pow(pi-pi_0,4-1.0); + r2_p=r21*1.0/p_t*pow(pi-pi_0,1-1.0)+r22*2.0/p_t*pow(pi-pi_0,2-1.0); + return g0_p+T_t*real(r2_p*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2)); + #else + return 1e99; + #endif } double dg2_dp2_Ice(double T, double p) { - #ifndef __powerpc__ - std::complex r2_pp; - double g0_pp,theta,pi,pi_0; - theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; - g0_pp=g02*2.0*(2.0-1.0)/p_t/p_t*pow(pi-pi_0,2.0-2.0)+g03*3.0*(3.0-1.0)/p_t/p_t*pow(pi-pi_0,3.0-2.0)+g04*4.0*(4.0-1.0)/p_t/p_t*pow(pi-pi_0,4-2.0); - r2_pp=r22*2.0/p_t/p_t; - return g0_pp+T_t*real(r2_pp*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2)); - #else - return 1e99; - #endif + #ifndef __powerpc__ + std::complex r2_pp; + double g0_pp,theta,pi,pi_0; + theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; + g0_pp=g02*2.0*(2.0-1.0)/p_t/p_t*pow(pi-pi_0,2.0-2.0)+g03*3.0*(3.0-1.0)/p_t/p_t*pow(pi-pi_0,3.0-2.0)+g04*4.0*(4.0-1.0)/p_t/p_t*pow(pi-pi_0,4-2.0); + r2_pp=r22*2.0/p_t/p_t; + return g0_pp+T_t*real(r2_pp*((t2-theta)*log(t2-theta)+(t2+theta)*log(t2+theta)-2.0*t2*log(t2)-theta*theta/t2)); + #else + return 1e99; + #endif } double dg_dT_Ice(double T, double p) { - #ifndef __powerpc__ - std::complex r2,term1,term2; - double theta,pi,pi_0; - theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; - r2=r20*pow(pi-pi_0,0.0)+r21*pow(pi-pi_0,1.0)+r22*pow(pi-pi_0,2.0); - // The two terms of the summation - term1=r1*(-log(t1-theta)+log(t1+theta)-2.0*theta/t1); - term2=r2*(-log(t2-theta)+log(t2+theta)-2.0*theta/t2); - return -s0+real(term1+term2); - #else - return 1e99; - #endif + #ifndef __powerpc__ + std::complex r2,term1,term2; + double theta,pi,pi_0; + theta= T/T_t; pi=p/p_t; pi_0=p_0/p_t; + r2=r20*pow(pi-pi_0,0.0)+r21*pow(pi-pi_0,1.0)+r22*pow(pi-pi_0,2.0); + // The two terms of the summation + term1=r1*(-log(t1-theta)+log(t1+theta)-2.0*theta/t1); + term2=r2*(-log(t2-theta)+log(t2+theta)-2.0*theta/t2); + return -s0+real(term1+term2); + #else + return 1e99; + #endif } double h_Ice(double T, double p) { - #ifndef __powerpc__ - // Returned value is in units of J/kg - return g_Ice(T,p)-T*dg_dT_Ice(T,p); - #else - return 1e99; - #endif + #ifndef __powerpc__ + // Returned value is in units of J/kg + return g_Ice(T,p)-T*dg_dT_Ice(T,p); + #else + return 1e99; + #endif } double rho_Ice(double T, double p) { - #ifndef __powerpc__ - // Returned value is in units of kg/m3 - return 1/g_Ice(T,p); - #else - return 1e99; - #endif + #ifndef __powerpc__ + // Returned value is in units of kg/m3 + return 1/g_Ice(T,p); + #else + return 1e99; + #endif } double s_Ice(double T, double p) { - #ifndef __powerpc__ - // Returned value is in units of J/kg/K - return -dg_dT_Ice(T,p); - #else - return 1e99; - #endif + #ifndef __powerpc__ + // Returned value is in units of J/kg/K + return -dg_dT_Ice(T,p); + #else + return 1e99; + #endif } diff --git a/src/MatrixMath.cpp b/src/MatrixMath.cpp index e2edc5e1..671ba86c 100644 --- a/src/MatrixMath.cpp +++ b/src/MatrixMath.cpp @@ -25,88 +25,88 @@ namespace CoolProp{ TEST_CASE("Internal consistency checks and example use cases for MatrixMath.h","[MatrixMath]") { - bool PRINT = false; + bool PRINT = false; - /// Test case for "SylthermXLT" by "Dow Chemicals" - std::vector cHeat; - cHeat.clear(); - cHeat.push_back(+1.1562261074E+03); - cHeat.push_back(+2.0994549103E+00); - cHeat.push_back(+7.7175381057E-07); - cHeat.push_back(-3.7008444051E-20); + /// Test case for "SylthermXLT" by "Dow Chemicals" + std::vector cHeat; + cHeat.clear(); + cHeat.push_back(+1.1562261074E+03); + cHeat.push_back(+2.0994549103E+00); + cHeat.push_back(+7.7175381057E-07); + cHeat.push_back(-3.7008444051E-20); - std::vector > cHeat2D; - cHeat2D.push_back(cHeat); - cHeat2D.push_back(cHeat); + std::vector > cHeat2D; + cHeat2D.push_back(cHeat); + cHeat2D.push_back(cHeat); - SECTION("Pretty printing tests") { + SECTION("Pretty printing tests") { - Eigen::MatrixXd matrix = Eigen::MatrixXd::Random(4,1); - std::string tmpStr; - if (PRINT) std::cout << std::endl; + Eigen::MatrixXd matrix = Eigen::MatrixXd::Random(4,1); + std::string tmpStr; + if (PRINT) std::cout << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat[0]) ); - if (PRINT) std::cout << tmpStr << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat) ); - if (PRINT) std::cout << tmpStr << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat2D) ); - if (PRINT) std::cout << tmpStr << std::endl; + CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat[0]) ); + if (PRINT) std::cout << tmpStr << std::endl; + CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat) ); + if (PRINT) std::cout << tmpStr << std::endl; + CHECK_NOTHROW( tmpStr = CoolProp::vec_to_string(cHeat2D) ); + if (PRINT) std::cout << tmpStr << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat[0])) ); - if (PRINT) std::cout << tmpStr << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat, 1)) ); - if (PRINT) std::cout << tmpStr << std::endl; - CHECK_THROWS( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat, 2)) ); - if (PRINT) std::cout << tmpStr << std::endl; - CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat2D)) ); - if (PRINT) std::cout << tmpStr << std::endl; - } + CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat[0])) ); + if (PRINT) std::cout << tmpStr << std::endl; + CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat, 1)) ); + if (PRINT) std::cout << tmpStr << std::endl; + CHECK_THROWS( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat, 2)) ); + if (PRINT) std::cout << tmpStr << std::endl; + CHECK_NOTHROW( tmpStr = CoolProp::mat_to_string(CoolProp::vec_to_eigen(cHeat2D)) ); + if (PRINT) std::cout << tmpStr << std::endl; + } - SECTION("Matrix modifications") { - Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(cHeat2D); + SECTION("Matrix modifications") { + Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(cHeat2D); - std::string tmpStr; - std::vector > vec2D; - if (PRINT) std::cout << std::endl; + std::string tmpStr; + std::vector > vec2D; + if (PRINT) std::cout << std::endl; - CHECK_NOTHROW( CoolProp::removeColumn(matrix,1) ); - if (PRINT) std::cout << CoolProp::mat_to_string(matrix) << std::endl; + CHECK_NOTHROW( CoolProp::removeColumn(matrix,1) ); + if (PRINT) std::cout << CoolProp::mat_to_string(matrix) << std::endl; - CHECK_NOTHROW( CoolProp::removeRow(matrix,1) ); - if (PRINT) std::cout << CoolProp::mat_to_string(matrix) << std::endl; + CHECK_NOTHROW( CoolProp::removeRow(matrix,1) ); + if (PRINT) std::cout << CoolProp::mat_to_string(matrix) << std::endl; - CHECK_THROWS( CoolProp::removeColumn(matrix,10) ); - CHECK_THROWS( CoolProp::removeRow(matrix,10) ); - } + CHECK_THROWS( CoolProp::removeColumn(matrix,10) ); + CHECK_THROWS( CoolProp::removeRow(matrix,10) ); + } - SECTION("std::vector to Eigen::Matrix and back") { - std::vector > vec2D(cHeat2D); - Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(vec2D); - for (size_t i = 0; i < matrix.cols(); ++i) { - for (size_t j = 0; j < matrix.rows(); ++j) { - CHECK( std::abs(matrix(j,i)-vec2D[j][i]) <= 1e-10 ); - } - } - vec2D = CoolProp::eigen_to_vec(matrix); - for (size_t i = 0; i < matrix.cols(); ++i) { - for (size_t j = 0; j < matrix.rows(); ++j) { - CHECK( std::abs(matrix(j,i)-vec2D[j][i]) <= 1e-10 ); - } - } - std::vector vec1D(cHeat); - matrix = CoolProp::vec_to_eigen(vec1D); - for (size_t i = 0; i < matrix.cols(); ++i) { - for (size_t j = 0; j < matrix.rows(); ++j) { - CHECK( std::abs(matrix(j,i)-vec1D[j]) <= 1e-10 ); - } - } - vec1D = CoolProp::eigen_to_vec1D(matrix); - for (size_t i = 0; i < matrix.cols(); ++i) { - for (size_t j = 0; j < matrix.rows(); ++j) { - CHECK( std::abs(matrix(j,i)-vec1D[j]) <= 1e-10 ); - } - } - } + SECTION("std::vector to Eigen::Matrix and back") { + std::vector > vec2D(cHeat2D); + Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(vec2D); + for (size_t i = 0; i < matrix.cols(); ++i) { + for (size_t j = 0; j < matrix.rows(); ++j) { + CHECK( std::abs(matrix(j,i)-vec2D[j][i]) <= 1e-10 ); + } + } + vec2D = CoolProp::eigen_to_vec(matrix); + for (size_t i = 0; i < matrix.cols(); ++i) { + for (size_t j = 0; j < matrix.rows(); ++j) { + CHECK( std::abs(matrix(j,i)-vec2D[j][i]) <= 1e-10 ); + } + } + std::vector vec1D(cHeat); + matrix = CoolProp::vec_to_eigen(vec1D); + for (size_t i = 0; i < matrix.cols(); ++i) { + for (size_t j = 0; j < matrix.rows(); ++j) { + CHECK( std::abs(matrix(j,i)-vec1D[j]) <= 1e-10 ); + } + } + vec1D = CoolProp::eigen_to_vec1D(matrix); + for (size_t i = 0; i < matrix.cols(); ++i) { + for (size_t j = 0; j < matrix.rows(); ++j) { + CHECK( std::abs(matrix(j,i)-vec1D[j]) <= 1e-10 ); + } + } + } } diff --git a/src/PolyMath.cpp b/src/PolyMath.cpp index 3358b32c..7d667079 100644 --- a/src/PolyMath.cpp +++ b/src/PolyMath.cpp @@ -26,16 +26,16 @@ namespace CoolProp{ /// @param rows unsigned integer value that represents the desired degree of the polynomial in the 1st dimension /// @param columns unsigned integer value that represents the desired degree of the polynomial in the 2nd dimension bool Polynomial2D::checkCoefficients(const Eigen::MatrixXd &coefficients, const unsigned int rows, const unsigned int columns){ - if (coefficients.rows() == rows) { - if (coefficients.cols() == columns) { - return true; - } else { - throw ValueError(format("%s (%d): The number of columns %d does not match with %d. ",__FILE__,__LINE__,coefficients.cols(),columns)); - } - } else { - throw ValueError(format("%s (%d): The number of rows %d does not match with %d. ",__FILE__,__LINE__,coefficients.rows(),rows)); - } - return false; + if (coefficients.rows() == rows) { + if (coefficients.cols() == columns) { + return true; + } else { + throw ValueError(format("%s (%d): The number of columns %d does not match with %d. ",__FILE__,__LINE__,coefficients.cols(),columns)); + } + } else { + throw ValueError(format("%s (%d): The number of rows %d does not match with %d. ",__FILE__,__LINE__,coefficients.rows(),rows)); + } + return false; } @@ -52,46 +52,46 @@ bool Polynomial2D::checkCoefficients(const Eigen::MatrixXd &coefficients, const /// @param axis integer value that represents the desired direction of integration /// @param times integer value that represents the desired order of integration Eigen::MatrixXd Polynomial2D::integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis = -1, const int × = 1){ - if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for integration, %d is not valid. ",__FILE__,__LINE__,times)); - if (times == 0) return Eigen::MatrixXd(coefficients); - Eigen::MatrixXd oldCoefficients; - Eigen::MatrixXd newCoefficients(coefficients); + if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for integration, %d is not valid. ",__FILE__,__LINE__,times)); + if (times == 0) return Eigen::MatrixXd(coefficients); + Eigen::MatrixXd oldCoefficients; + Eigen::MatrixXd newCoefficients(coefficients); - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - std::size_t r, c; - for (int k = 0; k < times; k++){ - oldCoefficients = Eigen::MatrixXd(newCoefficients); - r = oldCoefficients.rows(), c = oldCoefficients.cols(); - newCoefficients = Eigen::MatrixXd::Zero(r+1,c); - newCoefficients.block(1,0,r,c) = oldCoefficients.block(0,0,r,c); - for (size_t i = 0; i < r; ++i) { - for (size_t j = 0; j < c; ++j) newCoefficients(i+1,j) /= (i+1.); - } - } + std::size_t r, c; + for (int k = 0; k < times; k++){ + oldCoefficients = Eigen::MatrixXd(newCoefficients); + r = oldCoefficients.rows(), c = oldCoefficients.cols(); + newCoefficients = Eigen::MatrixXd::Zero(r+1,c); + newCoefficients.block(1,0,r,c) = oldCoefficients.block(0,0,r,c); + for (size_t i = 0; i < r; ++i) { + for (size_t j = 0; j < c; ++j) newCoefficients(i+1,j) /= (i+1.); + } + } - switch (axis) { - case 0: - break; - case 1: - newCoefficients.transposeInPlace(); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + break; + case 1: + newCoefficients.transposeInPlace(); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - return newCoefficients; + return newCoefficients; } @@ -103,47 +103,47 @@ Eigen::MatrixXd Polynomial2D::integrateCoeffs(const Eigen::MatrixXd &coefficient /// @param axis integer value that represents the desired direction of derivation /// @param times integer value that represents the desired order of integration Eigen::MatrixXd Polynomial2D::deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×){ - if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for derivation, %d is not valid. ",__FILE__,__LINE__,times)); - if (times == 0) return Eigen::MatrixXd(coefficients); - // Recursion is also possible, but not recommended - //Eigen::MatrixXd newCoefficients; - //if (times > 1) newCoefficients = deriveCoeffs(coefficients, axis, times-1); - //else newCoefficients = Eigen::MatrixXd(coefficients); - Eigen::MatrixXd newCoefficients; + if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for derivation, %d is not valid. ",__FILE__,__LINE__,times)); + if (times == 0) return Eigen::MatrixXd(coefficients); + // Recursion is also possible, but not recommended + //Eigen::MatrixXd newCoefficients; + //if (times > 1) newCoefficients = deriveCoeffs(coefficients, axis, times-1); + //else newCoefficients = Eigen::MatrixXd(coefficients); + Eigen::MatrixXd newCoefficients; - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - std::size_t r, c, i, j; - for (int k = 0; k < times; k++){ - r = newCoefficients.rows(), c = newCoefficients.cols(); - for (i = 1; i < r; ++i) { - for (j = 0; j < c; ++j) newCoefficients(i,j) *= i; - } - removeRow(newCoefficients,0); - } + std::size_t r, c, i, j; + for (int k = 0; k < times; k++){ + r = newCoefficients.rows(), c = newCoefficients.cols(); + for (i = 1; i < r; ++i) { + for (j = 0; j < c; ++j) newCoefficients(i,j) *= i; + } + removeRow(newCoefficients,0); + } - switch (axis) { - case 0: - break; - case 1: - newCoefficients.transposeInPlace(); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + break; + case 1: + newCoefficients.transposeInPlace(); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - return newCoefficients; + return newCoefficients; } /// The core functions to evaluate the polynomial @@ -157,22 +157,22 @@ Eigen::MatrixXd Polynomial2D::deriveCoeffs(const Eigen::MatrixXd &coefficients, /// @param coefficients vector containing the ordered coefficients /// @param x_in double value that represents the current input double Polynomial2D::evaluate(const Eigen::MatrixXd &coefficients, const double &x_in){ - double result = Eigen::poly_eval( makeVector(coefficients), x_in ); - if (this->do_debug()) std::cout << "Running 1D evaluate(" << mat_to_string(coefficients) << ", x_in:" << vec_to_string(x_in) << "): " << result << std::endl; - return result; + double result = Eigen::poly_eval( makeVector(coefficients), x_in ); + if (this->do_debug()) std::cout << "Running 1D evaluate(" << mat_to_string(coefficients) << ", x_in:" << vec_to_string(x_in) << "): " << result << std::endl; + return result; } /// @param coefficients vector containing the ordered coefficients /// @param x_in double value that represents the current input in the 1st dimension /// @param y_in double value that represents the current input in the 2nd dimension double Polynomial2D::evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in){ - size_t r = coefficients.rows(); - double result = evaluate(coefficients.row(r-1), y_in); - for(int i=r-2; i>=0; i--) { - result *= x_in; - result += evaluate(coefficients.row(i), y_in); - } - if (this->do_debug()) std::cout << "Running 2D evaluate(" << mat_to_string(coefficients) << ", x_in:" << vec_to_string(x_in) << ", y_in:" << vec_to_string(y_in) << "): " << result << std::endl; - return result; + size_t r = coefficients.rows(); + double result = evaluate(coefficients.row(r-1), y_in); + for(int i=r-2; i>=0; i--) { + result *= x_in; + result += evaluate(coefficients.row(i), y_in); + } + if (this->do_debug()) std::cout << "Running 2D evaluate(" << mat_to_string(coefficients) << ", x_in:" << vec_to_string(x_in) << ", y_in:" << vec_to_string(y_in) << "): " << result << std::endl; + return result; } @@ -181,7 +181,7 @@ double Polynomial2D::evaluate(const Eigen::MatrixXd &coefficients, const double /// @param y_in double value that represents the current input in the 2nd dimension /// @param axis unsigned integer value that represents the axis to derive for (0=x, 1=y) double Polynomial2D::derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis = -1){ - return this->evaluate(this->deriveCoeffs(coefficients, axis, 1), x_in, y_in); + return this->evaluate(this->deriveCoeffs(coefficients, axis, 1), x_in, y_in); } @@ -190,7 +190,7 @@ double Polynomial2D::derivative(const Eigen::MatrixXd &coefficients, const doubl /// @param y_in double value that represents the current input in the 2nd dimension /// @param axis unsigned integer value that represents the axis to integrate for (0=x, 1=y) double Polynomial2D::integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis = -1){ - return this->evaluate(this->integrateCoeffs(coefficients, axis, 1), x_in,y_in); + return this->evaluate(this->integrateCoeffs(coefficients, axis, 1), x_in,y_in); } /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in @@ -198,28 +198,28 @@ double Polynomial2D::integral(const Eigen::MatrixXd &coefficients, const double /// @param min double value that represents the minimum value /// @param max double value that represents the maximum value double Polynomial2D::solve_limits(Poly2DResidual* res, const double &min, const double &max){ - if (do_debug()) std::cout << format("Called solve_limits with: min=%f and max=%f", min, max) << std::endl; - std::string errstring; - double macheps = DBL_EPSILON; - double tol = DBL_EPSILON*1e3; - int maxiter = 10; - double result = Brent(res, min, max, macheps, tol, maxiter, errstring); - if (this->do_debug()) std::cout << "Brent solver message: " << errstring << std::endl; - return result; + if (do_debug()) std::cout << format("Called solve_limits with: min=%f and max=%f", min, max) << std::endl; + std::string errstring; + double macheps = DBL_EPSILON; + double tol = DBL_EPSILON*1e3; + int maxiter = 10; + double result = Brent(res, min, max, macheps, tol, maxiter, errstring); + if (this->do_debug()) std::cout << "Brent solver message: " << errstring << std::endl; + return result; } /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in /// @param res Poly2DResidual object to calculate residuals and derivatives /// @param guess double value that represents the start value double Polynomial2D::solve_guess(Poly2DResidual* res, const double &guess){ - if (do_debug()) std::cout << format("Called solve_guess with: guess=%f ", guess) << std::endl; - std::string errstring; - //set_debug_level(1000); - double tol = DBL_EPSILON*1e3; - int maxiter = 10; - double result = Newton(res, guess, tol, maxiter, errstring); - if (this->do_debug()) std::cout << "Newton solver message: " << errstring << std::endl; - return result; + if (do_debug()) std::cout << format("Called solve_guess with: guess=%f ", guess) << std::endl; + std::string errstring; + //set_debug_level(1000); + double tol = DBL_EPSILON*1e3; + int maxiter = 10; + double result = Newton(res, guess, tol, maxiter, errstring); + if (this->do_debug()) std::cout << "Newton solver message: " << errstring << std::endl; + return result; } @@ -228,41 +228,41 @@ double Polynomial2D::solve_guess(Poly2DResidual* res, const double &guess){ /// @param z_in double value that represents the current output in the 3rd dimension /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) Eigen::VectorXd Polynomial2D::solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis = -1){ - std::size_t r = coefficients.rows(), c = coefficients.cols(); - Eigen::VectorXd tmpCoefficients; - switch (axis) { - case 0: - tmpCoefficients = Eigen::VectorXd::Zero(r); - for(size_t i=0; ido_debug()) std::cout << "Coefficients: " << mat_to_string(Eigen::MatrixXd(tmpCoefficients)) << std::endl; - Eigen::PolynomialSolver polySolver( tmpCoefficients ); - std::vector rootsVec; - polySolver.realRoots(rootsVec); - if (this->do_debug()) std::cout << "Real roots: " << vec_to_string(rootsVec) << std::endl; - return vec_to_eigen(rootsVec); - //return rootsVec[0]; // TODO: implement root selection algorithm + std::size_t r = coefficients.rows(), c = coefficients.cols(); + Eigen::VectorXd tmpCoefficients; + switch (axis) { + case 0: + tmpCoefficients = Eigen::VectorXd::Zero(r); + for(size_t i=0; ido_debug()) std::cout << "Coefficients: " << mat_to_string(Eigen::MatrixXd(tmpCoefficients)) << std::endl; + Eigen::PolynomialSolver polySolver( tmpCoefficients ); + std::vector rootsVec; + polySolver.realRoots(rootsVec); + if (this->do_debug()) std::cout << "Real roots: " << vec_to_string(rootsVec) << std::endl; + return vec_to_eigen(rootsVec); + //return rootsVec[0]; // TODO: implement root selection algorithm } /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) /// @param z_in double value that represents the current output in the 3rd dimension /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) double Polynomial2D::solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis){ - Poly2DResidual res = Poly2DResidual(*this, coefficients, in, z_in, axis); - return solve_limits(&res, min, max); + Poly2DResidual res = Poly2DResidual(*this, coefficients, in, z_in, axis); + return solve_limits(&res, min, max); } /// @param in double value that represents the current input in x (1st dimension) or y (2nd dimension) @@ -270,8 +270,8 @@ double Polynomial2D::solve_limits(const Eigen::MatrixXd &coefficients, const dou /// @param guess double value that represents the start value /// @param axis unsigned integer value that represents the axis to solve for (0=x, 1=y) double Polynomial2D::solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis){ - Poly2DResidual res = Poly2DResidual(*this, coefficients, in, z_in, axis); - return solve_guess(&res, guess); + Poly2DResidual res = Poly2DResidual(*this, coefficients, in, z_in, axis); + return solve_guess(&res, guess); } @@ -280,20 +280,20 @@ double Polynomial2D::solve_guess(const Eigen::MatrixXd &coefficients, const doub * based on the length of the coefficient vector. * Starts with only the first coefficient at x^0. */ double Polynomial2D::simplePolynomial(std::vector const& coefficients, double x){ - double result = 0.; - for(unsigned int i=0; ido_debug()) std::cout << "Running simplePolynomial(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << "): " << result << std::endl; - return result; + double result = 0.; + for(unsigned int i=0; ido_debug()) std::cout << "Running simplePolynomial(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << "): " << result << std::endl; + return result; } double Polynomial2D::simplePolynomial(std::vector > const& coefficients, double x, double y){ - double result = 0; - for(unsigned int i=0; ido_debug()) std::cout << "Running simplePolynomial(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << ", " << vec_to_string(y) << "): " << result << std::endl; - return result; + double result = 0; + for(unsigned int i=0; ido_debug()) std::cout << "Running simplePolynomial(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << ", " << vec_to_string(y) << "): " << result << std::endl; + return result; } @@ -303,77 +303,77 @@ double Polynomial2D::simplePolynomial(std::vector > const& c * speeds up calculation. */ double Polynomial2D::baseHorner(std::vector const& coefficients, double x){ - double result = 0; - for(int i=coefficients.size()-1; i>=0; i--) { - result *= x; - result += coefficients[i]; - } - if (this->do_debug()) std::cout << "Running baseHorner(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << "): " << result << std::endl; - return result; + double result = 0; + for(int i=coefficients.size()-1; i>=0; i--) { + result *= x; + result += coefficients[i]; + } + if (this->do_debug()) std::cout << "Running baseHorner(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << "): " << result << std::endl; + return result; } double Polynomial2D::baseHorner(std::vector< std::vector > const& coefficients, double x, double y){ - double result = 0; - for(int i=coefficients.size()-1; i>=0; i--) { - result *= x; - result += baseHorner(coefficients[i], y); - } - if (this->do_debug()) std::cout << "Running baseHorner(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << ", " << vec_to_string(y) << "): " << result << std::endl; - return result; + double result = 0; + for(int i=coefficients.size()-1; i>=0; i--) { + result *= x; + result += baseHorner(coefficients[i], y); + } + if (this->do_debug()) std::cout << "Running baseHorner(" << vec_to_string(coefficients) << ", " << vec_to_string(x) << ", " << vec_to_string(y) << "): " << result << std::endl; + return result; } Poly2DResidual::Poly2DResidual(Polynomial2D &poly, const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis){ - switch (axis) { - case iX: - case iY: - this->axis = axis; - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension to the solver, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case iX: + case iY: + this->axis = axis; + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension to the solver, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - this->poly = poly; - this->coefficients = coefficients; - this->derIsSet = false; - this->in = in; - this->z_in = z_in; + this->poly = poly; + this->coefficients = coefficients; + this->derIsSet = false; + this->in = in; + this->z_in = z_in; } double Poly2DResidual::call(double target){ - if (axis==iX) return poly.evaluate(coefficients,target,in)-z_in; - if (axis==iY) return poly.evaluate(coefficients,in,target)-z_in; - return -_HUGE; + if (axis==iX) return poly.evaluate(coefficients,target,in)-z_in; + if (axis==iY) return poly.evaluate(coefficients,in,target)-z_in; + return -_HUGE; } double Poly2DResidual::deriv(double target){ - if (!this->derIsSet) { - this->coefficientsDer = poly.deriveCoeffs(coefficients,axis); - this->derIsSet = true; - } - return poly.evaluate(coefficientsDer,target,in); + if (!this->derIsSet) { + this->coefficientsDer = poly.deriveCoeffs(coefficients,axis); + this->derIsSet = true; + } + return poly.evaluate(coefficientsDer,target,in); } -// /// Integration functions -// /** Integrating coefficients for polynomials is done by dividing the -// * original coefficients by (i+1) and elevating the order by 1 -// * through adding a zero as first coefficient. -// * Some reslicing needs to be applied to integrate along the x-axis. -// * In the brine/solution equations, reordering of the parameters -// * avoids this expensive operation. However, it is included for the -// * sake of completeness. -// */ -// /// @param coefficients matrix containing the ordered coefficients -// /// @param axis unsigned integer value that represents the desired direction of integration -// /// @param times integer value that represents the desired order of integration -// /// @param firstExponent integer value that represents the first exponent of the polynomial in axis direction -// Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); +// /// Integration functions +// /** Integrating coefficients for polynomials is done by dividing the +// * original coefficients by (i+1) and elevating the order by 1 +// * through adding a zero as first coefficient. +// * Some reslicing needs to be applied to integrate along the x-axis. +// * In the brine/solution equations, reordering of the parameters +// * avoids this expensive operation. However, it is included for the +// * sake of completeness. +// */ +// /// @param coefficients matrix containing the ordered coefficients +// /// @param axis unsigned integer value that represents the desired direction of integration +// /// @param times integer value that represents the desired order of integration +// /// @param firstExponent integer value that represents the first exponent of the polynomial in axis direction +// Eigen::MatrixXd integrateCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent); // /// Derivative coefficients calculation /** Deriving coefficients for polynomials is done by multiplying the @@ -390,48 +390,48 @@ double Poly2DResidual::deriv(double target){ /// @param times integer value that represents the desired order of derivation /// @param firstExponent integer value that represents the lowest exponent of the polynomial in axis direction Eigen::MatrixXd Polynomial2DFrac::deriveCoeffs(const Eigen::MatrixXd &coefficients, const int &axis, const int ×, const int &firstExponent){ - if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for derivation, %d is not valid. ",__FILE__,__LINE__,times)); - if (times == 0) return Eigen::MatrixXd(coefficients); - // Recursion is also possible, but not recommended - //Eigen::MatrixXd newCoefficients; - //if (times > 1) newCoefficients = deriveCoeffs(coefficients, axis, times-1); - //else newCoefficients = Eigen::MatrixXd(coefficients); - Eigen::MatrixXd newCoefficients; + if (times < 0) throw ValueError(format("%s (%d): You have to provide a positive order for derivation, %d is not valid. ",__FILE__,__LINE__,times)); + if (times == 0) return Eigen::MatrixXd(coefficients); + // Recursion is also possible, but not recommended + //Eigen::MatrixXd newCoefficients; + //if (times > 1) newCoefficients = deriveCoeffs(coefficients, axis, times-1); + //else newCoefficients = Eigen::MatrixXd(coefficients); + Eigen::MatrixXd newCoefficients; - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - std::size_t r = newCoefficients.rows(), c = newCoefficients.cols(); - std::size_t i, j; - for (int k = 0; k < times; k++){ - for (i = 0; i < r; ++i) { - for (j = 0; j < c; ++j) { - newCoefficients(i,j) *= double(i)+double(firstExponent); - } - } - } + std::size_t r = newCoefficients.rows(), c = newCoefficients.cols(); + std::size_t i, j; + for (int k = 0; k < times; k++){ + for (i = 0; i < r; ++i) { + for (j = 0; j < c; ++j) { + newCoefficients(i,j) *= double(i)+double(firstExponent); + } + } + } - switch (axis) { - case 0: - break; - case 1: - newCoefficients.transposeInPlace(); - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + break; + case 1: + newCoefficients.transposeInPlace(); + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - return newCoefficients; + return newCoefficients; } @@ -451,45 +451,45 @@ Eigen::MatrixXd Polynomial2DFrac::deriveCoeffs(const Eigen::MatrixXd &coefficien /// @param firstExponent integer value that represents the lowest exponent of the polynomial /// @param x_base double value that represents the base value for a centred fit in the 1st dimension double Polynomial2DFrac::evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const int &firstExponent, const double &x_base){ - size_t r = coefficients.rows(); - size_t c = coefficients.cols(); + size_t r = coefficients.rows(); + size_t c = coefficients.cols(); - if ( (r!=1) && (c!=1) ) { - throw ValueError(format("%s (%d): You have a 2D coefficient matrix (%d,%d), please use the 2D functions. ",__FILE__,__LINE__,coefficients.rows(),coefficients.cols())); - } - if ( (firstExponent<0) && (std::abs(x_in-x_base)firstExponent; i--) { // only for firstExponent<0 - c=tmpCoeffs.cols(); - if (c>0) { - negExp += tmpCoeffs(0,0); - removeColumn(tmpCoeffs, 0); - } - negExp /= x_in-x_base; - } + for(int i=0; i>firstExponent; i--) { // only for firstExponent<0 + c=tmpCoeffs.cols(); + if (c>0) { + negExp += tmpCoeffs(0,0); + removeColumn(tmpCoeffs, 0); + } + negExp /= x_in-x_base; + } - for(int i=0; i0 - c = tmpCoeffs.cols(); - newCoeffs = Eigen::MatrixXd::Zero(r,c+1); - newCoeffs.block(0,1,r,c) = tmpCoeffs.block(0,0,r,c); - tmpCoeffs = Eigen::MatrixXd(newCoeffs); - } + for(int i=0; i0 + c = tmpCoeffs.cols(); + newCoeffs = Eigen::MatrixXd::Zero(r,c+1); + newCoeffs.block(0,1,r,c) = tmpCoeffs.block(0,0,r,c); + tmpCoeffs = Eigen::MatrixXd(newCoeffs); + } - c = tmpCoeffs.cols(); - if (c>0) posExp += Eigen::poly_eval( Eigen::RowVectorXd(tmpCoeffs), x_in-x_base ); - return negExp+posExp; + c = tmpCoeffs.cols(); + if (c>0) posExp += Eigen::poly_eval( Eigen::RowVectorXd(tmpCoeffs), x_in-x_base ); + return negExp+posExp; } /// @param coefficients vector containing the ordered coefficients @@ -500,46 +500,46 @@ double Polynomial2DFrac::evaluate(const Eigen::MatrixXd &coefficients, const dou /// @param x_base double value that represents the base value for a centred fit in the 1st dimension /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension double Polynomial2DFrac::evaluate(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - if ( (x_exp<0) && (std::abs(x_in-x_base)x_exp; i--) { // only for x_exp<0 - r = tmpCoeffs.rows(); - if (r>0) { - negExp += evaluate(tmpCoeffs.row(0), y_in, y_exp, y_base); - removeRow(tmpCoeffs, 0); - } - negExp /= x_in-x_base; - } + for(int i=0; i>x_exp; i--) { // only for x_exp<0 + r = tmpCoeffs.rows(); + if (r>0) { + negExp += evaluate(tmpCoeffs.row(0), y_in, y_exp, y_base); + removeRow(tmpCoeffs, 0); + } + negExp /= x_in-x_base; + } - r = tmpCoeffs.rows(); - for(int i=0; i0 - newCoeffs = Eigen::MatrixXd::Zero(r+1,c); - newCoeffs.block(1,0,r,c) = tmpCoeffs.block(0,0,r,c); - tmpCoeffs = Eigen::MatrixXd(newCoeffs); - r += 1; // r = tmpCoeffs.rows(); - } + r = tmpCoeffs.rows(); + for(int i=0; i0 + newCoeffs = Eigen::MatrixXd::Zero(r+1,c); + newCoeffs.block(1,0,r,c) = tmpCoeffs.block(0,0,r,c); + tmpCoeffs = Eigen::MatrixXd(newCoeffs); + r += 1; // r = tmpCoeffs.rows(); + } - //r = tmpCoeffs.rows(); - if (r>0) posExp += evaluate(tmpCoeffs.row(r-1), y_in, y_exp, y_base); - for(int i=r-2; i>=0; i--) { - posExp *= x_in-x_base; - posExp += evaluate(tmpCoeffs.row(i), y_in, y_exp, y_base); - } - if (this->do_debug()) std::cout << "Running 2D evaluate(" << mat_to_string(coefficients) << ", " << std::endl; - if (this->do_debug()) std::cout << "x_in:" << vec_to_string(x_in) << ", y_in:" << vec_to_string(y_in) << ", x_exp:" << vec_to_string(x_exp) << ", y_exp:" << vec_to_string(y_exp) << ", x_base:" << vec_to_string(x_base) << ", y_base:" << vec_to_string(y_base) << "): " << negExp+posExp << std::endl; - return negExp+posExp; + //r = tmpCoeffs.rows(); + if (r>0) posExp += evaluate(tmpCoeffs.row(r-1), y_in, y_exp, y_base); + for(int i=r-2; i>=0; i--) { + posExp *= x_in-x_base; + posExp += evaluate(tmpCoeffs.row(i), y_in, y_exp, y_base); + } + if (this->do_debug()) std::cout << "Running 2D evaluate(" << mat_to_string(coefficients) << ", " << std::endl; + if (this->do_debug()) std::cout << "x_in:" << vec_to_string(x_in) << ", y_in:" << vec_to_string(y_in) << ", x_exp:" << vec_to_string(x_exp) << ", y_exp:" << vec_to_string(y_exp) << ", x_base:" << vec_to_string(x_base) << ", y_base:" << vec_to_string(y_base) << "): " << negExp+posExp << std::endl; + return negExp+posExp; } @@ -552,40 +552,40 @@ double Polynomial2DFrac::evaluate(const Eigen::MatrixXd &coefficients, const dou /// @param x_base double value that represents the base value for a centred fit in the 1st dimension /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension double Polynomial2DFrac::derivative(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - Eigen::MatrixXd newCoefficients; - int der_exp,other_exp; - double der_val,other_val; - double int_base, other_base; + Eigen::MatrixXd newCoefficients; + int der_exp,other_exp; + double der_val,other_val; + double int_base, other_base; - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - der_exp = x_exp; - other_exp = y_exp; - der_val = x_in; - other_val = y_in; - int_base = x_base; - other_base = y_base; - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - der_exp = y_exp; - other_exp = x_exp; - der_val = y_in; - other_val = x_in; - int_base = y_base; - other_base = x_base; - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + der_exp = x_exp; + other_exp = y_exp; + der_val = x_in; + other_val = y_in; + int_base = x_base; + other_base = y_base; + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + der_exp = y_exp; + other_exp = x_exp; + der_val = y_in; + other_val = x_in; + int_base = y_base; + other_base = x_base; + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - const int times = 1; - newCoefficients = deriveCoeffs(newCoefficients,0,times,der_exp); - der_exp -= times; + const int times = 1; + newCoefficients = deriveCoeffs(newCoefficients,0,times,der_exp); + der_exp -= times; - return evaluate(newCoefficients,der_val,other_val,der_exp,other_exp,int_base,other_base); + return evaluate(newCoefficients,der_val,other_val,der_exp,other_exp,int_base,other_base); } /// @param coefficients vector containing the ordered coefficients @@ -598,67 +598,67 @@ double Polynomial2DFrac::derivative(const Eigen::MatrixXd &coefficients, const d /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension double Polynomial2DFrac::integral(const Eigen::MatrixXd &coefficients, const double &x_in, const double &y_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - Eigen::MatrixXd newCoefficients; - int int_exp,other_exp; - double int_val,other_val; - double int_base, other_base; + Eigen::MatrixXd newCoefficients; + int int_exp,other_exp; + double int_val,other_val; + double int_base, other_base; - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - int_exp = x_exp; - other_exp = y_exp; - int_val = x_in; - other_val = y_in; - int_base = x_base; - other_base = y_base; - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - int_exp = y_exp; - other_exp = x_exp; - int_val = y_in; - other_val = x_in; - int_base = y_base; - other_base = x_base; - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + int_exp = x_exp; + other_exp = y_exp; + int_val = x_in; + other_val = y_in; + int_base = x_base; + other_base = y_base; + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + int_exp = y_exp; + other_exp = x_exp; + int_val = y_in; + other_val = x_in; + int_base = y_base; + other_base = x_base; + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for integration, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - if (int_exp<-1) throw NotImplementedError(format("%s (%d): This function is only implemented for lowest exponents >= -1, int_exp=%d ",__FILE__,__LINE__,int_exp)); + if (int_exp<-1) throw NotImplementedError(format("%s (%d): This function is only implemented for lowest exponents >= -1, int_exp=%d ",__FILE__,__LINE__,int_exp)); - size_t r = newCoefficients.rows(); - size_t c = newCoefficients.cols(); + size_t r = newCoefficients.rows(); + size_t c = newCoefficients.cols(); - if (int_exp==-1) { - if (std::abs(int_base)0 - tmpCoeffs = Eigen::MatrixXd::Zero(r+1,c); - tmpCoeffs.block(1,0,r,c) = newCoefficients.block(0,0,r,c); - newCoefficients = Eigen::MatrixXd(tmpCoeffs); - r += 1; // r = newCoefficients.rows(); - } + Eigen::MatrixXd tmpCoeffs; + r = newCoefficients.rows(); + for(int i=0; i0 + tmpCoeffs = Eigen::MatrixXd::Zero(r+1,c); + tmpCoeffs.block(1,0,r,c) = newCoefficients.block(0,0,r,c); + newCoefficients = Eigen::MatrixXd(tmpCoeffs); + r += 1; // r = newCoefficients.rows(); + } - return evaluate(integrateCoeffs(newCoefficients, 0, 1),int_val,other_val,0,other_exp,int_base,other_base); + return evaluate(integrateCoeffs(newCoefficients, 0, 1),int_val,other_val,0,other_exp,int_base,other_base); } @@ -673,56 +673,56 @@ double Polynomial2DFrac::integral(const Eigen::MatrixXd &coefficients, const dou /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension Eigen::VectorXd Polynomial2DFrac::solve(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - Eigen::MatrixXd newCoefficients; - Eigen::VectorXd tmpCoefficients; - int solve_exp,other_exp; - double input; + Eigen::MatrixXd newCoefficients; + Eigen::VectorXd tmpCoefficients; + int solve_exp,other_exp; + double input; - switch (axis) { - case 0: - newCoefficients = Eigen::MatrixXd(coefficients); - solve_exp = x_exp; - other_exp = y_exp; - input = in - y_base; - break; - case 1: - newCoefficients = Eigen::MatrixXd(coefficients.transpose()); - solve_exp = y_exp; - other_exp = x_exp; - input = in - x_base; - break; - default: - throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for the solver, %d is not valid. ",__FILE__,__LINE__,axis)); - break; - } + switch (axis) { + case 0: + newCoefficients = Eigen::MatrixXd(coefficients); + solve_exp = x_exp; + other_exp = y_exp; + input = in - y_base; + break; + case 1: + newCoefficients = Eigen::MatrixXd(coefficients.transpose()); + solve_exp = y_exp; + other_exp = x_exp; + input = in - x_base; + break; + default: + throw ValueError(format("%s (%d): You have to provide a dimension, 0 or 1, for the solver, %d is not valid. ",__FILE__,__LINE__,axis)); + break; + } - if (this->do_debug()) std::cout << "Coefficients: " << mat_to_string(Eigen::MatrixXd(newCoefficients)) << std::endl; + if (this->do_debug()) std::cout << "Coefficients: " << mat_to_string(Eigen::MatrixXd(newCoefficients)) << std::endl; - const size_t r = newCoefficients.rows(); - for(size_t i=0; i=0) { // extend vector to zero exponent - tmpCoefficients = Eigen::VectorXd::Zero(r+solve_exp); - tmpCoefficients.block(solve_exp,0,r,1) = newCoefficients.block(0,0,r,1); - tmpCoefficients(0,0) -= z_in; - } else {// check if vector reaches to zero exponent - int diff = 1 - r - solve_exp; // How many entries have to be added - tmpCoefficients = Eigen::VectorXd::Zero(r+std::max(diff,0)); - tmpCoefficients.block(0,0,r,1) = newCoefficients.block(0,0,r,1); - tmpCoefficients(r+diff-1,0) -= z_in; - throw NotImplementedError(format("%s (%d): Currently, there is no solver for the generalised polynomial, an exponent of %d is not valid. ",__FILE__,__LINE__,solve_exp)); - } + //Eigen::VectorXd tmpCoefficients; + if (solve_exp>=0) { // extend vector to zero exponent + tmpCoefficients = Eigen::VectorXd::Zero(r+solve_exp); + tmpCoefficients.block(solve_exp,0,r,1) = newCoefficients.block(0,0,r,1); + tmpCoefficients(0,0) -= z_in; + } else {// check if vector reaches to zero exponent + int diff = 1 - r - solve_exp; // How many entries have to be added + tmpCoefficients = Eigen::VectorXd::Zero(r+std::max(diff,0)); + tmpCoefficients.block(0,0,r,1) = newCoefficients.block(0,0,r,1); + tmpCoefficients(r+diff-1,0) -= z_in; + throw NotImplementedError(format("%s (%d): Currently, there is no solver for the generalised polynomial, an exponent of %d is not valid. ",__FILE__,__LINE__,solve_exp)); + } - if (this->do_debug()) std::cout << "Coefficients: " << mat_to_string( Eigen::MatrixXd(tmpCoefficients) ) << std::endl; - Eigen::PolynomialSolver polySolver( tmpCoefficients ); - std::vector rootsVec; - polySolver.realRoots(rootsVec); - if (this->do_debug()) std::cout << "Real roots: " << vec_to_string(rootsVec) << std::endl; - return vec_to_eigen(rootsVec); - //return rootsVec[0]; // TODO: implement root selection algorithm + if (this->do_debug()) std::cout << "Coefficients: " << mat_to_string( Eigen::MatrixXd(tmpCoefficients) ) << std::endl; + Eigen::PolynomialSolver polySolver( tmpCoefficients ); + std::vector rootsVec; + polySolver.realRoots(rootsVec); + if (this->do_debug()) std::cout << "Real roots: " << vec_to_string(rootsVec) << std::endl; + return vec_to_eigen(rootsVec); + //return rootsVec[0]; // TODO: implement root selection algorithm } /// Uses the Brent solver to find the roots of p(x_in,y_in)-z_in @@ -737,9 +737,9 @@ Eigen::VectorXd Polynomial2DFrac::solve(const Eigen::MatrixXd &coefficients, con /// @param x_base double value that represents the base value for a centred fit in the 1st dimension /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension double Polynomial2DFrac::solve_limits(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - if (do_debug()) std::cout << format("Called solve_limits with: %f, %f, %f, %f, %d, %d, %d, %f, %f",in, z_in, min, max, axis, x_exp, y_exp, x_base, y_base) << std::endl; - Poly2DFracResidual res = Poly2DFracResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base); - return Polynomial2D::solve_limits(&res, min, max); + if (do_debug()) std::cout << format("Called solve_limits with: %f, %f, %f, %f, %d, %d, %d, %f, %f",in, z_in, min, max, axis, x_exp, y_exp, x_base, y_base) << std::endl; + Poly2DFracResidual res = Poly2DFracResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base); + return Polynomial2D::solve_limits(&res, min, max); } //TODO: Implement tests for this solver /// Uses the Newton solver to find the roots of p(x_in,y_in)-z_in @@ -753,9 +753,9 @@ double Polynomial2DFrac::solve_limits(const Eigen::MatrixXd &coefficients, const /// @param x_base double value that represents the base value for a centred fit in the 1st dimension /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension double Polynomial2DFrac::solve_guess(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base){ - if (do_debug()) std::cout << format("Called solve_guess with: %f, %f, %f, %d, %d, %d, %f, %f",in, z_in, guess, axis, x_exp, y_exp, x_base, y_base) << std::endl; - Poly2DFracResidual res = Poly2DFracResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base); - return Polynomial2D::solve_guess(&res, guess); + if (do_debug()) std::cout << format("Called solve_guess with: %f, %f, %f, %d, %d, %d, %f, %f",in, z_in, guess, axis, x_exp, y_exp, x_base, y_base) << std::endl; + Poly2DFracResidual res = Poly2DFracResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base); + return Polynomial2D::solve_guess(&res, guess); } //TODO: Implement tests for this solver /// Uses the Brent solver to find the roots of Int(p(x_in,y_in))-z_in @@ -771,8 +771,8 @@ double Polynomial2DFrac::solve_guess(const Eigen::MatrixXd &coefficients, const /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension /// @param int_axis axis for the integration (0=x, 1=y) double Polynomial2DFrac::solve_limitsInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &min, const double &max, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base, const int &int_axis){ - Poly2DFracIntResidual res = Poly2DFracIntResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base, int_axis); - return Polynomial2D::solve_limits(&res, min, max); + Poly2DFracIntResidual res = Poly2DFracIntResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base, int_axis); + return Polynomial2D::solve_limits(&res, min, max); } //TODO: Implement tests for this solver /// Uses the Newton solver to find the roots of Int(p(x_in,y_in))-z_in @@ -787,8 +787,8 @@ double Polynomial2DFrac::solve_limitsInt(const Eigen::MatrixXd &coefficients, co /// @param y_base double value that represents the base value for a centred fit in the 2nd dimension /// @param int_axis axis for the integration (0=x, 1=y) double Polynomial2DFrac::solve_guessInt(const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const double &guess, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base, const int &int_axis){ - Poly2DFracIntResidual res = Poly2DFracIntResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base, int_axis); - return Polynomial2D::solve_guess(&res, guess); + Poly2DFracIntResidual res = Poly2DFracIntResidual(*this, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base, int_axis); + return Polynomial2D::solve_guess(&res, guess); } //TODO: Implement tests for this solver @@ -806,7 +806,7 @@ double Polynomial2DFrac::solve_guessInt(const Eigen::MatrixXd &coefficients, con //http://rosettacode.org/wiki/Evaluate_binomial_coefficients#C.2B.2B /// @param nValue integer value that represents the order of the factorial double Polynomial2DFrac::factorial(const int &nValue){ - double value = 1; + double value = 1; for(int i = 2; i <= nValue; i++) value = value * i; return value; } @@ -821,74 +821,74 @@ double Polynomial2DFrac::binom(const int &nValue, const int &nValue2){ /// @param x_in double value that represents the current input /// @param x_base double value that represents the basis for the fit Eigen::MatrixXd Polynomial2DFrac::fracIntCentralDvector(const int &m, const double &x_in, const double &x_base){ - if (m<1) throw ValueError(format("%s (%d): You have to provide coefficients, a vector length of %d is not a valid. ",__FILE__,__LINE__,m)); + if (m<1) throw ValueError(format("%s (%d): You have to provide coefficients, a vector length of %d is not a valid. ",__FILE__,__LINE__,m)); - Eigen::MatrixXd D = Eigen::MatrixXd::Zero(1,m); - double tmp; - // TODO: This can be optimized using the Horner scheme! - for (int j=0; jdo_debug()) std::cout << "Running fracIntCentral(" << mat_to_string(coefficients) << ", " << vec_to_string(x_in) << ", " << vec_to_string(x_base) << "): " << result << std::endl; - return result; + if (coefficients.rows() != 1) { + throw ValueError(format("%s (%d): You have a 2D coefficient matrix (%d,%d), please use the 2D functions. ",__FILE__,__LINE__,coefficients.rows(),coefficients.cols())); + } + int m = coefficients.cols(); + Eigen::MatrixXd D = fracIntCentralDvector(m, x_in, x_base); + double result = 0; + for(int j=0; jdo_debug()) std::cout << "Running fracIntCentral(" << mat_to_string(coefficients) << ", " << vec_to_string(x_in) << ", " << vec_to_string(x_base) << "): " << result << std::endl; + return result; } Poly2DFracResidual::Poly2DFracResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base) : Poly2DResidual(poly, coefficients, in, z_in, axis){ - this->x_exp = x_exp; - this->y_exp = y_exp; - this->x_base = x_base; - this->y_base = y_base; + this->x_exp = x_exp; + this->y_exp = y_exp; + this->x_base = x_base; + this->y_base = y_base; } double Poly2DFracResidual::call(double target){ - if (axis==iX) return poly.evaluate(coefficients,target,in,x_exp,y_exp,x_base,y_base)-z_in; - if (axis==iY) return poly.evaluate(coefficients,in,target,x_exp,y_exp,x_base,y_base)-z_in; - return _HUGE; + if (axis==iX) return poly.evaluate(coefficients,target,in,x_exp,y_exp,x_base,y_base)-z_in; + if (axis==iY) return poly.evaluate(coefficients,in,target,x_exp,y_exp,x_base,y_base)-z_in; + return _HUGE; } double Poly2DFracResidual::deriv(double target){ - if (axis==iX) return poly.derivative(coefficients,target,in,axis,x_exp,y_exp,x_base,y_base); - if (axis==iY) return poly.derivative(coefficients,in,target,axis,x_exp,y_exp,x_base,y_base); - return _HUGE; + if (axis==iX) return poly.derivative(coefficients,target,in,axis,x_exp,y_exp,x_base,y_base); + if (axis==iY) return poly.derivative(coefficients,in,target,axis,x_exp,y_exp,x_base,y_base); + return _HUGE; } Poly2DFracIntResidual::Poly2DFracIntResidual(Polynomial2DFrac &poly, const Eigen::MatrixXd &coefficients, const double &in, const double &z_in, const int &axis, const int &x_exp, const int &y_exp, const double &x_base, const double &y_base, const int &int_axis) : Poly2DFracResidual(poly, coefficients, in, z_in, axis, x_exp, y_exp, x_base, y_base){ - this->int_axis = int_axis; + this->int_axis = int_axis; } double Poly2DFracIntResidual::call(double target){ - if (axis==iX) return poly.integral(coefficients,target,in,int_axis,x_exp,y_exp,x_base,y_base)-z_in; - if (axis==iY) return poly.integral(coefficients,in,target,int_axis,x_exp,y_exp,x_base,y_base)-z_in; - return _HUGE; + if (axis==iX) return poly.integral(coefficients,target,in,int_axis,x_exp,y_exp,x_base,y_base)-z_in; + if (axis==iY) return poly.integral(coefficients,in,target,int_axis,x_exp,y_exp,x_base,y_base)-z_in; + return _HUGE; } double Poly2DFracIntResidual::deriv(double target){ - if (axis==iX) return poly.evaluate(coefficients,target,in,x_exp,y_exp,x_base,y_base); - if (axis==iY) return poly.evaluate(coefficients,in,target,x_exp,y_exp,x_base,y_base); - return _HUGE; + if (axis==iX) return poly.evaluate(coefficients,target,in,x_exp,y_exp,x_base,y_base); + if (axis==iY) return poly.evaluate(coefficients,in,target,x_exp,y_exp,x_base,y_base); + return _HUGE; } @@ -904,464 +904,464 @@ double Poly2DFracIntResidual::deriv(double target){ TEST_CASE("Internal consistency checks and example use cases for PolyMath.cpp","[PolyMath]") { - bool PRINT = false; - std::string tmpStr; + bool PRINT = false; + std::string tmpStr; - /// Test case for "SylthermXLT" by "Dow Chemicals" - std::vector cHeat; - cHeat.clear(); - cHeat.push_back(+1.1562261074E+03); - cHeat.push_back(+2.0994549103E+00); - cHeat.push_back(+7.7175381057E-07); - cHeat.push_back(-3.7008444051E-20); + /// Test case for "SylthermXLT" by "Dow Chemicals" + std::vector cHeat; + cHeat.clear(); + cHeat.push_back(+1.1562261074E+03); + cHeat.push_back(+2.0994549103E+00); + cHeat.push_back(+7.7175381057E-07); + cHeat.push_back(-3.7008444051E-20); - double deltaT = 0.1; - double Tmin = 273.15- 50; - double Tmax = 273.15+250; - double Tinc = 200; + double deltaT = 0.1; + double Tmin = 273.15- 50; + double Tmax = 273.15+250; + double Tinc = 200; - std::vector > cHeat2D; - cHeat2D.push_back(cHeat); - cHeat2D.push_back(cHeat); - cHeat2D.push_back(cHeat); + std::vector > cHeat2D; + cHeat2D.push_back(cHeat); + cHeat2D.push_back(cHeat); + cHeat2D.push_back(cHeat); - Eigen::MatrixXd matrix2D = CoolProp::vec_to_eigen(cHeat2D); + Eigen::MatrixXd matrix2D = CoolProp::vec_to_eigen(cHeat2D); - Eigen::MatrixXd matrix2Dtmp; - std::vector > vec2Dtmp; + Eigen::MatrixXd matrix2Dtmp; + std::vector > vec2Dtmp; - SECTION("Coefficient parsing") { - CoolProp::Polynomial2D poly; - CHECK_THROWS(poly.checkCoefficients(matrix2D,4,5)); - CHECK( poly.checkCoefficients(matrix2D,3,4) ); - } + SECTION("Coefficient parsing") { + CoolProp::Polynomial2D poly; + CHECK_THROWS(poly.checkCoefficients(matrix2D,4,5)); + CHECK( poly.checkCoefficients(matrix2D,3,4) ); + } - SECTION("Coefficient operations") { - Eigen::MatrixXd matrix; - CoolProp::Polynomial2D poly; + SECTION("Coefficient operations") { + Eigen::MatrixXd matrix; + CoolProp::Polynomial2D poly; - CHECK_THROWS(poly.integrateCoeffs(matrix2D)); + CHECK_THROWS(poly.integrateCoeffs(matrix2D)); - CHECK_NOTHROW(matrix = poly.integrateCoeffs(matrix2D, 0)); - tmpStr = CoolProp::mat_to_string(matrix2D); - if (PRINT) std::cout << tmpStr << std::endl; - tmpStr = CoolProp::mat_to_string(matrix); - if (PRINT) std::cout << tmpStr << std::endl << std::endl; + CHECK_NOTHROW(matrix = poly.integrateCoeffs(matrix2D, 0)); + tmpStr = CoolProp::mat_to_string(matrix2D); + if (PRINT) std::cout << tmpStr << std::endl; + tmpStr = CoolProp::mat_to_string(matrix); + if (PRINT) std::cout << tmpStr << std::endl << std::endl; - CHECK_NOTHROW(matrix = poly.integrateCoeffs(matrix2D, 1)); - tmpStr = CoolProp::mat_to_string(matrix2D); - if (PRINT) std::cout << tmpStr << std::endl; - tmpStr = CoolProp::mat_to_string(matrix); - if (PRINT) std::cout << tmpStr << std::endl << std::endl; + CHECK_NOTHROW(matrix = poly.integrateCoeffs(matrix2D, 1)); + tmpStr = CoolProp::mat_to_string(matrix2D); + if (PRINT) std::cout << tmpStr << std::endl; + tmpStr = CoolProp::mat_to_string(matrix); + if (PRINT) std::cout << tmpStr << std::endl << std::endl; - CHECK_THROWS(poly.deriveCoeffs(matrix2D)); + CHECK_THROWS(poly.deriveCoeffs(matrix2D)); - CHECK_NOTHROW(matrix = poly.deriveCoeffs(matrix2D, 0)); - tmpStr = CoolProp::mat_to_string(matrix2D); - if (PRINT) std::cout << tmpStr << std::endl; - tmpStr = CoolProp::mat_to_string(matrix); - if (PRINT) std::cout << tmpStr << std::endl << std::endl; + CHECK_NOTHROW(matrix = poly.deriveCoeffs(matrix2D, 0)); + tmpStr = CoolProp::mat_to_string(matrix2D); + if (PRINT) std::cout << tmpStr << std::endl; + tmpStr = CoolProp::mat_to_string(matrix); + if (PRINT) std::cout << tmpStr << std::endl << std::endl; - CHECK_NOTHROW(matrix = poly.deriveCoeffs(matrix2D, 1)); - tmpStr = CoolProp::mat_to_string(matrix2D); - if (PRINT) std::cout << tmpStr << std::endl; - tmpStr = CoolProp::mat_to_string(matrix); - if (PRINT) std::cout << tmpStr << std::endl << std::endl; - } + CHECK_NOTHROW(matrix = poly.deriveCoeffs(matrix2D, 1)); + tmpStr = CoolProp::mat_to_string(matrix2D); + if (PRINT) std::cout << tmpStr << std::endl; + tmpStr = CoolProp::mat_to_string(matrix); + if (PRINT) std::cout << tmpStr << std::endl << std::endl; + } - SECTION("Evaluation and test values"){ + SECTION("Evaluation and test values"){ - Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(cHeat); - CoolProp::Polynomial2D poly; + Eigen::MatrixXd matrix = CoolProp::vec_to_eigen(cHeat); + CoolProp::Polynomial2D poly; - double acc = 0.0001; + double acc = 0.0001; - double T = 273.15+50; - double c = poly.evaluate(matrix, T, 0.0); - double d = 1834.746; + double T = 273.15+50; + double c = poly.evaluate(matrix, T, 0.0); + double d = 1834.746; - { - CAPTURE(T); - CAPTURE(c); - CAPTURE(d); - tmpStr = CoolProp::mat_to_string(matrix); - CAPTURE(tmpStr); - CHECK( check_abs(c,d,acc) ); - } + { + CAPTURE(T); + CAPTURE(c); + CAPTURE(d); + tmpStr = CoolProp::mat_to_string(matrix); + CAPTURE(tmpStr); + CHECK( check_abs(c,d,acc) ); + } - c = 2.0; - c = poly.solve(matrix, 0.0, d, 0)[0]; - { - CAPTURE(T); - CAPTURE(c); - CAPTURE(d); - CHECK( check_abs(c,T,acc) ); - } + c = 2.0; + c = poly.solve(matrix, 0.0, d, 0)[0]; + { + CAPTURE(T); + CAPTURE(c); + CAPTURE(d); + CHECK( check_abs(c,T,acc) ); + } - c = 2.0; - c = poly.solve_limits(matrix, 0.0, d, -50, 750, 0); - { - CAPTURE(T); - CAPTURE(c); - CAPTURE(d); - CHECK( check_abs(c,T,acc) ); - } + c = 2.0; + c = poly.solve_limits(matrix, 0.0, d, -50, 750, 0); + { + CAPTURE(T); + CAPTURE(c); + CAPTURE(d); + CHECK( check_abs(c,T,acc) ); + } - c = 2.0; - c = poly.solve_guess(matrix, 0.0, d, 350, 0); - { - CAPTURE(T); - CAPTURE(c); - CAPTURE(d); - CHECK( check_abs(c,T,acc) ); - } + c = 2.0; + c = poly.solve_guess(matrix, 0.0, d, 350, 0); + { + CAPTURE(T); + CAPTURE(c); + CAPTURE(d); + CHECK( check_abs(c,T,acc) ); + } -// T = 0.0; -// solve.setGuess(75+273.15); -// T = solve.polyval(cHeat,c); -// printf("Should be : T = %3.3f \t K \n",273.15+50.0); -// printf("From object: T = %3.3f \t K \n",T); +// T = 0.0; +// solve.setGuess(75+273.15); +// T = solve.polyval(cHeat,c); +// printf("Should be : T = %3.3f \t K \n",273.15+50.0); +// printf("From object: T = %3.3f \t K \n",T); // -// T = 0.0; -// solve.setLimits(273.15+10,273.15+100); -// T = solve.polyval(cHeat,c); -// printf("Should be : T = %3.3f \t K \n",273.15+50.0); -// printf("From object: T = %3.3f \t K \n",T); +// T = 0.0; +// solve.setLimits(273.15+10,273.15+100); +// T = solve.polyval(cHeat,c); +// printf("Should be : T = %3.3f \t K \n",273.15+50.0); +// printf("From object: T = %3.3f \t K \n",T); - } + } - SECTION("Integration and derivation tests") { + SECTION("Integration and derivation tests") { - CoolProp::Polynomial2D poly; + CoolProp::Polynomial2D poly; - Eigen::MatrixXd matrix(matrix2D); - Eigen::MatrixXd matrixInt = poly.integrateCoeffs(matrix, 1); - Eigen::MatrixXd matrixDer = poly.deriveCoeffs(matrix, 1); - Eigen::MatrixXd matrixInt2 = poly.integrateCoeffs(matrix, 1, 2); - Eigen::MatrixXd matrixDer2 = poly.deriveCoeffs(matrix, 1, 2); + Eigen::MatrixXd matrix(matrix2D); + Eigen::MatrixXd matrixInt = poly.integrateCoeffs(matrix, 1); + Eigen::MatrixXd matrixDer = poly.deriveCoeffs(matrix, 1); + Eigen::MatrixXd matrixInt2 = poly.integrateCoeffs(matrix, 1, 2); + Eigen::MatrixXd matrixDer2 = poly.deriveCoeffs(matrix, 1, 2); - CHECK_THROWS( poly.evaluate(matrix,0.0) ); + CHECK_THROWS( poly.evaluate(matrix,0.0) ); - double x = 0.3, y = 255.3, val1, val2, val3, val4; + double x = 0.3, y = 255.3, val1, val2, val3, val4; - //CHECK( std::abs( polyInt.derivative(x,y,0)-poly2D.evaluate(x,y) ) <= 1e-10 ); + //CHECK( std::abs( polyInt.derivative(x,y,0)-poly2D.evaluate(x,y) ) <= 1e-10 ); - std::string tmpStr; + std::string tmpStr; - double acc = 0.001; + double acc = 0.001; - for (double T = Tmin; T NDNewtonRaphson_Jacobian(FuncWrapperND *f, std::vector x0, double tol, int maxiter, std::string *errstring) { - int iter=0; - *errstring=std::string(""); - std::vector f0,v,negative_f0; - std::vector > J; - double error = 999; - while (iter==0 || std::abs(error)>tol){ - f0 = f->call(x0); - J = f->Jacobian(x0); + int iter=0; + *errstring=std::string(""); + std::vector f0,v,negative_f0; + std::vector > J; + double error = 999; + while (iter==0 || std::abs(error)>tol){ + f0 = f->call(x0); + J = f->Jacobian(x0); - // Negate f0 - negative_f0 = f0; - for (unsigned int i = 0; imaxiter){ - *errstring=std::string("reached maximum number of iterations"); - x0[0]=_HUGE; - } - iter++; - } - return x0; + // Negate f0 + negative_f0 = f0; + for (unsigned int i = 0; imaxiter){ + *errstring=std::string("reached maximum number of iterations"); + x0[0]=_HUGE; + } + iter++; + } + return x0; } /** @@ -64,31 +64,31 @@ In the newton function, a 1-D Newton-Raphson solver is implemented using exact s */ double Newton(FuncWrapper1D* f, double x0, double ftol, int maxiter, std::string &errstring) { - double x, dx, fval=999; + double x, dx, fval=999; int iter=1; errstring.clear(); - x = x0; + x = x0; while (iter < 2 || std::abs(fval) > ftol) { - fval = f->call(x); - dx = -fval/f->deriv(x); + fval = f->call(x); + dx = -fval/f->deriv(x); - if (!ValidNumber(fval)){ + if (!ValidNumber(fval)){ throw ValueError("Residual function in newton returned invalid number"); }; x += dx; - if (std::abs(dx/x) < 10*DBL_EPSILON) - { - return x; - } + if (std::abs(dx/x) < 10*DBL_EPSILON) + { + return x; + } - if (iter>maxiter) - { - errstring= "reached maximum number of iterations"; - throw SolutionError(format("Newton reached maximum number of iterations")); - } + if (iter>maxiter) + { + errstring= "reached maximum number of iterations"; + throw SolutionError(format("Newton reached maximum number of iterations")); + } iter=iter+1; } return x; @@ -112,11 +112,11 @@ double Secant(FuncWrapper1D* f, double x0, double dx, double tol, int maxiter, s xlog.clear(); flog.clear(); #endif - double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999; + double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999; int iter=1; - errstring = ""; + errstring = ""; - if (std::abs(dx)==0){ errstring="dx cannot be zero"; return _HUGE;} + if (std::abs(dx)==0){ errstring="dx cannot be zero"; return _HUGE;} while (iter<=2 || std::abs(fval)>tol) { if (iter==1){x1=x0; x=x1;} @@ -136,28 +136,28 @@ double Secant(FuncWrapper1D* f, double x0, double dx, double tol, int maxiter, s if (iter==1){y1=fval;} if (iter>1) { - double deltax = x2-x1; - if (std::abs(deltax)<1e-14) - { - if (std::abs(fval) < tol*10) - { - return x; - } - else - { - throw ValueError("Step is small but not solved to tolerance"); - } - } + double deltax = x2-x1; + if (std::abs(deltax)<1e-14) + { + if (std::abs(fval) < tol*10) + { + return x; + } + else + { + throw ValueError("Step is small but not solved to tolerance"); + } + } y2=fval; x3=x2-y2/(y2-y1)*(x2-x1); y1=y2; x1=x2; x2=x3; } - if (iter>maxiter) - { - errstring=std::string("reached maximum number of iterations"); - throw SolutionError(format("Secant reached maximum number of iterations")); - } + if (iter>maxiter) + { + errstring=std::string("reached maximum number of iterations"); + throw SolutionError(format("Secant reached maximum number of iterations")); + } iter=iter+1; } return x3; @@ -178,39 +178,39 @@ In the secant function, a 1-D Newton-Raphson solver is implemented. An initial */ double BoundedSecant(FuncWrapper1D* f, double x0, double xmin, double xmax, double dx, double tol, int maxiter, std::string &errstring) { - double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999; + double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999; int iter=1; - errstring = ""; + errstring = ""; - if (std::abs(dx)==0){ errstring = "dx cannot be zero"; return _HUGE;} + if (std::abs(dx)==0){ errstring = "dx cannot be zero"; return _HUGE;} while (iter<=3 || std::abs(fval)>tol) { if (iter==1){x1=x0; x=x1;} else if (iter==2){x2=x0+dx; x=x2;} else {x=x2;} - fval=f->call(x); + fval=f->call(x); if (iter==1){y1=fval;} else { y2=fval; x3=x2-y2/(y2-y1)*(x2-x1); - // Check bounds, go half the way to the limit if limit is exceeded - if (x3 < xmin) - { - x3 = (xmin + x2)/2; - } - if (x3 > xmax) - { - x3 = (xmax + x2)/2; - } + // Check bounds, go half the way to the limit if limit is exceeded + if (x3 < xmin) + { + x3 = (xmin + x2)/2; + } + if (x3 > xmax) + { + x3 = (xmax + x2)/2; + } y1=y2; x1=x2; x2=x3; } - if (iter>maxiter) - { - errstring = "reached maximum number of iterations"; - throw SolutionError(format("BoundedSecant reached maximum number of iterations")); - } + if (iter>maxiter) + { + errstring = "reached maximum number of iterations"; + throw SolutionError(format("BoundedSecant reached maximum number of iterations")); + } iter=iter+1; } return x3; @@ -234,29 +234,29 @@ at least one solution in the interval [a,b]. */ double Brent(FuncWrapper1D* f, double a, double b, double macheps, double t, int maxiter, std::string &errstr) { - int iter; + int iter; errstr.clear(); - double fa,fb,c,fc,m,tol,d,e,p,q,s,r; + double fa,fb,c,fc,m,tol,d,e,p,q,s,r; fa = f->call(a); fb = f->call(b); - // If one of the boundaries is to within tolerance, just stop - if (std::abs(fb) < t) { return b;} - if (!ValidNumber(fb)){ - throw ValueError(format("Brent's method f(b) is NAN for b = %g, other input was a = %g",b,a).c_str()); - } - if (std::abs(fa) < t) { return a;} - if (!ValidNumber(fa)){ - throw ValueError(format("Brent's method f(a) is NAN for a = %g, other input was b = %g",a,b).c_str()); - } - if (fa*fb>0){ - throw ValueError(format("Inputs in Brent [%f,%f] do not bracket the root. Function values are [%f,%f]",a,b,fa,fb)); - } + // If one of the boundaries is to within tolerance, just stop + if (std::abs(fb) < t) { return b;} + if (!ValidNumber(fb)){ + throw ValueError(format("Brent's method f(b) is NAN for b = %g, other input was a = %g",b,a).c_str()); + } + if (std::abs(fa) < t) { return a;} + if (!ValidNumber(fa)){ + throw ValueError(format("Brent's method f(a) is NAN for a = %g, other input was b = %g",a,b).c_str()); + } + if (fa*fb>0){ + throw ValueError(format("Inputs in Brent [%f,%f] do not bracket the root. Function values are [%f,%f]",a,b,fa,fb)); + } c=a; fc=fa; - iter=1; - if (std::abs(fc)tol && fb!=0){ + while (std::abs(m)>tol && fb!=0){ // See if a bisection is forced - if (std::abs(e)0){ - q=-q; - } - else{ - p=-p; - } + } + if (p>0){ + q=-q; + } + else{ + p=-p; + } s=e; e=d; m=0.5*(c-b); - if (2*p<3*m*q-std::abs(tol*q) || ptol){ + if (std::abs(d)>tol){ b+=d; - } + } else if (m>0){ b+=tol; - } - else{ + } + else{ b+=-tol; - } - fb=f->call(b); - if (!ValidNumber(fb)){ - throw ValueError(format("Brent's method f(t) is NAN for t = %g",b).c_str()); - } + } + fb=f->call(b); + if (!ValidNumber(fb)){ + throw ValueError(format("Brent's method f(t) is NAN for t = %g",b).c_str()); + } if (std::abs(fb) < macheps){ return b; } - if (fb*fc>0){ + if (fb*fc>0){ // Goto int: from Brent ALGOL code c=a; fc=fa; d=e=b-a; - } - if (std::abs(fc)maxiter){ - throw SolutionError(std::string("Brent's method reached maximum number of steps of %d ", maxiter));} + iter+=1; + if (!ValidNumber(a)){ + throw ValueError(format("Brent's method a is NAN").c_str());} + if (!ValidNumber(b)){ + throw ValueError(format("Brent's method b is NAN").c_str());} + if (!ValidNumber(c)){ + throw ValueError(format("Brent's method c is NAN").c_str());} + if (iter>maxiter){ + throw SolutionError(std::string("Brent's method reached maximum number of steps of %d ", maxiter));} if (std::abs(fb)< 2*macheps*std::abs(b)){ return b; } - } + } return b; } // Single-Dimensional solvers double Brent(FuncWrapper1D &f, double a, double b, double macheps, double t, int maxiter, std::string &errstr){ - return Brent(&f, a, b, macheps, t, maxiter, errstr); + return Brent(&f, a, b, macheps, t, maxiter, errstr); } double Secant(FuncWrapper1D &f, double x0, double dx, double ftol, int maxiter, std::string &errstring){ - return Secant(&f, x0, dx, ftol, maxiter, errstring); + return Secant(&f, x0, dx, ftol, maxiter, errstring); } double BoundedSecant(FuncWrapper1D &f, double x0, double xmin, double xmax, double dx, double ftol, int maxiter, std::string &errstring){ - return BoundedSecant(&f, x0, xmin, xmax, dx, ftol, maxiter, errstring); + return BoundedSecant(&f, x0, xmin, xmax, dx, ftol, maxiter, errstring); } double Newton(FuncWrapper1D &f, double x0, double ftol, int maxiter, std::string &errstring){ - return Newton(&f, x0, ftol, maxiter, errstring); + return Newton(&f, x0, ftol, maxiter, errstring); } }; /* namespace CoolProp */ diff --git a/src/Tests/TestObjects.cpp b/src/Tests/TestObjects.cpp index 9ee33bea..f549e7f4 100644 --- a/src/Tests/TestObjects.cpp +++ b/src/Tests/TestObjects.cpp @@ -13,206 +13,206 @@ #if defined ENABLE_CATCH Eigen::MatrixXd CoolPropTesting::makeMatrix(const std::vector &coefficients){ - //IncompressibleClass::checkCoefficients(coefficients,18); - std::vector< std::vector > matrix; - std::vector tmpVector; + //IncompressibleClass::checkCoefficients(coefficients,18); + std::vector< std::vector > matrix; + std::vector tmpVector; - tmpVector.clear(); - tmpVector.push_back(coefficients[0]); - tmpVector.push_back(coefficients[6]); - tmpVector.push_back(coefficients[11]); - tmpVector.push_back(coefficients[15]); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[0]); + tmpVector.push_back(coefficients[6]); + tmpVector.push_back(coefficients[11]); + tmpVector.push_back(coefficients[15]); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[1]*100.0); - tmpVector.push_back(coefficients[7]*100.0); - tmpVector.push_back(coefficients[12]*100.0); - tmpVector.push_back(coefficients[16]*100.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[1]*100.0); + tmpVector.push_back(coefficients[7]*100.0); + tmpVector.push_back(coefficients[12]*100.0); + tmpVector.push_back(coefficients[16]*100.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[2]*100.0*100.0); - tmpVector.push_back(coefficients[8]*100.0*100.0); - tmpVector.push_back(coefficients[13]*100.0*100.0); - tmpVector.push_back(coefficients[17]*100.0*100.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[2]*100.0*100.0); + tmpVector.push_back(coefficients[8]*100.0*100.0); + tmpVector.push_back(coefficients[13]*100.0*100.0); + tmpVector.push_back(coefficients[17]*100.0*100.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[3]*100.0*100.0*100.0); - tmpVector.push_back(coefficients[9]*100.0*100.0*100.0); - tmpVector.push_back(coefficients[14]*100.0*100.0*100.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[3]*100.0*100.0*100.0); + tmpVector.push_back(coefficients[9]*100.0*100.0*100.0); + tmpVector.push_back(coefficients[14]*100.0*100.0*100.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[4]*100.0*100.0*100.0*100.0); - tmpVector.push_back(coefficients[10]*100.0*100.0*100.0*100.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[4]*100.0*100.0*100.0*100.0); + tmpVector.push_back(coefficients[10]*100.0*100.0*100.0*100.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - tmpVector.push_back(coefficients[5]*100.0*100.0*100.0*100.0*100.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - tmpVector.push_back(0.0); - matrix.push_back(tmpVector); + tmpVector.clear(); + tmpVector.push_back(coefficients[5]*100.0*100.0*100.0*100.0*100.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + tmpVector.push_back(0.0); + matrix.push_back(tmpVector); - tmpVector.clear(); - return CoolProp::vec_to_eigen(matrix).transpose(); + tmpVector.clear(); + return CoolProp::vec_to_eigen(matrix).transpose(); } CoolProp::IncompressibleFluid CoolPropTesting::incompressibleFluidObject(){ - bool PRINT = false; - std::string tmpStr; - std::vector tmpVector; - std::vector< std::vector > tmpMatrix; + bool PRINT = false; + std::string tmpStr; + std::vector tmpVector; + std::vector< std::vector > tmpMatrix; - tmpVector.clear(); - tmpVector.push_back( 960.24665800); - tmpVector.push_back(-1.2903839100); - tmpVector.push_back(-0.0161042520); - tmpVector.push_back(-0.0001969888); - tmpVector.push_back( 1.131559E-05); - tmpVector.push_back( 9.181999E-08); - tmpVector.push_back(-0.4020348270); - tmpVector.push_back(-0.0162463989); - tmpVector.push_back( 0.0001623301); - tmpVector.push_back( 4.367343E-06); - tmpVector.push_back( 1.199000E-08); - tmpVector.push_back(-0.0025204776); - tmpVector.push_back( 0.0001101514); - tmpVector.push_back(-2.320217E-07); - tmpVector.push_back( 7.794999E-08); - tmpVector.push_back( 9.937483E-06); - tmpVector.push_back(-1.346886E-06); - tmpVector.push_back( 4.141999E-08); - CoolProp::IncompressibleData density; - density.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - density.coeffs = makeMatrix(tmpVector); + tmpVector.clear(); + tmpVector.push_back( 960.24665800); + tmpVector.push_back(-1.2903839100); + tmpVector.push_back(-0.0161042520); + tmpVector.push_back(-0.0001969888); + tmpVector.push_back( 1.131559E-05); + tmpVector.push_back( 9.181999E-08); + tmpVector.push_back(-0.4020348270); + tmpVector.push_back(-0.0162463989); + tmpVector.push_back( 0.0001623301); + tmpVector.push_back( 4.367343E-06); + tmpVector.push_back( 1.199000E-08); + tmpVector.push_back(-0.0025204776); + tmpVector.push_back( 0.0001101514); + tmpVector.push_back(-2.320217E-07); + tmpVector.push_back( 7.794999E-08); + tmpVector.push_back( 9.937483E-06); + tmpVector.push_back(-1.346886E-06); + tmpVector.push_back( 4.141999E-08); + CoolProp::IncompressibleData density; + density.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + density.coeffs = makeMatrix(tmpVector); - tmpVector.clear(); - tmpVector.push_back( 3822.9712300); - tmpVector.push_back(-23.122409500); - tmpVector.push_back( 0.0678775826); - tmpVector.push_back( 0.0022413893); - tmpVector.push_back(-0.0003045332); - tmpVector.push_back(-4.758000E-06); - tmpVector.push_back( 2.3501449500); - tmpVector.push_back( 0.1788839410); - tmpVector.push_back( 0.0006828000); - tmpVector.push_back( 0.0002101166); - tmpVector.push_back(-9.812000E-06); - tmpVector.push_back(-0.0004724176); - tmpVector.push_back(-0.0003317949); - tmpVector.push_back( 0.0001002032); - tmpVector.push_back(-5.306000E-06); - tmpVector.push_back( 4.242194E-05); - tmpVector.push_back( 2.347190E-05); - tmpVector.push_back(-1.894000E-06); - CoolProp::IncompressibleData specific_heat; - specific_heat.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - specific_heat.coeffs = makeMatrix(tmpVector); + tmpVector.clear(); + tmpVector.push_back( 3822.9712300); + tmpVector.push_back(-23.122409500); + tmpVector.push_back( 0.0678775826); + tmpVector.push_back( 0.0022413893); + tmpVector.push_back(-0.0003045332); + tmpVector.push_back(-4.758000E-06); + tmpVector.push_back( 2.3501449500); + tmpVector.push_back( 0.1788839410); + tmpVector.push_back( 0.0006828000); + tmpVector.push_back( 0.0002101166); + tmpVector.push_back(-9.812000E-06); + tmpVector.push_back(-0.0004724176); + tmpVector.push_back(-0.0003317949); + tmpVector.push_back( 0.0001002032); + tmpVector.push_back(-5.306000E-06); + tmpVector.push_back( 4.242194E-05); + tmpVector.push_back( 2.347190E-05); + tmpVector.push_back(-1.894000E-06); + CoolProp::IncompressibleData specific_heat; + specific_heat.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + specific_heat.coeffs = makeMatrix(tmpVector); - tmpVector.clear(); - tmpVector.push_back( 0.4082066700); - tmpVector.push_back(-0.0039816870); - tmpVector.push_back( 1.583368E-05); - tmpVector.push_back(-3.552049E-07); - tmpVector.push_back(-9.884176E-10); - tmpVector.push_back( 4.460000E-10); - tmpVector.push_back( 0.0006629321); - tmpVector.push_back(-2.686475E-05); - tmpVector.push_back( 9.039150E-07); - tmpVector.push_back(-2.128257E-08); - tmpVector.push_back(-5.562000E-10); - tmpVector.push_back( 3.685975E-07); - tmpVector.push_back( 7.188416E-08); - tmpVector.push_back(-1.041773E-08); - tmpVector.push_back( 2.278001E-10); - tmpVector.push_back( 4.703395E-08); - tmpVector.push_back( 7.612361E-11); - tmpVector.push_back(-2.734000E-10); - CoolProp::IncompressibleData conductivity; - conductivity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; - conductivity.coeffs = makeMatrix(tmpVector); + tmpVector.clear(); + tmpVector.push_back( 0.4082066700); + tmpVector.push_back(-0.0039816870); + tmpVector.push_back( 1.583368E-05); + tmpVector.push_back(-3.552049E-07); + tmpVector.push_back(-9.884176E-10); + tmpVector.push_back( 4.460000E-10); + tmpVector.push_back( 0.0006629321); + tmpVector.push_back(-2.686475E-05); + tmpVector.push_back( 9.039150E-07); + tmpVector.push_back(-2.128257E-08); + tmpVector.push_back(-5.562000E-10); + tmpVector.push_back( 3.685975E-07); + tmpVector.push_back( 7.188416E-08); + tmpVector.push_back(-1.041773E-08); + tmpVector.push_back( 2.278001E-10); + tmpVector.push_back( 4.703395E-08); + tmpVector.push_back( 7.612361E-11); + tmpVector.push_back(-2.734000E-10); + CoolProp::IncompressibleData conductivity; + conductivity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYNOMIAL; + conductivity.coeffs = makeMatrix(tmpVector); - tmpVector.clear(); - tmpVector.push_back( 1.4725525500); - tmpVector.push_back( 0.0022218998); - tmpVector.push_back(-0.0004406139); - tmpVector.push_back( 6.047984E-06); - tmpVector.push_back(-1.954730E-07); - tmpVector.push_back(-2.372000E-09); - tmpVector.push_back(-0.0411841566); - tmpVector.push_back( 0.0001784479); - tmpVector.push_back(-3.564413E-06); - tmpVector.push_back( 4.064671E-08); - tmpVector.push_back( 1.915000E-08); - tmpVector.push_back( 0.0002572862); - tmpVector.push_back(-9.226343E-07); - tmpVector.push_back(-2.178577E-08); - tmpVector.push_back(-9.529999E-10); - tmpVector.push_back(-1.699844E-06); - tmpVector.push_back(-1.023552E-07); - tmpVector.push_back( 4.482000E-09); - CoolProp::IncompressibleData viscosity; - viscosity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL; - viscosity.coeffs = makeMatrix(tmpVector); + tmpVector.clear(); + tmpVector.push_back( 1.4725525500); + tmpVector.push_back( 0.0022218998); + tmpVector.push_back(-0.0004406139); + tmpVector.push_back( 6.047984E-06); + tmpVector.push_back(-1.954730E-07); + tmpVector.push_back(-2.372000E-09); + tmpVector.push_back(-0.0411841566); + tmpVector.push_back( 0.0001784479); + tmpVector.push_back(-3.564413E-06); + tmpVector.push_back( 4.064671E-08); + tmpVector.push_back( 1.915000E-08); + tmpVector.push_back( 0.0002572862); + tmpVector.push_back(-9.226343E-07); + tmpVector.push_back(-2.178577E-08); + tmpVector.push_back(-9.529999E-10); + tmpVector.push_back(-1.699844E-06); + tmpVector.push_back(-1.023552E-07); + tmpVector.push_back( 4.482000E-09); + CoolProp::IncompressibleData viscosity; + viscosity.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_EXPPOLYNOMIAL; + viscosity.coeffs = makeMatrix(tmpVector); - tmpVector.clear(); - tmpVector.push_back( 27.755555600/100.0); // reference concentration in per cent - tmpVector.push_back(-22.973221700+273.15); - tmpVector.push_back(-1.1040507200*100.0); - tmpVector.push_back(-0.0120762281*100.0*100.0); - tmpVector.push_back(-9.343458E-05*100.0*100.0*100.0); - CoolProp::IncompressibleData T_freeze; - T_freeze.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYOFFSET; - T_freeze.coeffs = CoolProp::vec_to_eigen(tmpVector); - T_freeze.coeffs.transposeInPlace(); + tmpVector.clear(); + tmpVector.push_back( 27.755555600/100.0); // reference concentration in per cent + tmpVector.push_back(-22.973221700+273.15); + tmpVector.push_back(-1.1040507200*100.0); + tmpVector.push_back(-0.0120762281*100.0*100.0); + tmpVector.push_back(-9.343458E-05*100.0*100.0*100.0); + CoolProp::IncompressibleData T_freeze; + T_freeze.type = CoolProp::IncompressibleData::INCOMPRESSIBLE_POLYOFFSET; + T_freeze.coeffs = CoolProp::vec_to_eigen(tmpVector); + T_freeze.coeffs.transposeInPlace(); - // After preparing the coefficients, we have to create the objects - CoolProp::IncompressibleFluid CH3OH; - CH3OH.setName("CH3OH-testing"); - CH3OH.setDescription("Methanol solution"); - CH3OH.setReference("SecCool software"); - CH3OH.setTmax( 20 + 273.15); - CH3OH.setTmin(-50 + 273.15); - CH3OH.setxmax(0.5); - CH3OH.setxmin(0.0); - CH3OH.setxid(CoolProp::IFRAC_MASS); - CH3OH.setTminPsat( 20 + 273.15); + // After preparing the coefficients, we have to create the objects + CoolProp::IncompressibleFluid CH3OH; + CH3OH.setName("CH3OH-testing"); + CH3OH.setDescription("Methanol solution"); + CH3OH.setReference("SecCool software"); + CH3OH.setTmax( 20 + 273.15); + CH3OH.setTmin(-50 + 273.15); + CH3OH.setxmax(0.5); + CH3OH.setxmin(0.0); + CH3OH.setxid(CoolProp::IFRAC_MASS); + CH3OH.setTminPsat( 20 + 273.15); - CH3OH.setTbase(-4.48 + 273.15); - CH3OH.setxbase(31.57 / 100.0); + CH3OH.setTbase(-4.48 + 273.15); + CH3OH.setxbase(31.57 / 100.0); - /// Setters for the coefficients - CH3OH.setDensity(density); - CH3OH.setSpecificHeat(specific_heat); - CH3OH.setViscosity(viscosity); - CH3OH.setConductivity(conductivity); - //CH3OH.setPsat(saturation_pressure); - CH3OH.setTfreeze(T_freeze); - //CH3OH.setVolToMass(volume2mass); - //CH3OH.setMassToMole(mass2mole); + /// Setters for the coefficients + CH3OH.setDensity(density); + CH3OH.setSpecificHeat(specific_heat); + CH3OH.setViscosity(viscosity); + CH3OH.setConductivity(conductivity); + //CH3OH.setPsat(saturation_pressure); + CH3OH.setTfreeze(T_freeze); + //CH3OH.setVolToMass(volume2mass); + //CH3OH.setMassToMole(mass2mole); - //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); - double Tref = 20+273.15; - double pref = 101325; - double xref = 0.0; - double href = 0.0; - double sref = 0.0; - CH3OH.set_reference_state(Tref, pref, xref, href, sref); + //XLT.set_reference_state(25+273.15, 1.01325e5, 0.0, 0.0, 0.0); + double Tref = 20+273.15; + double pref = 101325; + double xref = 0.0; + double href = 0.0; + double sref = 0.0; + CH3OH.set_reference_state(Tref, pref, xref, href, sref); - /// A function to check coefficients and equation types. - CH3OH.validate(); + /// A function to check coefficients and equation types. + CH3OH.validate(); - return CH3OH; + return CH3OH; } //CoolProp::IncompressibleBackend CoolProp::Testing::incompressibleBackendObject(){ -// return CoolProp::IncompressibleBackend(CoolProp::Testing::incompressibleFluidObject()); +// return CoolProp::IncompressibleBackend(CoolProp::Testing::incompressibleFluidObject()); //} #endif // ENABLE_CATCH