From c9abf1707cd71436cd285e61c194c2a00aa20b14 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Sat, 14 Nov 2015 20:28:07 -0700 Subject: [PATCH] Fix code for setting REFPROP path; see #759 --- Web/coolprop/REFPROP.rst | 12 +++++++--- src/Backends/REFPROP/REFPROPBackend.cpp | 6 ++--- .../REFPROP/REFPROPMixtureBackend.cpp | 22 ++++++++++++++++--- src/Backends/REFPROP/REFPROPMixtureBackend.h | 6 ++++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Web/coolprop/REFPROP.rst b/Web/coolprop/REFPROP.rst index a260a4a5..0caed908 100644 --- a/Web/coolprop/REFPROP.rst +++ b/Web/coolprop/REFPROP.rst @@ -73,7 +73,13 @@ Path Issues In order for REFPROP to be able to be loaded by CoolProp, the default logic for each operating system is used to load the REFPROP shared library. This means that on windows, the ``PATH`` environmental variable is searched for the ``REFPROP.dll`` (32-bit applications) or ``REFPRP64.dll`` (64-bit applications). On linux/OSX, the default shared library loading protocol is used. If your REFPROP is installed in a non-standard location (not on the path), make sure that when you run code that uses REFPROP, that you add (temporarily) the location of the REFPROP shared library to your path. -REFPROP needs to be able to find the fluid and mixture files at runtime, at a location specified on your computer. CoolProp allows you to avoid the pains of decoding REFPROP's internal logic for finding these files by explicitly specifying the path that it should tell REFPROP to look for the fluid files. The configuration key (see :ref:`configuration`) is ``ALTERNATIVE_REFPROP_PATH``, and you can set it doing something like this in python: +REFPROP needs to be able to find the fluid and mixture files at runtime, at a location specified on your computer. CoolProp allows you to avoid the pains of decoding REFPROP's internal logic for finding these files by explicitly specifying the path that it should tell REFPROP to look for the fluid files. + +.. warning:: + + These configuration variables should be set at the beginning of your script and then not touched again. Otherwise, you can get some weird behavior! + +The configuration key for setting the REFPROP path (see :ref:`configuration`) is ``ALTERNATIVE_REFPROP_PATH``, and you can set it doing something like this in python: .. ipython:: @@ -85,7 +91,7 @@ REFPROP needs to be able to find the fluid and mixture files at runtime, at a lo In [3]: jj = CP.set_config_as_json_string(json.dumps(jj)) -If you do this, internally CoolProp will call the ``SETPATH`` function in REFPROP to tell REFPROP that it should find the ``fluids`` and ``mixtures`` within this directory. If you don't do this, CoolProp will use whatever default logic REFPROP uses to find the fluid files. +If you do this, internally CoolProp will call the ``SETPATH`` function in REFPROP to tell REFPROP that it should find the ``fluids`` and ``mixtures`` directories within this directory. If you don't do this, CoolProp will use whatever default logic REFPROP uses to find the fluid files. If you are playing around with mixture parameters, you might want to set a different path to the HMX.BNC file which contains the interaction parameters for the mixture. You can do that by changing the configuration variable (see :ref:`configuration`) ``ALTERNATIVE_REFPROP_HMX_BNC_PATH`` @@ -99,4 +105,4 @@ If you are playing around with mixture parameters, you might want to set a diffe In [3]: jj = CP.set_config_as_json_string(json.dumps(jj)) -If you have set both the ``ALTERNATIVE_REFPROP_PATH`` and ``ALTERNATIVE_REFPROP_HMX_BNC_PATH`` variables, ``ALTERNATIVE_REFPROP_PATH`` "wins", and this path will be used when loading mixture interaction parameters +If you have set both the ``ALTERNATIVE_REFPROP_PATH`` and ``ALTERNATIVE_REFPROP_HMX_BNC_PATH`` variables, ``ALTERNATIVE_REFPROP_PATH_HMX_BNC_PATH`` "wins", and this path will be used when loading mixture interaction parameters diff --git a/src/Backends/REFPROP/REFPROPBackend.cpp b/src/Backends/REFPROP/REFPROPBackend.cpp index 351f77ca..bcacff0b 100644 --- a/src/Backends/REFPROP/REFPROPBackend.cpp +++ b/src/Backends/REFPROP/REFPROPBackend.cpp @@ -25,12 +25,10 @@ namespace CoolProp { REFPROPBackend::REFPROPBackend(const std::string & fluid_name) { // 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); + construct(component_names); - // Set the mole fraction to 1 in the base class (we can't set the mole fraction in this class, + // 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) if (get_mole_fractions().empty()){ std::vector x(1, 1.0); // (one element with value of 1.0) diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp index 75fdbcb2..bc64abae 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp @@ -89,16 +89,30 @@ std::string get_REFPROP_fluid_path() namespace CoolProp { -REFPROPMixtureBackend::REFPROPMixtureBackend(const std::vector& fluid_names) { + +void REFPROPMixtureBackend::construct(const std::vector& fluid_names) { // Do the REFPROP instantiation for this fluid _mole_fractions_set = false; - + + // Force loading of REFPROP + REFPROP_supported(); + + // Call SETPATH if the ALTERNATIVE_REFPROP_PATH configuration variable has been set + std::string alt_rp_path = get_config_string(ALTERNATIVE_REFPROP_PATH); + if (!alt_rp_path.empty()){ + long len = alt_rp_path.length(); + char name[255]; + strcpy(name, alt_rp_path.c_str()); + SETPATHdll(name, 255); + } + // 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. this->set_REFPROP_fluids(fluid_names); - + // Bump the number of REFPROP backends that are in existence; REFPROPMixtureBackend::instance_counter++; + } REFPROPMixtureBackend::~REFPROPMixtureBackend() { @@ -220,6 +234,8 @@ void REFPROPMixtureBackend::set_REFPROP_fluids(const std::vector &f strcpy(mix, components_joined_raw.c_str()); char hmx_bnc[255] = "HMX.BNC", reference_state[4] = "DEF"; std::string alt_hmx_bnc_path = CoolProp::get_config_string(ALTERNATIVE_REFPROP_HMX_BNC_PATH); + if (alt_hmx_bnc_path.length() > refpropcharlength){ throw ValueError(format("ALTERNATIVE_REFPROP_HMX_BNC_PATH (%s) is too long", alt_hmx_bnc_path.c_str())); + } if (!alt_hmx_bnc_path.empty()){ strcpy(hmx_bnc, alt_hmx_bnc_path.c_str()); } diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.h b/src/Backends/REFPROP/REFPROPMixtureBackend.h index 1d717e39..f773e4b5 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.h +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.h @@ -40,7 +40,11 @@ public: /// The instantiator /// @param fluid_names The vector of strings of the fluid components, without file ending - REFPROPMixtureBackend(const std::vector& fluid_names); + REFPROPMixtureBackend(const std::vector& fluid_names) {construct(fluid_names);}; + + /// A function to actually do the initalization to allow it to be called in derived classes + void construct(const std::vector& fluid_names); + std::string backend_name(void){return "REFPROPMixtureBackend";} virtual ~REFPROPMixtureBackend();