mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
Merge c7910524da
into 0720efb02d
This commit is contained in:
commit
74e10f9989
@ -19,12 +19,12 @@ extern "C" {
|
||||
|
||||
CANTERA_CAPI int reactor_new(const char* type, int n, const char* name);
|
||||
CANTERA_CAPI int reactor_del(int i);
|
||||
CANTERA_CAPI int reactor_type(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int reactor_name(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int reactor_setName(int i, const char* name);
|
||||
CANTERA_CAPI int reactor_setInitialVolume(int i, double v);
|
||||
CANTERA_CAPI int reactor_setChemistry(int i, int cflag);
|
||||
CANTERA_CAPI int reactor_setEnergy(int i, int eflag);
|
||||
CANTERA_CAPI int reactor_setSolution(int i, int n);
|
||||
CANTERA_CAPI double reactor_mass(int i);
|
||||
CANTERA_CAPI double reactor_volume(int i);
|
||||
CANTERA_CAPI double reactor_density(int i);
|
||||
@ -51,11 +51,12 @@ extern "C" {
|
||||
CANTERA_CAPI double reactornet_atol(int i);
|
||||
CANTERA_CAPI double reactornet_sensitivity(int i, const char* v, int p, int r);
|
||||
|
||||
CANTERA_CAPI int flowdev_new(const char* type, const char* name);
|
||||
CANTERA_CAPI int flowdev_del(int i);
|
||||
CANTERA_CAPI int flowdev_name(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int flowdev_setName(int i, const char* name);
|
||||
CANTERA_CAPI int flowdev_install(int i, int n, int m);
|
||||
CANTERA_CAPI int connector_new(const char* type, int r0, int r1, const char* name);
|
||||
CANTERA_CAPI int connector_del(int i);
|
||||
CANTERA_CAPI int connector_type(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int connector_name(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int connector_setName(int i, const char* name);
|
||||
|
||||
CANTERA_CAPI int flowdev_setPrimary(int i, int n);
|
||||
CANTERA_CAPI double flowdev_massFlowRate(int i);
|
||||
CANTERA_CAPI int flowdev_setMassFlowCoeff(int i, double v);
|
||||
@ -64,11 +65,6 @@ extern "C" {
|
||||
CANTERA_CAPI int flowdev_setPressureFunction(int i, int n);
|
||||
CANTERA_CAPI int flowdev_setTimeFunction(int i, int n);
|
||||
|
||||
CANTERA_CAPI int wall_new(const char* type, const char* name);
|
||||
CANTERA_CAPI int wall_del(int i);
|
||||
CANTERA_CAPI int wall_name(int i, int len, char* nbuf);
|
||||
CANTERA_CAPI int wall_setName(int i, const char* name);
|
||||
CANTERA_CAPI int wall_install(int i, int n, int m);
|
||||
CANTERA_CAPI double wall_expansionRate(int i);
|
||||
CANTERA_CAPI double wall_heatRate(int i);
|
||||
CANTERA_CAPI double wall_area(int i);
|
||||
@ -79,7 +75,6 @@ extern "C" {
|
||||
CANTERA_CAPI int wall_setExpansionRateCoeff(int i, double k);
|
||||
CANTERA_CAPI int wall_setVelocity(int i, int n);
|
||||
CANTERA_CAPI int wall_setEmissivity(int i, double epsilon);
|
||||
CANTERA_CAPI int wall_ready(int i);
|
||||
|
||||
CANTERA_CAPI int reactorsurface_new(const char* name);
|
||||
CANTERA_CAPI int reactorsurface_del(int i);
|
||||
|
98
include/cantera/zeroD/ConnectorFactory.h
Normal file
98
include/cantera/zeroD/ConnectorFactory.h
Normal file
@ -0,0 +1,98 @@
|
||||
//! @file ConnectorFactory.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 CONNECTOR_FACTORY_H
|
||||
#define CONNECTOR_FACTORY_H
|
||||
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
#include "cantera/zeroD/ConnectorNode.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
class FlowDevice;
|
||||
class WallBase;
|
||||
|
||||
//! Factory class to create ConnectorNode objects.
|
||||
//!
|
||||
//! This class is mainly used via the newConnectorNode() function, for example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<ConnectorNode> valve = newConnectorNode("Valve", r0, r1, "my_valve");
|
||||
//! ```
|
||||
//!
|
||||
//! where `r0` and `r1` are reactor objects.
|
||||
class ConnectorFactory :
|
||||
public Factory<ConnectorNode,
|
||||
shared_ptr<ReactorBase>, shared_ptr<ReactorBase>, const string&>
|
||||
{
|
||||
public:
|
||||
static ConnectorFactory* factory();
|
||||
|
||||
void deleteFactory() override;
|
||||
|
||||
private:
|
||||
static ConnectorFactory* s_factory;
|
||||
static std::mutex connector_mutex;
|
||||
ConnectorFactory();
|
||||
};
|
||||
|
||||
//! @defgroup connectorGroup Connectors
|
||||
//! %ConnectorNode objects connect zero-dimensional reactors.
|
||||
//! ConnectorNode objects should be instantiated via the newConnectorNode() function,
|
||||
//! for example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<ConnectorNode> valve = newConnectorNode("Valve", r0, r1, "my_valve");
|
||||
//! ```
|
||||
//!
|
||||
//! where `r0` and `r1` are reactor objects.
|
||||
//!
|
||||
//! @since New in %Cantera 3.2.
|
||||
//!
|
||||
//! @ingroup zerodGroup
|
||||
//! @{
|
||||
|
||||
//! Create a ConnectorNode object of the specified type
|
||||
//! @param model String specifying reactor type.
|
||||
//! @param r0 First reactor.
|
||||
//! @param r1 Second reactor.
|
||||
//! @param name Name of the connector.
|
||||
//! @since New in %Cantera 3.2.
|
||||
shared_ptr<ConnectorNode> newConnectorNode(const string& model,
|
||||
shared_ptr<ReactorBase> r0,
|
||||
shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)");
|
||||
|
||||
//! Create a FlowDevice object of the specified type
|
||||
//! @since Starting in %Cantera 3.1, this method returns a `shared_ptr<FlowDevice>`
|
||||
//! @deprecated To be removed after %Cantera 3.2. Use version that provides reactors
|
||||
//! as parameter instead.
|
||||
shared_ptr<FlowDevice> newFlowDevice(const string& model, const string& name="(none)");
|
||||
|
||||
//! Create a FlowDevice object of the specified type.
|
||||
//! @copydetails newConnectorNode
|
||||
shared_ptr<FlowDevice> newFlowDevice(const string& model,
|
||||
shared_ptr<ReactorBase> r0,
|
||||
shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)");
|
||||
|
||||
//! Create a WallBase object of the specified type
|
||||
//! @since Starting in %Cantera 3.1, this method returns a `shared_ptr<WallBase>`
|
||||
//! @deprecated To be removed after %Cantera 3.2. Use version that provides reactors
|
||||
//! as parameter instead.
|
||||
shared_ptr<WallBase> newWall(const string& model, const string& name="(none)");
|
||||
|
||||
//! Create a WallBase object of the specified type.
|
||||
//! @copydetails newConnectorNode
|
||||
shared_ptr<WallBase> newWall(const string& model,
|
||||
shared_ptr<ReactorBase> r0,
|
||||
shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)");
|
||||
|
||||
//! @}
|
||||
}
|
||||
|
||||
#endif
|
74
include/cantera/zeroD/ConnectorNode.h
Normal file
74
include/cantera/zeroD/ConnectorNode.h
Normal file
@ -0,0 +1,74 @@
|
||||
//! @file ConnectorNode.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_CONNECTOR_H
|
||||
#define CT_CONNECTOR_H
|
||||
|
||||
#include "cantera/base/ct_defs.h"
|
||||
#include "cantera/base/global.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
class ReactorBase;
|
||||
|
||||
/**
|
||||
* Base class for walls and flow devices connecting reactors.
|
||||
* In a reactor network, walls and flow devices (e.g., valves, pressure regulators)
|
||||
* represent nodes in a directed bipartite graph - a graph whose vertices can be
|
||||
* divided into two disjoint sets such that no two vertices within the same set are
|
||||
* adjacent - with reactors forming the second set of nodes.
|
||||
*
|
||||
* @since New in %Cantera 3.2.
|
||||
*
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class ConnectorNode
|
||||
{
|
||||
public:
|
||||
//! Transitional constructor.
|
||||
//! @todo Implement deprecation warning.
|
||||
ConnectorNode(const string& name="(none)") : m_name(name) {}
|
||||
|
||||
//! Instantiate a ConnectorNode object with associated ReactorBase objects.
|
||||
//! @param r0 First reactor.
|
||||
//! @param r1 Second reactor.
|
||||
//! @param name Name of the connector.
|
||||
ConnectorNode(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)") : m_nodes({r0, r1}), m_name(name) {}
|
||||
|
||||
virtual ~ConnectorNode() = default;
|
||||
ConnectorNode(const ConnectorNode&) = delete;
|
||||
ConnectorNode& operator=(const ConnectorNode&) = delete;
|
||||
|
||||
//! String indicating the connector implemented. Usually
|
||||
//! corresponds to the name of the derived class.
|
||||
virtual string type() const {
|
||||
return "ConnectorNode";
|
||||
}
|
||||
|
||||
//! Retrieve connector name.
|
||||
string name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//! Set connector name.
|
||||
void setName(const string& name) {
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//! Set the default name of a connector. Returns `false` if it was previously set.
|
||||
void setDefaultName(map<string, int>& counts);
|
||||
|
||||
protected:
|
||||
//! Pair of reactors forming end points of the connector.
|
||||
pair<shared_ptr<ReactorBase>, shared_ptr<ReactorBase>> m_nodes;
|
||||
|
||||
string m_name; //!< ConnectorNode name.
|
||||
bool m_defaultNameSet = false; //!< `true` if default name has been previously set.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
#include "cantera/base/ct_defs.h"
|
||||
#include "cantera/base/global.h"
|
||||
#include "cantera/base/ctexceptions.h"
|
||||
#include "ConnectorNode.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
@ -18,36 +19,19 @@ class ReactorBase;
|
||||
/**
|
||||
* Base class for 'flow devices' (valves, pressure regulators, etc.)
|
||||
* connecting reactors.
|
||||
* @ingroup flowDeviceGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class FlowDevice
|
||||
class FlowDevice : public ConnectorNode
|
||||
{
|
||||
public:
|
||||
FlowDevice(const string& name="(none)") : m_name(name) {}
|
||||
FlowDevice(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)");
|
||||
using ConnectorNode::ConnectorNode; // inherit constructors
|
||||
|
||||
virtual ~FlowDevice() = default;
|
||||
FlowDevice(const FlowDevice&) = delete;
|
||||
FlowDevice& operator=(const FlowDevice&) = delete;
|
||||
|
||||
//! String indicating the flow device implemented. Usually
|
||||
//! corresponds to the name of the derived class.
|
||||
virtual string type() const {
|
||||
string type() const override {
|
||||
return "FlowDevice";
|
||||
}
|
||||
|
||||
//! Retrieve flow device name.
|
||||
string name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//! Set flow device name.
|
||||
void setName(const string& name) {
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//! Set the default name of a flow device. Returns `false` if it was previously set.
|
||||
bool setDefaultName(map<string, int>& counts);
|
||||
|
||||
//! Mass flow rate (kg/s).
|
||||
double massFlowRate() {
|
||||
if (m_mdot == Undef) {
|
||||
@ -73,6 +57,8 @@ public:
|
||||
/*!
|
||||
* @param in Upstream reactor.
|
||||
* @param out Downstream reactor.
|
||||
* @deprecated To be removed after %Cantera 3.2. Reactors should be provided to
|
||||
* constructor instead.
|
||||
*/
|
||||
bool install(ReactorBase& in, ReactorBase& out);
|
||||
|
||||
@ -133,9 +119,6 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
string m_name; //!< Flow device name.
|
||||
bool m_defaultNameSet = false; //!< `true` if default name has been previously set.
|
||||
|
||||
double m_mdot = Undef;
|
||||
|
||||
//! Function set by setPressureFunction; used by updateMassFlowRate
|
||||
|
@ -6,48 +6,9 @@
|
||||
#ifndef FLOWDEVICE_FACTORY_H
|
||||
#define FLOWDEVICE_FACTORY_H
|
||||
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
#include "cantera/zeroD/FlowDevice.h"
|
||||
#pragma message("warning: FlowDeviceFactory.h is deprecated and will be removed " \
|
||||
"after Cantera 3.2. Use ConnectorFactory.h instead.")
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
//! Factory class to create FlowDevice objects.
|
||||
//!
|
||||
//! This class is mainly used via the newFlowDevice() function, for example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<FlowDevice> mfc = newFlowDevice("MassFlowController");
|
||||
//! ```
|
||||
class FlowDeviceFactory : public Factory<FlowDevice, const string&>
|
||||
{
|
||||
public:
|
||||
static FlowDeviceFactory* factory();
|
||||
|
||||
void deleteFactory() override;
|
||||
|
||||
private:
|
||||
static FlowDeviceFactory* s_factory;
|
||||
static std::mutex flowDevice_mutex;
|
||||
FlowDeviceFactory();
|
||||
};
|
||||
|
||||
//! @defgroup flowDeviceGroup Flow Devices
|
||||
//! Flow device objects connect zero-dimensional reactors.
|
||||
//! FlowDevice objects should be instantiated via the newFlowDevice function, for
|
||||
//! example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<FlowDevice> mfc = newFlowDevice("MassFlowController", "my_mfc");
|
||||
//! ```
|
||||
//! @ingroup zerodGroup
|
||||
//! @{
|
||||
|
||||
//! Create a FlowDevice object of the specified type
|
||||
//! @since Starting in %Cantera 3.1, this method returns a `shared_ptr<FlowDevice>`
|
||||
shared_ptr<FlowDevice> newFlowDevice(const string& model, const string& name="(none)");
|
||||
|
||||
//! @}
|
||||
}
|
||||
#include "ConnectorFactory.h"
|
||||
|
||||
#endif
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
//! Set the Solution specifying the ReactorBase content.
|
||||
//! @param sol Solution object to be set.
|
||||
//! @since New in %Cantera 3.1.
|
||||
//! @deprecated To be removed after %Cantera 3.2. Superseded by instantiation of
|
||||
//! ReactorBase with Solution object.
|
||||
void setSolution(shared_ptr<Solution> sol);
|
||||
|
||||
//! @name Methods to set up a simulation
|
||||
|
@ -16,7 +16,6 @@ class SurfPhase;
|
||||
|
||||
//! A surface where reactions can occur that is in contact with the bulk fluid of a
|
||||
//! Reactor.
|
||||
//! @ingroup wallGroup
|
||||
class ReactorSurface
|
||||
{
|
||||
public:
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "cantera/base/ctexceptions.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
#include "ConnectorNode.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
@ -16,36 +17,19 @@ class Func1;
|
||||
|
||||
/**
|
||||
* Base class for 'walls' (walls, pistons, etc.) connecting reactors.
|
||||
* @ingroup wallGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class WallBase
|
||||
class WallBase : public ConnectorNode
|
||||
{
|
||||
public:
|
||||
WallBase(const string& name="(none)") : m_name(name) {}
|
||||
WallBase(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
|
||||
const string& name="(none)");
|
||||
using ConnectorNode::ConnectorNode; // inherit constructors
|
||||
|
||||
virtual ~WallBase() {}
|
||||
WallBase(const WallBase&) = delete;
|
||||
WallBase& operator=(const WallBase&) = delete;
|
||||
|
||||
//! String indicating the wall model implemented. Usually
|
||||
//! corresponds to the name of the derived class.
|
||||
virtual string type() const {
|
||||
string type() const override {
|
||||
return "WallBase";
|
||||
}
|
||||
|
||||
//! Retrieve wall name.
|
||||
string name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//! Set wall name.
|
||||
void setName(const string& name) {
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//! Set the default name of a wall. Returns `false` if it was previously set.
|
||||
bool setDefaultName(map<string, int>& counts);
|
||||
|
||||
//! Rate of volume change (m^3/s) for the adjacent reactors at current reactor
|
||||
//! network time.
|
||||
/*!
|
||||
@ -76,6 +60,8 @@ public:
|
||||
virtual void setArea(double a);
|
||||
|
||||
//! Install the wall between two reactors or reservoirs
|
||||
//! @deprecated To be removed after %Cantera 3.2. Reactors should be provided to
|
||||
//! constructor instead.
|
||||
bool install(ReactorBase& leftReactor, ReactorBase& rightReactor);
|
||||
|
||||
//! Called just before the start of integration
|
||||
@ -105,9 +91,6 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
string m_name; //!< Wall name.
|
||||
bool m_defaultNameSet = false; //!< `true` if default name has been previously set.
|
||||
|
||||
ReactorBase* m_left = nullptr;
|
||||
ReactorBase* m_right = nullptr;
|
||||
|
||||
@ -121,7 +104,7 @@ protected:
|
||||
/*!
|
||||
* Walls can move (changing the volume of the adjacent reactors) and allow heat
|
||||
* transfer between reactors.
|
||||
* @ingroup wallGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class Wall : public WallBase
|
||||
{
|
||||
|
@ -6,49 +6,9 @@
|
||||
#ifndef WALL_FACTORY_H
|
||||
#define WALL_FACTORY_H
|
||||
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
#pragma message("warning: WallFactory.h is deprecated and will be removed " \
|
||||
"after Cantera 3.2. Use ConnectorFactory.h instead.")
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
//! Factory class to create WallBase objects
|
||||
//!
|
||||
//! This class is mainly used via the newWall() function, for example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<WallBase> piston = newWall("Wall");
|
||||
//! ```
|
||||
class WallFactory : public Factory<WallBase, const string&>
|
||||
{
|
||||
public:
|
||||
static WallFactory* factory();
|
||||
|
||||
void deleteFactory() override;
|
||||
|
||||
private:
|
||||
static WallFactory* s_factory;
|
||||
static std::mutex wall_mutex;
|
||||
WallFactory();
|
||||
};
|
||||
|
||||
//! @defgroup wallGroup Walls
|
||||
//! Zero-dimensional objects adjacent to reactors.
|
||||
//! Wall objects should be instantiated via the newWall function, for
|
||||
//! example:
|
||||
//!
|
||||
//! ```cpp
|
||||
//! shared_ptr<WallBase> piston = newWall("Wall", "my_piston");
|
||||
//! ```
|
||||
//! @ingroup zerodGroup
|
||||
//! @{
|
||||
|
||||
//! Create a WallBase object of the specified type
|
||||
//! @since Starting in %Cantera 3.1, this method returns a `shared_ptr<WallBase>`
|
||||
shared_ptr<WallBase> newWall(const string& model, const string& name="(none)");
|
||||
|
||||
//! @}
|
||||
|
||||
}
|
||||
#include "ConnectorFactory.h"
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@ namespace Cantera
|
||||
/**
|
||||
* A class for mass flow controllers. The mass flow rate is constant or
|
||||
* specified as a function of time.
|
||||
* @ingroup flowDeviceGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class MassFlowController : public FlowDevice
|
||||
{
|
||||
@ -60,7 +60,7 @@ public:
|
||||
* A class for flow controllers where the flow rate is equal to the flow rate
|
||||
* of a primary mass flow controller plus a correction proportional to the
|
||||
* pressure difference between the inlet and outlet.
|
||||
* @ingroup flowDeviceGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class PressureController : public FlowDevice
|
||||
{
|
||||
@ -118,7 +118,7 @@ protected:
|
||||
* The default behavior is a linearly proportional to the pressure difference.
|
||||
* Note that real valves do not have this behavior, so this class does not
|
||||
* model real, physical valves.
|
||||
* @ingroup flowDeviceGroup
|
||||
* @ingroup connectorGroup
|
||||
*/
|
||||
class Valve : public FlowDevice
|
||||
{
|
||||
|
@ -33,8 +33,7 @@
|
||||
|
||||
// factories
|
||||
#include "cantera/zeroD/ReactorFactory.h"
|
||||
#include "cantera/zeroD/FlowDeviceFactory.h"
|
||||
#include "cantera/zeroD/WallFactory.h"
|
||||
#include "cantera/zeroD/ConnectorFactory.h"
|
||||
|
||||
// func1
|
||||
#include "cantera/numerics/Func1.h"
|
||||
|
@ -32,12 +32,11 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
# factories
|
||||
cdef shared_ptr[CxxReactorBase] newReactor(string) except +translate_exception
|
||||
cdef shared_ptr[CxxReactorBase] newReactor(string, shared_ptr[CxxSolution], string) except +translate_exception
|
||||
cdef shared_ptr[CxxFlowDevice] newFlowDevice(string, string) except +translate_exception
|
||||
cdef shared_ptr[CxxWallBase] newWall(string, string) except +translate_exception
|
||||
cdef shared_ptr[CxxConnectorNode] newConnectorNode(string, shared_ptr[CxxReactorBase], shared_ptr[CxxReactorBase], string) except +translate_exception
|
||||
|
||||
# reactors
|
||||
cdef cppclass CxxReactorBase "Cantera::ReactorBase":
|
||||
CxxReactorBase()
|
||||
CxxReactorBase() except +translate_exception
|
||||
string type()
|
||||
void setSolution(shared_ptr[CxxSolution]) except +translate_exception
|
||||
void restoreState() except +translate_exception
|
||||
@ -48,7 +47,7 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
void setInitialVolume(double)
|
||||
|
||||
cdef cppclass CxxReactor "Cantera::Reactor" (CxxReactorBase):
|
||||
CxxReactor()
|
||||
CxxReactor() except +translate_exception
|
||||
void setChemistry(cbool)
|
||||
cbool chemistryEnabled()
|
||||
void setEnergy(int)
|
||||
@ -59,7 +58,7 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
void getState(double*) except +translate_exception
|
||||
CxxSparseMatrix jacobian() except +translate_exception
|
||||
CxxSparseMatrix finiteDifferenceJacobian() except +translate_exception
|
||||
void addSurface(CxxReactorSurface*)
|
||||
void addSurface(CxxReactorSurface*) except +translate_exception
|
||||
void setAdvanceLimit(string&, double) except +translate_exception
|
||||
void addSensitivityReaction(size_t) except +translate_exception
|
||||
void addSensitivitySpeciesEnthalpy(size_t) except +translate_exception
|
||||
@ -82,40 +81,6 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
int inletSurfaceMaxErrorFailures()
|
||||
void setInletSurfaceMaxErrorFailures(int) except +translate_exception
|
||||
|
||||
# walls
|
||||
cdef cppclass CxxWallBase "Cantera::WallBase":
|
||||
CxxWallBase()
|
||||
string type()
|
||||
string name()
|
||||
void setName(string) except +translate_exception
|
||||
cbool install(CxxReactorBase&, CxxReactorBase&)
|
||||
double area()
|
||||
void setArea(double)
|
||||
void setKinetics(CxxKinetics*, CxxKinetics*)
|
||||
void setCoverages(int, double*)
|
||||
void setCoverages(int, Composition&) except +translate_exception
|
||||
void syncCoverages(int)
|
||||
double expansionRate() except +translate_exception
|
||||
double vdot(double) except +translate_exception
|
||||
double heatRate() except +translate_exception
|
||||
double Q(double) except +translate_exception
|
||||
|
||||
void addSensitivityReaction(int, size_t) except +translate_exception
|
||||
size_t nSensParams(int)
|
||||
|
||||
cdef cppclass CxxWall "Cantera::Wall" (CxxWallBase):
|
||||
CxxWall()
|
||||
void setExpansionRateCoeff(double)
|
||||
double getExpansionRateCoeff()
|
||||
void setHeatTransferCoeff(double)
|
||||
double getHeatTransferCoeff()
|
||||
void setEmissivity(double) except +translate_exception
|
||||
double getEmissivity()
|
||||
double velocity()
|
||||
void setVelocity(CxxFunc1*)
|
||||
double heatFlux()
|
||||
void setHeatFlux(CxxFunc1*)
|
||||
|
||||
# reactor surface
|
||||
|
||||
cdef cppclass CxxReactorSurface "Cantera::ReactorSurface":
|
||||
@ -132,25 +97,59 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
void addSensitivityReaction(size_t) except +translate_exception
|
||||
size_t nSensParams()
|
||||
|
||||
# flow devices
|
||||
# connectors
|
||||
|
||||
cdef cppclass CxxFlowDevice "Cantera::FlowDevice":
|
||||
CxxFlowDevice()
|
||||
cdef cppclass CxxConnectorNode "Cantera::ConnectorNode":
|
||||
CxxConnectorNode() except +translate_exception
|
||||
string type()
|
||||
string name()
|
||||
void setName(string) except +translate_exception
|
||||
|
||||
# walls
|
||||
cdef cppclass CxxWallBase "Cantera::WallBase" (CxxConnectorNode ):
|
||||
CxxWallBase() except +translate_exception
|
||||
double area()
|
||||
void setArea(double)
|
||||
void setKinetics(CxxKinetics*, CxxKinetics*)
|
||||
void setCoverages(int, double*)
|
||||
void setCoverages(int, Composition&) except +translate_exception
|
||||
void syncCoverages(int)
|
||||
double expansionRate() except +translate_exception
|
||||
double vdot(double) except +translate_exception
|
||||
double heatRate() except +translate_exception
|
||||
double Q(double) except +translate_exception
|
||||
|
||||
void addSensitivityReaction(int, size_t) except +translate_exception
|
||||
size_t nSensParams(int)
|
||||
|
||||
cdef cppclass CxxWall "Cantera::Wall" (CxxWallBase):
|
||||
CxxWall() except +translate_exception
|
||||
void setExpansionRateCoeff(double)
|
||||
double getExpansionRateCoeff()
|
||||
void setHeatTransferCoeff(double)
|
||||
double getHeatTransferCoeff()
|
||||
void setEmissivity(double) except +translate_exception
|
||||
double getEmissivity()
|
||||
double velocity()
|
||||
void setVelocity(CxxFunc1*)
|
||||
double heatFlux()
|
||||
void setHeatFlux(CxxFunc1*)
|
||||
|
||||
# flow devices
|
||||
|
||||
cdef cppclass CxxFlowDevice "Cantera::FlowDevice" (CxxConnectorNode):
|
||||
CxxFlowDevice() except +translate_exception
|
||||
double massFlowRate() except +translate_exception
|
||||
double massFlowRate(double) except +translate_exception
|
||||
cbool install(CxxReactorBase&, CxxReactorBase&) except +translate_exception
|
||||
double evalPressureFunction() except +translate_exception
|
||||
void setPressureFunction(CxxFunc1*) except +translate_exception
|
||||
double evalTimeFunction() except +translate_exception
|
||||
void setTimeFunction(CxxFunc1*) except +translate_exception
|
||||
|
||||
cdef cppclass CxxMassFlowController "Cantera::MassFlowController" (CxxFlowDevice):
|
||||
CxxMassFlowController()
|
||||
void setMassFlowRate(double)
|
||||
void setMassFlowCoeff(double)
|
||||
CxxMassFlowController() except +translate_exception
|
||||
void setMassFlowRate(double) except +translate_exception
|
||||
void setMassFlowCoeff(double) except +translate_exception
|
||||
double getMassFlowCoeff()
|
||||
|
||||
cdef cppclass CxxValve "Cantera::Valve" (CxxFlowDevice):
|
||||
@ -225,7 +224,7 @@ ctypedef CxxReactorAccessor* CxxReactorAccessorPtr
|
||||
cdef class ReactorBase:
|
||||
cdef shared_ptr[CxxReactorBase] _reactor
|
||||
cdef CxxReactorBase* rbase
|
||||
cdef object _thermo
|
||||
cdef object _contents
|
||||
cdef list _inlets
|
||||
cdef list _outlets
|
||||
cdef list _walls
|
||||
@ -241,7 +240,6 @@ cdef class ReactorBase:
|
||||
|
||||
cdef class Reactor(ReactorBase):
|
||||
cdef CxxReactor* reactor
|
||||
cdef object _kinetics
|
||||
cdef public str group_name
|
||||
"""
|
||||
Optional name of a grouping of reactors that will be drawn as a cluster in the
|
||||
@ -289,14 +287,9 @@ cdef class ReactorSurface:
|
||||
.. versionadded:: 3.1
|
||||
"""
|
||||
|
||||
cdef class WallBase:
|
||||
cdef shared_ptr[CxxWallBase] _wall
|
||||
cdef CxxWallBase* wall
|
||||
cdef object _velocity_func
|
||||
cdef object _heat_flux_func
|
||||
cdef ReactorBase _left_reactor
|
||||
cdef ReactorBase _right_reactor
|
||||
cdef str name
|
||||
cdef class ConnectorNode:
|
||||
cdef shared_ptr[CxxConnectorNode] _node
|
||||
cdef CxxConnectorNode* node
|
||||
cdef public dict edge_attr
|
||||
"""
|
||||
A dictionary containing draw attributes for the representation of the `WallBase` as
|
||||
@ -306,25 +299,24 @@ cdef class WallBase:
|
||||
.. versionadded:: 3.1
|
||||
"""
|
||||
|
||||
cdef class WallBase(ConnectorNode):
|
||||
# cdef shared_ptr[CxxWallBase] _wall
|
||||
cdef CxxWallBase* wall
|
||||
cdef object _velocity_func
|
||||
cdef object _heat_flux_func
|
||||
cdef ReactorBase _left_reactor
|
||||
cdef ReactorBase _right_reactor
|
||||
|
||||
cdef class Wall(WallBase):
|
||||
pass
|
||||
|
||||
cdef class FlowDevice:
|
||||
cdef shared_ptr[CxxFlowDevice] _dev
|
||||
cdef class FlowDevice(ConnectorNode):
|
||||
# cdef shared_ptr[CxxFlowDevice] _dev
|
||||
cdef CxxFlowDevice* dev
|
||||
cdef Func1 _rate_func
|
||||
cdef Func1 _time_func
|
||||
cdef str name
|
||||
cdef ReactorBase _upstream
|
||||
cdef ReactorBase _downstream
|
||||
cdef public dict edge_attr
|
||||
"""
|
||||
A dictionary containing draw attributes for the representation of the `FlowDevice`
|
||||
as a graphviz edge.See https://graphviz.org/docs/edges/ for a list of all usable
|
||||
attributes.
|
||||
|
||||
.. versionadded:: 3.1
|
||||
"""
|
||||
|
||||
cdef class MassFlowController(FlowDevice):
|
||||
pass
|
||||
|
@ -28,7 +28,7 @@ cdef class ReactorBase:
|
||||
self._walls = []
|
||||
self._surfaces = []
|
||||
if isinstance(contents, _SolutionBase):
|
||||
self.insert(contents) # leave insert for the time being
|
||||
self._contents = contents
|
||||
|
||||
if volume is not None:
|
||||
self.volume = volume
|
||||
@ -39,9 +39,14 @@ cdef class ReactorBase:
|
||||
"""
|
||||
Set ``solution`` to be the object used to compute thermodynamic
|
||||
properties and kinetic rates for this reactor.
|
||||
|
||||
.. deprecated:: 3.2
|
||||
|
||||
After Cantera 3.2, a change of reactor contents after instantiation
|
||||
will be disabled and this method will be removed.
|
||||
"""
|
||||
self._thermo = solution
|
||||
self.rbase.setSolution(solution._base)
|
||||
self.rbase.setSolution(solution._base) # raises warning in C++ core
|
||||
self._contents = solution
|
||||
|
||||
property type:
|
||||
"""The type of the reactor."""
|
||||
@ -64,10 +69,12 @@ cdef class ReactorBase:
|
||||
self.rbase.syncState()
|
||||
|
||||
property thermo:
|
||||
"""The `ThermoPhase` object representing the reactor's contents."""
|
||||
"""
|
||||
The `ThermoPhase` object representing the reactor's contents.
|
||||
"""
|
||||
def __get__(self):
|
||||
self.rbase.restoreState()
|
||||
return self._thermo
|
||||
return self._contents
|
||||
|
||||
property volume:
|
||||
"""The volume [m^3] of the reactor."""
|
||||
@ -239,14 +246,6 @@ cdef class Reactor(ReactorBase):
|
||||
|
||||
self.group_name = group_name
|
||||
|
||||
def insert(self, _SolutionBase solution):
|
||||
"""
|
||||
Set ``solution`` to be the object used to compute thermodynamic
|
||||
properties and kinetic rates for this reactor.
|
||||
"""
|
||||
ReactorBase.insert(self, solution)
|
||||
self._kinetics = solution
|
||||
|
||||
property kinetics:
|
||||
"""
|
||||
The `Kinetics` object used for calculating kinetic rates in
|
||||
@ -254,7 +253,7 @@ cdef class Reactor(ReactorBase):
|
||||
"""
|
||||
def __get__(self):
|
||||
self.rbase.restoreState()
|
||||
return self._kinetics
|
||||
return self._contents
|
||||
|
||||
property chemistry_enabled:
|
||||
"""
|
||||
@ -939,14 +938,52 @@ cdef class ReactorSurface:
|
||||
self.surface.addSensitivityReaction(m)
|
||||
|
||||
|
||||
cdef class WallBase:
|
||||
cdef class ConnectorNode:
|
||||
"""
|
||||
Common base class for walls and flow devices.
|
||||
"""
|
||||
node_type = "none"
|
||||
|
||||
def __cinit__(self, ReactorBase left=None, ReactorBase right=None, *,
|
||||
ReactorBase upstream=None, ReactorBase downstream=None,
|
||||
name="(none)", **kwargs):
|
||||
# ensure that both naming conventions (Wall and FlowDevice) are covered
|
||||
cdef ReactorBase r0 = left or upstream
|
||||
cdef ReactorBase r1 = right or downstream
|
||||
if isinstance(r0, ReactorBase) and isinstance(r1, ReactorBase):
|
||||
self._node = newConnectorNode(stringify(self.node_type),
|
||||
r0._reactor, r1._reactor, stringify(name))
|
||||
self.node = self._node.get()
|
||||
return
|
||||
raise TypeError(f"Invalid reactor types: {r0} and {r1}.")
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""The type of the connector."""
|
||||
return pystr(self.node.type())
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the connector."""
|
||||
return pystr(self.node.name())
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
self.node.setName(stringify(name))
|
||||
|
||||
def __reduce__(self):
|
||||
raise NotImplementedError('Reactor object is not picklable')
|
||||
|
||||
def __copy__(self):
|
||||
raise NotImplementedError('Reactor object is not copyable')
|
||||
|
||||
|
||||
cdef class WallBase(ConnectorNode):
|
||||
"""
|
||||
Common base class for walls.
|
||||
"""
|
||||
wall_type = "none"
|
||||
def __cinit__(self, *args, name="(none)", **kwargs):
|
||||
self._wall = newWall(stringify(self.wall_type), stringify(name))
|
||||
self.wall = self._wall.get()
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.wall = <CxxWall*>(self.node)
|
||||
|
||||
def __init__(self, left, right, *, name="(none)", A=None, K=None, U=None,
|
||||
Q=None, velocity=None, edge_attr=None):
|
||||
@ -985,8 +1022,6 @@ cdef class WallBase:
|
||||
self._velocity_func = None
|
||||
self._heat_flux_func = None
|
||||
|
||||
self._install(left, right)
|
||||
|
||||
if A is not None:
|
||||
self.area = A
|
||||
if K is not None:
|
||||
@ -999,30 +1034,12 @@ cdef class WallBase:
|
||||
self.velocity = velocity
|
||||
self.edge_attr = edge_attr or {}
|
||||
|
||||
def _install(self, ReactorBase left, ReactorBase right):
|
||||
"""
|
||||
Install this Wall between two `Reactor` objects or between a
|
||||
`Reactor` and a `Reservoir`.
|
||||
"""
|
||||
left._add_wall(self)
|
||||
right._add_wall(self)
|
||||
self.wall.install(deref(left.rbase), deref(right.rbase))
|
||||
# Keep references to prevent premature garbage collection
|
||||
self._left_reactor = left
|
||||
self._right_reactor = right
|
||||
|
||||
property type:
|
||||
"""The type of the wall."""
|
||||
def __get__(self):
|
||||
return pystr(self.wall.type())
|
||||
|
||||
property name:
|
||||
"""The name of the wall."""
|
||||
def __get__(self):
|
||||
return pystr(self.wall.name())
|
||||
def __set__(self, name):
|
||||
self.wall.setName(stringify(name))
|
||||
|
||||
property area:
|
||||
""" The wall area [m^2]. """
|
||||
def __get__(self):
|
||||
@ -1138,7 +1155,7 @@ cdef class Wall(WallBase):
|
||||
:math:`q_0(t)` is a specified function of time. The heat flux is positive
|
||||
when heat flows from the reactor on the left to the reactor on the right.
|
||||
"""
|
||||
wall_type = "Wall"
|
||||
node_type = "Wall"
|
||||
|
||||
property expansion_rate_coeff:
|
||||
"""
|
||||
@ -1207,7 +1224,7 @@ cdef class Wall(WallBase):
|
||||
(<CxxWall*>self.wall).setHeatFlux(f.func)
|
||||
|
||||
|
||||
cdef class FlowDevice:
|
||||
cdef class FlowDevice(ConnectorNode):
|
||||
"""
|
||||
Base class for devices that allow flow between reactors.
|
||||
|
||||
@ -1218,37 +1235,15 @@ cdef class FlowDevice:
|
||||
across a FlowDevice, and the pressure difference equals the difference in
|
||||
pressure between the upstream and downstream reactors.
|
||||
"""
|
||||
flowdevice_type = "none"
|
||||
def __cinit__(self, *args, name="(none)", **kwargs):
|
||||
self._dev = newFlowDevice(stringify(self.flowdevice_type), stringify(name))
|
||||
self.dev = self._dev.get()
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.dev = <CxxFlowDevice*>(self.node)
|
||||
|
||||
def __init__(self, upstream, downstream, *, name="(none)", edge_attr=None):
|
||||
assert self.dev != NULL
|
||||
self._rate_func = None
|
||||
self.edge_attr = edge_attr or {}
|
||||
self._install(upstream, downstream)
|
||||
|
||||
property type:
|
||||
"""The type of the flow device."""
|
||||
def __get__(self):
|
||||
return pystr(self.dev.type())
|
||||
|
||||
property name:
|
||||
"""The name of the flow device."""
|
||||
def __get__(self):
|
||||
return pystr(self.dev.name())
|
||||
def __set__(self, name):
|
||||
self.dev.setName(stringify(name))
|
||||
|
||||
def _install(self, ReactorBase upstream, ReactorBase downstream):
|
||||
"""
|
||||
Install the device between the ``upstream`` (source) and ``downstream``
|
||||
(destination) reactors or reservoirs.
|
||||
"""
|
||||
upstream._add_outlet(self)
|
||||
downstream._add_inlet(self)
|
||||
self.dev.install(deref(upstream.rbase), deref(downstream.rbase))
|
||||
# Keep references to prevent premature garbage collection
|
||||
self._upstream = upstream
|
||||
self._downstream = downstream
|
||||
@ -1387,10 +1382,10 @@ cdef class MassFlowController(FlowDevice):
|
||||
that this capability should be used with caution, since no account is
|
||||
taken of the work required to do this.
|
||||
"""
|
||||
flowdevice_type = "MassFlowController"
|
||||
node_type = "MassFlowController"
|
||||
|
||||
def __init__(self, upstream, downstream, *, name="(none)", mdot=1., **kwargs):
|
||||
super().__init__(upstream, downstream, name=name, **kwargs)
|
||||
def __init__(self, upstream, downstream, *, name="(none)", mdot=1., edge_attr=None):
|
||||
super().__init__(upstream, downstream, name=name, edge_attr=edge_attr)
|
||||
self.mass_flow_rate = mdot
|
||||
|
||||
property mass_flow_coeff:
|
||||
@ -1461,10 +1456,10 @@ cdef class Valve(FlowDevice):
|
||||
value, very small pressure differences will result in flow between the
|
||||
reactors that counteracts the pressure difference.
|
||||
"""
|
||||
flowdevice_type = "Valve"
|
||||
node_type = "Valve"
|
||||
|
||||
def __init__(self, upstream, downstream, *, name="(none)", K=1., **kwargs):
|
||||
super().__init__(upstream, downstream, name=name, **kwargs)
|
||||
def __init__(self, upstream, downstream, *, name="(none)", K=1., edge_attr=None):
|
||||
super().__init__(upstream, downstream, name=name, edge_attr=edge_attr)
|
||||
if isinstance(K, _numbers.Real):
|
||||
self.valve_coeff = K
|
||||
else:
|
||||
@ -1504,10 +1499,11 @@ cdef class PressureController(FlowDevice):
|
||||
|
||||
where :math:`f` is the arbitrary function of a single argument.
|
||||
"""
|
||||
flowdevice_type = "PressureController"
|
||||
node_type = "PressureController"
|
||||
|
||||
def __init__(self, upstream, downstream, *, name="(none)", primary=None, K=1.):
|
||||
super().__init__(upstream, downstream, name=name)
|
||||
def __init__(self, upstream, downstream, *,
|
||||
name="(none)", primary=None, K=1., edge_attr=None):
|
||||
super().__init__(upstream, downstream, name=name, edge_attr=edge_attr)
|
||||
if primary is not None:
|
||||
self.primary = primary
|
||||
if isinstance(K, _numbers.Real):
|
||||
|
@ -1,4 +1,4 @@
|
||||
classdef Interface < handle & ThermoPhase & Kinetics
|
||||
classdef Interface < Solution
|
||||
% Interface Class ::
|
||||
%
|
||||
% >> s = Interface(src, name, p1, p2)
|
||||
@ -13,11 +13,6 @@ classdef Interface < handle & ThermoPhase & Kinetics
|
||||
% :return:
|
||||
% Instance of class :mat:class:`Interface`.
|
||||
|
||||
properties (SetAccess = immutable)
|
||||
solnID % ID of the interface.
|
||||
interfaceName % Name of the interface.
|
||||
end
|
||||
|
||||
properties (SetAccess = public)
|
||||
|
||||
% Surface coverages of the species on an interface.
|
||||
@ -50,11 +45,8 @@ classdef Interface < handle & ThermoPhase & Kinetics
|
||||
|
||||
ID = ctFunc('soln_newInterface', src, name, na, adj);
|
||||
|
||||
% Inherit methods and properties from ThermoPhase and Kinetics
|
||||
s@ThermoPhase(ID);
|
||||
s@Kinetics(ID);
|
||||
s.solnID = ID;
|
||||
s.interfaceName = name;
|
||||
% Inherit methods and properties from Solution
|
||||
s@Solution(ID);
|
||||
s.nAdjacent = ctFunc('soln_nAdjacent', ID);
|
||||
s.adjacentNames = {};
|
||||
for i = 1:s.nAdjacent
|
||||
@ -62,13 +54,6 @@ classdef Interface < handle & ThermoPhase & Kinetics
|
||||
end
|
||||
end
|
||||
|
||||
%% Interface Class Destructor
|
||||
|
||||
function delete(s)
|
||||
% Delete :mat:class:`Interface` object.
|
||||
ctFunc('soln_del', s.solnID);
|
||||
end
|
||||
|
||||
%% Interface Get Methods
|
||||
|
||||
function adj = adjacent(s, name)
|
||||
|
84
interfaces/matlab_experimental/Reactor/Connector.m
Normal file
84
interfaces/matlab_experimental/Reactor/Connector.m
Normal file
@ -0,0 +1,84 @@
|
||||
classdef Connector < handle
|
||||
% Connector Class ::
|
||||
%
|
||||
% >> c = Connector(typ, r1, r2, name)
|
||||
%
|
||||
% Base class for walls and flow devices.
|
||||
%
|
||||
% See also: :mat:class:`FlowDevice`, :mat:class:`Wall`
|
||||
%
|
||||
% :param typ:
|
||||
% Type of connector.
|
||||
% :param r1:
|
||||
% Reactor one.
|
||||
% :param r2:
|
||||
% Reactor two.
|
||||
% :param name:
|
||||
% Connector name (optional; default is ``(none)``).
|
||||
% :return:
|
||||
% Instance of class :mat:class:`Connector`.
|
||||
|
||||
properties (SetAccess = immutable)
|
||||
|
||||
id % ID of Connector object.
|
||||
|
||||
end
|
||||
|
||||
properties (SetAccess = public)
|
||||
|
||||
type % Name of connector.
|
||||
|
||||
name % Name of connector.
|
||||
|
||||
end
|
||||
|
||||
methods
|
||||
%% Connector Class Constructor
|
||||
|
||||
function c = Connector(typ, r1, r2, name)
|
||||
% Create a :mat:class:`Connector` object.
|
||||
|
||||
ctIsLoaded;
|
||||
|
||||
if nargin < 3
|
||||
error('please specify type and reactors');
|
||||
end
|
||||
if nargin < 4
|
||||
name = '(none)';
|
||||
end
|
||||
|
||||
if ~isa(r1, 'Reactor') || ~isa(r1, 'Reactor')
|
||||
error(['Connectors can only be installed between', ...
|
||||
'reactors or reservoirs']);
|
||||
end
|
||||
|
||||
c.id = ctFunc('connector_new', typ, r1.id, r2.id, name);
|
||||
end
|
||||
|
||||
%% Connector Class Destructor
|
||||
|
||||
function delete(c)
|
||||
% Delete the :mat:class:`Connector` object.
|
||||
|
||||
ctFunc('connector_del', c.id);
|
||||
end
|
||||
|
||||
%% Connector Get Methods
|
||||
|
||||
function typ = get.type(c)
|
||||
typ = ctString('connector_type', c.id);
|
||||
end
|
||||
|
||||
function name = get.name(c)
|
||||
name = ctString('connector_name', c.id);
|
||||
end
|
||||
|
||||
%% Connector Set Methods
|
||||
|
||||
function set.name(c, name)
|
||||
ctFunc('connector_setName', c.id, name);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
classdef FlowDevice < handle
|
||||
classdef FlowDevice < Connector
|
||||
% FlowDevice Class ::
|
||||
%
|
||||
% >> x = FlowDevice(typ, name)
|
||||
@ -25,21 +25,16 @@ classdef FlowDevice < handle
|
||||
|
||||
properties (SetAccess = immutable)
|
||||
|
||||
type % Type of flow device.
|
||||
id % ID of FlowDevice object.
|
||||
|
||||
end
|
||||
|
||||
properties (SetAccess = public)
|
||||
|
||||
name % Name of flow device.
|
||||
|
||||
% Upstream object of type :mat:class:`Reactor` or :mat:class:`Reservoir`.
|
||||
upstream
|
||||
|
||||
% Downstream object of type :mat:class:`Reactor` or :mat:class:`Reservoir`.
|
||||
downstream
|
||||
|
||||
end
|
||||
|
||||
properties (SetAccess = public)
|
||||
|
||||
% The mass flow rate through the :mat:class:`FlowDevice` at the current time.
|
||||
%
|
||||
% The setter method can either take a double value or a function represented by
|
||||
@ -60,79 +55,28 @@ classdef FlowDevice < handle
|
||||
methods
|
||||
%% FlowDevice Class Constructor
|
||||
|
||||
function x = FlowDevice(typ, name)
|
||||
function x = FlowDevice(typ, upstream, downstream, name)
|
||||
% Create a :mat:class:`FlowDevice` object.
|
||||
|
||||
ctIsLoaded;
|
||||
|
||||
if nargin == 0
|
||||
error('please specify the type of flow device to be created');
|
||||
end
|
||||
if nargin < 2
|
||||
if nargin < 4
|
||||
name = '(none)';
|
||||
end
|
||||
|
||||
x.type = typ;
|
||||
x.id = ctFunc('flowdev_new', typ, name);
|
||||
x.upstream = -1;
|
||||
x.downstream = -1;
|
||||
end
|
||||
|
||||
%% FlowDevice Class Destructor
|
||||
|
||||
function delete(f)
|
||||
% Delete the :mat:class:`FlowDevice` object.
|
||||
|
||||
ctFunc('flowdev_del', f.id);
|
||||
end
|
||||
|
||||
%% Utility Methods
|
||||
|
||||
function install(f, upstream, downstream)
|
||||
% Install a flow device between reactors or reservoirs. ::
|
||||
%
|
||||
% >> f.install(upstream, downstream)
|
||||
%
|
||||
% :param f:
|
||||
% Instance of class :mat:class:`FlowDevice` to install.
|
||||
% :param upstream:
|
||||
% Upstream :mat:class:`Reactor` or :mat:class:`Reservoir`.
|
||||
% :param downstream:
|
||||
% Downstream :mat:class:`Reactor` or :mat:class:`Reservoir`.
|
||||
% :return:
|
||||
% Instance of class :mat:class:`FlowDevice`.
|
||||
|
||||
if nargin == 3
|
||||
|
||||
if ~isa(upstream, 'Reactor') || ~isa(downstream, 'Reactor')
|
||||
error(['Flow devices can only be installed between', ...
|
||||
'reactors or reservoirs']);
|
||||
end
|
||||
|
||||
i = upstream.id;
|
||||
j = downstream.id;
|
||||
ctFunc('flowdev_install', f.id, i, j);
|
||||
else error('install requires 3 arguments');
|
||||
end
|
||||
|
||||
x@Connector(typ, upstream, downstream, name)
|
||||
x.upstream = upstream;
|
||||
x.downstream = downstream;
|
||||
end
|
||||
|
||||
%% FlowDevice Get Methods
|
||||
|
||||
function name = get.name(f)
|
||||
name = ctString('flowdev_name', f.id);
|
||||
end
|
||||
|
||||
function mdot = get.massFlowRate(f)
|
||||
mdot = ctFunc('flowdev_massFlowRate2', f.id);
|
||||
end
|
||||
|
||||
%% FlowDevice Set Methods
|
||||
|
||||
function set.name(f, name)
|
||||
ctFunc('flowdev_setName', f.id, name);
|
||||
end
|
||||
|
||||
function set.massFlowRate(f, mdot)
|
||||
|
||||
if strcmp(f.type, 'MassFlowController')
|
||||
|
@ -31,8 +31,7 @@ classdef MassFlowController < FlowDevice
|
||||
name = '(none)';
|
||||
end
|
||||
|
||||
m@FlowDevice('MassFlowController', name);
|
||||
m.install(upstream, downstream)
|
||||
m@FlowDevice('MassFlowController', upstream, downstream, name);
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -2,13 +2,14 @@ classdef Reactor < handle
|
||||
|
||||
properties (SetAccess = immutable)
|
||||
|
||||
type % Type of Reactor.
|
||||
id % ID of Reactor.
|
||||
|
||||
end
|
||||
|
||||
properties (SetAccess = public)
|
||||
|
||||
type % Reactor type.
|
||||
|
||||
name % Name of reactor.
|
||||
|
||||
contents
|
||||
@ -131,8 +132,8 @@ classdef Reactor < handle
|
||||
error('Reactor contents must be an object of type "Solution"');
|
||||
end
|
||||
|
||||
r.type = char(typ);
|
||||
r.id = ctFunc('reactor_new', typ, content.solnID, name);
|
||||
r.contents = content;
|
||||
end
|
||||
|
||||
%% Reactor Class Destructor
|
||||
@ -160,6 +161,10 @@ classdef Reactor < handle
|
||||
|
||||
%% Reactor Get Methods
|
||||
|
||||
function typ = get.type(r)
|
||||
typ = ctString('reactor_type', r.id);
|
||||
end
|
||||
|
||||
function name = get.name(r)
|
||||
name = ctString('reactor_name', r.id);
|
||||
end
|
||||
|
@ -40,8 +40,7 @@ classdef Valve < FlowDevice
|
||||
name = '(none)';
|
||||
end
|
||||
|
||||
v@FlowDevice('Valve', name);
|
||||
v.install(upstream, downstream)
|
||||
v@FlowDevice('Valve', upstream, downstream, name);
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
classdef Wall < handle
|
||||
classdef Wall < Connector
|
||||
% Wall Class ::
|
||||
%
|
||||
% >> x = Wall(l, r, name)
|
||||
@ -47,15 +47,6 @@ classdef Wall < handle
|
||||
|
||||
properties (SetAccess = immutable)
|
||||
|
||||
id
|
||||
type
|
||||
|
||||
end
|
||||
|
||||
properties (SetAccess = protected)
|
||||
|
||||
name % Name of wall.
|
||||
|
||||
left % Reactor on the left.
|
||||
right % Reactor on the right.
|
||||
|
||||
@ -93,49 +84,26 @@ classdef Wall < handle
|
||||
|
||||
function w = Wall(l, r, name)
|
||||
% Create a :mat:class:`Wall` object.
|
||||
ctIsLoaded;
|
||||
|
||||
% At the moment, only one wall type is implemented
|
||||
typ = 'Wall';
|
||||
if nargin < 3
|
||||
name = '(none)';
|
||||
end
|
||||
|
||||
w.type = char(typ);
|
||||
w.id = ctFunc('wall_new', w.type, name);
|
||||
|
||||
% Install the wall between left and right reactors
|
||||
w@Connector('Wall', l, r, name)
|
||||
w.left = l;
|
||||
w.right = r;
|
||||
ctFunc('wall_install', w.id, l.id, r.id);
|
||||
|
||||
% Set default values.
|
||||
w.area = 1.0;
|
||||
w.expansionRateCoeff = 0.0;
|
||||
w.heatTransferCoeff = 0.0;
|
||||
|
||||
% Check whether the wall is ready.
|
||||
ok = ctFunc('wall_ready', w.id);
|
||||
if ~ok
|
||||
error('The wall object is not ready.');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%% Wall Class Destructor
|
||||
|
||||
function delete(w)
|
||||
% Clear the :mat:class:`Wall` object.
|
||||
|
||||
ctFunc('wall_del', w.id);
|
||||
end
|
||||
|
||||
%% ReactorNet get methods
|
||||
|
||||
function name = get.name(w)
|
||||
name = ctString('wall_name', w.id);
|
||||
end
|
||||
|
||||
function a = get.area(w)
|
||||
a = ctFunc('wall_area', w.id);
|
||||
end
|
||||
@ -150,10 +118,6 @@ classdef Wall < handle
|
||||
|
||||
%% ReactorNet set methods
|
||||
|
||||
function set.name(w, name)
|
||||
ctFunc('wall_setName', w.id, name);
|
||||
end
|
||||
|
||||
function set.area(w, a)
|
||||
ctFunc('wall_setArea', w.id, a);
|
||||
end
|
||||
|
@ -24,6 +24,7 @@ class_crosswalk:
|
||||
trans: Transport
|
||||
wall: Wall
|
||||
func: Func1
|
||||
connector: Connector
|
||||
|
||||
# Provides information on instance methods that return instances
|
||||
# of other C# classes.
|
||||
@ -42,6 +43,8 @@ class_accessors:
|
||||
# Derived: Base
|
||||
derived_handles:
|
||||
SurfaceHandle: ThermoPhaseHandle
|
||||
WallHandle: ConnectorHandle
|
||||
FlowDeviceHandle: ConnectorHandle
|
||||
|
||||
# Provides info for scaffolding higher-level idiomatic C# classes
|
||||
# At this stage, we can scaffold simple properties that follow the
|
||||
|
@ -73,8 +73,7 @@ function periodic_cstr
|
||||
sccm = 1.25;
|
||||
vdot = sccm * 1.0e-6/60.0 * ((OneAtm / gas.P) * (gas.T / 273.15)); % m^3/s
|
||||
mdot = gas.D * vdot; % kg/s
|
||||
mfc = MassFlowController;
|
||||
mfc.install(upstream, cstr);
|
||||
mfc = MassFlowController(upstream, cstr);
|
||||
mfc.massFlowRate = mdot;
|
||||
|
||||
% now create a downstream reservoir to exhaust into.
|
||||
@ -83,8 +82,7 @@ function periodic_cstr
|
||||
% connect the reactor to the downstream reservoir with a valve, and
|
||||
% set the coefficient sufficiently large to keep the reactor pressure
|
||||
% close to the downstream pressure of 60 Torr.
|
||||
v = Valve;
|
||||
v.install(cstr, downstream);
|
||||
v = Valve(cstr, downstream);
|
||||
v.valveCoeff = 1.0e-9;
|
||||
|
||||
% create the network
|
||||
|
@ -131,7 +131,7 @@ class SolidProperties:
|
||||
def effectiveConductivitySiC(Ts): # for silicon carbide
|
||||
return (1 - 0.84) * 1857.0 * Ts**(-0.5332)
|
||||
|
||||
# YZA: Thermal conductivity of zirconia–alumina composites, N.P. Bansal, D. Zhu,
|
||||
# YZA: Thermal conductivity of zirconia–alumina composites, N.P. Bansal, D. Zhu,
|
||||
# Ceramics International, 31(7), pp 911-916 (2015)
|
||||
def effectiveConductivityYZA(Ts): # for yittria-stabilized zirconia alumina
|
||||
return 0.3
|
||||
@ -409,3 +409,4 @@ plt.legend()
|
||||
plt.xlabel("x (m)")
|
||||
plt.ylabel("T (K)")
|
||||
plt.savefig("T.png")
|
||||
plt.show()
|
||||
|
@ -162,6 +162,7 @@ plt.figure()
|
||||
plt.semilogx(time_history.t, time_history("CO").X, "-o")
|
||||
plt.xlabel("Time (s)")
|
||||
plt.ylabel("Mole Fraction : $X_{CO}$")
|
||||
plt.show()
|
||||
|
||||
# %%
|
||||
# Illustration : Modeling experimental data
|
||||
@ -288,6 +289,7 @@ plt.ylabel(r"Mole Fractions")
|
||||
|
||||
plt.xlim([650, 1100])
|
||||
plt.legend(loc=1)
|
||||
plt.show()
|
||||
|
||||
# %%
|
||||
# References
|
||||
|
@ -19,8 +19,7 @@ using namespace Cantera;
|
||||
|
||||
typedef Cabinet<ReactorBase> ReactorCabinet;
|
||||
typedef Cabinet<ReactorNet> NetworkCabinet;
|
||||
typedef Cabinet<FlowDevice> FlowDeviceCabinet;
|
||||
typedef Cabinet<WallBase> WallCabinet;
|
||||
typedef Cabinet<ConnectorNode> ConnectorCabinet;
|
||||
typedef Cabinet<Func1> FuncCabinet;
|
||||
typedef Cabinet<ThermoPhase> ThermoCabinet;
|
||||
typedef Cabinet<Kinetics> KineticsCabinet;
|
||||
@ -29,8 +28,7 @@ typedef Cabinet<ReactorSurface> ReactorSurfaceCabinet;
|
||||
|
||||
template<> ReactorCabinet* ReactorCabinet::s_storage = 0;
|
||||
template<> NetworkCabinet* NetworkCabinet::s_storage = 0;
|
||||
template<> FlowDeviceCabinet* FlowDeviceCabinet::s_storage = 0;
|
||||
template<> WallCabinet* WallCabinet::s_storage = 0;
|
||||
template<> ConnectorCabinet* ConnectorCabinet::s_storage = 0;
|
||||
template<> ReactorSurfaceCabinet* ReactorSurfaceCabinet::s_storage = 0;
|
||||
template<> FuncCabinet* FuncCabinet::s_storage; // defined in ctfunc.cpp
|
||||
template<> ThermoCabinet* ThermoCabinet::s_storage; // defined in ct.cpp
|
||||
@ -44,7 +42,8 @@ extern "C" {
|
||||
int reactor_new(const char* type, int n, const char* name)
|
||||
{
|
||||
try {
|
||||
return ReactorCabinet::add(newReactor(type, SolutionCabinet::at(n), name));
|
||||
return ReactorCabinet::add(
|
||||
newReactor(type, SolutionCabinet::at(n), name));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
@ -60,6 +59,16 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
int reactor_type(int i, int len, char* nbuf)
|
||||
{
|
||||
try {
|
||||
return static_cast<int>(
|
||||
copyString(ReactorCabinet::at(i)->type(), nbuf, len));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int reactor_name(int i, int len, char* nbuf)
|
||||
{
|
||||
try {
|
||||
@ -90,16 +99,6 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
int reactor_setSolution(int i, int n)
|
||||
{
|
||||
try {
|
||||
ReactorCabinet::as<Reactor>(i)->setSolution(SolutionCabinet::at(n));
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
double reactor_mass(int i)
|
||||
{
|
||||
try {
|
||||
@ -348,67 +347,67 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
// flow devices
|
||||
// connectors
|
||||
|
||||
int flowdev_new(const char* type, const char* name)
|
||||
int connector_new(const char* type, int n, int m, const char* name)
|
||||
{
|
||||
try {
|
||||
return FlowDeviceCabinet::add(newFlowDevice(type, name));
|
||||
|
||||
return ConnectorCabinet::add(
|
||||
newConnectorNode(type,
|
||||
ReactorCabinet::at(n), ReactorCabinet::at(m), name));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int flowdev_del(int i)
|
||||
int connector_del(int i)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::del(i);
|
||||
ConnectorCabinet::del(i);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int flowdev_name(int i, int len, char* nbuf)
|
||||
int connector_type(int i, int len, char* nbuf)
|
||||
{
|
||||
try {
|
||||
return static_cast<int>(
|
||||
copyString(FlowDeviceCabinet::at(i)->name(), nbuf, len));
|
||||
copyString(ConnectorCabinet::at(i)->type(), nbuf, len));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int flowdev_setName(int i, const char* name)
|
||||
int connector_name(int i, int len, char* nbuf)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::at(i)->setName(name);
|
||||
return static_cast<int>(
|
||||
copyString(ConnectorCabinet::at(i)->name(), nbuf, len));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int connector_setName(int i, const char* name)
|
||||
{
|
||||
try {
|
||||
ConnectorCabinet::at(i)->setName(name);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int flowdev_install(int i, int n, int m)
|
||||
{
|
||||
try {
|
||||
bool ok = FlowDeviceCabinet::at(i)->install(*ReactorCabinet::at(n),
|
||||
*ReactorCabinet::at(m));
|
||||
if (!ok) {
|
||||
throw CanteraError("flowdev_install",
|
||||
"Could not install flow device.");
|
||||
}
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
// flow devices
|
||||
|
||||
int flowdev_setPrimary(int i, int n)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::as<PressureController>(i)->setPrimary(
|
||||
FlowDeviceCabinet::at(n).get());
|
||||
ConnectorCabinet::as<PressureController>(i)->setPrimary(
|
||||
ConnectorCabinet::as<FlowDevice>(n).get());
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -418,7 +417,7 @@ extern "C" {
|
||||
double flowdev_massFlowRate(int i)
|
||||
{
|
||||
try {
|
||||
return FlowDeviceCabinet::at(i)->massFlowRate();
|
||||
return ConnectorCabinet::as<FlowDevice>(i)->massFlowRate();
|
||||
} catch (...) {
|
||||
return handleAllExceptions(DERR, DERR);
|
||||
}
|
||||
@ -427,7 +426,7 @@ extern "C" {
|
||||
int flowdev_setMassFlowCoeff(int i, double v)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::as<MassFlowController>(i)->setMassFlowCoeff(v);
|
||||
ConnectorCabinet::as<MassFlowController>(i)->setMassFlowCoeff(v);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -437,7 +436,7 @@ extern "C" {
|
||||
int flowdev_setValveCoeff(int i, double v)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::as<Valve>(i)->setValveCoeff(v);
|
||||
ConnectorCabinet::as<Valve>(i)->setValveCoeff(v);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -447,7 +446,7 @@ extern "C" {
|
||||
int flowdev_setPressureCoeff(int i, double v)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::as<PressureController>(i)->setPressureCoeff(v);
|
||||
ConnectorCabinet::as<PressureController>(i)->setPressureCoeff(v);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -457,7 +456,8 @@ extern "C" {
|
||||
int flowdev_setPressureFunction(int i, int n)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::at(i)->setPressureFunction(FuncCabinet::at(n).get());
|
||||
ConnectorCabinet::as<FlowDevice>(i)->setPressureFunction(
|
||||
FuncCabinet::at(n).get());
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -467,7 +467,8 @@ extern "C" {
|
||||
int flowdev_setTimeFunction(int i, int n)
|
||||
{
|
||||
try {
|
||||
FlowDeviceCabinet::at(i)->setTimeFunction(FuncCabinet::at(n).get());
|
||||
ConnectorCabinet::as<FlowDevice>(i)->setTimeFunction(
|
||||
FuncCabinet::at(n).get());
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -476,60 +477,10 @@ extern "C" {
|
||||
|
||||
///////////// Walls ///////////////////////
|
||||
|
||||
int wall_new(const char* type, const char* name)
|
||||
{
|
||||
try {
|
||||
return WallCabinet::add(newWall(type, name));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int wall_del(int i)
|
||||
{
|
||||
try {
|
||||
WallCabinet::del(i);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int wall_name(int i, int len, char* nbuf)
|
||||
{
|
||||
try {
|
||||
return static_cast<int>(
|
||||
copyString(WallCabinet::at(i)->name(), nbuf, len));
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int wall_setName(int i, const char* name)
|
||||
{
|
||||
try {
|
||||
WallCabinet::at(i)->setName(name);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int wall_install(int i, int n, int m)
|
||||
{
|
||||
try {
|
||||
WallCabinet::at(i)->install(*ReactorCabinet::at(n),
|
||||
*ReactorCabinet::at(m));
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
double wall_expansionRate(int i)
|
||||
{
|
||||
try {
|
||||
return WallCabinet::at(i)->expansionRate();
|
||||
return ConnectorCabinet::as<Wall>(i)->expansionRate();
|
||||
} catch (...) {
|
||||
return handleAllExceptions(DERR, DERR);
|
||||
}
|
||||
@ -538,7 +489,7 @@ extern "C" {
|
||||
double wall_heatRate(int i)
|
||||
{
|
||||
try {
|
||||
return WallCabinet::at(i)->heatRate();
|
||||
return ConnectorCabinet::as<Wall>(i)->heatRate();
|
||||
} catch (...) {
|
||||
return handleAllExceptions(DERR, DERR);
|
||||
}
|
||||
@ -547,7 +498,7 @@ extern "C" {
|
||||
double wall_area(int i)
|
||||
{
|
||||
try {
|
||||
return WallCabinet::at(i)->area();
|
||||
return ConnectorCabinet::as<Wall>(i)->area();
|
||||
} catch (...) {
|
||||
return handleAllExceptions(DERR, DERR);
|
||||
}
|
||||
@ -556,7 +507,7 @@ extern "C" {
|
||||
int wall_setArea(int i, double v)
|
||||
{
|
||||
try {
|
||||
WallCabinet::at(i)->setArea(v);
|
||||
ConnectorCabinet::as<Wall>(i)->setArea(v);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -566,7 +517,7 @@ extern "C" {
|
||||
int wall_setThermalResistance(int i, double rth)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setThermalResistance(rth);
|
||||
ConnectorCabinet::as<Wall>(i)->setThermalResistance(rth);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -576,7 +527,7 @@ extern "C" {
|
||||
int wall_setHeatTransferCoeff(int i, double u)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setHeatTransferCoeff(u);
|
||||
ConnectorCabinet::as<Wall>(i)->setHeatTransferCoeff(u);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -586,7 +537,7 @@ extern "C" {
|
||||
int wall_setHeatFlux(int i, int n)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setHeatFlux(FuncCabinet::at(n).get());
|
||||
ConnectorCabinet::as<Wall>(i)->setHeatFlux(FuncCabinet::at(n).get());
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -596,7 +547,7 @@ extern "C" {
|
||||
int wall_setExpansionRateCoeff(int i, double k)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setExpansionRateCoeff(k);
|
||||
ConnectorCabinet::as<Wall>(i)->setExpansionRateCoeff(k);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -606,7 +557,7 @@ extern "C" {
|
||||
int wall_setVelocity(int i, int n)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setVelocity(FuncCabinet::at(n).get());
|
||||
ConnectorCabinet::as<Wall>(i)->setVelocity(FuncCabinet::at(n).get());
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
@ -616,22 +567,13 @@ extern "C" {
|
||||
int wall_setEmissivity(int i, double epsilon)
|
||||
{
|
||||
try {
|
||||
WallCabinet::as<Wall>(i)->setEmissivity(epsilon);
|
||||
ConnectorCabinet::as<Wall>(i)->setEmissivity(epsilon);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
int wall_ready(int i)
|
||||
{
|
||||
try {
|
||||
return int(WallCabinet::at(i)->ready());
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
}
|
||||
|
||||
// ReactorSurface
|
||||
|
||||
int reactorsurface_new(const char* name)
|
||||
@ -727,8 +669,7 @@ extern "C" {
|
||||
try {
|
||||
ReactorCabinet::clear();
|
||||
NetworkCabinet::clear();
|
||||
FlowDeviceCabinet::clear();
|
||||
WallCabinet::clear();
|
||||
ConnectorCabinet::clear();
|
||||
ReactorSurfaceCabinet::clear();
|
||||
return 0;
|
||||
} catch (...) {
|
||||
|
95
src/zeroD/ConnectorFactory.cpp
Normal file
95
src/zeroD/ConnectorFactory.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
//! @file ConnectorFactory.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/zeroD/ConnectorFactory.h"
|
||||
#include "cantera/zeroD/FlowDevice.h"
|
||||
#include "cantera/zeroD/flowControllers.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
ConnectorFactory* ConnectorFactory::s_factory = 0;
|
||||
std::mutex ConnectorFactory::connector_mutex;
|
||||
|
||||
ConnectorFactory::ConnectorFactory()
|
||||
{
|
||||
reg("MassFlowController",
|
||||
[](shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{ return new MassFlowController(r0, r1, name); });
|
||||
reg("PressureController",
|
||||
[](shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{ return new PressureController(r0, r1, name); });
|
||||
reg("Valve",
|
||||
[](shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{ return new Valve(r0, r1, name); });
|
||||
reg("Wall",
|
||||
[](shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{ return new Wall(r0, r1, name); });
|
||||
}
|
||||
|
||||
ConnectorFactory* ConnectorFactory::factory() {
|
||||
std::unique_lock<std::mutex> lock(connector_mutex);
|
||||
if (!s_factory) {
|
||||
s_factory = new ConnectorFactory;
|
||||
}
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
void ConnectorFactory::deleteFactory() {
|
||||
std::unique_lock<std::mutex> lock(connector_mutex);
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
shared_ptr<ConnectorNode> newConnectorNode(
|
||||
const string& model,
|
||||
shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{
|
||||
return shared_ptr<ConnectorNode>(
|
||||
ConnectorFactory::factory()->create(model, r0, r1, name));
|
||||
}
|
||||
|
||||
shared_ptr<FlowDevice> newFlowDevice(
|
||||
const string& model,
|
||||
shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{
|
||||
auto dev = std::dynamic_pointer_cast<FlowDevice>(
|
||||
newConnectorNode(model, r0, r1, name));
|
||||
if (!dev) {
|
||||
throw CanteraError("newFlowDevice",
|
||||
"Detected incompatible ConnectorNode type '{}'", model);
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
shared_ptr<FlowDevice> newFlowDevice(const string& model, const string& name)
|
||||
{
|
||||
warn_deprecated("newFlowDevice",
|
||||
"After Cantera 3.1, Reactors must be provided as parameters.");
|
||||
return newFlowDevice(model, nullptr, nullptr, name);
|
||||
}
|
||||
|
||||
shared_ptr<WallBase> newWall(
|
||||
const string& model,
|
||||
shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1, const string& name)
|
||||
{
|
||||
auto wall = std::dynamic_pointer_cast<WallBase>(
|
||||
newConnectorNode(model, r0, r1, name));
|
||||
if (!wall) {
|
||||
throw CanteraError("newWall",
|
||||
"Detected incompatible ConnectorNode type '{}'", model);
|
||||
}
|
||||
return wall;
|
||||
}
|
||||
|
||||
shared_ptr<WallBase> newWall(const string& model, const string& name)
|
||||
{
|
||||
warn_deprecated("newWall",
|
||||
"After Cantera 3.1, Reactors must be provided as parameters.");
|
||||
return newWall(model, nullptr, nullptr, name);
|
||||
}
|
||||
|
||||
}
|
25
src/zeroD/ConnectorNode.cpp
Normal file
25
src/zeroD/ConnectorNode.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//! @file ConnectorNode.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/zeroD/ConnectorNode.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
void ConnectorNode::setDefaultName(map<string, int>& counts)
|
||||
{
|
||||
if (m_defaultNameSet) {
|
||||
return;
|
||||
}
|
||||
m_defaultNameSet = true;
|
||||
string typ(type());
|
||||
if (m_name == "(none)" || m_name == "") {
|
||||
m_name = fmt::format("{}_{}", type(), counts[type()]);
|
||||
}
|
||||
counts[type()]++;
|
||||
}
|
||||
|
||||
}
|
@ -11,22 +11,45 @@
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
bool FlowDevice::setDefaultName(map<string, int>& counts)
|
||||
FlowDevice::FlowDevice(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
|
||||
const string& name) : ConnectorNode(r0, r1, name)
|
||||
{
|
||||
if (m_defaultNameSet) {
|
||||
return false;
|
||||
if (!m_nodes.first || !m_nodes.second) {
|
||||
warn_deprecated("FlowDevice::FlowDevice",
|
||||
"After Cantera 3.1, Reactors must be provided to a FlowDevice "
|
||||
"constructor.");
|
||||
return;
|
||||
}
|
||||
m_defaultNameSet = true;
|
||||
string typ(type());
|
||||
if (m_name == "(none)" || m_name == "") {
|
||||
m_name = fmt::format("{}_{}", type(), counts[type()]);
|
||||
m_in = r0.get();
|
||||
m_out = r1.get();
|
||||
m_in->addOutlet(*this);
|
||||
m_out->addInlet(*this);
|
||||
|
||||
// construct adapters between inlet and outlet species
|
||||
const ThermoPhase& mixin = m_in->contents();
|
||||
const ThermoPhase& mixout = m_out->contents();
|
||||
|
||||
m_nspin = mixin.nSpecies();
|
||||
m_nspout = mixout.nSpecies();
|
||||
string nm;
|
||||
size_t ki, ko;
|
||||
for (ki = 0; ki < m_nspin; ki++) {
|
||||
nm = mixin.speciesName(ki);
|
||||
ko = mixout.speciesIndex(nm);
|
||||
m_in2out.push_back(ko);
|
||||
}
|
||||
for (ko = 0; ko < m_nspout; ko++) {
|
||||
nm = mixout.speciesName(ko);
|
||||
ki = mixin.speciesIndex(nm);
|
||||
m_out2in.push_back(ki);
|
||||
}
|
||||
counts[type()]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FlowDevice::install(ReactorBase& in, ReactorBase& out)
|
||||
{
|
||||
warn_deprecated("FlowDevice::install",
|
||||
"To be removed after Cantera 3.1. Reactors should be provided to constructor "
|
||||
"instead.");
|
||||
if (m_in || m_out) {
|
||||
throw CanteraError("FlowDevice::install", "Already installed");
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
//! @file FlowDeviceFactory.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/zeroD/FlowDeviceFactory.h"
|
||||
#include "cantera/zeroD/flowControllers.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
FlowDeviceFactory* FlowDeviceFactory::s_factory = 0;
|
||||
std::mutex FlowDeviceFactory::flowDevice_mutex;
|
||||
|
||||
FlowDeviceFactory::FlowDeviceFactory()
|
||||
{
|
||||
reg("MassFlowController", [](const string& name) {
|
||||
return new MassFlowController(name);
|
||||
});
|
||||
reg("PressureController", [](const string& name) {
|
||||
return new PressureController(name);
|
||||
});
|
||||
reg("Valve", [](const string& name) {
|
||||
return new Valve(name);
|
||||
});
|
||||
}
|
||||
|
||||
FlowDeviceFactory* FlowDeviceFactory::factory() {
|
||||
std::unique_lock<std::mutex> lock(flowDevice_mutex);
|
||||
if (!s_factory) {
|
||||
s_factory = new FlowDeviceFactory;
|
||||
}
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
void FlowDeviceFactory::deleteFactory() {
|
||||
std::unique_lock<std::mutex> lock(flowDevice_mutex);
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
shared_ptr<FlowDevice> newFlowDevice(const string& model, const string& name)
|
||||
{
|
||||
return shared_ptr<FlowDevice>(FlowDeviceFactory::factory()->create(model, name));
|
||||
}
|
||||
|
||||
}
|
@ -23,14 +23,8 @@ namespace Cantera
|
||||
{
|
||||
|
||||
Reactor::Reactor(shared_ptr<Solution> sol, const string& name)
|
||||
: ReactorBase(name)
|
||||
: ReactorBase(sol, name)
|
||||
{
|
||||
if (!sol || !(sol->thermo())) {
|
||||
throw CanteraError("Reactor::Reactor",
|
||||
"Reactor contents must be provided as constructor arguments");
|
||||
}
|
||||
setSolution(sol);
|
||||
setThermo(*sol->thermo());
|
||||
setKinetics(*sol->kinetics());
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,14 @@ ReactorBase::ReactorBase(shared_ptr<Solution> sol, const string& name)
|
||||
throw CanteraError("ReactorBase::ReactorBase",
|
||||
"Missing or incomplete Solution object.");
|
||||
}
|
||||
setSolution(sol);
|
||||
m_solution = sol;
|
||||
setThermo(*sol->thermo());
|
||||
try {
|
||||
setKinetics(*sol->kinetics());
|
||||
} catch (NotImplementedError&) {
|
||||
// kinetics not used (example: Reservoir)
|
||||
}
|
||||
m_solution->thermo()->addSpeciesLock();
|
||||
}
|
||||
|
||||
ReactorBase::~ReactorBase()
|
||||
@ -47,7 +54,11 @@ bool ReactorBase::setDefaultName(map<string, int>& counts)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReactorBase::setSolution(shared_ptr<Solution> sol) {
|
||||
void ReactorBase::setSolution(shared_ptr<Solution> sol)
|
||||
{
|
||||
warn_deprecated("ReactorBase::setSolution",
|
||||
"After Cantera 3.2, a change of reactor contents after instantiation "
|
||||
"will be disabled.");
|
||||
if (!sol || !(sol->thermo())) {
|
||||
throw CanteraError("ReactorBase::setSolution",
|
||||
"Missing or incomplete Solution object.");
|
||||
|
@ -10,21 +10,26 @@
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
bool WallBase::setDefaultName(map<string, int>& counts)
|
||||
WallBase::WallBase(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
|
||||
const string& name) : ConnectorNode(r0, r1, name)
|
||||
{
|
||||
if (m_defaultNameSet) {
|
||||
return false;
|
||||
if (!m_nodes.first || !m_nodes.second) {
|
||||
warn_deprecated("FlowDevice::FlowDevice",
|
||||
"After Cantera 3.2, Reactors must be provided to a FlowDevice "
|
||||
"constructor.");
|
||||
return;
|
||||
}
|
||||
m_defaultNameSet = true;
|
||||
if (m_name == "(none)" || m_name == "") {
|
||||
m_name = fmt::format("{}_{}", type(), counts[type()]);
|
||||
}
|
||||
counts[type()]++;
|
||||
return true;
|
||||
m_left = r0.get();
|
||||
m_right = r1.get();
|
||||
m_left->addWall(*this, 0);
|
||||
m_right->addWall(*this, 1);
|
||||
}
|
||||
|
||||
bool WallBase::install(ReactorBase& rleft, ReactorBase& rright)
|
||||
{
|
||||
warn_deprecated("WallBase::install",
|
||||
"To be removed after Cantera 3.2. Reactors should be provided to constructor "
|
||||
"instead.");
|
||||
// check if wall is already installed
|
||||
if (m_left || m_right) {
|
||||
return false;
|
||||
|
@ -1,39 +0,0 @@
|
||||
//! @file WallFactory.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/zeroD/WallFactory.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
WallFactory* WallFactory::s_factory = 0;
|
||||
std::mutex WallFactory::wall_mutex;
|
||||
|
||||
WallFactory::WallFactory()
|
||||
{
|
||||
reg("Wall", [](const string& name) { return new Wall(name); });
|
||||
}
|
||||
|
||||
WallFactory* WallFactory::factory() {
|
||||
std::unique_lock<std::mutex> lock(wall_mutex);
|
||||
if (!s_factory) {
|
||||
s_factory = new WallFactory;
|
||||
}
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
void WallFactory::deleteFactory() {
|
||||
std::unique_lock<std::mutex> lock(wall_mutex);
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
shared_ptr<WallBase> newWall(const string& model, const string& name)
|
||||
{
|
||||
return shared_ptr<WallBase>(WallFactory::factory()->create(model, name));
|
||||
}
|
||||
|
||||
}
|
@ -728,13 +728,6 @@ class TestReactor:
|
||||
assert self.r1.name.startswith(f"{self.r1.type}_") # default name
|
||||
assert res.name.startswith(f"{res.type}_") # default name
|
||||
|
||||
def test_valve_errors(self):
|
||||
self.make_reactors()
|
||||
v = ct.Valve(self.r1, self.r2)
|
||||
with pytest.raises(ct.CanteraError, match='Already installed'):
|
||||
# inlet and outlet cannot be reassigned
|
||||
v._install(self.r2, self.r1)
|
||||
|
||||
def test_pressure_controller1(self):
|
||||
self.make_reactors(n_reactors=1)
|
||||
g = ct.Solution('h2o2.yaml', transport_model=None)
|
||||
|
@ -19,16 +19,16 @@ TEST(zerodim, simple)
|
||||
|
||||
auto sol = newSolution("gri30.yaml", "gri30", "none");
|
||||
sol->thermo()->setState_TPX(T, P, X);
|
||||
auto cppReactor = newReactor("IdealGasReactor", sol, "simple");
|
||||
ASSERT_EQ(cppReactor->name(), "simple");
|
||||
cppReactor->initialize();
|
||||
auto reactor = newReactor("IdealGasReactor", sol, "simple");
|
||||
ASSERT_EQ(reactor->name(), "simple");
|
||||
reactor->initialize();
|
||||
ReactorNet network;
|
||||
network.addReactor(dynamic_cast<IdealGasReactor&>(*cppReactor));
|
||||
network.addReactor(dynamic_cast<IdealGasReactor&>(*reactor));
|
||||
network.initialize();
|
||||
|
||||
double t = 0.0;
|
||||
while (t < 0.1) {
|
||||
ASSERT_GE(cppReactor->temperature(), T);
|
||||
ASSERT_GE(reactor->temperature(), T);
|
||||
t = network.time() + 5e-3;
|
||||
network.advance(t);
|
||||
}
|
||||
@ -56,6 +56,97 @@ TEST(zerodim, test_guards)
|
||||
EXPECT_THROW(Valve().updateMassFlowRate(0.), CanteraError);
|
||||
}
|
||||
|
||||
TEST(zerodim, flowdevice)
|
||||
{
|
||||
auto gas = newSolution("gri30.yaml", "gri30", "none");
|
||||
|
||||
auto node0 = newReactor("IdealGasReactor", gas, "upstream");
|
||||
auto node1 = newReactor("IdealGasReactor", gas, "downstream");
|
||||
|
||||
auto valve = newFlowDevice("Valve", node0, node1, "valve");
|
||||
ASSERT_EQ(valve->name(), "valve");
|
||||
ASSERT_EQ(valve->in().name(), "upstream");
|
||||
ASSERT_EQ(valve->out().name(), "downstream");
|
||||
|
||||
ASSERT_EQ(node0->nInlets(), 0);
|
||||
ASSERT_EQ(node0->nOutlets(), 1);
|
||||
ASSERT_EQ(node1->nInlets(), 1);
|
||||
ASSERT_EQ(node1->nOutlets(), 0);
|
||||
}
|
||||
|
||||
TEST(zerodim, wall)
|
||||
{
|
||||
auto gas = newSolution("gri30.yaml", "gri30", "none");
|
||||
|
||||
auto node0 = newReactor("IdealGasReactor", gas, "left");
|
||||
auto node1 = newReactor("IdealGasReactor", gas, "right");
|
||||
|
||||
auto wall = newWall("Wall", node0, node1, "wall");
|
||||
ASSERT_EQ(wall->name(), "wall");
|
||||
ASSERT_EQ(wall->left().name(), "left");
|
||||
ASSERT_EQ(wall->right().name(), "right");
|
||||
|
||||
ASSERT_EQ(node0->nWalls(), 1);
|
||||
ASSERT_EQ(node1->nWalls(), 1);
|
||||
}
|
||||
|
||||
TEST(zerodim, mole_reactor)
|
||||
{
|
||||
// simplified version of continuous_reactor.py
|
||||
auto gas = newSolution("h2o2.yaml", "ohmech", "none");
|
||||
|
||||
auto tank = make_shared<Reservoir>(gas, "fuel-air-tank");
|
||||
auto exhaust = make_shared<Reservoir>(gas, "exhaust");
|
||||
|
||||
auto stirred = make_shared<IdealGasMoleReactor>(gas, "stirred-reactor");
|
||||
stirred->setEnergy(0);
|
||||
stirred->setInitialVolume(30.5 * 1e-6);
|
||||
|
||||
auto mfc = make_shared<MassFlowController>(tank, stirred, "mass-flow-controller");
|
||||
double residenceTime = 2.;
|
||||
double mass = stirred->mass();
|
||||
mfc->setMassFlowRate(mass/residenceTime);
|
||||
|
||||
auto preg = make_shared<PressureController>(stirred, exhaust, "pressure-regulator");
|
||||
preg->setPrimary(mfc.get());
|
||||
preg->setPressureCoeff(1e-3);
|
||||
|
||||
auto net = ReactorNet();
|
||||
net.addReactor(*stirred);
|
||||
net.initialize();
|
||||
}
|
||||
|
||||
TEST(zerodim, mole_reactor_2)
|
||||
{
|
||||
// simplified version of continuous_reactor.py
|
||||
auto gas = newSolution("h2o2.yaml", "ohmech", "none");
|
||||
|
||||
auto tank = std::dynamic_pointer_cast<Reservoir>(
|
||||
newReactor("Reservoir", gas, "fuel-air-tank"));
|
||||
auto exhaust = std::dynamic_pointer_cast<Reservoir>(
|
||||
newReactor("Reservoir", gas, "exhaust"));
|
||||
|
||||
auto stirred = std::dynamic_pointer_cast<IdealGasMoleReactor>(
|
||||
newReactor("IdealGasMoleReactor", gas, "stirred-reactor"));
|
||||
stirred->setEnergy(0);
|
||||
stirred->setInitialVolume(30.5 * 1e-6);
|
||||
|
||||
auto mfc = std::dynamic_pointer_cast<MassFlowController>(
|
||||
newConnectorNode("MassFlowController", tank, stirred, "mass-flow-controller"));
|
||||
double residenceTime = 2.;
|
||||
double mass = stirred->mass();
|
||||
mfc->setMassFlowRate(mass/residenceTime);
|
||||
|
||||
auto preg = std::dynamic_pointer_cast<PressureController>(
|
||||
newConnectorNode("PressureController", stirred, exhaust, "pressure-regulator"));
|
||||
preg->setPrimary(mfc.get());
|
||||
preg->setPressureCoeff(1e-3);
|
||||
|
||||
auto net = ReactorNet();
|
||||
net.addReactor(*stirred);
|
||||
net.initialize();
|
||||
}
|
||||
|
||||
// This test ensures that prior reactor initialization of a reactor does
|
||||
// not affect later integration within a network. This example was
|
||||
// adapted from test_reactor.py::test_equilibrium_HP.
|
||||
|
Loading…
Reference in New Issue
Block a user