DynamicSimComponent Class
(CDPSim::DynamicSimComponent)The DynamicSimComponent should be used as base class for custom simulation components. More...
Header: | #include <DynamicSimComponent> |
Inherits: | CDPComponent and |
Public Functions
DynamicSimComponent() | |
virtual | ~DynamicSimComponent() override |
virtual void | EvaluateAlgebraicEquations(double t) |
virtual void | EvaluateDiffEquations(double t) |
double | GetOperatorPeriod() const override |
virtual SimSignal * | GetSimSignalWithMatchingFullName(const std::string &simSignalName) |
virtual double | GetSimulatorTimestep() |
virtual SolverType | GetSolverType() const |
virtual StateVariable * | GetStateVariableWithMatchingFullName(const std::string &stateVariableName) |
virtual bool | HasOperatorWithMatchingFullName(const std::string &fullName) |
virtual void | PostIntegrate() |
virtual void | PreIntegrate() |
virtual void | ReallocateStateVariables(int &offset, Matrix1D &Y, Matrix1D &Y_ddt, Matrix1D &Y_residual) |
virtual void | RegisterSimSignal(SimSignal *pSimSignal) |
virtual void | RegisterStateVariable(StateVariable *pStateVariable) |
virtual void | Reset() |
Reimplemented Public Functions
virtual void | Configure(const char *xml) override |
virtual void | Create(const char *fullName) override |
virtual void | FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const override |
virtual void | SetProperty(std::string propertyName, std::string propertyValue) override |
- 92 public functions inherited from CDPComponent
- 39 public functions inherited from CDPObject
- 49 public functions inherited from CDPBaseObject
- 27 public functions inherited from CDP::StudioAPI::CDPNode
- 22 public functions inherited from CDP::StudioAPI::ICDPNode
Protected Functions
void | ClockInNeededProperties() |
void | ClockOutNeededProperties() |
void | UpdateSimRoutedValues() |
Reimplemented Protected Functions
virtual bool | HandleXMLElement(XMLElementEx *pEx) override |
virtual void | ProcessSubSchedulables() override |
virtual bool | ShouldBeSubScheduled(CDPSchedulable *item) const override |
virtual void | UpdateSchedulerLists() override |
- 12 protected functions inherited from CDPComponent
- 15 protected functions inherited from CDPObject
- 1 protected function inherited from CDP::StudioAPI::CDPNode
Related Non-Members
typedef | SimSignalMap |
typedef | SimSignalVector |
typedef | StateVariableMap |
typedef | StateVariableVector |
Additional Inherited Members
- 2 static public members inherited from CDPComponent
- 6 static public members inherited from CDPObject
- 1 static public member inherited from CDPBaseObject
- 42 protected variables inherited from CDPComponent
- 9 protected variables inherited from CDPObject
- 10 protected variables inherited from CDPBaseObject
Detailed Description
The DynamicSimComponent should be used as base class for custom simulation components.
Description
The DynamicSimComponent is a component base class that can be used for implementing advanced dynamic real-time simulation. All simulation components automatically connect to SimulatorManager when created. The SimulatorManager runs all DynamicSimComponent components periodically and allows configuring parameters like simulation time step and integration algorithm.
Depending on the selected SolverType, override either EvaluateDiffEquations() or EvaluateAlgebraicEquations() to create new simulator components.
- EvaluateDiffEquations - Implement the first order differential state equations `dx/dt` for state variables.
- EvaluateAlgebraicEquations - Implement `0 = f(y,dot y,t)` for solving differential-algebraic equations (DAEs). This method is intended for algebraic constraints that cannot be handled by standard ODE solvers, such as equations containing algebraic loops.
The dynamic simulation runs independent of the state machine, so the state machine can be used to create states to control the simulation component behaviour.
If Operators are used in a DynamicSimComponent, they will be processed every TimeStep of the SimulatorManager.
Choose SimulatorManager TimeStep high enough to be sure to avoid numeric errors and instability. If SimulatorManager's TimeStep or fs is changed during runtime, SimulatorManager's message 'Reset' is automatically called, so DynamicSimComponent::Reset() is called for all DynamicSimComponents.
Properties
The DynamicSimComponent has the following properties:
Property | Description |
SolverType | The solver type for the simulation component. The solver type can be set to:
It is not necessary to implement both EvaluateDiffEquations() and EvaluateAlgebraicEquations() in the same component. |
Example of Simple Simulation Component
State variables:
- `v`: Speed
- `x`: Position
Process:
- `(dv)/(dt) = F/m`
- `(dx)/(dt) = v`
Code example of a simple simulation component based on DynamicSimComponent:
class SimpleExampleSimulator : public CDPSim::DynamicSimComponent { public: void EvaluateDiffEquations(double t) override; // Calculates the derivatives for the integrator void EvaluateAlgebraicEquations(double t) override {} // Not used in this example // Creates a component instance. void Create(const char* fullName) override; protected: // Declaring state variables CDPSim::StateVariable x; CDPSim::StateVariable v; // Declaring arrays of state variables. The size is set by Create() or SetSize() CDPSim::StateVariableArray pos; CDPSim::StateVariableArray vel; // Declaring SimSignals. They are useful when Routing values from another DynamicSimComponent CDPSim::SimSignal F; // Standard CDPProperties can be used CDPProperty<double> m; }; // Create must set up signals to point into buffers. void SimpleExampleSimulator::Create(const char* fullName) { CDPSim::DynamicSimComponent::Create(fullName); // Always call base class. x.Create("x", this); v.Create("v", this); pos.Create("pos", this, arraySize); vel.Create("vel", this, arraySize); } // This method must set all the derivatives of the state variables. // To calculate the derivatives, use state variables v and x, and all other signals that are have been created. void SimpleExampleSimulator::EvaluateDiffEquations(double t) { x.ddt = v; v.ddt = F / static_cast<double>(m); } // In this function, fresh values of state variables (and derivatives) may be read and used in calculations of output SimSignals. // This function is called just after EvaluateDiffEquations(), once per simulator time period. void SimpleExampleSimulator::PostIntegrate() { if (x < 0) // Simulate a wall at x==0 { x.OverrideStateValue(0); v.OverrideStateValue(0); // Reset speed to 0 after hitting a wall x.ddt = 0; } }
Member Function Documentation
DynamicSimComponent::DynamicSimComponent()
Constructs a DynamicSimComponent. Initializes all member variables to safe default values.
[override virtual]
DynamicSimComponent::~DynamicSimComponent()
Destructs the instance.
[protected]
void DynamicSimComponent::ClockInNeededProperties()
Called automatically by the framework every time step. For SimSignals routed from properties, this syncs the property value into the SimSignal.
[protected]
void DynamicSimComponent::ClockOutNeededProperties()
Called automatically by the framework every time step. For SimSignals and StateVariables this publishes their current value to the operators routing from them.
[override virtual]
void DynamicSimComponent::Configure(const char *xml)
Reimplemented from CDPObject::Configure().
Reads configuration from XML. Called automatically by parent.
[override virtual]
void DynamicSimComponent::Create(const char *fullName)
Reimplemented from CDPComponent::Create().
Creates the instance.
[virtual]
void DynamicSimComponent::EvaluateAlgebraicEquations(double t)
Implements `0 = f(y,dot y,t)` for solving differential-algebraic equations (DAEs).
Note: This method is only used when SolverType="1 - Algebraic (DAE)"
. If SolverType="0 - Differential (ODE)"
, implement EvaluateDiffEquations() instead.
Behavior:
- This method is intended for algebraic constraints that cannot be handled by standard ODE solvers, such as equations containing algebraic loops.
- It computes residuals (the difference between the current algebraic constraint and its desired value) rather than derivatives.
- The solver will iterate to ensure these residuals converge to zero, effectively solving any algebraic loops.
Input:
- t - simulator time in seconds.
- All state variables.
Output:
- State variable residuals that must be set by this method.
Note, this method must not alter the state variables or their derivatives, only the residuals.
Tip! Most ODEs can be converted to algebraic equations by subtracting the right-hand side of the diff equation from the left-hand side. E.g. the diff equation x.ddt = v;
can be converted to the algebraic equation x.residual = x.ddt - v;
. This is often used when an ODE-based equation introduces an algebraic loop that typical ODE solvers cannot resolve.
[virtual]
void DynamicSimComponent::EvaluateDiffEquations(double t)
Implements `dydt = f(y,t)` for solving ordinary differential equations (ODEs).
Note: This method is only used when SolverType="0 - Differential (ODE)"
. If SolverType="1 - Algebraic (DAE)"
, implement EvaluateAlgebraicEquations() instead.
To obtain a high degree of accuracy, this method is run with very small time steps, much smaller than the periodic processes of standard CDP components.
Input:
- t - simulator time in seconds.
- All state variables.
Output:
- All state variable derivatives must be set by this method.
Note, that state variables must not be written in this method, only the derivatives!
[override virtual]
void DynamicSimComponent::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.
double DynamicSimComponent::GetOperatorPeriod() const
Returns the Operator sampling period.
For Operators used by DynamicSimComponent, SimulatorManager::GetSimulatorTimestep() is returned.
[virtual]
SimSignal *DynamicSimComponent::GetSimSignalWithMatchingFullName(const std::string &simSignalName)
Returns a pointer to a SimSignal if this component has a SimSignal with name equal simSignalName, or nullptr if not found.
[virtual]
double DynamicSimComponent::GetSimulatorTimestep()
Timestep used in SimulatorManager (requested simulation period). Starting at 1/simulatorFs, but may change dynamically.
[virtual]
SolverType DynamicSimComponent::GetSolverType() const
Returns the type of the solver used by this component.
Differential equation solver requires the component to implement the EvaluateDiffEquations method while algebraic equation solver requires the component to implement EvaluateAlgebraicEquations.
[virtual]
StateVariable *DynamicSimComponent::GetStateVariableWithMatchingFullName(const std::string &stateVariableName)
Returns a pointer to a StateVariable if this component has a StateVariable with name equal stateVariableName, or nullptr if not found. stateVariableName may also be equal name.Value or name.ddt.
[override virtual protected]
bool DynamicSimComponent::HandleXMLElement(XMLElementEx *pEx)
Reimplemented from CDPComponent::HandleXMLElement().
Handles creation of objects that have an XML configuration in component configuration file. Handle XMLElement <Name...>
Return true
for each element that should not be handled by CDP (properties are generated for unhandled elements)
[virtual]
bool DynamicSimComponent::HasOperatorWithMatchingFullName(const std::string &fullName)
Returns true if this component has an operator given by fullName.
[virtual]
void DynamicSimComponent::PostIntegrate()
In this function, fresh values of state variables (and derivatives) may read and used in calculations of output SimSignals. This function is called just after EvaluateDiffEquations/EvaluateAlgebraicEquations (in end of Integrate()), once per simulator time period.
It is also possible to overwrite the calculated state using StateVariable::OverrideStateValue().
Note: Avoid overriding state variables too often as it will cause jump discontinuities in the simulation and for some integration methods, the solver needs to reinitialize its internal state every time a state is overridden.
[virtual]
void DynamicSimComponent::PreIntegrate()
This function is called just before EvaluateDiffEquations/EvaluateAlgebraicEquations, once per simulator time period. In this function, the state variables may be set directly using StateVariable::OverrideStateValue(). The integration will then update the state normally, causing the overridden value to be different after the intergration.
Note: Avoid overriding state variables too often as it will cause jump discontinuities in the simulation and for some integration methods, the solver needs to reinitialize its internal state every time a state is overridden.
[override virtual protected]
void DynamicSimComponent::ProcessSubSchedulables()
Reimplemented from CDPComponent::ProcessSubSchedulables().
CDPComponent::ProcessSubSchedulables() is normally run from a CDPComponent's Process-function. This overrided version will only run CDPComponent::ProcessSubSchedulables() if called during simulation-loop (from IntegrationBase::ScheduleSubComponents()), and not when called from SimulatorManager::RunProcessForDynamicSimComponents().
[virtual]
void DynamicSimComponent::ReallocateStateVariables(int &offset, Matrix1D &Y, Matrix1D &Y_ddt, Matrix1D &Y_residual)
Maps StateVariables into Matrixes
[virtual]
void DynamicSimComponent::RegisterSimSignal(SimSignal *pSimSignal)
Adds SimSignal to list of SimSignal.
[virtual]
void DynamicSimComponent::RegisterStateVariable(StateVariable *pStateVariable)
Adds StateVariable to m_stateVariables (map of StateVariables).
[virtual]
void DynamicSimComponent::Reset()
Resets the value of every CDPSignal, SimSignal and StateVariable back to default, and Init() is called on all operators. Useful to restart simulation.
[override virtual]
void DynamicSimComponent::SetProperty(std::string propertyName, std::string propertyValue)
Reimplemented from CDPBaseObject::SetProperty().
Will check if propertyName corresponds to a registered StateVariable (propertyName must match the name of the StateVariable itself, or be equal to name.Value). If a match is found, StateVariable::OverrideStateValue() will be called with value of propertyValue. If not found, CDPComponent::SetProperty() will be called.
See also CDPComponent::SetProperty().
[override virtual protected]
bool DynamicSimComponent::ShouldBeSubScheduled(CDPSchedulable *item) const
Reimplemented from CDPComponent::ShouldBeSubScheduled().
Returns false if item
is a CDPComponent, because SimulatorManager does the scheduling, otherwise CDPComponent::ShouldBeSubScheduled(item) is returned.
[override virtual protected]
void DynamicSimComponent::UpdateSchedulerLists()
Reimplemented from CDPComponent::UpdateSchedulerLists().
For DynamicSimComponent this function is overrided and should do nothing (because they are scheduled by SimulatorManager).
[protected]
void DynamicSimComponent::UpdateSimRoutedValues()
Called automatically by the framework every time step. For input SimSignals routed from StateVariables or other SimSignals, this syncs the remote value into the SimSignal.
Related Non-Members
typedef CDPSim::SimSignalMap
Synonym for std::map<std::string, SimSignal*>. Contains SimSignal fullName and pointer.
typedef CDPSim::SimSignalVector
Synonym for std::vector<SimSignal*>.
typedef CDPSim::StateVariableMap
Synonym for std::map<std::string, StateVariable*>. Contains StateVariable fullName and pointer.
typedef CDPSim::StateVariableVector
Synonym for std::vector<StateVariable*>.
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.