diff --git a/include/cantera/base/Base.h b/include/cantera/base/Base.h index 9c0846422..a73c35113 100644 --- a/include/cantera/base/Base.h +++ b/include/cantera/base/Base.h @@ -31,29 +31,42 @@ public: //! String indicating the type of the SolutionBase object. Corresponds //! to the type of phase originally instantiated - std::string type() const { - return m_type; - } + std::string type() const; //! Set the type of this SolutionBase object - void setType(const std::string& type){ - m_type = type; - } + void setType(const std::string& type); + + /*! Name and ID + * Class SolutionBase references two strings that identify a SolutionBase. + * The ID is the value of the ID attribute of the XML/YAML node that is used + * to initialize a phase when it is read. The name field is also initialized + * to the value of the ID attribute of the XML/YAML node. + * + * However, the name field may be changed to another value during the course + * of a calculation. For example, if a SolutionBase is located in two places, + * but has the same constitutive input, the IDs of the two SolutionBases + * will be the same, but the names of the two SOlutionBases may be different. + * + * It is an error to have two phases in a single problem with the same name + * and ID (or the name from one phase being the same as the id of another + * SolutionBase). Thus, it is expected that there is a 1-1 correspondence + * between names and unique SolutionBase objects within a Cantera problem. + */ + + //! Return the string id for the SolutionBase. + std::string id() const; + + //! Set the string id for the SolutionBase. + void setID(const std::string& id); //! Return the name of this SolutionBase object - std::string name() const { - return m_name; - } + std::string name() const; //! Set the name of this SolutionBase object - void setName(const std::string& name){ - m_name = name; - } + void setName(const std::string& name); //! Generate self-documenting YAML string - virtual std::string toYAML() const { - throw NotImplementedError("SolutionBase::toYAML"); - } + virtual std::string toYAML() const; //! Set the ThermoPhase object void setThermoPhase(shared_ptr thermo); @@ -70,7 +83,6 @@ protected: shared_ptr m_transport; //! Transport manager std::string m_type; //! type of SolutionBase object - std::string m_name; //! name of SolutionBase object }; } diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index fa93cc36e..db4d7957e 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -126,6 +126,8 @@ cdef extern from "cantera/base/Base.h" namespace "Cantera": CxxSolutionBase() string type() string setType(string) + string id() + void setID(string) string name() void setName(string) void setThermoPhase(shared_ptr[CxxThermoPhase]) @@ -142,10 +144,6 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": # miscellaneous string type() string report(cbool, double) except +translate_exception - string name() - void setName(string) - string id() - void setID(string) double minTemp() except +translate_exception double maxTemp() except +translate_exception double refPressure() except +translate_exception diff --git a/interfaces/cython/cantera/base.pyx b/interfaces/cython/cantera/base.pyx index 7a2715938..de5ef9cd9 100644 --- a/interfaces/cython/cantera/base.pyx +++ b/interfaces/cython/cantera/base.pyx @@ -60,7 +60,7 @@ cdef class _SolutionBase: else: raise ValueError('Missing required keyword `base_type`.') - phase_name = pystr(self.thermo.id()) + phase_name = pystr(self.base.id()) name = kwargs.get('name', None) if name is not None: self.name = name @@ -73,10 +73,23 @@ cdef class _SolutionBase: self.name = phase_name property type: - """The type of the SolutionBase object.""" + """ + The type of the SolutionBase object. The type is set during object + instantiation and cannot be modified. + """ def __get__(self): return pystr(self.base.type()) + property ID: + """ + The ID of the SolutionBase object. The default is taken from the + CTI/XML/YAML input file. + """ + def __get__(self): + return pystr(self.base.id()) + def __set__(self, id_): + self.base.setID(stringify(id_)) + property name: """ The name assigned to this SolutionBase object. The default is diff --git a/interfaces/cython/cantera/thermo.pyx b/interfaces/cython/cantera/thermo.pyx index a3f0b1cf6..20088b6e4 100644 --- a/interfaces/cython/cantera/thermo.pyx +++ b/interfaces/cython/cantera/thermo.pyx @@ -285,15 +285,6 @@ cdef class ThermoPhase(_SolutionBase): def __call__(self, *args, **kwargs): print(self.report(*args, **kwargs)) - property ID: - """ - The ID of the phase. The default is taken from the CTI/XML input file. - """ - def __get__(self): - return pystr(self.thermo.id()) - def __set__(self, id_): - self.thermo.setID(stringify(id_)) - property basis: """ Determines whether intensive thermodynamic properties are treated on a diff --git a/src/base/Base.cpp b/src/base/Base.cpp index 82fe246e0..29043517e 100644 --- a/src/base/Base.cpp +++ b/src/base/Base.cpp @@ -15,8 +15,7 @@ SolutionBase::SolutionBase() : m_thermo(nullptr), m_kinetics(nullptr), m_transport(nullptr), - m_type(""), - m_name("") + m_type("") {} SolutionBase::SolutionBase(const std::string& infile, @@ -27,6 +26,53 @@ SolutionBase::SolutionBase(const std::string& infile, throw NotImplementedError("SolutionBase constructor from file"); } +std::string SolutionBase::type() const { + return m_type; +} + +void SolutionBase::setType(const std::string& type){ + m_type = type; +} + +std::string SolutionBase::id() const { + // currently managed by ThermoPhase + if (m_thermo) { + return m_thermo->id(); + } else { + throw CanteraError("SolutionBase::id()", "Missing ThermoPhase."); + } +} + +void SolutionBase::setID(const std::string& id) { + // currently managed by ThermoPhase + if (m_thermo) { + return m_thermo->setID(id); + } else { + throw CanteraError("SolutionBase::setID()", "Missing ThermoPhase."); + } +} + +std::string SolutionBase::name() const { + // currently managed by ThermoPhase + if (m_thermo) { + return m_thermo->name(); + } else { + throw CanteraError("SolutionBase::name()", "Missing ThermoPhase."); + } +} + +void SolutionBase::setName(const std::string& name){ + // currently managed by ThermoPhase + if (m_thermo) { + return m_thermo->setName(name); + } else { + throw CanteraError("SolutionBase::setName()", "Missing ThermoPhase."); + } +} + +std::string SolutionBase::toYAML() const { + throw NotImplementedError("SolutionBase::toYAML"); +} void SolutionBase::setThermoPhase(shared_ptr thermo) { m_thermo = thermo; diff --git a/src/thermo/Phase.cpp b/src/thermo/Phase.cpp index fc21d66ea..c82b3e756 100644 --- a/src/thermo/Phase.cpp +++ b/src/thermo/Phase.cpp @@ -4,13 +4,12 @@ */ // This file is part of Cantera. See License.txt in the top-level directory or -// at https://cantera.org/license.txt for license and copyright information. +// at http://www.cantera.org/license.txt for license and copyright information. #include "cantera/thermo/Phase.h" #include "cantera/base/utilities.h" #include "cantera/base/stringUtils.h" #include "cantera/base/ctml.h" -#include "cantera/base/Base.h" #include "cantera/thermo/ThermoFactory.h" using namespace std; @@ -79,22 +78,12 @@ void Phase::setID(const std::string& id_) std::string Phase::name() const { - if (m_root.expired()) { - return m_name; - } else { - auto root = m_root.lock(); - return root->name(); - } + return m_name; } void Phase::setName(const std::string& nm) { - if (m_root.expired()) { - m_name = nm; - } else { - auto root = m_root.lock(); - root->setName(nm); - } + m_name = nm; } size_t Phase::nElements() const