Generating Data using a FMU
Functional Mockup Units (FMUs) are files that enclose a simulation model standardized in the FMI format. FMI standards define two types of FMUs.
- Model Exchange (ME-FMU): A ME FMU needs an external numerical solver.
- Co-Simulation (CS-FMU) : A CS FMU encompass an internal solver, and does not need an external numerical solver.
For this manual, we will generate data using a FMU for the Coupled Clutches system. We start by setting up the enviornment. We will load FMI
to load the FMU. We additionally load OrdinaryDiffEq
for optionally providing a solver through keyword arguments.
using DataGeneration
using FMI
using OrdinaryDiffEq
Model Exchange FMU
Similar to previous section, when start by loading the FMU using FMI.fmi2load
. For more information on loading the FMU, geting the output labels and parameter labels see: FMI.jl
fmu_me = FMI.fmi2Load(fmu_file_path, type = :ME)
Model name: CoupledClutches
Type: 0
We get the output labels using fmi2GetOutputNames
outputs_me = FMI.FMIImport.fmi2GetOutputNames(fmu_me) .|> string
4-element Vector{String}:
"outputs[1]"
"outputs[2]"
"outputs[3]"
"outputs[4]"
We define the ParameterSpace
and CtrlSpace
. For more detailed information on defining the data generation configuration see DataGeneration Strategies.
nsamples_ctrl = 4
ctrl_lb = [0.0]
ctrl_ub = [0.2]
ctrl_func(u, p, t) = p * exp(-t)
ctrl_space = CtrlSpace(ctrl_lb, ctrl_ub, ctrl_func, nsamples_ctrl)
1 dimensional CtrlSpace with 4 samples
╭──────────────┬──────────────────────────────────────────────┬──────────────...
─────╮...
│ Space Type │ Statistics │ Number...
Samples │...
├──────────────┼──────────────────────────────────────────────┼──────────────...
─────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ CtrlSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ x_1 │ 0.0 │ 0.2 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────┴──────────────────────────────────────────────┴──────────────...
─────╯...
nsamples_p = 5
p_lb = [0.19, 0.39]
p_ub = [0.21, 0.41]
param_space = ParameterSpace(p_lb, p_ub, nsamples_p; labels = ["freqHz", "T2"])
2 dimensional ParameterSpace with 5 samples
╭──────────────────┬──────────────────────────────────────────────┬──────────...
─────────╮...
│ Space Type │ Statistics │ Number...
of Samples │...
├──────────────────┼──────────────────────────────────────────────┼──────────...
─────────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ freqHz │ 0.19 │ 0.21 │ │...
│ ParameterSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ T2 │ 0.39 │ 0.41 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────────┴──────────────────────────────────────────────┴──────────...
─────────╯...
Now we define the SimulatorConfig
simconfig = SimulatorConfig(param_space, ctrl_space)
Simulator Config with : CtrlSpace ParameterSpace
Statistics for all Spaces
1 dimensional CtrlSpace with 4 samples
╭──────────────┬──────────────────────────────────────────────┬──────────────...
─────╮...
│ Space Type │ Statistics │ Number...
Samples │...
├──────────────┼──────────────────────────────────────────────┼──────────────...
─────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ CtrlSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ x_1 │ 0.0 │ 0.2 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────┴──────────────────────────────────────────────┴──────────────...
─────╯...
2 dimensional ParameterSpace with 5 samples
╭──────────────────┬──────────────────────────────────────────────┬──────────...
─────────╮...
│ Space Type │ Statistics │ Number...
of Samples │...
├──────────────────┼──────────────────────────────────────────────┼──────────...
─────────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ freqHz │ 0.19 │ 0.21 │ │...
│ ParameterSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ T2 │ 0.39 │ 0.41 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────────┴──────────────────────────────────────────────┴──────────...
─────────╯...
We call the SimulatorConfig
on the fmu. We additionally can give outputs
as keyword arguments.
ed_me = simconfig(fmu_me; outputs = outputs_me, verbose = false);
[ Info: FMU Type: ME
┌ Warning: Using arrays or dicts to store parameters of different types can hurt performance.
│ Consider using tuples instead.
└ @ SciMLBase ~/.julia/packages/SciMLBase/aft1j/src/performance_warnings.jl:32
Simulating ME-FMU ... 0%| | ETA: N/A
Simulating ME-FMU ... 100%|██████████████████████████████| Time: 0:00:10
Progress: 10%|████▏ | ETA: 0:02:25
Progress: 65%|██████████████████████████▋ | ETA: 0:00:09
Progress: 100%|█████████████████████████████████████████| Time: 0:00:16
We can also give t_start
, t_stop
and solver
as keyword arguments.
ed_me = simconfig(fmu_me; outputs = outputs_me, t_start = 0.5, t_stop = 1.0, solver = Tsit5(), verbose = false)
Number of Trajectories in ExperimentData: 20
Basic Statistics for Given Dynamical System's Specifications
Number of u0s in the ExperimentData: 18
Number of y0s in the ExperimentData: 4
Number of ps in the ExperimentData: 2
╭─────────┬──────────────────────────────────────────────────────────────────...
──╮...
│ Field │...
│...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭─────────────┬──────────────┬──────────────┬────────┬──────────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ states_1 │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ u0s │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ states_18 │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ │ ╰─────────────┴──────────────┴──────────────┴────────┴──────────...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭──────────────┬──────────────┬──────────────┬────────┬─────────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ outputs[1] │ 10.0 │ 10.0 │ 10.0 │ 0.0...
│ y0s │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │...
│ │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ outputs[4] │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ │ ╰──────────────┴──────────────┴──────────────┴────────┴─────────...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭──────────┬──────────────┬──────────────┬─────────┬──────────╮...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ freqHz │ 0.192 │ 0.208 │ 0.199 │ 0.006...
│ ps │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ T2 │ 0.392 │ 0.408 │ 0.399 │ 0.005...
│ │ ╰──────────┴──────────────┴──────────────┴─────────┴──────────╯...
╰─────────┴──────────────────────────────────────────────────────────────────...
──╯...
Basic Statistics for Given Dynamical System's Continuous Fields
Number of states in the ExperimentData: 18
Number of observables in the ExperimentData: 4
Number of controls in the ExperimentData: 1
╭───────────────┬────────────────────────────────────────────────────────────...
─────────╮...
│ Field │...
│...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭─────────────┬──────────────┬──────────────┬─────────┬───...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ states_1 │ 0.0 │ 3.953 │ 2.17...
│ states │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ states_18 │ 0.0 │ 0.497 │ 0.221...
│ │ ╰─────────────┴──────────────┴──────────────┴─────────┴───...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭──────────────┬──────────────┬──────────────┬─────────┬──...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ outputs[1] │ 5.935 │ 10.0 │ 7.883...
│ observables │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ outputs[4] │ 0.0 │ 0.073 │ 0.004...
│ │ ╰──────────────┴──────────────┴──────────────┴─────────┴──...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭──────────┬──────────────┬──────────────┬─────────┬────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ controls │ ├──────────┼──────────────┼──────────────┼─────────┼────...
│ │ │ x_1 │ 0.009 │ 0.106 │ 0.048...
│ │ ╰──────────┴──────────────┴──────────────┴─────────┴────...
╰───────────────┴────────────────────────────────────────────────────────────...
─────────╯...
Co-Simulation FMU
We start by loading the FMU using FMI.fmi2load
.
fmu_cs = FMI.fmi2Load(fmu_file_path, type = :CS)
Model name: CoupledClutches
Type: 1
We get the output labels using fmi2GetOutputNames
outputs_cs = FMI.FMIImport.fmi2GetOutputNames(fmu_cs) .|> string
4-element Vector{String}:
"outputs[1]"
"outputs[2]"
"outputs[3]"
"outputs[4]"
We use the same SimulatorConfig
from previous section with the CS FMU.
simconfig = SimulatorConfig(param_space, ctrl_space)
Simulator Config with : CtrlSpace ParameterSpace
Statistics for all Spaces
1 dimensional CtrlSpace with 4 samples
╭──────────────┬──────────────────────────────────────────────┬──────────────...
─────╮...
│ Space Type │ Statistics │ Number...
Samples │...
├──────────────┼──────────────────────────────────────────────┼──────────────...
─────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ CtrlSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ x_1 │ 0.0 │ 0.2 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────┴──────────────────────────────────────────────┴──────────────...
─────╯...
2 dimensional ParameterSpace with 5 samples
╭──────────────────┬──────────────────────────────────────────────┬──────────...
─────────╮...
│ Space Type │ Statistics │ Number...
of Samples │...
├──────────────────┼──────────────────────────────────────────────┼──────────...
─────────┤...
│ │ ╭──────────┬──────────────┬──────────────╮ │...
│ │ │ Labels │ LowerBound │ UpperBound │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ freqHz │ 0.19 │ 0.21 │ │...
│ ParameterSpace │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ │...
│ │ ├──────────┼──────────────┼──────────────┤ │...
│ │ │ T2 │ 0.39 │ 0.41 │ │...
│ │ ╰──────────┴──────────────┴──────────────╯ │...
╰──────────────────┴──────────────────────────────────────────────┴──────────...
─────────╯...
We call the SimulatorConfig
on the fmu. We additionally can give outputs
as keyword arguments.
ed_cs = simconfig(fmu_me; outputs = outputs_cs, verbose = false);
[ Info: FMU Type: ME
┌ Warning: Using arrays or dicts to store parameters of different types can hurt performance.
│ Consider using tuples instead.
└ @ SciMLBase ~/.julia/packages/SciMLBase/aft1j/src/performance_warnings.jl:32
Progress: 65%|██████████████████████████▋ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00
We can also give t_start
, t_stop
as keyword arguments.
ed_cs = simconfig(fmu_me; outputs = outputs_me, t_start = 0.5, t_stop = 1.0, verbose = false)
Number of Trajectories in ExperimentData: 20
Basic Statistics for Given Dynamical System's Specifications
Number of u0s in the ExperimentData: 18
Number of y0s in the ExperimentData: 4
Number of ps in the ExperimentData: 2
╭─────────┬──────────────────────────────────────────────────────────────────...
──╮...
│ Field │...
│...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭─────────────┬──────────────┬──────────────┬────────┬──────────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ states_1 │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ u0s │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├─────────────┼──────────────┼──────────────┼────────┼──────────...
│ │ │ states_18 │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ │ ╰─────────────┴──────────────┴──────────────┴────────┴──────────...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭──────────────┬──────────────┬──────────────┬────────┬─────────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ outputs[1] │ 10.0 │ 10.0 │ 10.0 │ 0.0...
│ y0s │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │...
│ │ ├──────────────┼──────────────┼──────────────┼────────┼─────────...
│ │ │ outputs[4] │ 0.0 │ 0.0 │ 0.0 │ 0.0...
│ │ ╰──────────────┴──────────────┴──────────────┴────────┴─────────...
├─────────┼──────────────────────────────────────────────────────────────────...
──┤...
│ │ ╭──────────┬──────────────┬──────────────┬─────────┬──────────╮...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean │ StdDev...
│ │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ freqHz │ 0.192 │ 0.208 │ 0.199 │ 0.006...
│ ps │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├──────────┼──────────────┼──────────────┼─────────┼──────────┤...
│ │ │ T2 │ 0.392 │ 0.408 │ 0.399 │ 0.005...
│ │ ╰──────────┴──────────────┴──────────────┴─────────┴──────────╯...
╰─────────┴──────────────────────────────────────────────────────────────────...
──╯...
Basic Statistics for Given Dynamical System's Continuous Fields
Number of states in the ExperimentData: 18
Number of observables in the ExperimentData: 4
Number of controls in the ExperimentData: 1
╭───────────────┬────────────────────────────────────────────────────────────...
─────────╮...
│ Field │...
│...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭─────────────┬──────────────┬──────────────┬─────────┬───...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ states_1 │ 0.0 │ 3.953 │ 2.17...
│ states │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├─────────────┼──────────────┼──────────────┼─────────┼───...
│ │ │ states_18 │ 0.0 │ 0.497 │ 0.221...
│ │ ╰─────────────┴──────────────┴──────────────┴─────────┴───...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭──────────────┬──────────────┬──────────────┬─────────┬──...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ outputs[1] │ 5.935 │ 10.0 │ 7.883...
│ observables │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ │ ⋮ │ ⋮ │ ⋮ │ ⋮...
│ │ ├──────────────┼──────────────┼──────────────┼─────────┼──...
│ │ │ outputs[4] │ 0.0 │ 0.073 │ 0.004...
│ │ ╰──────────────┴──────────────┴──────────────┴─────────┴──...
├───────────────┼────────────────────────────────────────────────────────────...
─────────┤...
│ │ ╭──────────┬──────────────┬──────────────┬─────────┬────...
│ │ │ Labels │ LowerBound │ UpperBound │ Mean...
│ controls │ ├──────────┼──────────────┼──────────────┼─────────┼────...
│ │ │ x_1 │ 0.009 │ 0.106 │ 0.048...
│ │ ╰──────────┴──────────────┴──────────────┴─────────┴────...
╰───────────────┴────────────────────────────────────────────────────────────...
─────────╯...
Parellelization
Similar to generating data for ODEProblem, we can take advantage of multiple processes in generating data using FMUs. We add the Distributed, for using multiple processes.
using Distributed
We add processes using addprocs
. For more detailed understanding about distributed computing see: Distributed.jl.
addprocs(2, exeflags = ["--project=."])
We need to load the packages on all processes using the @everywhere
macro.
@everywhere using FMI
@everywhere using DataGeneration
And then we define the functions that we will need to be defined on all processes.
@everywhere ctrl_func(u, p, t) = p * exp(-t)
Now we can use the multiple processes for generating data.
ed_me = simconfig(fmu_me; outputs = outputs_me, verbose = false)
ed_cs = simconfig(fmu_cs; outputs = outputs_cs, verbose = false);
[ Info: FMU Type: ME
┌ Warning: Using arrays or dicts to store parameters of different types can hurt performance.
│ Consider using tuples instead.
└ @ SciMLBase ~/.julia/packages/SciMLBase/aft1j/src/performance_warnings.jl:32
Progress: 45%|██████████████████▌ | ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00
[ Info: FMU Type: CS
Progress: 10%|████▏ | ETA: 0:00:02
Progress: 100%|█████████████████████████████████████████| Time: 0:00:00