From b9582a45e1766bf0c5009d592cbad2002ecc0728 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Fri, 6 Jun 2014 21:22:48 +0200 Subject: [PATCH] Added structure of incompressible library and backend - the core is there, implementation is empty. Signed-off-by: Ian Bell --- .gitignore | 4 + .../Incompressible/IncompressibleBackend.cpp | 10 +- .../Incompressible/IncompressibleBackend.h | 12 +- .../Incompressible/IncompressibleLibrary.cpp | 35 +++ .../Incompressible/IncompressibleLibrary.h | 203 ++++++++++++++++++ 5 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 src/Backends/Incompressible/IncompressibleLibrary.cpp create mode 100644 src/Backends/Incompressible/IncompressibleLibrary.h diff --git a/.gitignore b/.gitignore index eb139051..181667e4 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ /build/ /dev/hashes.json /include/cpversion.h +/dev/all_incompressibles.json +/dev/all_incompressibles_verbose.json +/include/IncompressibleFluid.h +/include/all_incompressibles_JSON.h diff --git a/src/Backends/Incompressible/IncompressibleBackend.cpp b/src/Backends/Incompressible/IncompressibleBackend.cpp index 5f46abea..fee4d67d 100644 --- a/src/Backends/Incompressible/IncompressibleBackend.cpp +++ b/src/Backends/Incompressible/IncompressibleBackend.cpp @@ -11,23 +11,21 @@ //#include "CoolProp.h" #include "IncompressibleBackend.h" -#include "../Helmholtz/Fluids/FluidLibrary.h" +#include "IncompressibleFluid.h" +#include "IncompressibleLibrary.h" #include "Solvers.h" #include "MatrixMath.h" namespace CoolProp { IncompressibleBackend::IncompressibleBackend(const std::string &fluid_name) { - throw CoolProp::NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids"); + fluid = &get_incompressible_fluid(fluid_name); } IncompressibleBackend::IncompressibleBackend(const std::vector &component_names) { - throw CoolProp::NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids"); + throw NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids"); } -bool IncompressibleBackend::using_mole_fractions(){return false;} - - void IncompressibleBackend::update(long input_pair, double value1, double value2) { switch (input_pair) { case PT_INPUTS: { diff --git a/src/Backends/Incompressible/IncompressibleBackend.h b/src/Backends/Incompressible/IncompressibleBackend.h index c4f788fa..f0db90f8 100644 --- a/src/Backends/Incompressible/IncompressibleBackend.h +++ b/src/Backends/Incompressible/IncompressibleBackend.h @@ -2,6 +2,7 @@ #ifndef INCOMPRESSIBLEBACKEND_H_ #define INCOMPRESSIBLEBACKEND_H_ +#include "IncompressibleFluid.h" #include "AbstractState.h" #include "Exceptions.h" @@ -15,6 +16,7 @@ protected: bool _mole_fractions_set; static bool _REFPROP_supported; std::vector mass_fractions; + IncompressibleFluid *fluid; public: IncompressibleBackend(){}; virtual ~IncompressibleBackend(){}; @@ -27,10 +29,10 @@ public: IncompressibleBackend(const std::vector &component_names); // Incompressible backend uses mole fractions - bool using_mole_fractions(); + bool using_mole_fractions(){return false;}; /// Updating function for incompressible fluid - /** + /** 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. @@ -41,13 +43,13 @@ public: void update(long input_pair, double value1, double value2); /// 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); diff --git a/src/Backends/Incompressible/IncompressibleLibrary.cpp b/src/Backends/Incompressible/IncompressibleLibrary.cpp new file mode 100644 index 00000000..70343e37 --- /dev/null +++ b/src/Backends/Incompressible/IncompressibleLibrary.cpp @@ -0,0 +1,35 @@ +#include "IncompressibleLibrary.h" +#include "all_incompressibles_JSON.h" // Makes a std::string variable called all_fluids_JSON + +namespace CoolProp{ + +static JSONIncompressibleLibrary library; + +void load_incompressible_library() +{ + 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_incompressibles_JSON.c_str()); + 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;} + } +} + +JSONIncompressibleLibrary & get_incompressible_library(void){ + if (library.is_empty()){ load_incompressible_library(); } + return library; +} + +IncompressibleFluid& get_incompressible_fluid(std::string fluid_string){ + if (library.is_empty()){ load_incompressible_library(); } + return library.get(fluid_string); +} + +std::string get_incompressible_list(void){ + if (library.is_empty()){ load_incompressible_library(); } + return library.get_fluid_list(); +}; + +} /* namespace CoolProp */ diff --git a/src/Backends/Incompressible/IncompressibleLibrary.h b/src/Backends/Incompressible/IncompressibleLibrary.h new file mode 100644 index 00000000..fe3fa41f --- /dev/null +++ b/src/Backends/Incompressible/IncompressibleLibrary.h @@ -0,0 +1,203 @@ + +#ifndef INCOMPRESSIBLELIBRARY_H +#define INCOMPRESSIBLELIBRARY_H + +#include "IncompressibleFluid.h" + +#include "rapidjson/rapidjson_include.h" + +#include +#include + +namespace CoolProp{ + +// Forward declaration of the necessary debug function to avoid including the whole header +extern int get_debug_level(); + +/// A container for the fluid parameters for the incompressible fluids +/** +This container holds copies of all of the fluid instances for the fluids that are loaded in incompressible. +New fluids can be added by passing in a rapidjson::Value instance to the add_one function, or +a rapidjson array of fluids to the add_many function. +*/ +class JSONIncompressibleLibrary +{ + /// Map from CAS code to JSON instance. For pseudo-pure fluids, use name in place of CAS code since no CASE number is defined for mixtures + std::map fluid_map; + std::vector name_vector; + std::map string_to_index_map; + bool _is_empty; +protected: + + /// Parse the viscosity + void parse_viscosity(rapidjson::Value &viscosity, IncompressibleFluid & fluid) + { + if (viscosity.HasMember("type")){ + std::string type = cpjson::get_string(viscosity, "type"); + if (!type.compare("polynomial")){ + fluid.viscosity.type = CoolProp::IncompressibleViscosityVariables::INCOMPRESSIBLE_VISCOSITY_POLYNOMIAL; + fluid.viscosity.poly.coeffs = cpjson::get_double_array(viscosity["coeffs"]); + return; + } + else{ + throw ValueError(format("viscosity type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str())); + } + } + else{ + throw ValueError(format("viscosity does not have \"type\" for fluid %s", fluid.name.c_str())); + } + }; + + /// Parse the conductivity + void parse_conductivity(rapidjson::Value &conductivity, IncompressibleFluid & fluid) + { + if (conductivity.HasMember("type")){ + std::string type = cpjson::get_string(conductivity, "type"); + if (!type.compare("polynomial")){ + fluid.conductivity.type = CoolProp::IncompressibleConductivityVariables::INCOMPRESSIBLE_CONDUCTIVITY_POLYNOMIAL; + fluid.conductivity.poly.coeffs = cpjson::get_double_array(conductivity["coeffs"]); + return; + } + else{ + throw ValueError(format("conductivity type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str())); + } + } + else{ + throw ValueError(format("conductivity does not have \"type\" for fluid %s", fluid.name.c_str())); + } + }; + + /// Parse the specific_heat + void parse_specific_heat(rapidjson::Value &specific_heat, IncompressibleFluid & fluid) + { + if (specific_heat.HasMember("type")){ + std::string type = cpjson::get_string(specific_heat, "type"); + if (!type.compare("polynomial")){ + fluid.specific_heat.type = CoolProp::IncompressibleSpecificHeatVariables::INCOMPRESSIBLE_SPECIFIC_HEAT_POLYNOMIAL; return; + fluid.specific_heat.poly.coeffs = cpjson::get_double_array(specific_heat["coeffs"]); + } + else{ + throw ValueError(format("specific_heat type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str())); + } + } + else{ + throw ValueError(format("specific_heat does not have \"type\" for fluid %s", fluid.name.c_str())); + } + }; + + /// Parse the density + void parse_density(rapidjson::Value &density, IncompressibleFluid & fluid) + { + if (density.HasMember("type")){ + std::string type = cpjson::get_string(density, "type"); + if (!type.compare("polynomial")){ + fluid.density.type = CoolProp::IncompressibleDensityVariables::INCOMPRESSIBLE_DENSITY_POLYNOMIAL; return; + fluid.density.poly.coeffs = cpjson::get_double_array(density["coeffs"]); + } + else{ + throw ValueError(format("density type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str())); + } + } + else{ + throw ValueError(format("density does not have \"type\" for fluid %s", fluid.name.c_str())); + } + }; + + /// Validate the fluid file that was just constructed + void validate(IncompressibleFluid & fluid) + { + } +public: + + // Default constructor; + JSONIncompressibleLibrary(){ + _is_empty = true; + }; + bool is_empty(void){ return _is_empty;}; + + /// Add all the fluid entries in the rapidjson::Value instance passed in + void add_many(rapidjson::Value &listing) + { + for (rapidjson::Value::ValueIterator itr = listing.Begin(); itr != listing.End(); ++itr) + { + add_one(*itr); + } + }; + void add_one(rapidjson::Value &fluid_json) + { + _is_empty = false; + + // Get the next index for this fluid + std::size_t index = fluid_map.size(); + + // Add index->fluid mapping + fluid_map[index] = IncompressibleFluid(); + + // Create an instance of the fluid + IncompressibleFluid &fluid = fluid_map[index]; + + fluid.name = cpjson::get_string(fluid_json, "name"); + fluid.Tmin = cpjson::get_double(fluid_json, "Tmin"); + fluid.Tmax = cpjson::get_double(fluid_json, "Tmax"); + + parse_conductivity(fluid_json["conductivity"], fluid); + parse_density(fluid_json["density"], fluid); + parse_viscosity(fluid_json["viscosity"], fluid); + parse_specific_heat(fluid_json["specific_heat"], fluid); + + // Add name->index mapping + string_to_index_map[fluid.name] = index; + + }; + /// Get an IncompressibleFluid instance stored in this library + /** + @param name Name of the fluid + */ + IncompressibleFluid& 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())); + } + }; + /// Get a CoolPropFluid instance stored in this library + /** + @param key The index of the fluid in the map + */ + IncompressibleFluid& 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)); + } + }; + /// Return a comma-separated list of fluid names + std::string get_fluid_list(void) + { + return strjoin(name_vector, ","); + }; +}; + +/// Get a reference to the library instance +JSONIncompressibleLibrary & get_incompressible_library(void); + +/// Get a comma-separated-list of incompressible fluids that are included +std::string get_incompressible_list(void); + +/// Get the fluid structure returned as a reference +IncompressibleFluid& get_incompressible_fluid(std::string fluid_string); + +} /* namespace CoolProp */ +#endif