Giter Club home page Giter Club logo

fmi.jl's People

Contributors

0815creeper avatar adribrune avatar dilumaluthge avatar github-actions[bot] avatar jokircher avatar juguma avatar kristofferc avatar ranjanan avatar sharanry avatar stoljarjo avatar thummeto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fmi.jl's Issues

Error : FMU is not in instantiation mode

@ThummeTo

when the FMU is exported (License Free FMU) using Dymola Solver (4th Option) as shown in the Figure below.

image

fmiSimulate gives the error FMU is not in instantiation mode

the same model when a license-free FMU is generated with Cvode (3rd Option in the figure above). the model works file.

I tried to find the cause of the error but I didn't have any luck.

Note: this error exists in both V 0.1.2 and V 0.1.3. checked FMU with Dymola Solver in FMPy- works fine.

Regards
Prem

Error while Parallelizing a batch Simulation

Hi @ThummeTo

I am trying to Prallelising the batch simulations.

FMU used - SpringPendulum1D

Serial batch running Code:
Given below is the code that I used to run the batch cases in serial. This code works perfectly fine.

using FMI, Plots, Distributed 
modelFMUPath = joinpath(dirname(@__FILE__), "../model/SpringPendulum1D.fmu")
FMU = fmiLoad(modelFMUPath; unpackPath = nothing)
results = []
@time for i in 0.1:0.1:1

    myFMU = fmiInstantiate!(FMU; loggingOn=false)
    fmiSetupExperiment(myFMU, 0.0)
    fmiEnterInitializationMode(myFMU)
 
    springConstant = fmiGetReal(myFMU, "spring.c") * i
    fmiSetReal(myFMU, "spring.c", springConstant)
    fmiExitInitializationMode(myFMU)

    t_start = 0.0
    t_stop = 5

    result = fmiSimulate(myFMU,t_start, t_stop; recordValues= ["mass.s"],setup=false)
    push!( results, result)

end

fmiUnload(FMU)

Parallelizing Code:
Below is the code that I tried to parallelizing the Code Above using Distributed.jl but I am not able to solve it.

using FMI, Plots, Distributed 
addprocs(3, exeflags=`--project=$@__DIR__`)
modelFMUPath = joinpath(dirname(@__FILE__), "../model/SpringPendulum1D.fmu")
FMU = fmiLoad(modelFMUPath; unpackPath = nothing)
results = []
@time  @distributed for i in 0.1:0.1:1

    myFMU = fmiInstantiate!(FMU; loggingOn=false)
    fmiSetupExperiment(myFMU, 0.0)
    fmiEnterInitializationMode(myFMU)
 
    springConstant = fmiGetReal(myFMU, "spring.c") * i
    fmiSetReal(myFMU, "spring.c", springConstant)
    fmiExitInitializationMode(myFMU)

    t_start = 0.0
    t_stop = 5

    result = fmiSimulate(myFMU,t_start, t_stop; recordValues= ["mass.s"],setup=false)
    push!( results, result)

end

fmiUnload(FMU)

can you give some suggestions where I am going wrong. I tried debugging not able to find what is the issue.

Regards
Prem

Integration seems to get stuck at event

I've been trying to integrate this FMU, which has three events, all of which occur at 0.1 seconds. When I print the time, the integrator gets stuck at 0.1 seconds (or oscillates thereabouts).

DCPM_Temperature.zip

To reproduce:

using FMI
using Sundials
using OrdinaryDiffEq

fmupath = "DCPM_Temperature.fmu"

fmu = fmiLoad(fmupath)

fmiInstantiate!(fmu)

fmiSimulateME(fmu, solver = CVODE_BDF())

