[Base] create SolutionBase object in C++

* Add Base.h/Base.cpp with definition of SolutionBase
* Link C++ object into Cython interface
* Add unique_name and type attributes to Cython _SolutionBase
This commit is contained in:
Ingmar Schoegl 2019-08-16 07:26:24 -05:00 committed by Ray Speth
parent c149c4ed73
commit afd36b1c1e
8 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,72 @@
//! @file Base.h
// 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.
#ifndef CT_BASE_H
#define CT_BASE_H
#include "cantera/base/ctexceptions.h"
namespace Cantera
{
class ThermoPhase;
class Kinetics;
class Transport;
//! A container class holding managers for all pieces defining a phase
class SolutionBase {
public:
SolutionBase();
SolutionBase(const std::string& infile, const std::string& phasename);
~SolutionBase() {}
SolutionBase(const SolutionBase&) = delete;
SolutionBase& operator=(const SolutionBase&) = delete;
//! String indicating the type of the SolutionBase object. Corresponds
//! to the type of phase originally instantiated
std::string type() const {
return m_type;
}
//! Set the type of this SolutionBase object
void setType(const std::string& type){
m_type = type;
}
//! Return the name of this SolutionBase object
std::string name() const {
return m_name;
}
//! Set the name of this SolutionBase object
void setName(const std::string& name){
m_name = name;
}
//! Generate self-documenting YAML string
virtual std::string toYAML() const {
throw NotImplementedError("SolutionBase::toYAML");
}
//! Set the ThermoPhase object
void setThermoPhase(shared_ptr<ThermoPhase> thermo);
//! Set the Kinetics object
void setKinetics(shared_ptr<Kinetics> kinetics);
//! Set the Transport object
void setTransport(shared_ptr<Transport> transport);
protected:
shared_ptr<ThermoPhase> m_thermo; //! ThermoPhase manager
shared_ptr<Kinetics> m_kinetics; //! Kinetics manager
shared_ptr<Transport> m_transport; //! Transport manager
std::string m_type; //! type of SolutionBase object
std::string m_name; //! name of SolutionBase object
};
}
#endif

View file

@ -120,6 +120,19 @@ cdef extern from "cantera/thermo/Species.h" namespace "Cantera":
cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (CxxAnyMap&) except +translate_exception cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (CxxAnyMap&) except +translate_exception
cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (CxxAnyValue&) except +translate_exception cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (CxxAnyValue&) except +translate_exception
cdef extern from "cantera/base/Base.h" namespace "Cantera":
cdef cppclass CxxSolutionBase "Cantera::SolutionBase":
CxxSolutionBase()
string type()
string setType(string)
string name()
void setName(string)
void setThermoPhase(shared_ptr[CxxThermoPhase])
void setKinetics(shared_ptr[CxxKinetics])
void setTransport(shared_ptr[CxxTransport])
cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
cdef cppclass CxxThermoPhase "Cantera::ThermoPhase": cdef cppclass CxxThermoPhase "Cantera::ThermoPhase":
CxxThermoPhase() CxxThermoPhase()
@ -928,6 +941,7 @@ cdef class GasTransportData:
cdef _assign(self, shared_ptr[CxxTransportData] other) cdef _assign(self, shared_ptr[CxxTransportData] other)
cdef class _SolutionBase: cdef class _SolutionBase:
cdef CxxSolutionBase* base
cdef shared_ptr[CxxThermoPhase] _thermo cdef shared_ptr[CxxThermoPhase] _thermo
cdef CxxThermoPhase* thermo cdef CxxThermoPhase* thermo
cdef shared_ptr[CxxKinetics] _kinetics cdef shared_ptr[CxxKinetics] _kinetics

View file

