API
Contents
- Contents
- Core concepts
- Problems and algorithms
- Connections
- Timestepping and multirate solving
- Saving and solutions
- Components
- Abstract Types
- User-Defined Components
This page documents the public API and the execution model used by Sirens. The Tutorial is a narrative introduction; this page is a reference for understanding the structure and interfaces.
Core concepts
A Sirens simulation has four layers:
- A component is an immutable description of a model and its configuration.
- A component integrator is the mutable runtime state created from a component via
init(component). - A
SirenProblemstores components, connectors, the global time span, and component time scales. - A
SirenSolutionstores selected variables at selected global times.
The typical workflow is:
prob = SirenProblem(components=..., connectors=..., tspan=...)
sol = solve(prob, alg; save_vars=..., saveat=...)The convenience function solve is provided by CommonSolve and performs initialization followed by solving. For manual stepping, use init(prob, alg) to create a SirenIntegrator, then call step! repeatedly or solve! to run to completion.
Problems and algorithms
SirenProblem
Sirens.SirenProblem — Type
SirenProblem <: AbstractSirenProblem
SirenProblem(components, connectors, tspan, timescales=ones(length(components)))
SirenProblem(;
components::Union{Tuple, Vector},
connectors::Union{Tuple, Vector},
tspan::Tuple{Float64, Float64},
timescales::Vector{Float64}=ones(length(components)))Defines a Sirens hybrid simulation problem.
Arguments
components::Union{Tuple, Vector}: Tuple or Vector of Components. Order is significant because it determines stepping order when multiple components can be stepped together. Component names must be unique. Using a tuple preserves type information for each element.connectors::Union{Tuple, Vector}: Tuple or Vector of Connectors. Order is significant; connectors are applied in order, and later connectors can observe changes made by earlier ones. Using a tuple preserves type information for each element.tspan::Tuple{Float64, Float64}: The time span of the simulation, from start to end time.timescales::Vector{Float64}=ones(length(components)): Timescales for each component. For componenti, global time is computed ast_global[i] = timescales[i] * t_local[i]. A component with timescale 0.1 advances ten local time units per one global time unit. This allows components using different time units to be connected in a single simulation.
Notes on Ordering
componentsorder determines stepping priority when multiple components are ready.connectorsorder is critical. Connectors are applied before component steps, in the order given. A connector is eligible only when every input is no later than every output in global time. Later connectors see changes made by earlier connectors. This is particularly important for setting#idsand#init_statesin a DuplicatedComponent.
SirenIntegrator
Sirens.SirenIntegrator — Type
SirenIntegrator <: AbstractSirenIntegrator
SirenIntegrator(;
integrators::Tuple,
connectors::Tuple,
tspan::Tuple{Float64, Float64},
currtime::Float64,
alg::AbstractSirenSolver,
save_vars::Vector{<:Union{ConnectedVariable,AbstractString}},
saveat::Union{Function, AbstractVector},
timescales::Vector{Float64})Created using init(prob::SirenProblem, alg::AbstractSirenSolver; save_vars=[]). All fields are considered internal.
Initialization and solving
CommonSolve.init — Method
init(prob::AbstractSirenProblem, alg::AbstractSirenSolver;
save_vars = nothing, saveat = nothing)Defines the integrator for a Sirens hybrid simulation.
Arguments
prob::AbstractSirenProblem: The problem to be solved.alg::AbstractSirenSolver: The Sirens solver algorithm to be used.save_vars: Variables to be saved during the simulation. Options include:nothing(default): Save all non-special variables (those not starting with '#').:all: Save all variables, including special variables.:noneorString[]: Save no variables (time is still recorded).Vector{String}: A vector of connected variable fullnames to save, including optional indices like"forest.life[1]"or"tree[1:10].life".Tuple{Vararg{ConnectedVariable}}: A tuple of ConnectedVariable objects to save.
saveat: When to save the variables during the simulation. Options include:nothing(default): Save after initialization and after every Sirens syncronisation event.- A number
Δt: Save at timestspan[1]:Δt:tspan[2]. - A vector of times: Save at exactly these time points.
- A function
(integrator, t) -> Bool: Save when it returns true (checked at scheduled stops).
Returns
SirenIntegrator: A mutable integrator ready for solving.
CommonSolve.solve! — Function
solve!(sirenInt::AbstractSirenIntegrator)Solves the problem using the SirenIntegrator by advancing it until the end of the time span, recording solutions according to the saveat configuration.
Arguments
sirenInt::AbstractSirenIntegrator: The integrator to be solved.
Returns
SirenSolution: The solution of the problem, containing saved times and states.
Behavior
- Records initial state if
saveatis satisfied att=tspan[1]. - Repeatedly calls
step!(integrator)untilcurrtime >= tspan[2]. - Records state after each step if
saveatis satisfied.
CommonSolve.step! — Method
step!(int::AbstractSirenIntegrator)Advance the state of the integrator int by one time step.
Arguments
int::Union{AbstractSirenIntegrator, AbstractComponentIntegrator}: The integrator to advance.
Solvers
Sirens.MinimumTimeStepper — Type
MinimumTimeStepper() <: AbstractSirenSolverA solver that advances the SirenIntegrator by stepping to the next event.
Algorithm
The minimum stepper chooses the smallest upcoming value of (local_time + timestep) * timescale across all components. It then:
- Applies connectors whose input global times are no later than their output global times.
- Steps all components whose next local event reaches the new global time.
- Adjusts component times after stepping to mitigate floating-point roundoff accumulation.
Timestepping and Multirate Behavior
For component i with timescale s_i, the global time is t_global = s_i * t_local.
The minimum stepper guarantees that possible connection applications cannot be jumped over. If the method synchronized at different timepoints, a connection that could have been applied if time were treated continuously might be missed.
Connections
Connections use the most recently available state at each synchronization event. They do not interpolate between component states and do not guarantee identical local times across components.
See also Connector.
Connections
Connected variables
Sirens.ConnectedVariable — Type
ConnectedVariable <: AbstractConnectedVariablePoints to a variable within a component.
Fields
component::String: Name of the component.variable::String: Name of the variable.variableindex::Union{Nothing,Vector{Int}}: Index or range for the variable, if applicable.duplicatedindex::Union{Nothing,Vector{Int}}: Index for duplicated components, if applicable.
Sirens.ConnectedVariable — Method
ConnectedVariable(name::AbstractString)Construct a ConnectedVariable from its canonical fullname.
Arguments
name::AbstractString: The full variable name.
Syntax and Examples
Connected variables are specified as strings in one of these forms:
| Syntax | Meaning |
|---|---|
component.variable | A variable in a component |
component.variable[i] | An index into a variable |
component[j].variable | Instance j of a duplicated component |
component[j].variable[i] | Both kinds of indexing |
Examples
ConnectedVariable("comp.var"): Variablevarin componentcomp.ConnectedVariable("comp.var[1:5]"): Variable indices 1 through 5 (variable index).ConnectedVariable("comp[2].var"): Variablevarfrom duplicated instance 2 (duplicated index).ConnectedVariable("comp[1:3].var[4]"): Variable index 4 from duplicated instances 1-3.
Parsing
Indices are parsed as Julia expressions, so use literal integer indices and ranges:
1for a single index.1:5for a range.[1, 3]for a vector of indices.
Base.fullname — Function
fullname(var::AbstractConnectedVariable)Return the full name of a ConnectedVariable as a string.
Arguments
var::AbstractConnectedVariable: The connected variable to get the full name for.
Returns
String: The full name of the connected variable.
Connectors
Sirens.Connector — Type
Connector <: AbstractConnectorRepresents a connection between multiple ConnectedVariables, possibly with a transformation function.
Fields
inputs::Tuple{<:AbstractConnectedVariable}: Input variables for the connector.outputs::Tuple{<:AbstractConnectedVariable}: Output variables for the connector.func::Union{Nothing,Function}: Optional function to transform inputs to outputs.
Sirens.ImplicitConnector — Type
ImplicitConnector(; inputs::Vector{T}, outputs::Vector{S}) where {T<:AbstractString} where {S<:AbstractString}Construct an ImplicitConnector from string names for inputs and outputs.
Implicit connectors are only used for algebraic loop detection and are not executed during the simulation.
Arguments
inputs::Vector{<:AbstractString}: Names of input variables.outputs::Vector{<:AbstractString}: Names of output variables.
Sirens.runconnection — Function
runconnection(sirenInt::AbstractSirenIntegrator, conn::AbstractConnector)Extract all the input states from sirenInt, apply the connection function, and return the output.
Arguments
sirenInt::AbstractSirenIntegrator: The Sirens integrator containing the components.conn::AbstractConnector: The connector defining the connection.
Sirens.runconnection! — Function
runconnection!(sirenInt::AbstractSirenIntegrator, conn::AbstractConnector)Extract all input states from sirenInt, apply the connection function, and set output states in sirenInt.
Arguments
sirenInt::AbstractSirenIntegrator: The Sirens integrator containing components.conn::AbstractConnector: The connector defining inputs, outputs, and transformation.
Behavior
- Calls
runconnectionto compute outputs. - Sets each output value in the corresponding component via
setstate!. - Outputs are set in order; later outputs can depend on earlier ones if they share state.
Timestepping and multirate solving
SirenProblem accepts one timescales value per component. For component i with timescale $s_i$:
\[t_{global,i} = s_i \cdot t_{local,i}\]
A component with $s_i = 0.1$ advances ten local time units per one global time unit.
See the MinimumTimeStepper docstring for details on the stepping algorithm.
Saving and solutions
Saving options
Saving configuration is passed during init or solve:
CommonSolve.init — Method
init(prob::AbstractSirenProblem, alg::AbstractSirenSolver;
save_vars = nothing, saveat = nothing)Defines the integrator for a Sirens hybrid simulation.
Arguments
prob::AbstractSirenProblem: The problem to be solved.alg::AbstractSirenSolver: The Sirens solver algorithm to be used.save_vars: Variables to be saved during the simulation. Options include:nothing(default): Save all non-special variables (those not starting with '#').:all: Save all variables, including special variables.:noneorString[]: Save no variables (time is still recorded).Vector{String}: A vector of connected variable fullnames to save, including optional indices like"forest.life[1]"or"tree[1:10].life".Tuple{Vararg{ConnectedVariable}}: A tuple of ConnectedVariable objects to save.
saveat: When to save the variables during the simulation. Options include:nothing(default): Save after initialization and after every Sirens syncronisation event.- A number
Δt: Save at timestspan[1]:Δt:tspan[2]. - A vector of times: Save at exactly these time points.
- A function
(integrator, t) -> Bool: Save when it returns true (checked at scheduled stops).
Returns
SirenIntegrator: A mutable integrator ready for solving.
SirenSolution
Sirens.SirenSolution — Type
SirenSolution{X, Y<:SirenSolutionData} <: AbstractSirenSolutionStores the solution of a SirenProblem over time.
Fields
t::X: Time points at which the solution is saved.u::Y<:SirenSolutionData: A dictionary-like structure storing the saved states for each variable in the problem.
Interpolation
A solution can be interpolated at arbitrary times using callable syntax:
(sol::AbstractSirenSolution)(t::Real)This returns a new SirenSolution with interpolated states at time t.
Interpolation Rules:
- For numeric states and numeric arrays: Uses linear interpolation between saved time points.
- For non-numeric states (e.g., Agents.jl models, objects): Uses constant interpolation (returns the state from the last saved time point before or at
t).
The time t must be within [sol.t[1], sol.t[end]], otherwise a BoundsError is thrown.
Examples
sol(2.5) # Interpolate solution at time t=2.5A solution has sol.t (saved global times) and sol.u (dictionary mapping variable names to saved states).
Solution indexing and interpolation
Base.getindex — Method
Base.getindex(sol::AbstractSirenSolution, var::AbstractString)
Base.getindex(sol::AbstractSirenSolution, var::AbstractConnectedVariable)
Base.getindex(sol::AbstractSirenSolution, index::Int)Get the solution for a variable var or at a time index index from a SirenSolution.
Arguments
sol::AbstractSirenSolution: The solution object.var::Union{AbstractString, AbstractConnectedVariable}: The variable name, optionally with indices like"comp.var[1:3]"or"comp[2].var[4]".index::Int: The time index (1-based) into the saved times.
Returns
- If
varis provided, returns a vector of saved states for that variable across all times. - If
indexis provided, returns a new SirenSolution containing only the data at that time index for each variable.
Examples
sol["comp.var"] # All saved states for variable "comp.var"
sol[ConnectedVariable("comp[1].var")] # States for duplicated instance 1
sol[3] # Solution data at the 3rd saved time pointSee the SirenSolution docstring for details on interpolation behavior, including handling of numeric vs. non-numeric states.
Components
All time-dependent components expose name, timestep, variables, init, step!, getstate, setstate!, gettime, and settime! through the common interface. Each component type documents its special variables and specific behavior in its docstring.
Differential Equations Components
Sirens.DEComponent — Type
DEComponent(model::DiffEqBase.AbstractDEProblem, alg;
name::String="DE", timestep::Float64=1.0, intkwargs::NamedTuple=(;),
state_names::Dict{String,Any}=Dict{String,Any}())
DEComponent(model::DiffEqBase.AbstractDEProblem; kwargs...)A Sirens component that wraps a SciML Differential Equations problem (ODEProblem, DAEProblem, etc).
Arguments
model::DiffEqBase.AbstractDEProblem: The SciML Differential Equations problem (e.g., ODEProblem, etc.)alg: Algorithm from DifferentialEquations.jl to be used for solving the DEProblem. If no algorithm is provided, the algorithm will be automatically chosen by DifferentialEquations.jl.
Keyword Arguments
name::AbstractString: Name of the component. Defaults to "DE".timestep::Real: Time step for the component. Defaults to 1.0.intkwargs: Additional keyword arguments for the DE solver. Defaults to no keywords.state_names: Dictionary mapping variable names (as strings) to their corresponding indices in the state vector or symbols from Symbolics.jl. Defaults to an empty dictionary. Map strings like "x" to indices (1, 2, ...) or symbolic variables.
Special Variables
#time: The current time (integrator.t).#state: The full state vector (integrator.u).#integrator: The underlying DifferentialEquations.jl integrator object.
Examples
function f!(du, u, p, t)
du[1] = -u[1]
end
prob = ODEProblem(f!, [1.0], (0.0, 10.0))
comp = DEComponent(prob, Tsit5(); name="ode_comp",
state_names=Dict("x" => 1))Sirens.DEComponentIntegrator — Type
mutable struct DEComponentIntegrator{A, B} <: AbstractComponentIntegratorAgents Components
Sirens.AgentsComponent — Type
AgentsComponent(model::StandardABM; name="Agents Component",
state_names=Dict{String,Any}(), timestep::Real=1.0)A Sirens component that wraps an agent-based model (ABM) using the Agents.jl package.
Arguments
model::StandardABM: The agent-based model to be solved.
Keyword Arguments
name::AbstractString: The name of the component. Defaults to "Agents".state_names: A dictionary mapping variable names (as strings) to their corresponding properties (agent properties or model properties) in themodel. Defaults to an empty dictionary. Values can be agent properties (accessed per agent) or model properties.timestep::Real=1: The time step for the component (not the ABM solver timestep), i.e. how frequently should the inputs and outputs be updated (in units ofabmtime(model)). For example, iftimestep=5, the component will step the ABM 5 times for every synchronization, and set #time=5.
Special Variables
#time: The component clock (independent fromabmtime(model)).#model: The currentStandardABMobject (read-only; usegetstatewithcopy=trueto get a copy).#ids: The vector of all current agent IDs (read-only; cannot be used withsetstate!).
state_names Semantics
- A key without a variable index accesses agent properties for all agents or model properties.
- A key with a variable index (e.g., `"comp.var[1:5]"") accesses specific agent IDs.
- Since the
variableindexis used for accessing the properties of particular agents, use a connector function to index into complex properties.
Examples
comp = AgentsComponent(model;
name="abm_comp",
state_names=Dict("x" => :pos_x, "y" => :pos_y))Sirens.AgentsComponentIntegrator — Type
mutable struct AgentsComponentIntegrator{A, B} <: AbstractComponentIntegratorMethodOfLines Components
Sirens.MOLComponent — Type
MOLComponent(model::DiffEqBase.AbstractDEProblem, alg::DiffEqBase.AbstractDEAlgorithm;
name::String="MOL", timestep::Real=1.0, intkwargs::NamedTuple=(;),
state_names::Dict{String,Any}=Dict{String,Any}())A Sirens component that wraps a Method of Lines discretized PDE as a SciML DifferentialEquations problem.
Arguments
model::DiffEqBase.AbstractDEProblem: The SciML Differential Equations problem (e.g., ODEProblem, etc.) from MethodOfLines discretization.alg::DiffEqBase.AbstractDEAlgorithm: Algorithm from DifferentialEquations.jl to be used for solving the DEProblem.
Keyword Arguments
name::AbstractString: Name of the component. Defaults to "MOL".timestep::Real: Time step for the component. Defaults to 1.0.intkwargs: Additional keyword arguments for the DE solver. Defaults to no keywords.state_names: Dictionary mapping variable names (as strings) to their corresponding indices in the state vector or symbols from Symbolics.jl. Defaults to an empty dictionary. For PDEs with spatial discretization, map logical variable names (e.g., "concentration") to state vector indices or ranges.
Special Variables
#time: The current time (integrator.t).#state: The full discretized state vector (integrator.u).#integrator: The underlying DifferentialEquations.jl integrator object.
Notes
MOLComponent is useful for connecting discretized PDEs to other models. When mapping between different spatial grids or resolutions (e.g., PDE grid to agent positions), use a connector function to perform interpolation or other spatial transformations.
Sirens.MOLComponentIntegrator — Type
mutable struct MOLComponentIntegrator{A, B} <: AbstractComponentIntegratorJumpProcesses Components
Sirens.JumpComponent — Type
JumpComponent(model::JumpProblem, alg;
name::String="Jump", timestep::Float64=1.0, intkwargs::NamedTuple=(;),
state_names::Dict{String,Any}=Dict{String,Any}())A Sirens component that wraps a JumpProcesses.jl jump process problem.
Arguments
model::JumpProblem: SciML Jump problem containing a continuous ODE and jump events.alg: Algorithm from DifferentialEquations.jl to be used for solving the JumpProblem.
Keyword Arguments
name::AbstractString: Name of the component. Defaults to "Jump".timestep::Real: Time step for the component. Defaults to 1.0.intkwargs: Additional keyword arguments for the Jump solver. Defaults to no keywords.state_names: Dictionary mapping variable names (as strings) to their corresponding indices in the state vector or symbols from Symbolics.jl. Defaults to an empty dictionary.
Special Variables
#time: The current time (integrator.t).#state: The full state vector (integrator.u).#integrator: The underlying DifferentialEquations.jl integrator object.
Sirens.JumpComponentIntegrator — Type
mutable struct JumpComponentIntegrator{A, B} <: AbstractComponentIntegratorTrixiParticles Components
Sirens.TrixiParticlesComponent — Type
TrixiParticlesComponent(semi::TrixiParticles.Semidiscretization, alg;
name::String="TrixiParticles", timestep::Float64=1.0,
intkwargs::NamedTuple=(;), tspan=(0.0, Inf),
state_names::Dict{String,Any}=Dict{String,Any}())A Sirens component that wraps a TrixiParticles.jl particle method simulation.
Arguments
semi::TrixiParticles.Semidiscretization: TrixiParticles semidiscretization object.alg: Algorithm from DifferentialEquations.jl or TrixiParticles.jl to solve the DynamicalODEProblem.
Keyword Arguments
name::AbstractString: Name of the component. Defaults to "TrixiParticles".timestep::Real: Time step for the component. Defaults to 1.0.intkwargs: Additional keyword arguments for the DE solver. Defaults to no keywords.tspan: Time span for the simulation. Defaults to (0.0, Inf).state_names: Dictionary mapping variable names (as strings) to their corresponding indices in the state vector or symbols from Symbolics.jl. Defaults to an empty dictionary. Typically maps particle positions, velocities, or properties.
Special Variables
#time: The current time (integrator.t).#state: The full particle state vector (integrator.u).#integrator: The underlying DifferentialEquations.jl integrator object.#semi: The TrixiParticles semidiscretization object (read-only; cannot be used withsetstate!).
Sirens.TrixiParticlesComponentIntegrator — Type
mutable struct TrixiParticlesComponentIntegrator{A, B} <: AbstractComponentIntegratorSurrogate Components
Sirens.SurrogateComponent — Type
SurrogateComponent(args...; kwargs...)Represents a component that is replaced with a surrogate in the simulation, speeding up computation of a complex step! function.
Arguments
component::AbstractTimeDependentComponent: The original component to be replaced with a surrogate.surrogate: The surrogate model or method to use for the component.lower_bound: Lower bounds for each state variable for surrogate sampling.upper_bound: Upper bounds for each state variable for surrogate sampling.
Keyword Arguments
name::AbstractString: Name of the component. Defaults to the same as the original component.timestep::Real: Time step for the component. Defaults to the same as the original component.model: A Flux.jl model to use as the surrogate. Ifnothing, a default feedforward neural network is created.state_names: Dictionary mapping variable names (as strings) to their corresponding indices in the state vector or symbols from ModelingToolkit/Symbolics. Defaults to the same as the original component.n_samples::Integer: Number of samples to use for training the surrogate. Defaults to 1000.n_epochs::Integer: Number of training epochs for the surrogate. Defaults to 1000.
Sirens.SurrogateComponentIntegrator — Type
mutable struct SurrogateComponentIntegrator{A, B, C, D, E} <: AbstractComponentIntegratorDuplicated Components
Sirens.DuplicatedComponent — Type
DuplicatedComponent <: AbstractComponentRepresents a component that is duplicated in the simulation, allowing a single component to have multiple states.
Fields
component::AbstractTimeDependentComponent: The original component to be duplicated.instances::Union{Int,Nothing}: Number of instances of the component. Ifnothing, then the number is variable and determined by the simulation.name::String: Name of the duplicated component.init_states::Vector: Vector of states for the duplicated component, where each state corresponds to a particular instance.
Sirens.DuplicatedComponentIntegrator — Type
mutable struct DuplicatedComponentIntegrator{T<:AbstractComponentIntegrator, U, V} <: AbstractComponentIntegratorTime-independent Components
Sirens.TimeIndependentComponent — Type
TimeIndependentComponent(name::String, func::Function, initial_state)TimeIndependentComponent represents a component that does not evolve in time, but instead computes its state based on its inputs, irregardless of the change in time.
Arguments
name::String: The name of the component.func::Function: The function that computes the component's state based on its inputs. It should take a single input of the same type as initial_state.initial_state: The initial state of the component. This should be a valid input tofunc.
Abstract Types
These abstract types are extension points and are useful for method signatures:
Sirens.AbstractComponent — Type
abstract type AbstractComponentSirens.AbstractTimeDependentComponent — Type
abstract type AbstractTimeDependentComponent <: AbstractComponentSirens.AbstractTimeIndependentComponent — Type
abstract type AbstractTimeIndependentComponent <: AbstractComponentSirens.AbstractComponentIntegrator — Type
abstract type AbstractComponentIntegratorSirens.AbstractSirenSolver — Type
abstract type AbstractSirenSolverSirens.AbstractSirenIntegrator — Type
abstract type AbstractSirenIntegratorSirens.AbstractSirenProblem — Type
abstract type AbstractSirenProblemSirens.AbstractSirenSolution — Type
abstract type AbstractSirenSolutionSirens.AbstractConnectedVariable — Type
abstract type AbstractConnectedVariableSirens.AbstractConnector — Type
abstract type AbstractConnectorUser-Defined Components
One of the main goals of Sirens is to make it simple and accessible to expand functionality with user-defined components. This is done through the component interface—a set of functions that can be implemented to support all of Sirens functionality.
Core interface functions
Sirens.name — Function
name(int::AbstractComponentIntegrator)
name(comp::AbstractComponent)Get the name of the integrator or component.
Sirens.timestep — Function
timestep(int::AbstractComponent)
timestep(comp::AbstractComponentIntegrator)Get the proposed time step of the integrator or component. It can depend on the current state.
Sirens.variables — Function
variables(comp::AbstractComponentIntegrator)
variables(comp::AbstractComponent)Retrieve the variable names of a component.
Arguments
comp::Union{AbstractComponent, AbstractComponentIntegrator}: The component (or component integrator) whose variable names are to be retrieved.
Returns
- A collection of variable names (as strings) associated with the component. This includes all special variables such as
#timeand#modelif applicable.
Sirens.getstate — Function
getstate(comp::AbstractComponentIntegrator; copy = false)
getstate(comp::AbstractComponentIntegrator, key; copy = false)Retrieve the state of a component.
Arguments
comp::AbstractComponentIntegrator: The component whose state is to be retrieved.key: The key specifying which part of the component's state to retrieve.
Keyword Arguments
copy::Bool: Iftrue, a deep copy of the state is returned; otherwise, a reference to the state is returned (assuming the state is mutable).
Sirens.setstate! — Function
setstate!(comp::AbstractComponentIntegrator, state)
setstate!(comp::AbstractComponentIntegrator, key, value)Set the state of a component.
Arguments
comp::AbstractComponentIntegrator: The component whose state is to be set.state: The new state to set for the entire component.key: The key specifying which part of the component's state to set.value: The value to set for the specified part of the component's state.
Sirens.gettime — Function
gettime(sirenInt::AbstractComponentIntegrator)Get the current time of the integrator.
Arguments
int::AbstractComponentIntegrator: The integrator whose time is to be retrieved.
Returns
- The current time of the integrator.
Sirens.settime! — Function
settime!(sirenInt::AbstractComponentIntegrator, t)Set the current time of the integrator.
Arguments
int::AbstractComponentIntegrator: The integrator whose time is to be set.t: The time to set.
CommonSolve.step! — Method
step!(int::AbstractComponentIntegrator)Advance the state of the integrator int by one time step.
Arguments
int::AbstractComponentIntegrator: The integrator to advance.
CommonSolve.init — Method
init(comp::AbstractComponent)Initialises an integrator (AbstractComponentIntegrator) for the given AbstractComponent.
Arguments
comp::AbstractComponent: The component to be initialised.
Returns
SirenIntegrator: The initialised integrator for the problem.
Implementing a custom component
To implement a custom component:
- Define an immutable
struct MyComponentto hold the configuration. - Define a
mutable struct MyComponentIntegratorto hold runtime state. - Implement
init(::MyComponent)to return aMyComponentIntegrator. - Implement
step!(integrator::MyComponentIntegrator)to advance the state. - Implement
name,timestep, andvariablesfor both structs. - Implement
getstateandsetstate!to expose your component's variables. - Implement
gettimeandsettime!to expose your component integrator's current time.
While there are quite a few functions here that need to be defined, the majority of them have default behaviour that you can opt in to.
name(integrator),timestep(integrator), andvariables(integrator)can use the default behavior ofname(integrator) = name(integrator.component)(and other equivalents) if the component is stored as a property of the integrator.timestep(component)andname(component)can use the default behaviour ofcomponent.timestepandcomponent.name, if the property or field exists.gettimeandsettime!will default to attempting to access the#timespecial variable ofgetstateandsetstate!.getstateandsetstate!do not need to implement any of the keyword argument features (i.e.copy).