You can reproduce this with Rodas5(autodiff=false), KenCarp4(autodiff=false), RadauIIA5(autodiff=false). With Rosenbrock23(autdiff=false)` you get the same error as here.

However, it integrates with ImplicitEuler(autodiff=false)

Support for 32-bit-FMUs

  • change fmi2-Datatypes, so they fit the system architecture (e.g. fmi2Real=Float32 for 32-bit architectures)

BoundsError access Bool

Description

When I simulate a FMU generated from the Modelica Standard Library I get a bounds error.

How to reproduce

Consider the following minimal example with a CS-ME 2.0 FMU Modelica.Mechanics.Translational.Examples.Damper.fmu generatet from OpenModelica (OMCompiler v1.19.0-dev.505+ga499198eb3):

using FMI

myFMU = fmiLoad("Modelica.Mechanics.Translational.Examples.Damper.fmu")
fmiInstantiate!(myFMU)
success, simData = fmiSimulate(myFMU, 0.0, 1.0)

The error message:

julia> success, simData = fmiSimulate(myFMU, 0.0, 1.0)
ERROR: BoundsError: attempt to access Bool at index [2]
Stacktrace:
 [1] indexed_iterate(I::Bool, i::Int64, state::Nothing)
   @ Base ./tuple.jl:98
 [2] top-level scope
   @ REPL[4]:1

OMSimulator can simulate the FMU fine, so I guess it is not an issue with the FMU. But I didn't test a non-OpenModelica tool on it.

Additional files

Here is the FMU (remove the .zip file extension) with Linux binaries:
Modelica.Mechanics.Translational.Examples.Damper.fmu.zip


Version 'n stuff

OS: Ubuntu 20.04
Julia:

Julia Version 1.7.1
Commit ac5cc99908 (2021-12-22 19:35 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-10700KF CPU @ 3.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
(@v1.7) pkg> status FMI
      Status `~/.julia/environments/v1.7/Project.toml`
  [14a09403] FMI v0.3.6

OpenModelica: OMCompiler v1.18.1 and v1.19.0-dev.505+ga499198eb3

Save simulation results to CSV / MAT

Feature Request

Is there a (simple) way to save the simulation results to a *.csv or *.mat file? I couldn't find one.

I can create a DataFrame and save it myself, but it is very inconvenient. An API function would be very nice.

My Workaround

using FMI
using DataFrames
using CSV

outputVars = ["outputs[1]", "outputs[2]", "outputs[3]", "outputs[4]", "outputs[5]", "outputs[6]", "outputs[7]", "outputs[8]"]
result = fmiSimulate(fmu, 0.0, 10.0; recordValues=outputVars)

df = DataFrame(time = result.values.t)
for i in 1:length(result.values.saveval[1])
  df[!, Symbol(names[i])] = [val[i] for val in result.values.saveval]
end
CSV.write(resultFile, df)

ERROR: LoadError: AssertionError: Target platform is Windows, but can’t find valid FMU binary

I am using Julia v. 1.6.3 64bit in my windows machine. I have an FMU model (generated by 32bits simulation tool) which I tried to load it. However, I got the below error.

ERROR: LoadError: AssertionError: Target platform is Windows, but can't find valid FMU binary at `` for path `path/to/file/myFMU`.

I am wondering if the problem is because:
1- there are some other missing files that need to be existed? or
2- this julia is 64bit and the FMU model is 32bit. If so, how can I let julia reads the 32bits FMU model? do I need to uninstall the current version and then install 32bit julia or there is a better way?
This is what I get when from REPL of VS Code:

julia> versioninfo()
Julia Version 1.6.3
Commit ae8452a9e0 (2021-09-23 17:34 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 6

Example in documentation not working

I tried to execute the following example:
https://thummeto.github.io/FMI.jl/dev/examples/CS_simulation/

using FMI
pathToFMU = joinpath(dirname(@__FILE__), "../model/OpenModelica/v1.17.0/SpringFrictionPendulum1D.fmu")
"../model/OpenModelica/v1.17.0/SpringFrictionPendulum1D.fmu"
julia> myFMU = fmiLoad(pathToFMU)
ERROR: IOError: open("../model/OpenModelica/v1.17.0/SpringFrictionPendulum1D.fmu", 0, 0): no such file or directory (ENOENT)
Stacktrace:
  [1] uv_error
    @ ./libuv.jl:97 [inlined]
  [2] open(path::String, flags::UInt8, mode::Int64)
    @ Base.Filesystem ./filesystem.jl:106
  [3] open
    @ ./filesystem.jl:98 [inlined]
  [4] sendfile(src::String, dst::String)
    @ Base.Filesystem ./file.jl:978
  [5] cp(src::String, dst::String; force::Bool, follow_symlinks::Bool)
    @ Base.Filesystem ./file.jl:370
  [6] fmi2Unzip(pathToFMU::String; unpackPath::Nothing)
    @ FMIImport ~/.julia/packages/FMIImport/S8pFT/src/FMI2_ext.jl:33
  [7] fmi2Load(pathToFMU::String; unpackPath::Nothing, type::Nothing)
    @ FMIImport ~/.julia/packages/FMIImport/S8pFT/src/FMI2_ext.jl:111
  [8] fmi2Load
    @ ~/.julia/packages/FMIImport/S8pFT/src/FMI2_ext.jl:101 [inlined]
  [9] #fmiLoad#136
    @ ~/.julia/packages/FMI/pXX2j/src/FMI.jl:228 [inlined]
 [10] fmiLoad(args::String)
    @ FMI ~/.julia/packages/FMI/pXX2j/src/FMI.jl:228
 [11] top-level scope
    @ REPL[9]:1

julia> 

Any idea?

I think the file is not included in the package, or the path is wrong.

Any way to get access to default parameter values specified in the xml?

I was looking to get access to the default parameter values specified in the modelDescription.xml. For example, I hope to get access to the 0 in the model description excerpt below through FMI. Is there currently any way to do this? If not, I am open to submitting a PR.

<ScalarVariable
    name="p_integer"
    valueReference="3"
    variability="fixed"
    causality="parameter"
    >
    <Integer start="0"/>
 </ScalarVariable>

@ThummeTo
CC: @ChrisRackauckas

Improve DocStrings

  • Improve DocString Format (linebrakes)
  • Start DocStrings for every function with function explanations
  • add automated code coverage service for repo

Error while calling fmi2SimulateCS

I got:
Error: UndefVarError: inputFunctiont not defined
which caused by a typo in:
src/FMI2/sim.jl line:464
_inputFunction = inputFunctiont

Logging function not replacing format placeholder

Description

The log function provided by FMI.jl is not replacing format placeholders with the actual string.

How to reproduce

When initializing a Pendulum FMU and enabling loggingOn = true:

julia> using FMI
julia> fmu = fmiLoad("Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum.fmu");
julia> fmiInstantiate!(fmu; loggingOn = true);
[ Info: [OK][logAll][Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum]: fmi2Instantiate: Trying to find simulation settings %s.
[ Info: [OK][logAll][Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum]: fmi2Instantiate: Using default simulation settings.
[ Info: [OK][logFmi2Call][Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum]: fmi2Instantiate: GUID=%s

I would expect %s to be replaced by the GUID string.

FMU (remove the .zip from name):
Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum.fmu.zip

Version 'n stuff

Generation Tool: OpenModelica v1.19.0-dev.505+ga499198eb3
OS: Ubuntu 20.04
Julia:

Julia Version 1.7.1
Commit ac5cc99908 (2021-12-22 19:35 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-10700KF CPU @ 3.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
(@v1.7) pkg> status FMI
      Status `~/.julia/environments/v1.7/Project.toml`
  [14a09403] FMI v0.3.6

Solving non-linear system 101 failed at time (condition must be called in continuoustime mode)

Error while simulating attached FMU on FMI 0.8.6. Code:

using FMI
using Sundials
using OrdinaryDiffEq
using Plots

fmu = FMI.fmi2Load("SimpleTriacCircuit.fmu", type = :ME)
fmiInstantiate!(fmu)

r1 = FMI.fmi2SimulateME(fmu, solver = CVODE_BDF())

Logs:

julia> include("test.jl")
[ Info: Precompiling FMI [14a09403-18e3-468f-ad8a-74f8dda2d9ac]
[ Info: Precompiling Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80]
[ Info: fmi2Unzip(...): Written file `binaries/win64/Modelica_Electrical_Analog_Examples_SimpleTriacCircuit_FMU.libs`, but file is empty.
[ Info: fmi2Unzip(...): Successfully unzipped 7 files at `C:\Users\RANJAN~1\AppData\Local\Temp\fmijl_Ok1TCj\SimpleTriacCircuit`.
[ Info: fmi2Load(...): FMU resources location is `file:///C:/Users/RANJAN~1/AppData/Local/Temp/fmijl_Ok1TCj/SimpleTriacCircuit/resources`
[ Info: fmi2Load(...): FMU supports both CS and ME, using CS as default if nothing specified.
Simulating ME-FMU ...   0%||  ETA: N/Aassert            | debug   | Solving non-linear system 101 failed at time=3e-05.
|                 | |       | For more information please use -lv LOG_NLS.
assert            | debug   | Solving non-linear system 101 failed at time=3e-05.
|                 | |       | For more information please use -lv LOG_NLS.
assert            | debug   | Solving non-linear system 101 failed at time=3e-05.
|                 | |       | For more information please use -lv LOG_NLS.
assert            | debug   | Solving non-linear system 101 failed at time=3e-05.
|                 | |       | For more information please use -lv LOG_NLS.
ERROR: LoadError: AssertionError: condition(...): Must be called in mode continuous time.
Stacktrace:
  [1] condition
    @ C:\Users\Ranjan Anantharaman\.julia\packages\FMI\iS1K4\src\FMI2_sim.jl:89 [inlined]
  [2] #87
    @ C:\Users\Ranjan Anantharaman\.julia\packages\FMI\iS1K4\src\FMI2_sim.jl:739 [inlined]
  [3] determine_event_occurance
    @ C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\callbacks.jl:183 [inlined]
  [4] find_callback_time(integrator::Sundials.CVODEIntegrator{Vector{Float64}, Vector{Any}, Sundials.Handle{Sundials.CVODEMem}, ODESolution{Float64, 2, Vector{Vector{Float64}}, Nothing, Nothing, Vector{Float64}, Nothing, ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, SciMLBase.HermiteInterpolation{Vector{Float64}, Vector{Vector{Float64}}, Vector{Vector{Float64}}}, DiffEqBase.DEStats}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Sundials.FunJac{ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Nothing, Nothing, Vector{Any}, Nothing, Nothing, Vector{Float64}, Nothing, Nothing, Nothing}, Nothing, Sundials.DEOptions{DataStructures.BinaryMinHeap{Any}, DataStructures.BinaryMinHeap{Float64}, Vector{Any}, Vector{Float64}, Nothing, CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Float64, Float64, typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE)}, Vector{Float64}, Tuple{Int64}, Vector{Float64}, Sundials.LinSolHandle{Sundials.Dense}, Sundials.MatrixHandle{Sundials.DenseMatrix}, DiffEqBase.CallbackCache{Vector{Float64}, Vector{Float64}}}, callback::VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}, counter::Int64)
    @ DiffEqBase C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\callbacks.jl:455
  [5] find_first_continuous_callback
    @ C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\callbacks.jl:123 [inlined]
  [6] handle_callbacks!(integrator::Sundials.CVODEIntegrator{Vector{Float64}, Vector{Any}, Sundials.Handle{Sundials.CVODEMem}, ODESolution{Float64, 2, Vector{Vector{Float64}}, Nothing, Nothing, Vector{Float64}, Nothing, ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, SciMLBase.HermiteInterpolation{Vector{Float64}, Vector{Vector{Float64}}, Vector{Vector{Float64}}}, DiffEqBase.DEStats}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Sundials.FunJac{ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Nothing, Nothing, Vector{Any}, Nothing, Nothing, Vector{Float64}, Nothing, Nothing, Nothing}, Nothing, Sundials.DEOptions{DataStructures.BinaryMinHeap{Any}, DataStructures.BinaryMinHeap{Float64}, Vector{Any}, Vector{Float64}, Nothing, CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Float64, Float64, typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE)}, Vector{Float64}, Tuple{Int64}, Vector{Float64}, Sundials.LinSolHandle{Sundials.Dense}, Sundials.MatrixHandle{Sundials.DenseMatrix}, DiffEqBase.CallbackCache{Vector{Float64}, Vector{Float64}}})
    @ Sundials C:\Users\Ranjan Anantharaman\.julia\packages\Sundials\k9hc3\src\common_interface\integrator_utils.jl:10
  [7] solve!(integrator::Sundials.CVODEIntegrator{Vector{Float64}, Vector{Any}, Sundials.Handle{Sundials.CVODEMem}, ODESolution{Float64, 2, Vector{Vector{Float64}}, Nothing, Nothing, Vector{Float64}, Nothing, ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, SciMLBase.HermiteInterpolation{Vector{Float64}, Vector{Vector{Float64}}, Vector{Vector{Float64}}}, DiffEqBase.DEStats}, CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Sundials.FunJac{ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Nothing, Nothing, Vector{Any}, Nothing, Nothing, Vector{Float64}, Nothing, Nothing, Nothing}, Nothing, Sundials.DEOptions{DataStructures.BinaryMinHeap{Any}, DataStructures.BinaryMinHeap{Float64}, Vector{Any}, Vector{Float64}, Nothing, CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Float64, Float64, typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE)}, Vector{Float64}, Tuple{Int64}, Vector{Float64}, Sundials.LinSolHandle{Sundials.Dense}, Sundials.MatrixHandle{Sundials.DenseMatrix}, DiffEqBase.CallbackCache{Vector{Float64}, Vector{Float64}}}; early_free::Bool, calculate_error::Bool)
    @ Sundials C:\Users\Ranjan Anantharaman\.julia\packages\Sundials\k9hc3\src\common_interface\solve.jl:1576
  [8] __solve(prob::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, alg::CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, timeseries::Vector{Any}, ts::Vector{Any}, ks::Vector{Any}, recompile::Type{Val{true}}; calculate_error::Bool, kwargs::Base.Pairs{Symbol, Any, NTuple{5, Symbol}, NamedTuple{(:callback, :saveat, :reltol, :dt, :dtmax), Tuple{CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Vector{Any}, Float64, Float64, Float64}}})
    @ Sundials C:\Users\Ranjan Anantharaman\.julia\packages\Sundials\k9hc3\src\common_interface\solve.jl:16
  [9] solve_call(_prob::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, args::CVODE_BDF{:Newton, :Dense, Nothing, Nothing}; merge_callbacks::Bool, kwargshandle::KeywordArgError, kwargs::Base.Pairs{Symbol, Any, NTuple{5, Symbol}, NamedTuple{(:callback, :saveat, :reltol, :dt, :dtmax), Tuple{CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Vector{Any}, Float64, Float64, Float64}}})
    @ DiffEqBase C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\solve.jl:422
 [10] solve_up(prob::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, ODEFunction{true, FMI.var"#84#92"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, sensealg::Nothing, u0::Vector{Float64}, p::Vector{Any}, args::CVODE_BDF{:Newton, :Dense, Nothing, Nothing}; kwargs::Base.Pairs{Symbol, Any, NTuple{5, Symbol}, NamedTuple{(:callback, :saveat, :reltol, :dt, :dtmax), Tuple{CallbackSet{Tuple{VectorContinuousCallback{FMI.var"#87#95"{Vector{UInt32}, Nothing, FMU2Component}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, FMI.var"#88#96"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT), Float64, Int64, Rational{Int64}, Nothing, Int64}}, Tuple{DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#97"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Vector{Any}, Float64, Float64, Float64}}})
    @ DiffEqBase C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\solve.jl:719
 [11] #solve#29
    @ C:\Users\Ranjan Anantharaman\.julia\packages\DiffEqBase\ydAoL\src\solve.jl:704 [inlined]
 [12] fmi2SimulateME(fmu::FMU2, c::Nothing, t_start::Nothing, t_stop::Nothing; tolerance::Nothing, dt::Nothing, solver::CVODE_BDF{:Newton, :Dense, Nothing, Nothing}, customFx::Nothing, recordValues::Nothing, saveat::Vector{Any}, x0::Nothing, setup::Nothing, reset::Nothing, instantiate::Nothing, freeInstance::Nothing, terminate::Nothing, inputValueReferences::Nothing, inputFunction::Nothing, parameters::Nothing, dtmax::Nothing, callbacks::Vector{Any}, showProgress::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\iS1K4\src\FMI2_sim.jl:768

SimpleTriacCircuit.zip

Readme / documentation for fmi2Simulate outdated

Issue

Both the README and the Documentation state that fmi2Simulate has two separate inputs for start and stop time:

fmiSimulate(str::fmi2Struct, 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::fmi2ValueReferenceFormat = nothing,
            saveat = [],
            setup::Bool = true,
            reset::Union{Bool, Nothing} = nothing, # nothing = auto
            inputValueReferences::fmi2ValueReferenceFormat = nothing,
            inputFunction = nothing,
            parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing,
            dtmax::Union{Real, Nothing} = nothing,
            kwargs...)

But I think in some of the latest versions of FMI.jl (v0.11.0 maybe?) the inputs t_start and t_stop became one tuple instead.

So the example from the README doesn't work any more and the documentation isn't up to date.

Versions 'n stuff

  • FMI.jl @v0.11.3

Default to auto selecting the solver

Currently, FMI simulates a given ME FMU using Tsit5 solver. This is often silently fails to solve without any warning or error. It might be better to let DifferentialEquations.jl auto select the solver based on its heuristics which has proved to be quite effective in my experience.

Warning with bouncingball FMU; it doesn't import

I was running into some problems while trying to run this FMU from https://github.com/modelica/Reference-FMUs. I've attached the FMU here.

First, we get an error because the XML says `dependenciesKind=constant". Fixed it with ThummeTo/FMICore.jl#20.

After that fix, I've been getting these warnings on a seemingly infinite loop from FMIImport:

....
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
┌ Warning: fmi2NewDiscreteStates(...): Needs to be called in state `fmi2ComponentStateEventMode`.
└ @ FMIImport C:\Users\Ranjan Anantharaman\.julia\packages\FMIImport\DJ6oi\src\FMI2_c.jl:702
....

and it never imports

BouncingBall.zip

Support for UInt Model Variable Identifiers

... some FMUs are using model varibale identfiers larger than 2147483647, which results in failures during parsing the model description. This will be solved in the next update.

Optional xml elements in modelDescription.xml not handled

According to 2.2.1 Definition of an FMU (fmiModelDescription) of the 2.0.2 FMI standard a lot of xml elements are optional for the modelDescription.xml.
FMI.jl doesn't handle (all) optional elements if they are not present.

Try simulating the fmi-cross-check VanDerPol FMU.

julia> pathToFMU="fmi-cross-check/fmus/2.0/me/linux64/Test-FMUs/0.0.2/VanDerPol/VanDerPol.fmu"
julia> myFMU = fmiLoad(pathToFMU)
ERROR: MethodError: no method matching createEnum(::Nothing)
Closest candidates are:
  createEnum(::EzXML.Node) at /home/andreas/workspace/julia/FMI.jl/src/FMI2_md.jl:253
Stacktrace:
 [1] fmi2readModelDescription(pathToModellDescription::String)
   @ FMI ~/workspace/julia/FMI.jl/src/FMI2_md.jl:59
 [2] fmi2Load(pathTofmu2::String)
   @ FMI ~/workspace/julia/FMI.jl/src/FMI2.jl:279
 [3] fmiLoad(pathToFMU::String)
   @ FMI ~/workspace/julia/FMI.jl/src/FMI.jl:85
 [4] top-level scope
   @ REPL[9]:1

In this case the model description is not defining TypeDefinitions.

v0.3.10 is a breaking release

Due to the changes in the causality, variability and initial enums, 0.3.10 is a breaking release.

@ThummeTo Shall I yank these releases (0.3.10 and 0.3.11) (example) to avoid any downstream failures?

We can re-release them as breaking changes after that.

Let us please follow semver moving forward.

Force FMI functions to be executed in the correct order/ FMU state

Similar to #64.

The FMI interface functions are only allowed to b executed in a certain order or FMU state. Currently I get errors when I call them in the wrong order. E.g. when calling fmiSimulate before calling fmiInstantiate!:

julia> using FMI
julia> myFMU = fmiLoad("Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum.fmu")
julia> fmiSimulate(myFMU, 0.0, 1.0; recordValues=["rev.w"])
ERROR: BoundsError: attempt to access 0-element Vector{fmi2Component} at index [0]
Stacktrace:
 [1] getindex(A::Vector{fmi2Component}, i1::Int64)
   @ Base ./array.jl:861
 [2] fmi2Simulate(fmu::FMU2, t_start::Float64, t_stop::Float64; kwargs::Base.Pairs{Symbol, Vector{String}, Tuple{Symbol}, NamedTuple{(:recordValues,), Tuple{Vector{String}}}})
   @ FMI ~/.julia/packages/FMI/K8UGW/src/FMI2.jl:585
 [3] #fmiSimulate#57
   @ ~/.julia/packages/FMI/K8UGW/src/FMI.jl:249 [inlined]
 [4] top-level scope
   @ REPL[5]:1

Error: The filename or extension is too long

Hi @ThummeTo

when I placed my FMU in the folder where the path is 136 char, function fmiLoad gives an error The filename or extension is too long.

Based on my understanding to avoid this problem, it would be nice to create a folder (with some random name) in the Temp folder (in Windows "C:\Users\username\AppData\Local\Temp" ) to extract the FMU and use the FMU files, in this way the length of the path will not be an issue.

Regards
Prem

Segmentation fault when calling function after fmiUnload()

Description

When I call a function after fmiUnload I get an segmentation fault and Julia crashes.

How to reproduce

I have a FMU that I can't share that produces this error, but I can't get a FMU from the Modelica Standard Library to simulate because of #63. But I guess this should work for any FMU.

using FMI

myFMU = fmiLoad("someFMu.fmu")
fmiInstantiate!(myFMU)
success, simData = fmiSimulate(myFMU, 0.0, 1.0)
fmiUnload(myFMU)

fmiInfo(myFMU)

Of course I expect an error, but not a segmentation fault.


Version 'n stuff

OS: Ubuntu 20.04
Julia:

Julia Version 1.7.1
Commit ac5cc99908 (2021-12-22 19:35 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-10700KF CPU @ 3.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
(@v1.7) pkg> status FMI
      Status `~/.julia/environments/v1.7/Project.toml`
  [14a09403] FMI v0.3.6

Warnings during Event-Handlings

Some FMUs with events (model-folder) generate warnings during simulation. However, simulation results are right, but the warnings aren't nice ...

Keyword `saveat` does no clean interpolation for ME-Simulation

This may be an issue by another package and will be checked.

Workaround: Remove the keyword saveat for fmiSimulate or fmiSimualteME if you are doing ME-Simulation, so you can get values with the step width of the integrator. If you need the values in smaller steps, limit the max step width of the integrator with keyword argument dtmax.

Fix: In the next release.

Error while loading FMU

While loading the attached FMU, I get the following error:

julia> fmiLoad(fmupath)
[ Info: fmi2Unzip(...): Successfully unzipped 2 files at `C:\Users\RANJAN~1\AppData\Local\Temp\fmifluxjl_naultd\heating`.
┌ Warning: Found enum, but no type definition. Skipping enums.
└ @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI2_md.jl:86
ERROR: ArgumentError: invalid base 10 digit 'f' in "false"
Stacktrace:
  [1] tryparse_internal(#unused#::Type{Int32}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool)
    @ Base .\parse.jl:137
  [2] parse(::Type{Int32}, s::String; base::Nothing)
    @ Base .\parse.jl:241
  [3] parse
    @ .\parse.jl:241 [inlined]
  [4] setDatatypeVariables(node::EzXML.Node, md::FMI.fmi2ModelDescription)
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI2_md.jl:414
  [5] parseModelVariables(nodes::EzXML.Node, md::FMI.fmi2ModelDescription, derivativeIndices::Vector{Int64})
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI2_md.jl:249
  [6] fmi2readModelDescription(pathToModellDescription::String)
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI2_md.jl:93
  [7] fmi2Load(pathToFMU::String; unpackPath::Nothing)
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI2.jl:335
  [8] #fmiLoad#40
    @ C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI.jl:193 [inlined]
  [9] fmiLoad(pathToFMU::String)
    @ FMI C:\Users\Ranjan Anantharaman\.julia\packages\FMI\8Hncl\src\FMI.jl:193
 [10] top-level scope
    @ REPL[6]:1

heating.zip

Add description to git repository

Any words mentioned in the description can be searched for in JuliaHub package repository, so it is useful to put a few keywords into the description to make it easier to find this package.

FMU: Windows to Linux?

Thank you for this helpful package.

I am sorry to ask this question here, but I request for some pointers. We have Matlab/Simulink installed on a Windows machine, and when exporting the FMUs, we are not able to load it on a Linux machine. How do you suggest loading such an FMUs using FMI.jl?

Thanks,
Sam

FMI Load Function Error

fmiLoad Function gives an error "AssertionError: Target platform is Windows, but can't valid find FMU binary.", the same FMU works fine in fmpy.

I found that fmiLoad function is looking for binary with the same name as FMU name in the unzipped folder, which might not be true in all the cases. FMU Birnarys have the same name as modelIdentifier in modelDescription.xml

I can create a pull request and resolve this issue @ThummeTo

FMU without state variables

Description

I have a (2.0, ME) FMU that doesn't have any state variables. It seems that FMI.jl is not catching these and calls the ODE solver on an empty array of states which results in a crash.

How to reproduce

mwe.mo

model Mwe
  Real x;
  Real y;
equation
  1 = x^2 + y*time;
  0 = x + y^2;
end Mwe;

Create 2.0 ModelExchange FMU with e.g. OpenModelica.
Windows FMU (remove the .zip part): Mwe.fmu.zip
Ubuntu Focal FMU: Mwe.fmu.zip

julia> using FMI
julia> myFMU = fmiLoad("Mwe.fmu");
julia> simData = fmiSimulate(myFMU, 0.0, 1.0; recordValues=["x", "y"])
ERROR: BoundsError: attempt to access 0-element Vector{Float64} at index [1]
Stacktrace:
  [1] getindex
    @ ./array.jl:861 [inlined]
  [2] ODE_DEFAULT_NORM
    @ ~/.julia/packages/DiffEqBase/Da1WO/src/common_defaults.jl:25 [inlined]
  [3] __init(prob::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, SciMLBase.ODEFunction{true, FMI.var"#84#93"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, alg::OrdinaryDiffEq.CompositeAlgorithm{Tuple{OrdinaryDiffEq.Vern7, OrdinaryDiffEq.Rodas4{0, false, LinearSolve.GenericLUFactorization{LinearAlgebra.RowMaximum}, typeof(OrdinaryDiffEq.DEFAULT_PRECS), Val{:forward}, true, nothing}}, OrdinaryDiffEq.AutoSwitch{OrdinaryDiffEq.Vern7, OrdinaryDiffEq.Rodas4{0, false, Nothing, typeof(OrdinaryDiffEq.DEFAULT_PRECS), Val{:forward}, true, nothing}, Rational{Int64}, Int64}}, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{Val{true}}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#98"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}, SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#30#31", DiffEqCallbacks.SavingAffect{FMI.var"#91#100"{Vector{UInt32}, Vector{UInt32}, Nothing, FMU2Component}, Float64, Tuple{Float64, Float64}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.saving_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, dense::Bool, calck::Bool, dt::Float64, dtmin::Nothing, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Rational{Int64}, abstol::Nothing, reltol::Float64, qmin::Rational{Int64}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{Int64}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:default_set, :second_time), Tuple{Bool, Bool}}})
    @ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/5B7d7/src/solve.jl:274
  [4] #__solve#502
    @ ~/.julia/packages/OrdinaryDiffEq/5B7d7/src/solve.jl:4 [inlined]
  [5] __solve(::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, SciMLBase.ODEFunction{true, FMI.var"#84#93"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Nothing; default_set::Bool, kwargs::Base.Pairs{Symbol, Any, NTuple{4, Symbol}, NamedTuple{(:second_time, :callback, :dtmax, :reltol), Tuple{Bool, SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#98"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}, SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#30#31", DiffEqCallbacks.SavingAffect{FMI.var"#91#100"{Vector{UInt32}, Vector{UInt32}, Nothing, FMU2Component}, Float64, Tuple{Float64, Float64}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.saving_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Float64, Float64}}})
    @ DifferentialEquations ~/.julia/packages/DifferentialEquations/TZ7Qg/src/default_solve.jl:9
  [6] #__solve#52
    @ ~/.julia/packages/DiffEqBase/Da1WO/src/solve.jl:1036 [inlined]
  [7] #solve_call#28
    @ ~/.julia/packages/DiffEqBase/Da1WO/src/solve.jl:448 [inlined]
  [8] solve_up(::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Any}, SciMLBase.ODEFunction{true, FMI.var"#84#93"{FMU2Component}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Nothing, ::Vector{Float64}, ::Vector{Any}; kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:callback, :dtmax, :reltol), Tuple{SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#27#28", DiffEqCallbacks.FunctionCallingAffect{FMI.var"#89#98"{Vector{UInt32}, Nothing, FMU2Component, FMICore.FMU2Solution}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.functioncalling_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}, SciMLBase.DiscreteCallback{DiffEqCallbacks.var"#30#31", DiffEqCallbacks.SavingAffect{FMI.var"#91#100"{Vector{UInt32}, Vector{UInt32}, Nothing, FMU2Component}, Float64, Tuple{Float64, Float64}, DataStructures.BinaryMinHeap{Float64}, Vector{Float64}}, typeof(DiffEqCallbacks.saving_initialize), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, Float64, Float64}}})
    @ DiffEqBase ~/.julia/packages/DiffEqBase/Da1WO/src/solve.jl:805
  [9] #solve#33
    @ ~/.julia/packages/DiffEqBase/Da1WO/src/solve.jl:771 [inlined]
 [10] fmi2SimulateME(fmu::FMU2, c::Nothing, t_start::Float64, t_stop::Float64; tolerance::Nothing, dt::Nothing, solver::Nothing, customFx::Nothing, recordValues::Vector{String}, saveat::Nothing, x0::Nothing, setup::Nothing, reset::Nothing, instantiate::Nothing, freeInstance::Nothing, terminate::Nothing, inputValueReferences::Nothing, inputFunction::Nothing, parameters::Nothing, dtmax::Nothing, callbacks::Vector{Any}, showProgress::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ FMI ~/.julia/packages/FMI/1vhoW/src/FMI2_sim.jl:814
 [11] #fmi2Simulate#107
    @ ~/.julia/packages/FMI/1vhoW/src/FMI2_sim.jl:1034 [inlined]
 [12] #fmi2Simulate#15
    @ ~/.julia/packages/FMI/1vhoW/src/FMI2_comp_wraps.jl:17 [inlined]
 [13] fmiSimulate(::FMU2, ::Float64, ::Vararg{Float64}; kwargs::Base.Pairs{Symbol, Vector{String}, Tuple{Symbol}, NamedTuple{(:recordValues,), Tuple{Vector{String}}}})
    @ FMI ~/.julia/packages/FMI/1vhoW/src/FMI.jl:527
 [14] top-level scope
    @ REPL[17]:1

Versions

  • Julia Version 1.7.2
    Commit bf53498635 (2022-02-06 15:21 UTC)
    Platform Info:
    OS: Linux (x86_64-pc-linux-gnu)
    CPU: Intel(R) Xeon(R) Gold 6248R CPU @ 3.00GHz
    WORD_SIZE: 64
    LIBM: libopenlibm
    LLVM: libLLVM-12.0.1 (ORCJIT, cascadelake)
  • FMI.jl: 0.9.0

Simulation aborts unstable solution

I have a model as a 2.0 ME FMU that I can't share here, but I could provide it via mail.

When simulating it with FMI.jl I'm getting an error from SciMLBase:

julia> simData = fmiSimulate(fmu, (0.0, 10.0); recordValues=recordValues)
┌ Warning: dt(4.440892098500626e-16) <= dtmin(1.7763568394002505e-15) at t=2.0. Aborting. There is either an error in your model specification or the true solution is unstable.
└ @ SciMLBase ~/.julia/packages/SciMLBase/QqtZA/src/integrator_interface.jl:518

and the simulation is aborted, but without throwing an error / warning in FMI.jl.

In the previous version v0.10.2 of FMI.jl this example never finishes (at least I don't have enough patience to wait any longer). Probably the underlying issue just didn't throw an error in the older version of SciMLBase.

OMSimulator can handle this FMU.

Versions 'n stuff

  • Tested FMI.jl @v0.11.2
  • OS: Ubuntu Focal
  • Julia: v1.8.1
  • FMU Exporting tool: OpenModelica v1.21.0-dev-288-g01b6764df5-cmake

Mismatch in simulation by using saveat in fmi2SimulateME

FMU used: https://github.com/modelica/fmi-cross-check/blob/master/fmus/2.0/me/linux64/MapleSim/2021.2/CoupledClutches/CoupledClutches.fmu

Code to reproduce this error:

using FMI, Test, DifferentialEquations

fmu_coupled_clutches_ME = FMI.fmi2Load(joinpath(@__DIR__, "CoupledClutches.fmu"), type=:ME)
outputs = FMI.FMIImport.fmi2GetOutputNames(fmu_coupled_clutches_ME) .|> string

sim1 = FMI.fmi2SimulateME(fmu_coupled_clutches_ME;
                        recordValues=outputs,
                        solver=Tsit5(),
                        saveat=[i for i in 0:0.01:1.5]);

sim2 = FMI.fmi2SimulateME(fmu_coupled_clutches_ME;
                        recordValues=nothing,
                        solver=Tsit5(),
                        saveat=[i for i in 0:0.01:1.5]);

@test sim1.values !== nothing
@test sim2.values === nothing
@test isapprox(sim1.states.t, sim2.states.t)

## This is erroring out (but it should not)
@test isapprox(sim1.states.u[5], sim2.states.u[5])
## 

sim3 = FMI.fmi2SimulateME(fmu_coupled_clutches_ME;
                        recordValues=outputs,
                        solver=Tsit5());

sim4 = FMI.fmi2SimulateME(fmu_coupled_clutches_ME;
                        recordValues=nothing,
                        solver=Tsit5());

@test sim3.values !== nothing
@test sim4.values === nothing
@test isapprox(sim3.states.t, sim4.states.t)
@test isapprox(sim3.states.u, sim4.states.u)
[0c46a032] DifferentialEquations v7.1.0
[14a09403] FMI v0.8.5
[8dfed614] Test

The states in sim1 and sim2 should match as the only difference is in the recordValues argument which just stores values.
Also, without using saveat, the states in sim3 and sim4 are matching.

@ThummeTo

cc: @sharanry

Support for (u, t) Input Functions

Currently, the input functions supported in FMI.jl only depend on time. Can we expand to input functions which involve both the current state and time as arguments (like in feedback controls)?

@ThummeTo

fmiSimulateCS did not work with fmiSetReal?

I have a simple fmu file which is addition module (for testing) with two inputs var1,var2 and single output y. I have three issues:

1- When I run it, the execution time is 0.068864 second for the fmiSimulate(myFMU, 0.0, 0.0; recordValues="y") function. It is kind of slow. Any reason why and how to speed it up?
2- I tried to change the values of inputs and simulate, as below. However, the fmiSetReal worked butfmiSimulate did not take the new values and returned zero values (default). Any reason for that and how to solve the problem?

# Model built with fmuType = "me_cs" (both model exchange and co-simulation)
@time begin 
fmiSetupExperiment(myFMU, 0.0)
fmiEnterInitializationMode(myFMU)
fmiSetReal(myFMU, "var1", 10.2)
K1 = fmiGetReal(myFMU, "var1") # Return K1=10.2
fmiSetReal(myFMU, "var2", 2.1)
K2 = fmiGetReal(myFMU, "var2") # Return K2=2.1
fmiExitInitializationMode(myFMU)
success, simData = fmiSimulateCS(myFMU, 0.0, 0.0; recordValues=["y"])
end

[ Info: Path to zmq file="C:\Users\name\AppData\Local\Temp\openmodelica.port.julia.57bEY9ySSc"
[ Info: fmi2Unzip(...): Written file `binaries/win64/SumDu_FMU.libs`, but file is empty.
[ Info: fmi2Unzip(...): Written file `sources/isfmi2`, but file is empty.
[ Info: fmi2Unzip(...): Written file `sources/SumDu_11mix.h`, but file is empty.
[ Info: fmi2Unzip(...): Written file `sources/SumDu_FMU.libs`, but file is empty.
[ Info: fmi2Unzip(...): Written file `sources/SumDu_includes.h`, but file is empty.
[ Info: fmi2Unzip(...): Successfully unzipped 187 files at `C:/Users/name/AppData/Local/Temp/OpenModelica/Output/SumDu`.
[ Info: fmi2Load(...): FMU supports both CS and ME, using CS as default if nothing specified.
[ Info: fmi2Load(...): FMU resources location is `file:///C:/Users/name/AppData/Local/Temp/OpenModelica/Output/SumDu/resources`
  #################### Begin information for FMU ####################
        Model name:                     SumDu
        FMI-Version:                    2.0
        GUID:                           {b9ecbe80-2827-4748-94f5-81e2d23027be}
        Generation tool:                OpenModelica Compiler OpenModelica v1.18.0 (64-bit)
        Generation time:                2022-01-13T15:44:58Z
        Var. naming conv.:              structured
        Event indicators:               0
        Inputs:                         0
        Outputs:                        0
        States:                         0
        Supports Co-Simulation:         true
                Model identifier:       SumDu
                Get/Set State:          false
                Serialize State:        false
                Dir. Derivatives:       false
                Var. com. steps:        true
                Input interpol.:        false
                Max order out. der.:    0
        Supports Model-Exchange:        true
                Model identifier:       SumDu
                Get/Set State:          false
                Serialize State:        false
                Dir. Derivatives:       false
##################### End information for FMU #####################
0.068864 seconds (75.61 k allocations: 4.961 MiB, 97.79% compilation time)
(SavedValues{tType=Float64, savevalType=Tuple{Float64, Float64}}
julia> simData
SavedValues{tType=Float64, savevalType=Tuple{Float64, Float64}}
t:
[0.0]
saveval:
[(0.0, 0.0)]

3- When using fmiSimulateME() Instead of fmiSimulate(), it gives error. Any reason for that?

success, simData = fmiSimulateME(myFMU, 0.0, 0.0; setup=true)
ERROR: LoadError: BoundsError: attempt to access 0-element Vector{Float64} at index [1]
Stacktrace:

Extracting ODEProblem from FMU

Is there an easy way to extract the ODEProblem/ODEFunction from the FMU?

So far I've hijacked the fmiSimulateME function and added return problem, customFxright after

problem = ODEProblem(customFx, x0, (t_start, t_stop), p,)

I've tried with a simple RC circuit exported from OMEdit, and I'm then able to solve the returned ODE.

Illegal call sequence

Description

I think I'm using FMI.jl to call FMI2 functions in an illegal call sequence.
When the FMU is in event mode it should not be allowed to call fmi2SetReal on a non-input variable.

I'm not sure if I want this to get fixed, because I'm doing it wrong by changing a non-input variable that is not a state
and need this capability of FMI.jl.

How to reproduce

Create a FMI 2 ModelExchange FMU with e.g. OpenModelica for

model simpleLoop
  Real r(min = 0);
  Real s(min = -sqrt(2), max = sqrt(2));
  Real x(start=1.0), y(start=0.5);
  Real x_ref, y_ref;
equation
  r = 1+time;
  s = sqrt((2-time)*0.9);

  r^2 = x^2 + y^2;
  r*s = x + y;

  x_ref = r * (s/2 + sqrt(1/2-s^2/4));
  y_ref = r*s - x_ref;
end simpleLoop;

Here variables r and s should have default variability continuous and causality local:

<ScalarVariable
  name="r"
  valueReference="0"
  >
  <Real min="0.0"/>
</ScalarVariable>
<ScalarVariable
  name="s"
  valueReference="1"
  >
  <Real min="-1.414213562373095" max="1.414213562373095"/>
</ScalarVariable>

Judging from the State Machine of Calling Sequence (FMI Specification 2.0.2 section 3.2.3) it is only allowed to call fmi2SetReal on a real input variables.
So if it has causality=input and variability=continuous
or it has causality=input and variability=discrete
or variability=tunable.

As far as I can tell FMI.jl is not stopping me from calling fmiSet on r or s.

import FMI
import FMIImport
fmu = FMI.fmiLoad("simpleLoop.fmu")
FMI.fmiInstantiate!(fmu)
# FMU instantiated
FMI.fmiSetupExperiment(fmu, 0.0, 1.0)
FMI.fmiEnterInitializationMode(fmu)
# FMU in initialization iode
FMI.fmiExitInitializationMode(fmu)
# FMU in event mode
FMIImport.fmi2SetReal(fmu, "r", 42)  # Illegal call

Expected Result

Throw an error when calling fmi2SetReal is not allowed and add a flag to allow illegal call sequences anyway.

Versions 'n Stuff

  • Julia: Julia Version 1.8.1
  • OS: Ubuntu Focal
  • FMI.jl v0.10.0
  • FMIImport.jl v0.11.1

Suggestion on Logo Appearance in Dark Theme

HI Team

I know this not trivial, but just giving my observation. FMI.jl logo doesn't have good visibility in dark model as shown in the picture below.

image

Julia Logo doesn't have this problem because there is a 1 or 2 Pixel border around each letter so the logo appears even in Dark Mode

image

Regards
Prem

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Save all variables not straight forward

Description

I want to simulate a FMU and save all varaibles in the results. For me this would be the default way to simulate a given FMU.

I have two problems:

a) I have to provide all variable names.
b) The data type returned by fmiSimulate can't be used to create a DataFrame, so I need to do it manually.

So my request would be to get a simple method to save all variables and to return a format that can be directly used by DataFrames.

fmu = fmiLoad("Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum")
allVariables = [fmu.modelDescription.modelVariables[i].name for i in 1:length(fmu.modelDescription.modelVariables)]
fmiInstantiate!(fmu)
success, simData = fmiSimulateME(fmu; recordValues=allVariables)

I would preferer to just use success, simData = fmiSimulateME(fmu) or success, simData = fmiSimulateME(fmu; recordValues=true).
Collecting all variable names can be done internally as well.

julia> typeof(simData)
SavedValues{Float64, NTuple{1094, Float64}}

julia> DataFrame(simData)
ERROR: ArgumentError: no default `Tables.columns` implementation for type: SavedValues{Float64, NTuple{1094, Float64}}

I can convert it myself, but the object returned by the ODE solver was of type SciMLBase.ODESolution and can be used just fine in a data frame. I guess the callbacks used to filter the results is a problem. Not sure what is faster, adding SavedValues to Tables.column or just use the ODESolution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.