IntegrationBase Class
(CDPSim::IntegrationBase)The IntegrationBase is a base class of all integration algorithms. Inherit it to add custom algorithms. More...
Header: | #include <IntegrationBase> |
Inherits: | CDP::StudioAPI::CDPNode |
Public Functions
IntegrationBase() | |
virtual | ~IntegrationBase() override |
virtual void | AddSimComponent(DynamicSimComponent *simComponent) |
virtual void | Configure(XMLElementEx *integration, SimulatorManager *owner) |
std::vector<Matrix1D *> & | GetMatrices() |
virtual std::vector<DynamicSimComponent *> & | GetSimComponents() |
virtual SolverType | GetSolverType() const |
virtual void | Integrate(double t, double &dt, double &T) = 0 |
virtual void | Process() |
virtual void | RegisterMatrix1D(Matrix1D *matrix1D) |
virtual void | ScheduleSubComponents() |
Reimplemented Public Functions
virtual void | FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const override |
virtual const std::string | GetNodeName() const override |
virtual std::string | GetNodeTypeName() const override |
- 27 public functions inherited from CDP::StudioAPI::CDPNode
- 22 public functions inherited from CDP::StudioAPI::ICDPNode
Protected Variables
Matrix1D | Y |
Matrix1D | Y_ddt |
Matrix1D | Y_residual |
CDPProperty<std::string> | m_model |
CDPProperty<std::string> | m_name |
SimulatorManager * | m_owner |
Additional Inherited Members
- 1 protected function inherited from CDP::StudioAPI::CDPNode
Detailed Description
The IntegrationBase is a base class of all integration algorithms. Inherit it to add custom algorithms.
Inheriting class must override Integrate() method. See example in Integrate() documentation.
Member Function Documentation
IntegrationBase::IntegrationBase()
Default constructs an instance of IntegrationBase.
[override virtual]
IntegrationBase::~IntegrationBase()
Destroys the instance of IntegrationBase. The destructor is virtual.
[virtual]
void IntegrationBase::AddSimComponent(DynamicSimComponent *simComponent)
Called automatically by the framework. Adds a simulator component to the list of components this integration algorithm will handle.
[virtual]
void IntegrationBase::Configure(XMLElementEx *integration, SimulatorManager *owner)
Reads configuration from XML. Called automatically by parent.
[override virtual]
void IntegrationBase::FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const
Reimplemented from CDPNode::FillNodeChildren().
Exposes child nodes of this node to StudioAPI.
Must be overridden if node has child nodes to expose.
std::vector<Matrix1D *> &IntegrationBase::GetMatrices()
Returns the list of matrixes registered by the integration algorithm using RegisterMatrix1D().
[override virtual]
const std::string IntegrationBase::GetNodeName() const
Reimplemented from ICDPNode::GetNodeName().
Returns node's unique name.
[override virtual]
std::string IntegrationBase::GetNodeTypeName() const
Reimplemented from ICDPNode::GetNodeTypeName().
Returns node's model name "CDPNode".
[virtual]
std::vector<DynamicSimComponent *> &IntegrationBase::GetSimComponents()
Returns a list of all simulator components. Needed to implement Integrate()
[virtual]
SolverType IntegrationBase::GetSolverType() const
Returns the type of the solver used by this integration algorithm.
Differential equation solvers support DynamicSimComponents implementing the EvaluateDiffEquations method while algebraic equation solvers handle components implementing EvaluateAlgebraicEquations.
[pure virtual]
void IntegrationBase::Integrate(double t, double &dt, double &T)
Depending on the SolverType of this integrator, the implementation here should call either EvaluateDiffEquations() or EvaluateAlgebraicEquations() on every DynamicSimComponent and integrate the state variables.
Parameters passed to the method are:
- t – simulator time (the end time the simulation should reach - start time is
t - dt
). - dt – Time since previous calculation. Should equal T, but may not be exactly T because of scheduler imperfection.
- T – Timestep (requested simulation period). Can be updated by the method to increase or decrease the timestep. Note, it is not recommended to increase the timestep under SimulationManager processing period (process frequency is set by the SimulatorManager fs property).
Fields this method should use:
- Y – State variable values matrix used to pass state variable values to the PreIntegrate(), EvaluateDiffEquations(), EvaluateAlgebraicEquations() and PostIntegrate() methods.
- Y_ddt – Derivatives of the state variables.
- Y_residual – Residuals of the state variables (only used when SolverType is
Algebraic (DAE)"
).
Sequence:
- Call PreIntegrate() on every DynamicSimComponent.
- If SolverType is
Differential (ODE)"
, call EvaluateDiffEquations() of every DynamicSimComponent. The EvaluateDiffEquations() method will use the state variable initial values array Y to calculate the derivative for each state variable and store the results in the Y_ddt array. The IntegrationBase implementation is expected to use the Y_ddt to integrate and store the new state variable values in the Y array. Note, it is allowed to call EvaluateDiffEquations() multiple times during one Integrate step if needed (with different initial values set to Y). This can be useful to improve accuracy and estimate errors. - If SolverType is
Algebraic (DAE)"
, call EvaluateAlgebraicEquations() of every DynamicSimComponent. The EvaluateAlgebraicEquations() method will use the state variable initial values array Y and the derivative array Y_ddt to calculate the residual for each state variable and store the result in the Y_residual array. The IntegrationBase implementation is expected to use it for finding Y_ddt values where the residual would be close to zero, then integrate and store the new state variables values in the Y array. Note, it is allowed to call EvaluateAlgebraicEquations() multiple times during one Integrate step if needed (with different values set to Y and Y_ddt). This can be used by iterative solvers to get the residuals as close to zero as possible. - Call PostIntegrate() on every DynamicSimComponent.
- [Optional] Update the timestep T argument to request the SimulatorManager to change its TimeStep.
Example implementation of an ODE solver using Euler algorithm.
void Euler::Integrate(double t, double& dt, double& T) { // At the beginning of the method, Y contains the current values of the state variables. const auto& simComponents = GetSimComponents(); for (auto comp : simComponents) comp->PreIntegrate(); // Can override StateVariable's value mapped to Y for (auto comp : simComponents) comp->EvaluateDiffEquations(t); // Uses StateVariable's value mapped to Y to calculate Y_ddt Y += dt * Y_ddt; // Assign result to Y which is mapped to StateVariable's value and will be published for (auto comp : simComponents) comp->PostIntegrate(); // Usually used to publish values to output SimSignals // or to cap StateVariable values (mapped to Y) }
Note that previous code can be optimized as Y += dt * Y_ddt;
will allocate memory for calculating intermediate values. This can be improved by using another matrix for temporary values.
// In header file class Euler : public CDPSim::IntegrationBase { ... private: CDPSim::Matrix1D tmp; }; // In cpp file: void Euler::Configure(XMLElementEx* integration, CDPSim::SimulatorManager* owner) { CDPSim::IntegrationBase::Configure(integration, owner); RegisterMatrix1D(&tmp); } void Euler::Integrate(double t, double& dt, double& T) { ... // Instead of 'Y += dt * Y_ddt;' tmp = Y_ddt; // Use tmp to prevent allocating memory for intermediate values every time this method is called tmp *= dt; Y += tmp; ... }
[virtual]
void IntegrationBase::Process()
Called automatically by the framework with the frequency set by the SimulatorManager fs property (unlike Integrate() which is normally called much more often - with frequency set by the SimulatorManager TimeStep property).
It is normally not necessary to override this method but it can be useful to report statistics or similar at regular intervals, for example with CDPProperties.
When overriding this method, remember to call the base class method to ensure that the base class implementation is also called.
[virtual]
void IntegrationBase::RegisterMatrix1D(Matrix1D *matrix1D)
Registeres the matrix meaning that enough memory will be allocated for it to hold all state variables of all simulator components. These matrixes can be for example used as temporary buffers for calculations done in Integrate().
[virtual]
void IntegrationBase::ScheduleSubComponents()
Schedules all the subcomponents (operators)
Member Variable Documentation
Matrix1D IntegrationBase::Y
This variable holds state variables values matrix used to pass state variables to the EvaluateDiffEquations() or the EvaluateAlgebraicEquations() method. Used when implementing Integrate().
Matrix1D IntegrationBase::Y_ddt
This variable holds derivative of the state variables. Used when implementing Integrate().
Matrix1D IntegrationBase::Y_residual
This variable holds residual of the state variables. Used when implementing Integrate() for algebraic equations.
CDPProperty<std::string> IntegrationBase::m_model
This variable specifies the type name of the node.
CDPProperty<std::string> IntegrationBase::m_name
This variable holds unique name given to this node.
SimulatorManager *IntegrationBase::m_owner
This variable holds parent of this node.
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.