diff --git a/SConstruct b/SConstruct index a1e215365..804809615 100644 --- a/SConstruct +++ b/SConstruct @@ -230,6 +230,8 @@ else: defaults.singleLibrary = False defaults.fsLayout = 'compact' if env['OS'] == 'Windows' else 'standard' +defaults.env_vars = 'LD_LIBRARY_PATH' if 'LD_LIBRARY_PATH' in os.environ else '' +defaults.python_prefix = '$prefix' if env['OS'] != 'Windows' else '' # ************************************** # *** Read user-configurable options *** @@ -279,11 +281,12 @@ opts.AddVariables( '', PathVariable.PathAccept), PathVariable( 'python_prefix', - """If you want to install the Cantera Python package somewhere other - than the default 'site-packages' directory within the Python library - directory, then set this to the desired directory. This is useful - when you do not have write access to the Python library directory.""", - '', PathVariable.PathAccept), + """Use this option if you want to install the Cantera Python package to + an alternate location. On Unix-like systems, the default is the same + as the $prefix option. If this option is set to the empty string (the + default on Windows), then the Package will be installed to the system + default 'site-packages' directory.""", + defaults.python_prefix, PathVariable.PathAccept), EnumVariable( 'matlab_toolbox', """This variable controls whether the Matlab toolbox will be built. If @@ -396,7 +399,7 @@ opts.AddVariables( """Environment variables to propagate through to SCons. Either the string "all" or a comma separated list of variable names, e.g. 'LD_LIBRARY_PATH,HOME'""", - ''), + defaults.env_vars), ('cxx_flags', 'Compiler flags passed to the C++ compiler only.', defaults.cxxFlags), @@ -1186,6 +1189,7 @@ build_cantera = Alias('build', finish_build) Default('build') def postInstallMessage(target, source, env): + env['python_module_loc'] = env.subst(env['python_module_loc']) print """ Cantera has been successfully installed. diff --git a/include/cantera/kinetics/ReactionData.h b/include/cantera/kinetics/ReactionData.h index 0bab6ce51..ddcf48dc4 100644 --- a/include/cantera/kinetics/ReactionData.h +++ b/include/cantera/kinetics/ReactionData.h @@ -19,6 +19,7 @@ public: //! Default constructor ReactionData() { reactionType = ELEMENTARY_RXN; + validate = false; number = 0; rxn_number = 0; reversible = true; @@ -41,6 +42,7 @@ public: */ int reactionType; + bool validate; int number; int rxn_number; std::vector reactants; diff --git a/include/cantera/kinetics/RxnRates.h b/include/cantera/kinetics/RxnRates.h index ce951c6a7..2fe523d87 100644 --- a/include/cantera/kinetics/RxnRates.h +++ b/include/cantera/kinetics/RxnRates.h @@ -165,7 +165,7 @@ public: m_logA = log(m_A); } - const vector_fp& data = rdata.auxRateCoeffParameters; + const vector_fp& data = rdata.rateCoeffParameters; if (data.size() >= 7) { for (size_t n = 3; n < data.size()-3; n += 4) { addCoverageDependence(size_t(data[n]), data[n+1], @@ -420,6 +420,10 @@ public: n2_.resize(maxRates_); Ea1_.resize(maxRates_); Ea2_.resize(maxRates_); + + if (rdata.validate) { + validate(); + } } //! Update concentration-dependent parts of the rate coefficient. @@ -469,7 +473,7 @@ public: if (m1_ == 1) { log_k1 = A1_[0] + n1_[0] * logT - Ea1_[0] * recipT; } else { - double k = 0.0; + double k = 1e-300; // non-zero to make log(k) finite for (size_t m = 0; m < m1_; m++) { k += A1_[m] * exp(n1_[m] * logT - Ea1_[m] * recipT); } @@ -479,7 +483,7 @@ public: if (m2_ == 1) { log_k2 = A2_[0] + n2_[0] * logT - Ea2_[0] * recipT; } else { - double k = 0.0; + double k = 1e-300; // non-zero to make log(k) finite for (size_t m = 0; m < m2_; m++) { k += A2_[m] * exp(n2_[m] * logT - Ea2_[m] * recipT); } @@ -506,6 +510,32 @@ public: return false; } + //! Check to make sure that the rate expression is finite over a range of + //! temperatures at each interpolation pressure. This is potentially an + //! issue when one of the Arrhenius expressions at a particular pressure + //! has a negative pre-exponential factor. + void validate() { + double T[] = {1.0, 10.0, 100.0, 1000.0, 10000.0}; + for (pressureIter iter = pressures_.begin(); + iter->first < 1000; + iter++) + { + update_C(&iter->first); + for (size_t i=0; i < 5; i++) { + double k = updateRC(log(T[i]), 1.0/T[i]); + if (!(k >= 0)) { + // k is NaN. Increment the iterator so that the error + // message will correctly indicate that the problematic rate + // expression is at the higher of the adjacent pressures. + throw CanteraError("Plog::validate", + "Invalid rate coefficient at P = " + + fp2str(exp((++iter)->first)) + + ", T = " + fp2str(T[i])); + } + } + } + } + protected: //! log(p) to (index range) in A_, n, Ea vectors std::map > pressures_; diff --git a/interfaces/python/Cantera/Reactor.py b/interfaces/python/Cantera/Reactor.py index 733301abf..acda04e93 100644 --- a/interfaces/python/Cantera/Reactor.py +++ b/interfaces/python/Cantera/Reactor.py @@ -432,7 +432,7 @@ class FlowReactor(ReactorBase): self.setMassFlowRate(mdot) def setMassFlowRate(self, mdot): - _cantera.flowReactor_setMassFlowRate(self.__reactor_id, mdot) + _cantera.flowReactor_setMassFlowRate(self.reactor_id(), mdot) class ConstPressureReactor(ReactorBase): diff --git a/src/kinetics/importKinetics.cpp b/src/kinetics/importKinetics.cpp index e759ea434..97d5f14a1 100644 --- a/src/kinetics/importKinetics.cpp +++ b/src/kinetics/importKinetics.cpp @@ -689,6 +689,7 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin, // xml data. Then, when we have collected everything we add the reaction to // the kinetics object, kin, at the end of the routine. ReactionData rdata; + rdata.validate = validate_rxn; // Check to see if the reaction is specified to be a duplicate of another // reaction. It's an error if the reaction is a duplicate and this is not