added factories for FlowDevice and Wall objects
This commit is contained in:
parent
751afa3c2b
commit
5d62f3bacc
25 changed files with 709 additions and 340 deletions
|
|
@ -1,7 +1,7 @@
|
|||
//! @file FlowDevice.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_FLOWDEVICE_H
|
||||
#define CT_FLOWDEVICE_H
|
||||
|
|
@ -27,9 +27,7 @@ const int Valve_Type = 3;
|
|||
class FlowDevice
|
||||
{
|
||||
public:
|
||||
FlowDevice() : m_mdot(0.0), m_func(0), m_type(0),
|
||||
m_nspin(0), m_nspout(0),
|
||||
m_in(0), m_out(0) {}
|
||||
FlowDevice();
|
||||
|
||||
virtual ~FlowDevice() {}
|
||||
FlowDevice(const FlowDevice&) = delete;
|
||||
|
|
|
|||
72
include/cantera/zeroD/FlowDeviceFactory.h
Normal file
72
include/cantera/zeroD/FlowDeviceFactory.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//! @file FlowDeviceFactory.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 FLOWDEVICE_FACTORY_H
|
||||
#define FLOWDEVICE_FACTORY_H
|
||||
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
#include "cantera/zeroD/FlowDevice.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
class FlowDeviceFactory : public Factory<FlowDevice>
|
||||
{
|
||||
public:
|
||||
static FlowDeviceFactory* factory() {
|
||||
std::unique_lock<std::mutex> lock(flowDevice_mutex);
|
||||
if (!s_factory) {
|
||||
s_factory = new FlowDeviceFactory;
|
||||
}
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
virtual void deleteFactory() {
|
||||
std::unique_lock<std::mutex> lock(flowDevice_mutex);
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
//! Create a new flow device by type identifier.
|
||||
/*!
|
||||
* @param n the type to be created.
|
||||
*/
|
||||
virtual FlowDevice* newFlowDevice(int n);
|
||||
|
||||
//! Create a new flow device by type name.
|
||||
/*!
|
||||
* @param flowDeviceType the type to be created.
|
||||
*/
|
||||
virtual FlowDevice* newFlowDevice(const std::string& flowDeviceType);
|
||||
|
||||
//! Register a new flow device type identifier.
|
||||
/*!
|
||||
* @param name the name of the flow device type.
|
||||
* @param type the type identifier of the flow device.
|
||||
* Integer type identifiers are used by clib and matlab interfaces.
|
||||
*/
|
||||
void reg_type(const std::string& name, const int type) {
|
||||
m_types[type] = name;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Map containing flow device type identifier / type name pairs.
|
||||
std::unordered_map<int, std::string> m_types;
|
||||
|
||||
private:
|
||||
static FlowDeviceFactory* s_factory;
|
||||
static std::mutex flowDevice_mutex;
|
||||
FlowDeviceFactory();
|
||||
};
|
||||
|
||||
//! Create a FlowDevice object of the specified type
|
||||
inline FlowDevice* newFlowDevice(const std::string& model)
|
||||
{
|
||||
return FlowDeviceFactory::factory()->newFlowDevice(model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file FlowReactor.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_FLOWREACTOR_H
|
||||
#define CT_FLOWREACTOR_H
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file ConstPressureReactor.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_IDEALGASCONSTP_REACTOR_H
|
||||
#define CT_IDEALGASCONSTP_REACTOR_H
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file IdealGasReactor.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_IDEALGASREACTOR_H
|
||||
#define CT_IDEALGASREACTOR_H
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file Reactor.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_REACTOR_H
|
||||
#define CT_REACTOR_H
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file ReactorBase.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_REACTORBASE_H
|
||||
#define CT_REACTORBASE_H
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
namespace Cantera
|
||||
{
|
||||
class FlowDevice;
|
||||
class Wall;
|
||||
class WallBase;
|
||||
class ReactorNet;
|
||||
class ReactorSurface;
|
||||
|
||||
|
|
@ -111,12 +111,12 @@ public:
|
|||
/*!
|
||||
* `lr` = 0 if this reactor is to the left of the wall and `lr` = 1 if
|
||||
* this reactor is to the right of the wall. This method is called
|
||||
* automatically for both the left and right reactors by Wall::install.
|
||||
* automatically for both the left and right reactors by WallBase::install.
|
||||
*/
|
||||
void addWall(Wall& w, int lr);
|
||||
void addWall(WallBase& w, int lr);
|
||||
|
||||
//! Return a reference to the *n*-th Wall connected to this reactor.
|
||||
Wall& wall(size_t n);
|
||||
WallBase& wall(size_t n);
|
||||
|
||||
void addSurface(ReactorSurface* surf);
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ protected:
|
|||
doublereal m_pressure;
|
||||
vector_fp m_state;
|
||||
std::vector<FlowDevice*> m_inlet, m_outlet;
|
||||
std::vector<Wall*> m_wall;
|
||||
std::vector<WallBase*> m_wall;
|
||||
std::vector<ReactorSurface*> m_surfaces;
|
||||
vector_int m_lr;
|
||||
std::string m_name;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
//! @file ReactorFactory.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef REACTOR_FACTORY_H
|
||||
#define REACTOR_FACTORY_H
|
||||
|
||||
#include "ReactorBase.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
|
||||
namespace Cantera
|
||||
|
|
@ -29,13 +29,32 @@ public:
|
|||
s_factory = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new reactor.
|
||||
//! Create a new reactor by type identifier.
|
||||
/*!
|
||||
* @param n the type to be created.
|
||||
*/
|
||||
virtual ReactorBase* newReactor(int n);
|
||||
|
||||
//! Create a new reactor by type name.
|
||||
/*!
|
||||
* @param reactorType the type to be created.
|
||||
*/
|
||||
virtual ReactorBase* newReactor(const std::string& reactorType);
|
||||
|
||||
//! Register a new reactor type identifier.
|
||||
/*!
|
||||
* @param name the name of the reactor type.
|
||||
* @param type the type identifier of the reactor.
|
||||
* Integer type identifiers are used by clib and matlab interfaces.
|
||||
*/
|
||||
void reg_type(const std::string& name, const int type) {
|
||||
m_types[type] = name;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Map containing reactor type identifier / reactor type name pairs.
|
||||
std::unordered_map<int, std::string> m_types;
|
||||
|
||||
private:
|
||||
static ReactorFactory* s_factory;
|
||||
static std::mutex reactor_mutex;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file Reservoir.h
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_RESERVOIR_H
|
||||
#define CT_RESERVOIR_H
|
||||
|
|
|
|||
|
|
@ -1,127 +1,81 @@
|
|||
//! @file Wall.h Header file for class Wall.
|
||||
//! @file Wall.h Header file for base class WallBase.
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_WALL_H
|
||||
#define CT_WALL_H
|
||||
|
||||
#include "cantera/base/ctexceptions.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
#include "cantera/zeroD/ReactorSurface.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
class Kinetics;
|
||||
class SurfPhase;
|
||||
class Func1;
|
||||
|
||||
//! Represents a wall between between two ReactorBase objects.
|
||||
/*!
|
||||
* Walls can move (changing the volume of the adjacent reactors) and allow heat
|
||||
* transfer between reactors.
|
||||
const int WallType = 1;
|
||||
|
||||
/**
|
||||
* Base class for 'walls' (walls, pistons, etc.) connecting reactors.
|
||||
* @ingroup reactor0
|
||||
*/
|
||||
class Wall
|
||||
class WallBase
|
||||
{
|
||||
public:
|
||||
Wall();
|
||||
WallBase();
|
||||
|
||||
virtual ~Wall() {}
|
||||
Wall(const Wall&) = delete;
|
||||
Wall& operator=(const Wall&) = delete;
|
||||
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 std::string type() const {
|
||||
return "WallBase";
|
||||
}
|
||||
|
||||
//! Rate of volume change (m^3/s) for the adjacent reactors.
|
||||
/*!
|
||||
* The volume rate of change is given by
|
||||
* \f[
|
||||
* \dot V = K A (P_{left} - P_{right}) + F(t)
|
||||
* \f]
|
||||
* where *K* is the specified expansion rate coefficient, *A* is the wall
|
||||
* area, and *F(t)* is a specified function of time. Positive values for
|
||||
* `vdot` correspond to increases in the volume of reactor on left, and
|
||||
* decreases in the volume of the reactor on the right.
|
||||
* This method is called by Reactor::evalWalls(). Base class method
|
||||
* does nothing (i.e. constant volume), but may be overloaded.
|
||||
*/
|
||||
virtual doublereal vdot(doublereal t);
|
||||
virtual double vdot(double t) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//! Heat flow rate through the wall (W).
|
||||
/*!
|
||||
* The heat flux is given by
|
||||
* \f[
|
||||
* Q = h A (T_{left} - T_{right}) + A G(t)
|
||||
* \f]
|
||||
* where *h* is the heat transfer coefficient, *A* is the wall area, and
|
||||
* *G(t)* is a specified function of time. Positive values denote a flux
|
||||
* from left to right.
|
||||
* This method is called by Reactor::evalWalls(). Base class method
|
||||
* does nothing (i.e. adiabatic wall), but may be overloaded.
|
||||
*/
|
||||
virtual doublereal Q(doublereal t);
|
||||
virtual double Q(double t) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//! Area in m^2.
|
||||
doublereal area() {
|
||||
//! Area in (m^2).
|
||||
double area() {
|
||||
return m_area;
|
||||
}
|
||||
|
||||
//! Set the area [m^2].
|
||||
void setArea(doublereal a) {
|
||||
m_area = a;
|
||||
m_surf[0].setArea(a);
|
||||
m_surf[1].setArea(a);
|
||||
}
|
||||
virtual void setArea(double a);
|
||||
|
||||
//! Get the area [m^2]
|
||||
/*!
|
||||
* Redundant function (same as WallBase::area()).
|
||||
* @deprecated To be removed after Cantera 2.5.
|
||||
*/
|
||||
double getArea() const {
|
||||
warn_deprecated("WallBase::getArea()",
|
||||
"To be removed after Cantera 2.5. "
|
||||
"Replace with WallBase::area().");
|
||||
return m_area;
|
||||
}
|
||||
|
||||
void setThermalResistance(doublereal Rth) {
|
||||
m_rrth = 1.0/Rth;
|
||||
}
|
||||
|
||||
//! Set the overall heat transfer coefficient [W/m^2/K].
|
||||
void setHeatTransferCoeff(doublereal U) {
|
||||
m_rrth = U;
|
||||
}
|
||||
|
||||
//! Get the overall heat transfer coefficient [W/m^2/K].
|
||||
double getHeatTransferCoeff() const {
|
||||
return m_rrth;
|
||||
}
|
||||
|
||||
//! Set the emissivity.
|
||||
void setEmissivity(doublereal epsilon) {
|
||||
if (epsilon > 1.0 || epsilon < 0.0) {
|
||||
throw CanteraError("Wall::setEmissivity",
|
||||
"emissivity must be between 0.0 and 1.0");
|
||||
}
|
||||
m_emiss = epsilon;
|
||||
}
|
||||
|
||||
double getEmissivity() const {
|
||||
return m_emiss;
|
||||
}
|
||||
|
||||
//! Set the wall velocity to a specified function of time
|
||||
void setVelocity(Func1* f=0) {
|
||||
if (f) {
|
||||
m_vf = f;
|
||||
}
|
||||
}
|
||||
|
||||
//! Set the expansion rate coefficient.
|
||||
void setExpansionRateCoeff(doublereal k) {
|
||||
m_k = k;
|
||||
}
|
||||
|
||||
//! Get the expansion rate coefficient
|
||||
double getExpansionRateCoeff() const {
|
||||
return m_k;
|
||||
}
|
||||
|
||||
//! Specify the heat flux function \f$ q_0(t) \f$.
|
||||
void setHeatFlux(Func1* q) {
|
||||
m_qf = q;
|
||||
}
|
||||
|
||||
//! Install the wall between two reactors or reservoirs
|
||||
bool install(ReactorBase& leftReactor, ReactorBase& rightReactor);
|
||||
|
||||
|
|
@ -149,12 +103,118 @@ protected:
|
|||
|
||||
std::vector<ReactorSurface> m_surf;
|
||||
|
||||
doublereal m_area, m_k, m_rrth;
|
||||
doublereal m_emiss;
|
||||
Func1* m_vf;
|
||||
Func1* m_qf;
|
||||
double m_area;
|
||||
};
|
||||
|
||||
//! Represents a wall between between two ReactorBase objects.
|
||||
/*!
|
||||
* Walls can move (changing the volume of the adjacent reactors) and allow heat
|
||||
* transfer between reactors.
|
||||
*/
|
||||
class Wall : public WallBase
|
||||
{
|
||||
public:
|
||||
Wall();
|
||||
|
||||
//! String indicating the wall model implemented. Usually
|
||||
//! corresponds to the name of the derived class.
|
||||
virtual std::string type() const {
|
||||
return "Wall";
|
||||
}
|
||||
|
||||
//! Set the wall velocity to a specified function of time, i.e. \f$ v(t) \f$.
|
||||
void setVelocity(Func1* f=0) {
|
||||
if (f) {
|
||||
m_vf = f;
|
||||
}
|
||||
}
|
||||
|
||||
//! Rate of volume change (m^3/s) for the adjacent reactors.
|
||||
/*!
|
||||
* The volume rate of change is given by
|
||||
* \f[
|
||||
* \dot V = K A (P_{left} - P_{right}) + F(t)
|
||||
* \f]
|
||||
* where *K* is the specified expansion rate coefficient, *A* is the wall
|
||||
* area, and *F(t)* is a specified function of time. Positive values for
|
||||
* `vdot` correspond to increases in the volume of reactor on left, and
|
||||
* decreases in the volume of the reactor on the right.
|
||||
*/
|
||||
virtual double vdot(double t);
|
||||
|
||||
//! Specify the heat flux function \f$ q_0(t) \f$.
|
||||
void setHeatFlux(Func1* q) {
|
||||
m_qf = q;
|
||||
}
|
||||
|
||||
//! Heat flow rate through the wall (W).
|
||||
/*!
|
||||
* The heat flux is given by
|
||||
* \f[
|
||||
* Q = h A (T_{left} - T_{right}) + A G(t)
|
||||
* \f]
|
||||
* where *h* is the heat transfer coefficient, *A* is the wall area, and
|
||||
* *G(t)* is a specified function of time. Positive values denote a flux
|
||||
* from left to right.
|
||||
*/
|
||||
virtual double Q(double t);
|
||||
|
||||
void setThermalResistance(double Rth) {
|
||||
m_rrth = 1.0/Rth;
|
||||
}
|
||||
|
||||
//! Set the overall heat transfer coefficient [W/m^2/K].
|
||||
void setHeatTransferCoeff(double U) {
|
||||
m_rrth = U;
|
||||
}
|
||||
|
||||
//! Get the overall heat transfer coefficient [W/m^2/K].
|
||||
double getHeatTransferCoeff() const {
|
||||
return m_rrth;
|
||||
}
|
||||
|
||||
//! Set the emissivity.
|
||||
void setEmissivity(double epsilon) {
|
||||
if (epsilon > 1.0 || epsilon < 0.0) {
|
||||
throw CanteraError("WallBase::setEmissivity",
|
||||
"emissivity must be between 0.0 and 1.0");
|
||||
}
|
||||
m_emiss = epsilon;
|
||||
}
|
||||
|
||||
//! Get the emissivity.
|
||||
double getEmissivity() const {
|
||||
return m_emiss;
|
||||
}
|
||||
|
||||
//! Set the expansion rate coefficient.
|
||||
void setExpansionRateCoeff(double k) {
|
||||
m_k = k;
|
||||
}
|
||||
|
||||
//! Get the expansion rate coefficient
|
||||
double getExpansionRateCoeff() const {
|
||||
return m_k;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! expansion rate coefficient
|
||||
double m_k;
|
||||
|
||||
//! heat transfer coefficient
|
||||
double m_rrth;
|
||||
|
||||
//! emissivity
|
||||
double m_emiss;
|
||||
|
||||
//! Velocity function
|
||||
Func1* m_vf;
|
||||
|
||||
//! Heat flux function
|
||||
Func1* m_qf;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
72
include/cantera/zeroD/WallFactory.h
Normal file
72
include/cantera/zeroD/WallFactory.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//! @file WallFactory.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 WALL_FACTORY_H
|
||||
#define WALL_FACTORY_H
|
||||
|
||||
#include "cantera/base/FactoryBase.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
class WallFactory : public Factory<WallBase>
|
||||
{
|
||||
public:
|
||||
static WallFactory* factory() {
|
||||
std::unique_lock<std::mutex> lock(wall_mutex);
|
||||
if (!s_factory) {
|
||||
s_factory = new WallFactory;
|
||||
}
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
virtual void deleteFactory() {
|
||||
std::unique_lock<std::mutex> lock(wall_mutex);
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
//! Create a new wall by type identifier.
|
||||
/*!
|
||||
* @param n the type to be created.
|
||||
*/
|
||||
virtual WallBase* newWall(int n);
|
||||
|
||||
//! Create a new wall by type name.
|
||||
/*!
|
||||
* @param wallType the type to be created.
|
||||
*/
|
||||
virtual WallBase* newWall(const std::string& wallType);
|
||||
|
||||
//! Register a new wall type identifier.
|
||||
/*!
|
||||
* @param name the name of the wall type.
|
||||
* @param type the type identifier of the wall.
|
||||
* Integer type identifiers are used by clib and matlab interfaces.
|
||||
*/
|
||||
void reg_type(const std::string& name, const int type) {
|
||||
m_types[type] = name;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Map containing wall type identifier / wall type name pairs.
|
||||
std::unordered_map<int, std::string> m_types;
|
||||
|
||||
private:
|
||||
static WallFactory* s_factory;
|
||||
static std::mutex wall_mutex;
|
||||
WallFactory();
|
||||
};
|
||||
|
||||
//! Create a Wall object of the specified type
|
||||
inline WallBase* newWall(const std::string& model)
|
||||
{
|
||||
return WallFactory::factory()->newWall(model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
//! @file flowControllers.h Some flow devices derived from class FlowDevice.
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#ifndef CT_FLOWCONTR_H
|
||||
#define CT_FLOWCONTR_H
|
||||
|
||||
#include "FlowDevice.h"
|
||||
#include "ReactorBase.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
/**
|
||||
* A class for mass flow controllers. The mass flow rate is constant or
|
||||
* specified as a function of time..
|
||||
|
|
@ -19,9 +18,7 @@ namespace Cantera
|
|||
class MassFlowController : public FlowDevice
|
||||
{
|
||||
public:
|
||||
MassFlowController() : FlowDevice() {
|
||||
m_type = MFC_Type;
|
||||
}
|
||||
MassFlowController();
|
||||
|
||||
virtual bool ready() {
|
||||
return FlowDevice::ready() && m_mdot >= 0.0;
|
||||
|
|
@ -30,12 +27,7 @@ public:
|
|||
/// If a function of time has been specified for mdot, then update the
|
||||
/// stored mass flow rate. Otherwise, mdot is a constant, and does not
|
||||
/// need updating.
|
||||
virtual void updateMassFlowRate(doublereal time) {
|
||||
if (m_func) {
|
||||
m_mdot = m_func->eval(time);
|
||||
}
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
virtual void updateMassFlowRate(double time);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -46,9 +38,7 @@ public:
|
|||
class PressureController : public FlowDevice
|
||||
{
|
||||
public:
|
||||
PressureController() : FlowDevice(), m_master(0) {
|
||||
m_type = PressureController_Type;
|
||||
}
|
||||
PressureController();
|
||||
|
||||
virtual bool ready() {
|
||||
return FlowDevice::ready() && m_master != 0 && m_coeffs.size() == 1;
|
||||
|
|
@ -68,15 +58,7 @@ public:
|
|||
m_coeffs = {c};
|
||||
}
|
||||
|
||||
virtual void updateMassFlowRate(doublereal time) {
|
||||
if (!ready()) {
|
||||
throw CanteraError("PressureController::updateMassFlowRate",
|
||||
"Device is not ready; some parameters have not been set.");
|
||||
}
|
||||
m_mdot = m_master->massFlowRate(time)
|
||||
+ m_coeffs[0]*(in().pressure() - out().pressure());
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
virtual void updateMassFlowRate(double time);
|
||||
|
||||
protected:
|
||||
FlowDevice* m_master;
|
||||
|
|
@ -92,9 +74,7 @@ protected:
|
|||
class Valve : public FlowDevice
|
||||
{
|
||||
public:
|
||||
Valve() : FlowDevice() {
|
||||
m_type = Valve_Type;
|
||||
}
|
||||
Valve();
|
||||
|
||||
virtual bool ready() {
|
||||
return FlowDevice::ready() && (m_coeffs.size() == 1 || m_func);
|
||||
|
|
@ -111,19 +91,7 @@ public:
|
|||
}
|
||||
|
||||
/// Compute the currrent mass flow rate, based on the pressure difference.
|
||||
virtual void updateMassFlowRate(doublereal time) {
|
||||
if (!ready()) {
|
||||
throw CanteraError("Valve::updateMassFlowRate",
|
||||
"Device is not ready; some parameters have not been set.");
|
||||
}
|
||||
double delta_P = in().pressure() - out().pressure();
|
||||
if (m_func) {
|
||||
m_mdot = m_func->eval(delta_P);
|
||||
} else {
|
||||
m_mdot = m_coeffs[0]*delta_P;
|
||||
}
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
virtual void updateMassFlowRate(double time);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,34 @@
|
|||
//! @file zerodim.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_INCL_ZERODIM_H
|
||||
#define CT_INCL_ZERODIM_H
|
||||
#include "zeroD/Reactor.h"
|
||||
|
||||
// reactor network
|
||||
#include "zeroD/ReactorNet.h"
|
||||
#include "zeroD/Reservoir.h"
|
||||
#include "zeroD/Wall.h"
|
||||
#include "zeroD/flowControllers.h"
|
||||
#include "zeroD/FlowReactor.h"
|
||||
#include "zeroD/ConstPressureReactor.h"
|
||||
#include "zeroD/IdealGasReactor.h"
|
||||
#include "zeroD/IdealGasConstPressureReactor.h"
|
||||
|
||||
// reactors
|
||||
#include "cantera/zeroD/Reservoir.h"
|
||||
#include "cantera/zeroD/Reactor.h"
|
||||
#include "cantera/zeroD/FlowReactor.h"
|
||||
#include "cantera/zeroD/ConstPressureReactor.h"
|
||||
#include "cantera/zeroD/IdealGasReactor.h"
|
||||
#include "cantera/zeroD/IdealGasConstPressureReactor.h"
|
||||
|
||||
// flow devices
|
||||
#include "cantera/zeroD/flowControllers.h"
|
||||
|
||||
// walls
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
|
||||
// surface
|
||||
#include "cantera/zeroD/ReactorSurface.h"
|
||||
|
||||
// factories
|
||||
#include "cantera/zeroD/ReactorFactory.h"
|
||||
#include "cantera/zeroD/FlowDeviceFactory.h"
|
||||
#include "cantera/zeroD/WallFactory.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# This file is part of Cantera. See License.txt in the top-level directory or
|
||||
# at http://www.cantera.org/license.txt for license and copyright information.
|
||||
# at https://cantera.org/license.txt for license and copyright information.
|
||||
# cython: language_level=3
|
||||
|
||||
from libcpp.vector cimport vector
|
||||
|
|
@ -466,11 +466,20 @@ cdef extern from "cantera/equil/MultiPhase.h" namespace "Cantera":
|
|||
double volume() except +translate_exception
|
||||
|
||||
|
||||
cdef extern from "cantera/zeroD/ReactorBase.h" namespace "Cantera":
|
||||
cdef extern from "cantera/zerodim.h" namespace "Cantera":
|
||||
|
||||
cdef cppclass CxxWall "Cantera::Wall"
|
||||
cdef cppclass CxxReactorSurface "Cantera::ReactorSurface"
|
||||
cdef cppclass CxxFlowDevice "Cantera::FlowDevice"
|
||||
|
||||
# factories
|
||||
|
||||
cdef CxxReactorBase* newReactor(string) except +translate_exception
|
||||
cdef CxxFlowDevice* newFlowDevice(string) except +translate_exception
|
||||
cdef CxxWallBase* newWall(string) except +translate_exception
|
||||
|
||||
# reactors
|
||||
|
||||
cdef cppclass CxxReactorBase "Cantera::ReactorBase":
|
||||
CxxReactorBase()
|
||||
void setThermoMgr(CxxThermoPhase&) except +translate_exception
|
||||
|
|
@ -481,8 +490,6 @@ cdef extern from "cantera/zeroD/ReactorBase.h" namespace "Cantera":
|
|||
void setName(string)
|
||||
void setInitialVolume(double)
|
||||
|
||||
|
||||
cdef extern from "cantera/zeroD/Reactor.h":
|
||||
cdef cppclass CxxReactor "Cantera::Reactor" (CxxReactorBase):
|
||||
CxxReactor()
|
||||
void setKineticsMgr(CxxKinetics&)
|
||||
|
|
@ -500,30 +507,20 @@ cdef extern from "cantera/zeroD/Reactor.h":
|
|||
void addSensitivitySpeciesEnthalpy(size_t) except +translate_exception
|
||||
size_t nSensParams()
|
||||
|
||||
|
||||
cdef extern from "cantera/zeroD/FlowReactor.h":
|
||||
cdef cppclass CxxFlowReactor "Cantera::FlowReactor" (CxxReactor):
|
||||
CxxFlowReactor()
|
||||
void setMassFlowRate(double) except +translate_exception
|
||||
double speed()
|
||||
double distance()
|
||||
|
||||
# walls
|
||||
|
||||
cdef extern from "cantera/zeroD/Wall.h":
|
||||
cdef cppclass CxxWall "Cantera::Wall":
|
||||
CxxWall()
|
||||
cdef cppclass CxxWallBase "Cantera::WallBase":
|
||||
CxxWallBase()
|
||||
string type()
|
||||
cbool install(CxxReactorBase&, CxxReactorBase&)
|
||||
void setExpansionRateCoeff(double)
|
||||
double getExpansionRateCoeff()
|
||||
double area()
|
||||
void setArea(double)
|
||||
double getArea()
|
||||
void setHeatTransferCoeff(double)
|
||||
double getHeatTransferCoeff()
|
||||
void setEmissivity(double) except +translate_exception
|
||||
double getEmissivity()
|
||||
void setVelocity(CxxFunc1*)
|
||||
void setHeatFlux(CxxFunc1*)
|
||||
void setKinetics(CxxKinetics*, CxxKinetics*)
|
||||
void setCoverages(int, double*)
|
||||
void setCoverages(int, Composition&) except +translate_exception
|
||||
|
|
@ -534,8 +531,19 @@ cdef extern from "cantera/zeroD/Wall.h":
|
|||
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()
|
||||
void setVelocity(CxxFunc1*)
|
||||
void setHeatFlux(CxxFunc1*)
|
||||
|
||||
# reactor surface
|
||||
|
||||
cdef extern from "cantera/zeroD/ReactorSurface.h":
|
||||
cdef cppclass CxxReactorSurface "Cantera::ReactorSurface":
|
||||
CxxReactorSurface()
|
||||
double area()
|
||||
|
|
@ -547,8 +555,8 @@ cdef extern from "cantera/zeroD/ReactorSurface.h":
|
|||
void addSensitivityReaction(size_t) except +translate_exception
|
||||
size_t nSensParams()
|
||||
|
||||
# flow devices
|
||||
|
||||
cdef extern from "cantera/zeroD/flowControllers.h":
|
||||
cdef cppclass CxxFlowDevice "Cantera::FlowDevice":
|
||||
CxxFlowDevice()
|
||||
double massFlowRate(double) except +translate_exception
|
||||
|
|
@ -567,8 +575,8 @@ cdef extern from "cantera/zeroD/flowControllers.h":
|
|||
void setPressureCoeff(double)
|
||||
void setMaster(CxxFlowDevice*)
|
||||
|
||||
# reactor net
|
||||
|
||||
cdef extern from "cantera/zeroD/ReactorNet.h":
|
||||
cdef cppclass CxxReactorNet "Cantera::ReactorNet":
|
||||
CxxReactorNet()
|
||||
void addReactor(CxxReactor&)
|
||||
|
|
@ -612,9 +620,6 @@ cdef extern from "cantera/transport/TransportFactory.h" namespace "Cantera":
|
|||
cdef CxxTransport* newDefaultTransportMgr(CxxThermoPhase*) except +translate_exception
|
||||
cdef CxxTransport* newTransportMgr(string, CxxThermoPhase*) except +translate_exception
|
||||
|
||||
cdef extern from "cantera/zeroD/ReactorFactory.h" namespace "Cantera":
|
||||
cdef CxxReactorBase* newReactor(string) except +translate_exception
|
||||
|
||||
cdef extern from "cantera/oneD/Domain1D.h":
|
||||
cdef cppclass CxxDomain1D "Cantera::Domain1D":
|
||||
size_t domainIndex()
|
||||
|
|
@ -974,13 +979,13 @@ cdef class ReactorSurface:
|
|||
cdef Kinetics _kinetics
|
||||
|
||||
cdef class WallSurface:
|
||||
cdef CxxWall* cxxwall
|
||||
cdef CxxWallBase* cxxwall
|
||||
cdef object wall
|
||||
cdef int side
|
||||
cdef Kinetics _kinetics
|
||||
|
||||
cdef class Wall:
|
||||
cdef CxxWall wall
|
||||
cdef class WallBase:
|
||||
cdef CxxWallBase* wall
|
||||
cdef WallSurface left_surface
|
||||
cdef WallSurface right_surface
|
||||
cdef object _velocity_func
|
||||
|
|
@ -989,6 +994,9 @@ cdef class Wall:
|
|||
cdef ReactorBase _right_reactor
|
||||
cdef str name
|
||||
|
||||
cdef class Wall(WallBase):
|
||||
pass
|
||||
|
||||
cdef class FlowDevice:
|
||||
cdef CxxFlowDevice* dev
|
||||
cdef Func1 _rate_func
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# This file is part of Cantera. See License.txt in the top-level directory or
|
||||
# at http://www.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
|
||||
import numbers as _numbers
|
||||
|
|
@ -450,33 +450,13 @@ cdef class ReactorSurface:
|
|||
self.surface.addSensitivityReaction(m)
|
||||
|
||||
|
||||
cdef class Wall:
|
||||
r"""
|
||||
A Wall separates two reactors, or a reactor and a reservoir. A wall has a
|
||||
finite area, may conduct or radiate heat between the two reactors on either
|
||||
side, and may move like a piston.
|
||||
|
||||
Walls are stateless objects in Cantera, meaning that no differential
|
||||
equation is integrated to determine any wall property. Since it is the wall
|
||||
(piston) velocity that enters the energy equation, this means that it is
|
||||
the velocity, not the acceleration or displacement, that is specified.
|
||||
The wall velocity is computed from
|
||||
|
||||
.. math:: v = K(P_{\rm left} - P_{\rm right}) + v_0(t),
|
||||
|
||||
where :math:`K` is a non-negative constant, and :math:`v_0(t)` is a
|
||||
specified function of time. The velocity is positive if the wall is
|
||||
moving to the right.
|
||||
|
||||
The heat flux through the wall is computed from
|
||||
|
||||
.. math:: q = U(T_{\rm left} - T_{\rm right}) + \epsilon\sigma (T_{\rm left}^4 - T_{\rm right}^4) + q_0(t),
|
||||
|
||||
where :math:`U` is the overall heat transfer coefficient for
|
||||
conduction/convection, and :math:`\epsilon` is the emissivity. The function
|
||||
: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.
|
||||
cdef class WallBase:
|
||||
"""
|
||||
Common base class for walls.
|
||||
"""
|
||||
wall_type = "None"
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.wall = newWall(stringify(self.wall_type))
|
||||
|
||||
# The signature of this function causes warnings for Sphinx documentation
|
||||
def __init__(self, left, right, *, name=None, A=None, K=None, U=None,
|
||||
|
|
@ -540,6 +520,11 @@ cdef class Wall:
|
|||
self._left_reactor = left
|
||||
self._right_reactor = right
|
||||
|
||||
property type:
|
||||
""" The left surface of this wall. """
|
||||
def __get__(self):
|
||||
return pystr(self.wall.type())
|
||||
|
||||
property left:
|
||||
""" The left surface of this wall. """
|
||||
def __get__(self):
|
||||
|
|
@ -550,16 +535,6 @@ cdef class Wall:
|
|||
def __get__(self):
|
||||
return self.right_surface
|
||||
|
||||
property expansion_rate_coeff:
|
||||
"""
|
||||
The coefficient *K* [m/s/Pa] that determines the velocity of the wall
|
||||
as a function of the pressure difference between the adjacent reactors.
|
||||
"""
|
||||
def __get__(self):
|
||||
return self.wall.getExpansionRateCoeff()
|
||||
def __set__(self, double val):
|
||||
self.wall.setExpansionRateCoeff(val)
|
||||
|
||||
property area:
|
||||
""" The wall area [m^2]. """
|
||||
def __get__(self):
|
||||
|
|
@ -567,48 +542,6 @@ cdef class Wall:
|
|||
def __set__(self, double value):
|
||||
self.wall.setArea(value)
|
||||
|
||||
property heat_transfer_coeff:
|
||||
"""the overall heat transfer coefficient [W/m^2/K]"""
|
||||
def __get__(self):
|
||||
return self.wall.getHeatTransferCoeff()
|
||||
def __set__(self, double value):
|
||||
self.wall.setHeatTransferCoeff(value)
|
||||
|
||||
property emissivity:
|
||||
"""The emissivity (nondimensional)"""
|
||||
def __get__(self):
|
||||
return self.wall.getEmissivity()
|
||||
def __set__(self, double value):
|
||||
self.wall.setEmissivity(value)
|
||||
|
||||
def set_velocity(self, v):
|
||||
"""
|
||||
The wall velocity [m/s]. May be either a constant or an arbitrary
|
||||
function of time. See `Func1`.
|
||||
"""
|
||||
cdef Func1 f
|
||||
if isinstance(v, Func1):
|
||||
f = v
|
||||
else:
|
||||
f = Func1(v)
|
||||
|
||||
self._velocity_func = f
|
||||
self.wall.setVelocity(f.func)
|
||||
|
||||
def set_heat_flux(self, q):
|
||||
"""
|
||||
Heat flux [W/m^2] across the wall. May be either a constant or
|
||||
an arbitrary function of time. See `Func1`.
|
||||
"""
|
||||
cdef Func1 f
|
||||
if isinstance(q, Func1):
|
||||
f = q
|
||||
else:
|
||||
f = Func1(q)
|
||||
|
||||
self._heat_flux_func = f
|
||||
self.wall.setHeatFlux(f.func)
|
||||
|
||||
def vdot(self, double t):
|
||||
"""
|
||||
The rate of volumetric change [m^3/s] associated with the wall
|
||||
|
|
@ -626,6 +559,88 @@ cdef class Wall:
|
|||
return self.wall.Q(t)
|
||||
|
||||
|
||||
cdef class Wall(WallBase):
|
||||
r"""
|
||||
A Wall separates two reactors, or a reactor and a reservoir. A wall has a
|
||||
finite area, may conduct or radiate heat between the two reactors on either
|
||||
side, and may move like a piston.
|
||||
|
||||
Walls are stateless objects in Cantera, meaning that no differential
|
||||
equation is integrated to determine any wall property. Since it is the wall
|
||||
(piston) velocity that enters the energy equation, this means that it is
|
||||
the velocity, not the acceleration or displacement, that is specified.
|
||||
The wall velocity is computed from
|
||||
|
||||
.. math:: v = K(P_{\rm left} - P_{\rm right}) + v_0(t),
|
||||
|
||||
where :math:`K` is a non-negative constant, and :math:`v_0(t)` is a
|
||||
specified function of time. The velocity is positive if the wall is
|
||||
moving to the right.
|
||||
|
||||
The heat flux through the wall is computed from
|
||||
|
||||
.. math:: q = U(T_{\rm left} - T_{\rm right}) + \epsilon\sigma (T_{\rm left}^4 - T_{\rm right}^4) + q_0(t),
|
||||
|
||||
where :math:`U` is the overall heat transfer coefficient for
|
||||
conduction/convection, and :math:`\epsilon` is the emissivity. The function
|
||||
: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"
|
||||
|
||||
property expansion_rate_coeff:
|
||||
"""
|
||||
The coefficient *K* [m/s/Pa] that determines the velocity of the wall
|
||||
as a function of the pressure difference between the adjacent reactors.
|
||||
"""
|
||||
def __get__(self):
|
||||
return (<CxxWall*>(self.wall)).getExpansionRateCoeff()
|
||||
def __set__(self, double val):
|
||||
(<CxxWall*>(self.wall)).setExpansionRateCoeff(val)
|
||||
|
||||
property heat_transfer_coeff:
|
||||
"""the overall heat transfer coefficient [W/m^2/K]"""
|
||||
def __get__(self):
|
||||
return (<CxxWall*>(self.wall)).getHeatTransferCoeff()
|
||||
def __set__(self, double value):
|
||||
(<CxxWall*>(self.wall)).setHeatTransferCoeff(value)
|
||||
|
||||
property emissivity:
|
||||
"""The emissivity (nondimensional)"""
|
||||
def __get__(self):
|
||||
return (<CxxWall*>(self.wall)).getEmissivity()
|
||||
def __set__(self, double value):
|
||||
(<CxxWall*>(self.wall)).setEmissivity(value)
|
||||
|
||||
def set_velocity(self, v):
|
||||
"""
|
||||
The wall velocity [m/s]. May be either a constant or an arbitrary
|
||||
function of time. See `Func1`.
|
||||
"""
|
||||
cdef Func1 f
|
||||
if isinstance(v, Func1):
|
||||
f = v
|
||||
else:
|
||||
f = Func1(v)
|
||||
|
||||
self._velocity_func = f
|
||||
(<CxxWall*>(self.wall)).setVelocity(f.func)
|
||||
|
||||
def set_heat_flux(self, q):
|
||||
"""
|
||||
Heat flux [W/m^2] across the wall. May be either a constant or
|
||||
an arbitrary function of time. See `Func1`.
|
||||
"""
|
||||
cdef Func1 f
|
||||
if isinstance(q, Func1):
|
||||
f = q
|
||||
else:
|
||||
f = Func1(q)
|
||||
|
||||
self._heat_flux_func = f
|
||||
(<CxxWall*>self.wall).setHeatFlux(f.func)
|
||||
|
||||
|
||||
cdef class FlowDevice:
|
||||
"""
|
||||
Base class for devices that allow flow between reactors.
|
||||
|
|
@ -637,9 +652,9 @@ 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, **kwargs):
|
||||
# Children of this abstract class are responsible for allocating dev
|
||||
self.dev = NULL
|
||||
self.dev = newFlowDevice(stringify(self.flowdevice_type))
|
||||
|
||||
# The signature of this function causes warnings for Sphinx documentation
|
||||
def __init__(self, upstream, downstream, *, name=None):
|
||||
|
|
@ -698,8 +713,7 @@ cdef class MassFlowController(FlowDevice):
|
|||
that this capability should be used with caution, since no account is
|
||||
taken of the work required to do this.
|
||||
"""
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.dev = new CxxMassFlowController()
|
||||
flowdevice_type = "MassFlowController"
|
||||
|
||||
# The signature of this function causes warnings for Sphinx documentation
|
||||
def __init__(self, upstream, downstream, *, name=None, mdot=None):
|
||||
|
|
@ -751,8 +765,7 @@ cdef class Valve(FlowDevice):
|
|||
value, very small pressure differences will result in flow between the
|
||||
reactors that counteracts the pressure difference.
|
||||
"""
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.dev = new CxxValve()
|
||||
flowdevice_type = "Valve"
|
||||
|
||||
# The signature of this function causes warnings for Sphinx documentation
|
||||
def __init__(self, upstream, downstream, *, name=None, K=None):
|
||||
|
|
@ -797,8 +810,7 @@ cdef class PressureController(FlowDevice):
|
|||
|
||||
.. math:: \dot m = \dot m_{\rm master} + K_v(P_1 - P_2).
|
||||
"""
|
||||
def __cinit__(self, *args, **kwargs):
|
||||
self.dev = new CxxPressureController()
|
||||
flowdevice_type = "PressureController"
|
||||
|
||||
# The signature of this function causes warnings for Sphinx documentation
|
||||
def __init__(self, upstream, downstream, *, name=None, master=None, K=None):
|
||||
|
|
|
|||
|
|
@ -156,6 +156,11 @@ class TestReactor(utilities.CanteraTest):
|
|||
self.assertLessEqual(self.net.time, max_steps * max_step_size)
|
||||
self.assertEqual(self.net.max_steps, max_steps)
|
||||
|
||||
def test_wall_type(self):
|
||||
self.make_reactors(P1=101325, P2=300000)
|
||||
self.add_wall(K=0.1, A=1.0)
|
||||
self.assertEqual(self.w.type, "Wall")
|
||||
|
||||
def test_equalize_pressure(self):
|
||||
self.make_reactors(P1=101325, P2=300000)
|
||||
self.add_wall(K=0.1, A=1.0)
|
||||
|
|
|
|||
|
|
@ -3,18 +3,14 @@
|
|||
*/
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#define CANTERA_USE_INTERNAL
|
||||
#include "cantera/clib/ctreactor.h"
|
||||
|
||||
// Cantera includes
|
||||
#include "cantera/zeroD/Reactor.h"
|
||||
#include "cantera/zeroD/FlowReactor.h"
|
||||
#include "cantera/zeroD/ReactorNet.h"
|
||||
#include "cantera/zeroD/ReactorFactory.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
#include "cantera/zeroD/flowControllers.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
#include "cantera/zerodim.h"
|
||||
#include "Cabinet.h"
|
||||
|
||||
using namespace Cantera;
|
||||
|
|
@ -23,7 +19,7 @@ using namespace std;
|
|||
typedef Cabinet<ReactorBase> ReactorCabinet;
|
||||
typedef Cabinet<ReactorNet> NetworkCabinet;
|
||||
typedef Cabinet<FlowDevice> FlowDeviceCabinet;
|
||||
typedef Cabinet<Wall> WallCabinet;
|
||||
typedef Cabinet<WallBase> WallCabinet;
|
||||
typedef Cabinet<Func1> FuncCabinet;
|
||||
typedef Cabinet<ThermoPhase> ThermoCabinet;
|
||||
typedef Cabinet<Kinetics> KineticsCabinet;
|
||||
|
|
@ -351,21 +347,8 @@ extern "C" {
|
|||
int flowdev_new(int type)
|
||||
{
|
||||
try {
|
||||
FlowDevice* r;
|
||||
switch (type) {
|
||||
case MFC_Type:
|
||||
r = new MassFlowController();
|
||||
break;
|
||||
case PressureController_Type:
|
||||
r = new PressureController();
|
||||
break;
|
||||
case Valve_Type:
|
||||
r = new Valve();
|
||||
break;
|
||||
default:
|
||||
r = new FlowDevice();
|
||||
}
|
||||
return FlowDeviceCabinet::add(r);
|
||||
FlowDevice* f = FlowDeviceFactory::factory()->newFlowDevice(type);
|
||||
return FlowDeviceCabinet::add(f);
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
|
|
@ -450,7 +433,8 @@ extern "C" {
|
|||
int wall_new(int type)
|
||||
{
|
||||
try {
|
||||
return WallCabinet::add(new Wall());
|
||||
WallBase* w = WallFactory::factory()->newWall(type);
|
||||
return WallCabinet::add(w);
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
}
|
||||
|
|
@ -517,7 +501,7 @@ extern "C" {
|
|||
int wall_setThermalResistance(int i, double rth)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setThermalResistance(rth);
|
||||
WallCabinet::get<Wall>(i).setThermalResistance(rth);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
@ -527,7 +511,7 @@ extern "C" {
|
|||
int wall_setHeatTransferCoeff(int i, double u)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setHeatTransferCoeff(u);
|
||||
WallCabinet::get<Wall>(i).setHeatTransferCoeff(u);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
@ -537,7 +521,7 @@ extern "C" {
|
|||
int wall_setHeatFlux(int i, int n)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setHeatFlux(&FuncCabinet::item(n));
|
||||
WallCabinet::get<Wall>(i).setHeatFlux(&FuncCabinet::item(n));
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
@ -547,7 +531,7 @@ extern "C" {
|
|||
int wall_setExpansionRateCoeff(int i, double k)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setExpansionRateCoeff(k);
|
||||
WallCabinet::get<Wall>(i).setExpansionRateCoeff(k);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
@ -557,7 +541,7 @@ extern "C" {
|
|||
int wall_setVelocity(int i, int n)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setVelocity(&FuncCabinet::item(n));
|
||||
WallCabinet::get<Wall>(i).setVelocity(&FuncCabinet::item(n));
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
@ -567,7 +551,7 @@ extern "C" {
|
|||
int wall_setEmissivity(int i, double epsilon)
|
||||
{
|
||||
try {
|
||||
WallCabinet::item(i).setEmissivity(epsilon);
|
||||
WallCabinet::get<Wall>(i).setEmissivity(epsilon);
|
||||
return 0;
|
||||
} catch (...) {
|
||||
return handleAllExceptions(-1, ERR);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
namespace Cantera
|
||||
{
|
||||
|
||||
FlowDevice::FlowDevice() : m_mdot(0.0), m_func(0), m_type(0),
|
||||
m_nspin(0), m_nspout(0),
|
||||
m_in(0), m_out(0) {}
|
||||
|
||||
bool FlowDevice::install(ReactorBase& in, ReactorBase& out)
|
||||
{
|
||||
if (m_in || m_out) {
|
||||
|
|
|
|||
43
src/zeroD/FlowDeviceFactory.cpp
Normal file
43
src/zeroD/FlowDeviceFactory.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//! @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"
|
||||
|
||||
using namespace std;
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
FlowDeviceFactory* FlowDeviceFactory::s_factory = 0;
|
||||
std::mutex FlowDeviceFactory::flowDevice_mutex;
|
||||
|
||||
FlowDeviceFactory::FlowDeviceFactory()
|
||||
{
|
||||
reg("MassFlowController", []() { return new MassFlowController(); });
|
||||
reg("PressureController", []() { return new PressureController(); });
|
||||
reg("Valve", []() { return new Valve(); });
|
||||
|
||||
// only used by clib
|
||||
reg_type("MassFlowController", MFC_Type);
|
||||
reg_type("PressureController", PressureController_Type);
|
||||
reg_type("Valve", Valve_Type);
|
||||
}
|
||||
|
||||
FlowDevice* FlowDeviceFactory::newFlowDevice(const std::string& flowDeviceType)
|
||||
{
|
||||
return create(flowDeviceType);
|
||||
}
|
||||
|
||||
FlowDevice* FlowDeviceFactory::newFlowDevice(int ir)
|
||||
{
|
||||
try {
|
||||
return create(m_types.at(ir));
|
||||
} catch (out_of_range&) {
|
||||
throw CanteraError("FlowDeviceFactory::newFlowDevice",
|
||||
"unknown flowDevice type!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file Reactor.cpp A zero-dimensional reactor
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#include "cantera/zeroD/Reactor.h"
|
||||
#include "cantera/zeroD/FlowDevice.h"
|
||||
|
|
@ -87,7 +87,7 @@ void Reactor::initialize(doublereal t0)
|
|||
m_intEnergy = m_thermo->intEnergy_mass();
|
||||
|
||||
for (size_t n = 0; n < m_wall.size(); n++) {
|
||||
Wall* W = m_wall[n];
|
||||
WallBase* W = m_wall[n];
|
||||
W->initialize();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file ReactorBase.cpp
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
#include "cantera/zeroD/FlowDevice.h"
|
||||
|
|
@ -54,7 +54,7 @@ void ReactorBase::addOutlet(FlowDevice& outlet)
|
|||
m_outlet.push_back(&outlet);
|
||||
}
|
||||
|
||||
void ReactorBase::addWall(Wall& w, int lr)
|
||||
void ReactorBase::addWall(WallBase& w, int lr)
|
||||
{
|
||||
m_wall.push_back(&w);
|
||||
if (lr == 0) {
|
||||
|
|
@ -64,7 +64,7 @@ void ReactorBase::addWall(Wall& w, int lr)
|
|||
}
|
||||
}
|
||||
|
||||
Wall& ReactorBase::wall(size_t n)
|
||||
WallBase& ReactorBase::wall(size_t n)
|
||||
{
|
||||
return *m_wall[n];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! @file ReactorFactory.cpp
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#include "cantera/zeroD/ReactorFactory.h"
|
||||
#include "cantera/zeroD/Reservoir.h"
|
||||
|
|
@ -15,6 +15,8 @@ using namespace std;
|
|||
namespace Cantera
|
||||
{
|
||||
|
||||
class Reservoir;
|
||||
|
||||
ReactorFactory* ReactorFactory::s_factory = 0;
|
||||
std::mutex ReactorFactory::reactor_mutex;
|
||||
|
||||
|
|
@ -26,6 +28,14 @@ ReactorFactory::ReactorFactory()
|
|||
reg("FlowReactor", []() { return new FlowReactor(); });
|
||||
reg("IdealGasReactor", []() { return new IdealGasReactor(); });
|
||||
reg("IdealGasConstPressureReactor", []() { return new IdealGasConstPressureReactor(); });
|
||||
|
||||
// only used by clib
|
||||
reg_type("Reservoir", ReservoirType);
|
||||
reg_type("Reactor", ReactorType);
|
||||
reg_type("ConstPressureReactor", ConstPressureReactorType);
|
||||
reg_type("FlowReactor", FlowReactorType);
|
||||
reg_type("IdealGasReactor", IdealGasReactorType);
|
||||
reg_type("IdealGasConstPressureReactor", IdealGasConstPressureReactorType);
|
||||
}
|
||||
|
||||
ReactorBase* ReactorFactory::newReactor(const std::string& reactorType)
|
||||
|
|
@ -33,20 +43,10 @@ ReactorBase* ReactorFactory::newReactor(const std::string& reactorType)
|
|||
return create(reactorType);
|
||||
}
|
||||
|
||||
|
||||
ReactorBase* ReactorFactory::newReactor(int ir)
|
||||
{
|
||||
static const unordered_map<int, string> types {
|
||||
{ReservoirType, "Reservoir"},
|
||||
{ReactorType, "Reactor"},
|
||||
{ConstPressureReactorType, "ConstPressureReactor"},
|
||||
{FlowReactorType, "FlowReactor"},
|
||||
{IdealGasReactorType, "IdealGasReactor"},
|
||||
{IdealGasConstPressureReactorType, "IdealGasConstPressureReactor"}
|
||||
};
|
||||
|
||||
try {
|
||||
return create(types.at(ir));
|
||||
return create(m_types.at(ir));
|
||||
} catch (out_of_range&) {
|
||||
throw CanteraError("ReactorFactory::newReactor",
|
||||
"unknown reactor type!");
|
||||
|
|
|
|||
|
|
@ -1,24 +1,19 @@
|
|||
//! @file Wall.cpp
|
||||
//! @file WallBase.cpp
|
||||
|
||||
// This file is part of Cantera. See License.txt in the top-level directory or
|
||||
// at http://www.cantera.org/license.txt for license and copyright information.
|
||||
// at https://cantera.org/license.txt for license and copyright information.
|
||||
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
#include "cantera/zeroD/ReactorNet.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
#include "cantera/thermo/SurfPhase.h"
|
||||
#include "cantera/base/stringUtils.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
#include "cantera/zeroD/Wall.h"
|
||||
#include "cantera/thermo/SurfPhase.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
Wall::Wall() : m_left(0), m_right(0),
|
||||
m_surf(2),
|
||||
m_area(1.0), m_k(0.0), m_rrth(0.0), m_emiss(0.0),
|
||||
m_vf(0), m_qf(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool Wall::install(ReactorBase& rleft, ReactorBase& rright)
|
||||
WallBase::WallBase() : m_left(0), m_right(0), m_surf(2), m_area(1.0) {}
|
||||
|
||||
bool WallBase::install(ReactorBase& rleft, ReactorBase& rright)
|
||||
{
|
||||
// check if wall is already installed
|
||||
if (m_left || m_right) {
|
||||
|
|
@ -33,16 +28,25 @@ bool Wall::install(ReactorBase& rleft, ReactorBase& rright)
|
|||
return true;
|
||||
}
|
||||
|
||||
doublereal Wall::vdot(doublereal t)
|
||||
{
|
||||
double rate1 = m_k * m_area * (m_left->pressure() - m_right->pressure());
|
||||
if (m_vf) {
|
||||
rate1 += m_area * m_vf->eval(t);
|
||||
}
|
||||
return rate1;
|
||||
void WallBase::setArea(double a) {
|
||||
m_area = a;
|
||||
m_surf[0].setArea(a);
|
||||
m_surf[1].setArea(a);
|
||||
}
|
||||
|
||||
doublereal Wall::Q(doublereal t)
|
||||
Wall::Wall() : WallBase(), m_k(0.0), m_rrth(0.0), m_emiss(0.0), m_vf(0), m_qf(0) {}
|
||||
|
||||
double Wall::vdot(double t)
|
||||
{
|
||||
double rate = m_k * m_area * (m_left->pressure() - m_right->pressure());
|
||||
|
||||
if (m_vf) {
|
||||
rate += m_area * m_vf->eval(t);
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
double Wall::Q(double t)
|
||||
{
|
||||
double q1 = (m_area * m_rrth) *
|
||||
(m_left->temperature() - m_right->temperature());
|
||||
|
|
@ -51,10 +55,11 @@ doublereal Wall::Q(doublereal t)
|
|||
double tr = m_right->temperature();
|
||||
q1 += m_emiss * m_area * StefanBoltz * (tl*tl*tl*tl - tr*tr*tr*tr);
|
||||
}
|
||||
|
||||
if (m_qf) {
|
||||
q1 += m_area * m_qf->eval(t);
|
||||
}
|
||||
return q1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
39
src/zeroD/WallFactory.cpp
Normal file
39
src/zeroD/WallFactory.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//! @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"
|
||||
|
||||
using namespace std;
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
WallFactory* WallFactory::s_factory = 0;
|
||||
std::mutex WallFactory::wall_mutex;
|
||||
|
||||
WallFactory::WallFactory()
|
||||
{
|
||||
reg("Wall", []() { return new Wall(); });
|
||||
|
||||
// only used by clib
|
||||
reg_type("Wall", WallType);
|
||||
}
|
||||
|
||||
WallBase* WallFactory::newWall(const std::string& wallType)
|
||||
{
|
||||
return create(wallType);
|
||||
}
|
||||
|
||||
WallBase* WallFactory::newWall(int ir)
|
||||
{
|
||||
try {
|
||||
return create(m_types.at(ir));
|
||||
} catch (out_of_range&) {
|
||||
throw CanteraError("WallFactory::newWall",
|
||||
"unknown wall type!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
src/zeroD/flowControllers.cpp
Normal file
59
src/zeroD/flowControllers.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//! @file flowControllers.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/flowControllers.h"
|
||||
#include "cantera/zeroD/ReactorBase.h"
|
||||
#include "cantera/numerics/Func1.h"
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
MassFlowController::MassFlowController() : FlowDevice() {
|
||||
m_type = MFC_Type;
|
||||
}
|
||||
|
||||
void MassFlowController::updateMassFlowRate(double time)
|
||||
{
|
||||
if (m_func) {
|
||||
m_mdot = m_func->eval(time);
|
||||
}
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
|
||||
PressureController::PressureController() : FlowDevice(), m_master(0) {
|
||||
m_type = PressureController_Type;
|
||||
}
|
||||
|
||||
void PressureController::updateMassFlowRate(double time)
|
||||
{
|
||||
if (!ready()) {
|
||||
throw CanteraError("PressureController::updateMassFlowRate",
|
||||
"Device is not ready; some parameters have not been set.");
|
||||
}
|
||||
m_mdot = m_master->massFlowRate(time)
|
||||
+ m_coeffs[0]*(in().pressure() - out().pressure());
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
|
||||
Valve::Valve() : FlowDevice() {
|
||||
m_type = Valve_Type;
|
||||
}
|
||||
|
||||
void Valve::updateMassFlowRate(double time)
|
||||
{
|
||||
if (!ready()) {
|
||||
throw CanteraError("Valve::updateMassFlowRate",
|
||||
"Device is not ready; some parameters have not been set.");
|
||||
}
|
||||
double delta_P = in().pressure() - out().pressure();
|
||||
if (m_func) {
|
||||
m_mdot = m_func->eval(delta_P);
|
||||
} else {
|
||||
m_mdot = m_coeffs[0]*delta_P;
|
||||
}
|
||||
m_mdot = std::max(m_mdot, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue