diff --git a/src/FMI2/sim.jl b/src/FMI2/sim.jl index 05d590ab..62f577b1 100644 --- a/src/FMI2/sim.jl +++ b/src/FMI2/sim.jl @@ -263,7 +263,12 @@ function fx(c::FMU2Component, return dx end -# wrapper +""" + fmi2SimulateME(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) + +Wrapper for `fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. +(FMU2 `fmu` is taken from `c`) +""" function fmi2SimulateME(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) fmi2SimulateME(c.fmu, c, tspan; kwargs...) end @@ -295,66 +300,76 @@ function setupODEProblem(c::FMU2Component, x0::AbstractArray{fmi2Real}, tspan::U end """ - function fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing, - recordEigenvalues::Bool=false, - saveat = nothing, - x0::Union{AbstractArray{<:Real}, Nothing} = nothing, - setup::Union{Bool, Nothing} = nothing, - reset::Union{Bool, Nothing} = nothing, - instantiate::Union{Bool, Nothing} = nothing, - freeInstance::Union{Bool, Nothing} = nothing, - terminate::Union{Bool, Nothing} = nothing, - inputValueReferences::fmi2ValueReferenceFormat = nothing, - inputFunction = nothing, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, - dtmax::Union{Real, Nothing} = nothing, - callbacksBefore = [], - callbacksAfter = [], - showProgress::Bool = true, - kwargs...) - -Simulates a FMU instance for the given simulation time interval. -State- and Time-Events are handled correctly. - -Via the optional keyword arguemnts `inputValues` and `inputFunction`, a custom input function `f(c, u, t)`, `f(c, t)`, `f(u, t)`, `f(c, u)` or `f(t)` with `c` current component, `u` current state and `t` current time can be defined, that should return a array of values for `fmi2SetReal(..., inputValues, inputFunction(...))`. - -Keywords: - -- solver: Any Julia-supported ODE-solver (default is the DifferentialEquations.jl default solver, currently `AutoTsit5(Rosenbrock23())`) - -- customFx: [deprecated] Ability to give a custom state derivative function ẋ=f(x,t) - -- recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - -- recordEventIndicators: Array or Range of event indicators (identified by integers) to record - -- recordEigenvalues: Boolean value, if eigenvalues shall be computed and recorded - -- saveat: Time points to save values at (interpolated) - -- setup: Boolean, if FMU should be setup (default=true) - -- reset: Union{Bool, :auto}, if FMU should be reset before simulation (default reset=:auto) - -- inputValueReferences: Array of input variables (strings or variableIdentifiers) to set at every simulation step - -- inputFunction: Function to retrieve the values to set the inputs to - -- parameters: Dictionary of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization - -- `callbacks`: custom callbacks to add + fmi2SimulateME(fmu::FMU2, + c::Union{FMU2Component, Nothing}=nothing, + tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; + [tolerance::Union{Real, Nothing} = nothing, + dt::Union{Real, Nothing} = nothing, + solver = nothing, + customFx = nothing, + recordValues::fmi2ValueReferenceFormat = nothing, + recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing, + recordEigenvalues::Bool=false, + saveat = nothing, + x0::Union{AbstractArray{<:Real}, Nothing} = nothing, + setup::Union{Bool, Nothing} = nothing, + reset::Union{Bool, Nothing} = nothing, + instantiate::Union{Bool, Nothing} = nothing, + freeInstance::Union{Bool, Nothing} = nothing, + terminate::Union{Bool, Nothing} = nothing, + inputValueReferences::fmi2ValueReferenceFormat = nothing, + inputFunction = nothing, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, + dtmax::Union{Real, Nothing} = nothing, + callbacksBefore = [], + callbacksAfter = [], + showProgress::Bool = true, + kwargs...]) -Returns: +Simulate ME-FMU for the given simulation time interval. -- If keyword `recordValues` is not set, a struct of type `ODESolution`. +State- and Time-Events are handled correctly. -- If keyword `recordValues` is set, a tuple of type (ODESolution, DiffEqCallbacks.SavedValues). +# Arguments +- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances. +- `c::Union{FMU2Component, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from `fmu`'s model description or (0.0, 1.0)) + +- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) +- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) +- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) +- `customFx`: [deprecated] custom state derivative function ẋ=f(x,t) +- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing`: Array or Range of event indicators to record +- `recordEigenvalues::Bool=false`: compute and record eigenvalues +- `saveat = nothing`: Time points to save (interpolated) values at (default = nothing: save at each solver timestep) +- `x0::Union{AbstractArray{<:Real}, Nothing} = nothing`: inital fmu State (default = nothing: use current or default-inital fmu state) +- `setup::Union{Bool, Nothing} = nothing`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `reset::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `instantiate::Union{Bool, Nothing} = nothing`: call fmi2Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `terminate::Union{Bool, Nothing} = nothing`: call fmi2Terminate after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each simulation step +- `inputFunction = nothing`: Function to get values for the input variables at each simulation step. + + ## Pattern [`c`: current component, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))`]: + - `inputFunction(t::fmi2Real)` + - `inputFunction(c::FMU2Component, t::fmi2Real)` + - `inputFunction(c::FMU2Component, u::Union{AbstractArray{fmi2Real,1}, Nothing})` + - `inputFunction(u::Union{AbstractArray{fmi2Real,1}, Nothing}, t::fmi2Real)` + - `inputFunction(c::FMU2Component, u::Union{AbstractArray{fmi2Real,1}, Nothing}, t::fmi2Real)` + +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `dtmax::Union{Real, Nothing} = nothing`: sets the maximum stepszie for the solver (default = nothing: use `(Simulation-time-span-length)/100.0`) +- `callbacksBefore = [], callbacksAfter = []`: functions that are to be called before and after internal time-event-, state-event- and step-event-callbacks are called +- `showProgress::Bool = true`: print simulation progressmeter in REPL +- `kwargs...`: keyword arguments that get passed onto the solvers solve call + +# Returns: +- If keyword `recordValues` has value `nothing`, a struct of type `ODESolution`. +- If keyword `recordValues` is set, a tuple of type `(ODESolution, DiffEqCallbacks.SavedValues)`. + +See also [`fmi2Simulate`](@ref), [`fmi2SimulateCS`](@ref). """ function fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; tolerance::Union{Real, Nothing} = nothing, @@ -633,16 +648,23 @@ export fmi2SimulateME # return ThreadPool.foreach((c, x0, parameters) -> fmi2SimulateME(fmu, c; x0=x0, parameters=parameters, kwargs...), zip()) # end -# wrapper +############ Co-Simulation ############ + +""" + fmi2SimulateCS(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) + +Wrapper for `fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. +(FMU2 `fmu` is taken from `c`) +""" function fmi2SimulateCS(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) fmi2SimulateCS(c.fmu, c, tspan; kwargs...) end -############ Co-Simulation ############ - """ - fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - tolerance::Union{Real, Nothing} = nothing, + fmi2SimulateCS(fmu::FMU2, + c::Union{FMU2Component, Nothing}=nothing, + tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; + [tolerance::Union{Real, Nothing} = nothing, dt::Union{Real, Nothing} = nothing, recordValues::fmi2ValueReferenceFormat = nothing, saveat = [], @@ -654,23 +676,38 @@ end inputValueReferences::fmi2ValueReferenceFormat = nothing, inputFunction = nothing, showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) - -Starts a simulation of the Co-Simulation FMU instance. - -Via the optional keyword arguments `inputValues` and `inputFunction`, a custom input function `f(c, t)` or `f(t)` with time `t` and component `c` can be defined, that should return a array of values for `fmi2SetReal(..., inputValues, inputFunction(...))`. - -Keywords: - - recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - - saveat: Time points to save values at (interpolated) - - setup: Boolean, if FMU should be setup (default=true) - - reset: Boolean, if FMU should be reset before simulation (default reset=setup) - - inputValueReferences: Array of input variables (strings or variableIdentifiers) to set at every simulation step - - inputFunction: Function to retrieve the values to set the inputs to - - parameters: Dictionary of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization -Returns: - - If keyword `recordValues` is not set, a boolean `success` is returned (simulation success). - - If keyword `recordValues` is set, a tuple of type (true, DiffEqCallbacks.SavedValues) or (false, nothing). + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) + +Simulate CS-FMU for the given simulation time interval. + +# Arguments +- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances. +- `c::Union{FMU2Component, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from `fmu`'s model description or (0.0, 1.0)) + +- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or 0.0) +- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or 1e-3) +- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `saveat = nothing`: Time points to save values at (default = nothing: save at each communication timestep) +- `setup::Union{Bool, Nothing} = nothing`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `reset::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `instantiate::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `terminate::Union{Bool, Nothing} = nothing`: call fmi2Terminate after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each communication step +- `inputFunction = nothing`: Function to get values for the input variables at each communication step. + + ## Pattern [`c`: current component, `t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))`]: + - `inputFunction(t::fmi2Real)` + - `inputFunction(c::FMU2Component, t::fmi2Real)` + +- `showProgress::Bool = true`: print simulation progressmeter in REPL +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization + +# Returns: +- `fmusol::FMU2Solution`, containing bool `fmusol.success` and if keyword `recordValues` is set, the saved values as `fmusol.values`. + +See also [`fmi2Simulate`](@ref), [`fmi2SimulateME`](@ref). """ function fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; tolerance::Union{Real, Nothing} = nothing, @@ -831,7 +868,12 @@ export fmi2SimulateCS ##### CS & ME ##### -# wrapper +""" + fmi2Simulate(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) + +Wrapper for `fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. +(FMU2 `fmu` is taken from `c`) +""" function fmi2Simulate(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) fmi2Simulate(c.fmu, c, tspan; kwargs...) end @@ -845,24 +887,11 @@ end # end """ -fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) -Starts a simulation of the FMU instance for the matching FMU type, if both types are available, CS is preferred. - -Keywords: - - recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - - setup: Boolean, if FMU should be setup (default=true) - - reset: Boolean, if FMU should be reset before simulation (default reset=setup) - - inputValues: Array of input variables (strings or variableIdentifiers) to set at every simulation step - - inputFunction: Function to retrieve the values to set the inputs to - - saveat: [ME only] Time points to save values at (interpolated) - - solver: [ME only] Any Julia-supported ODE-solver (default is default from DifferentialEquations.jl) - - customFx: [ME only, deprecated] Ability to give a custom state derivative function ẋ=f(x,t) - -Returns: - - `success::Bool` for CS-FMUs - - `ODESolution` for ME-FMUs - - if keyword `recordValues` is set, a tuple of type (success::Bool, DiffEqCallbacks.SavedValues) for CS-FMUs - - if keyword `recordValues` is set, a tuple of type (ODESolution, DiffEqCallbacks.SavedValues) for ME-FMUs + fmi2Simulate(args...) + +Starts a simulation of the `FMU2` for the matching type (`fmi2SimulateCS(args...)` or `fmi2SimulateME(args...)`); if both types are available, CS is preferred. + +See also [`fmi2SimulateCS`](@ref), [`fmi2SimulateME`](@ref). """ function fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) diff --git a/src/FMI3/sim.jl b/src/FMI3/sim.jl index a6ec262c..8e617240 100644 --- a/src/FMI3/sim.jl +++ b/src/FMI3/sim.jl @@ -546,7 +546,7 @@ function prepareFMU(fmu::FMU3, c::Union{Nothing, FMU3Instance}, type::fmi3Type, if length(fmu.instances) > 0 c = fmu.instances[end] else - @warn "Found no FMU instance, but executionConfig doesn't force allocation. Allocating one. Use `fmi2Instantiate(fmu)` to prevent this message." + @warn "Found no FMU instance, but executionConfig doesn't force allocation. Allocating one. Use `fmi3Instantiate(fmu)` to prevent this message." if type == fmi3TypeCoSimulation c = fmi3InstantiateCoSimulation!(fmu) elseif type == fmi3TypeModelExchange @@ -793,7 +793,12 @@ function finishFMU(fmu::FMU3, c::FMU3Instance, terminate::Union{Nothing, Bool}, end end -# wrapper +""" + fmi3SimulateME(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) + +Wrapper for `fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. +(FMU3 `fmu` is taken from `c`) +""" function fmi3SimulateME(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) fmi3SimulateME(c.fmu, c, t_start, t_stop; kwargs...) end @@ -811,59 +816,73 @@ function setupODEProblem(c::FMU3Instance, x0::AbstractArray{fmi3Float64}, t_star end """ - fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = nothing, - x0::Union{AbstractArray{<:Real}, Nothing} = nothing, - setup::Union{Bool, Nothing} = nothing, - reset::Union{Bool, Nothing} = nothing, - instantiate::Union{Bool, Nothing} = nothing, - freeInstance::Union{Bool, Nothing} = nothing, - terminate::Union{Bool, Nothing} = nothing, - inputValueReferences::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, - dtmax::Union{Real, Nothing} = nothing, - callbacks = [], - showProgress::Bool = true, - kwargs...) - -Simulates a FMU instance for the given simulation time interval. -State- and Time-Events are handled correctly. - -Via the optional keyword arguemnts `inputValues` and `inputFunction`, a custom input function `f(c, u, t)`, `f(c, t)`, `f(u, t)`, `f(c, u)` or `f(t)` with `c` current instance, `u` current state and `t` current time can be defined, that should return a array of values for `fmi3SetFloat64(..., inputValues, inputFunction(...))`. - -Keywords: - -- solver: Any Julia-supported ODE-solver (default is Tsit5) - -- customFx: [deperecated] Ability to give a custom state derivative function ẋ=f(x,t) - -- recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - -- saveat: Time points to save values at (interpolated) - -- setup: Boolean, if FMU should be setup (default=true) - -- reset: Union{Bool, :auto}, if FMU should be reset before simulation (default reset=:auto) - -- inputValueReferences: Array of input variables (strings or variableIdentifiers) to set at every simulation step - -- inputFunction: Function to retrieve the values to set the inputs to - -- parameters: Dictionary of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization - -- `callbacks`: custom callbacks to add - -Returns: + fmi3SimulateME(fmu::FMU3, + c::Union{FMU3Instance, Nothing}=nothing, + t_start::Union{Real, Nothing} = nothing, + t_stop::Union{Real, Nothing} = nothing; + [tolerance::Union{Real, Nothing} = nothing, + dt::Union{Real, Nothing} = nothing, + solver = nothing, + customFx = nothing, + recordValues::fmi3ValueReferenceFormat = nothing, + saveat = nothing, + x0::Union{AbstractArray{<:Real}, Nothing} = nothing, + setup::Union{Bool, Nothing} = nothing, + reset::Union{Bool, Nothing} = nothing, + instantiate::Union{Bool, Nothing} = nothing, + freeInstance::Union{Bool, Nothing} = nothing, + terminate::Union{Bool, Nothing} = nothing, + inputValueReferences::fmi3ValueReferenceFormat = nothing, + inputFunction = nothing, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, + dtmax::Union{Real, Nothing} = nothing, + callbacks = [], + showProgress::Bool = true, + kwargs...]) + +Simulate ME-FMU for the given simulation time interval. -- If keyword `recordValues` is not set, a struct of type `ODESolution`. +State- and Time-Events are handled correctly. -- If keyword `recordValues` is set, a tuple of type (ODESolution, DiffEqCallbacks.SavedValues). +# Arguments +- `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances. +- `c::Union{FMU3Instance, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. +- `t_start::Union{Real, Nothing} = nothing`: Simulation-time-span start time (default = nothing: use default value from `fmu`'s model description or 0.0) +- `t_stop::Union{Real, Nothing} = nothing`: Simulation-time-span stop time (default = nothing: use default value from `fmu`'s model description or 1.0) + +- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) +- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) +- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) +- `customFx`: [deprecated] custom state derivative function ẋ=f(x,t) +- `recordValues::fmi3ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `saveat = nothing`: Time points to save (interpolated) values at (default = nothing: save at each solver timestep) +- `x0::Union{AbstractArray{<:Real}, Nothing} = nothing`: inital fmu State (default = nothing: use current or default-inital fmu state) +- `setup::Union{Bool, Nothing} = nothing`: call fmi3EnterInitializationMode and fmi3ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `reset::Union{Bool, Nothing} = nothing`: call fmi3Reset before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `instantiate::Union{Bool, Nothing} = nothing`: call fmi3Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi3FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `terminate::Union{Bool, Nothing} = nothing`: call fmi3Terminate after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `inputValueReferences::fmi3ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each simulation step +- `inputFunction = nothing`: Function to get values for the input variables at each simulation step. + + ## Pattern [`c`: current instance, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi3SetFloat64(..., inputValueReferences, inputFunction(...))`]: + - `inputFunction(t::fmi3Float64)` + - `inputFunction(c::FMU3Instance, t::fmi3Float64)` + - `inputFunction(c::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing})` + - `inputFunction(u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)` + - `inputFunction(c::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)` + +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `dtmax::Union{Real, Nothing} = nothing`: sets the maximum stepszie for the solver (default = nothing: use `(Simulation-time-span-length)/100.0`) +- `callbacks = []`: functions that are to be called at each solver time step +- `showProgress::Bool = true`: print simulation progressmeter in REPL +- `kwargs...`: keyword arguments that get passed onto the solvers solve call + +# Returns: +- If keyword `recordValues` has value `nothing`, a struct of type `ODESolution`. +- If keyword `recordValues` is set, a tuple of type `(ODESolution, DiffEqCallbacks.SavedValues)`. + +See also [`fmi3Simulate`](@ref), [`fmi3SimulateCS`](@ref), [`fmi3SimulateSE`](@ref). """ function fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; tolerance::Union{Real, Nothing} = nothing, @@ -1068,55 +1087,69 @@ end export fmi3SimulateME +############ Co-Simulation ############ + +""" + fmi3SimulateCS(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) -# wrapper +Wrapper for `fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. +(FMU3 `fmu` is taken from `c`) +""" function fmi3SimulateCS(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) fmi3SimulateCS(c.fmu, c, t_start, t_stop; kwargs...) end -############ Co-Simulation ############ - """ - fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - setup::Union{Bool, Nothing} = nothing, - reset::Union{Bool, Nothing} = nothing, - instantiate::Union{Bool, Nothing} = nothing, - freeInstance::Union{Bool, Nothing} = nothing, - terminate::Union{Bool, Nothing} = nothing, - inputValueReferences::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) - -Starts a simulation of the Co-Simulation FMU instance. - -Via the optional keyword arguments `inputValues` and `inputFunction`, a custom input function `f(c, t)` or `f(t)` with time `t` and instance `c` can be defined, that should return a array of values for `fmi3SetFloat64(..., inputValues, inputFunction(...))`. - -Keywords: - -- recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - -- saveat: Time points to save values at (interpolated) - -- setup: Boolean, if FMU should be setup (default=true) - -- reset: Boolean, if FMU should be reset before simulation (default reset=setup) - -- inputValueReferences: Array of input variables (strings or variableIdentifiers) to set at every simulation step - -- inputFunction: Function to retrieve the values to set the inputs to + fmi3SimulateCS(fmu::FMU3, + c::Union{FMU3Instance, Nothing}=nothing, + t_start::Union{Real, Nothing} = nothing, + t_stop::Union{Real, Nothing} = nothing; + [tolerance::Union{Real, Nothing} = nothing, + dt::Union{Real, Nothing} = nothing, + recordValues::fmi3ValueReferenceFormat = nothing, + saveat = [], + setup::Union{Bool, Nothing} = nothing, + reset::Union{Bool, Nothing} = nothing, + instantiate::Union{Bool, Nothing} = nothing, + freeInstance::Union{Bool, Nothing} = nothing, + terminate::Union{Bool, Nothing} = nothing, + inputValueReferences::fmi3ValueReferenceFormat = nothing, + inputFunction = nothing, + showProgress::Bool=true, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) + +Simulate CS-FMU for the given simulation time interval. + +# Arguments +- `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances. +- `c::Union{FMU3Instance, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. +- `t_start::Union{Real, Nothing} = nothing`: Simulation-time-span start time (default = nothing: use default value from `fmu`'s model description or 0.0) +- `t_stop::Union{Real, Nothing} = nothing`: Simulation-time-span stop time (default = nothing: use default value from `fmu`'s model description or 1.0) + +- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or 0.0) +- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or 1e-3) +- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) +- `recordValues::fmi3ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `saveat = nothing`: Time points to save values at (default = nothing: save at each communication timestep) +- `setup::Union{Bool, Nothing} = nothing`: call fmi3EnterInitializationMode and fmi3ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `reset::Union{Bool, Nothing} = nothing`: call fmi3Reset before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `instantiate::Union{Bool, Nothing} = nothing`: call fmi3Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi3FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `terminate::Union{Bool, Nothing} = nothing`: call fmi3Terminate after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) +- `inputValueReferences::fmi3ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each communication step +- `inputFunction = nothing`: Function to get values for the input variables at each communication step. + + ## Pattern [`c`: current instance, `t`: current time, returning array of values to be passed to `fmi3SetFloat64(..., inputValueReferences, inputFunction(...))`]: + - `inputFunction(t::fmi3Float64)` + - `inputFunction(c::FMU3Instance, t::fmi3Float64)` -- parameters: Dictionary of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `showProgress::Bool = true`: print simulation progressmeter in REPL +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Boolean, String, Float64, ...) to set parameters during initialization -Returns: - -- If keyword `recordValues` is not set, a boolean `success` is returned (simulation success). +# Returns: +- `fmusol::FMU3Solution`, containing bool `fmusol.success` and if keyword `recordValues` is set, the saved values as `fmusol.values`. -- If keyword `recordValues` is set, a tuple of type (true, DiffEqCallbacks.SavedValues) or (false, nothing). +See also [`fmi3Simulate`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateSE`](@ref). """ function fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; tolerance::Union{Real, Nothing} = nothing, @@ -1295,22 +1328,27 @@ export fmi3SimulateCS # TODO simulate ScheduledExecution """ - fmi3SimulateSE(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - setup::Union{Bool, Nothing} = nothing, - reset::Union{Bool, Nothing} = nothing, - instantiate::Union{Bool, Nothing} = nothing, - freeInstance::Union{Bool, Nothing} = nothing, - terminate::Union{Bool, Nothing} = nothing, - inputValueReferences::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) - -TODO simulate ScheduledExecution not yet implemented in library + fmi3SimulateSE(fmu::FMU3, + c::Union{FMU3Instance, Nothing}=nothing, + t_start::Union{Real, Nothing} = nothing, + t_stop::Union{Real, Nothing} = nothing; + [tolerance::Union{Real, Nothing} = nothing, + dt::Union{Real, Nothing} = nothing, + recordValues::fmi3ValueReferenceFormat = nothing, + saveat = [], + setup::Union{Bool, Nothing} = nothing, + reset::Union{Bool, Nothing} = nothing, + instantiate::Union{Bool, Nothing} = nothing, + freeInstance::Union{Bool, Nothing} = nothing, + terminate::Union{Bool, Nothing} = nothing, + inputValueReferences::fmi3ValueReferenceFormat = nothing, + inputFunction = nothing, + showProgress::Bool=true, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) + +Simulate SE-FMU; not yet implemented in library + +See also [`fmi3Simulate`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateCS`](@ref). """ function fmi3SimulateSE(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; tolerance::Union{Real, Nothing} = nothing, @@ -1332,31 +1370,22 @@ export fmi3SimulateSE ##### CS & ME ##### -# wrapper +""" + fmi3Simulate(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) + +Wrapper for `fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. +(FMU3 `fmu` is taken from `c`) +""" function fmi3Simulate(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) fmi3Simulate(c.fmu, c, t_start, t_stop; kwargs...) end """ - fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - -Starts a simulation of the FMU instance for the matching FMU type, if multiple types are available, CS is preferred over ME, over SE. - -Keywords: - - recordValues: Array of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` - - setup: Boolean, if FMU should be setup (default=true) - - reset: Boolean, if FMU should be reset before simulation (default reset=setup) - - inputValues: Array of input variables (strings or variableIdentifiers) to set at every simulation step - - inputFunction: Function to retrieve the values to set the inputs to - - saveat: Time points to save values at (interpolated) - - solver: Any Julia-supported ODE-solver (default is default from DifferentialEquations.jl) - - customFx: [ME only, deprecated] Ability to give a custom state derivative function ẋ=f(x,t) - -Returns: - - `success::Bool` for CS-FMUs - - `ODESolution` for ME-FMUs - - if keyword `recordValues` is set, a tuple of type (success::Bool, DiffEqCallbacks.SavedValues) for CS-FMUs - - if keyword `recordValues` is set, a tuple of type (ODESolution, DiffEqCallbacks.SavedValues) for ME-FMUs + fmi3Simulate(args...) + +Starts a simulation of the `FMU3` for the matching type (`fmi3SimulateCS(args...)`, `fmi3SimulateME(args...)` or `fmi3SimulateSE(args...)`); if multiple types are available, CS is preferred over ME, over SE. + +See also [`fmi3SimulateCS`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateSE`](@ref). """ function fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)