@ -1,6 +1,10 @@
# This file is part of Cantera. See License.txt in the top-level directory or # 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 https://cantera.org/license.txt for license and copyright information.
from collections import defaultdict as _defaultdict
_phase_counts = _defaultdict(int)
cdef class _SolutionBase: cdef class _SolutionBase:
def __cinit__(self, infile='', phaseid='', phases=(), origin=None, def __cinit__(self, infile='', phaseid='', phases=(), origin=None,
source=None, yaml=None, thermo=None, species=(), source=None, yaml=None, thermo=None, species=(),
@ -10,6 +14,7 @@ cdef class _SolutionBase:
if origin is not None: if origin is not None:
other = <_SolutionBase?>origin other = <_SolutionBase?>origin
self.base = other.base
self.thermo = other.thermo self.thermo = other.thermo
self.kinetics = other.kinetics self.kinetics = other.kinetics
self.transport = other.transport self.transport = other.transport
@ -21,6 +26,9 @@ cdef class _SolutionBase:
self._selected_species = other._selected_species.copy() self._selected_species = other._selected_species.copy()
return return
# Assign type and unique_name during __init__
self.base = new CxxSolutionBase()
if infile.endswith('.yml') or infile.endswith('.yaml') or yaml: if infile.endswith('.yml') or infile.endswith('.yaml') or yaml:
self._init_yaml(infile, phaseid, phases, yaml) self._init_yaml(infile, phaseid, phases, yaml)
elif infile or source: elif infile or source:
@ -31,6 +39,8 @@ cdef class _SolutionBase:
raise ValueError("Arguments are insufficient to define a phase") raise ValueError("Arguments are insufficient to define a phase")
# Initialization of transport is deferred to Transport.__init__ # Initialization of transport is deferred to Transport.__init__
self.base.setThermoPhase(self._thermo)
self.base.setKinetics(self._kinetics)
self.transport = NULL self.transport = NULL
self._selected_species = np.ndarray(0, dtype=np.integer) self._selected_species = np.ndarray(0, dtype=np.integer)
@ -39,6 +49,34 @@ cdef class _SolutionBase:
if isinstance(self, Transport): if isinstance(self, Transport):
assert self.transport is not NULL assert self.transport is not NULL
base_type = kwargs.get('base_type', None)
if base_type:
self.base.setType(stringify(base_type))
else:
raise ValueError('Missing required keyword `base_type`.')
phasename = pystr(self.thermo.name())
name = kwargs.get('name', None)
if name is not None:
self.unique_name = name
else:
_phase_counts[phasename] += 1
n = _phase_counts[phasename]
self.unique_name = '{0}_{1}'.format(phasename, n)
property type:
"""The type of the SolutionBase object."""
def __get__(self):
return pystr(self.base.type())
property unique_name:
"""The unique name of the SolutionBase object."""
def __get__(self):
return pystr(self.base.name())
def __set__(self, name):
self.base.setName(stringify(name))
def _init_yaml(self, infile, phaseid, phases, source): def _init_yaml(self, infile, phaseid, phases, source):
""" """
Instantiate a set of new Cantera C++ objects from a YAML Instantiate a set of new Cantera C++ objects from a YAML

View file

@ -69,6 +69,9 @@ class Solution(ThermoPhase, Kinetics, Transport):
""" """
__slots__ = () __slots__ = ()
def __init__(self, *args, **kwargs):
super().__init__(*args, base_type='Solution', **kwargs)
class Interface(InterfacePhase, InterfaceKinetics): class Interface(InterfacePhase, InterfaceKinetics):
""" """
@ -88,6 +91,9 @@ class Interface(InterfacePhase, InterfaceKinetics):
""" """
__slots__ = ('_phase_indices',) __slots__ = ('_phase_indices',)
def __init__(self, *args, **kwargs):
super().__init__(*args, base_type='Interface', **kwargs)
class DustyGas(ThermoPhase, Kinetics, DustyGasTransport): class DustyGas(ThermoPhase, Kinetics, DustyGasTransport):
""" """
@ -99,6 +105,9 @@ class DustyGas(ThermoPhase, Kinetics, DustyGasTransport):
""" """
__slots__ = () __slots__ = ()
def __init__(self, *args, **kwargs):
super().__init__(*args, base_type='DustyGas', **kwargs)
class Quantity: class Quantity:
""" """

View file

@ -26,6 +26,11 @@ cdef class Kinetics(_SolutionBase):
a reaction mechanism. a reaction mechanism.
""" """
def __init__(self, *args, **kwargs):
base_type = kwargs.pop('base_type', 'Kinetics')
kwargs['base_type'] = base_type
super().__init__(*args, **kwargs)
property n_total_species: property n_total_species:
""" """
Total number of species in all phases participating in the kinetics Total number of species in all phases participating in the kinetics

View file

@ -264,6 +264,8 @@ cdef class ThermoPhase(_SolutionBase):
# The signature of this function causes warnings for Sphinx documentation # The signature of this function causes warnings for Sphinx documentation
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
base_type = kwargs.pop('base_type', 'ThermoPhase')
kwargs['base_type'] = base_type
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if 'source' not in kwargs: if 'source' not in kwargs:
self.thermo_basis = mass_basis self.thermo_basis = mass_basis

View file

@ -144,7 +144,11 @@ cdef class Transport(_SolutionBase):
model = 'None' model = 'None'
self.transport = newTransportMgr(stringify(model), self.thermo) self.transport = newTransportMgr(stringify(model), self.thermo)
self._transport.reset(self.transport) self._transport.reset(self.transport)
base_type = kwargs.pop('base_type', 'Transport')
kwargs['base_type'] = base_type
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.base.setTransport(self._transport)
property transport_model: property transport_model:
""" """

38
src/base/Base.cpp Normal file
View file

@ -0,0 +1,38 @@
//! @file Base.cpp
// 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.
#include "cantera/base/Base.h"
namespace Cantera
{
SolutionBase::SolutionBase() :
m_thermo(nullptr),
m_kinetics(nullptr),
m_transport(nullptr),
m_type("<SolutionBase_type>"),
m_name("<unique_name>")
{}
SolutionBase::SolutionBase(const std::string& infile,
const std::string& phasename) :
SolutionBase()
{
// this *may* be a spot to load all pieces of a phase
throw NotImplementedError("SolutionBase constructor from file");
}
void SolutionBase::setThermoPhase(shared_ptr<ThermoPhase> thermo) {
m_thermo = thermo;
}
void SolutionBase::setKinetics(shared_ptr<Kinetics> kinetics) {
m_kinetics = kinetics;
}
void SolutionBase::setTransport(shared_ptr<Transport> transport) {
m_transport = transport;
}
}