Skip to content

Commit

Permalink
Merge branch 'ThummeTo:main' into fmiUnload-segfault
Browse files Browse the repository at this point in the history
  • Loading branch information
JoKircher authored Aug 4, 2023
2 parents 99ef761 + 7f75ca1 commit 03702f6
Show file tree
Hide file tree
Showing 8 changed files with 429 additions and 429 deletions.
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "FMIImport"
uuid = "9fcbc62e-52a0-44e9-a616-1359a0008194"
authors = ["TT <tobias.thummerer@informatik.uni-augsburg.de>", "LM <lars.mikelsons@informatik.uni-augsburg.de>", "JK <josef.kircher@student.uni-augsburg.de>"]
version = "0.15.5"
version = "0.15.8"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Expand All @@ -14,10 +14,10 @@ SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea"

[compat]
ChainRulesCore = "1.15.0"
ChainRulesCore = "1.16"
EzXML = "1.1.0"
FMICore = "0.17.0"
FMICore = "0.17.3"
ForwardDiffChainRules = "0.1.1"
SciMLSensitivity = "7.27.0"
SciMLSensitivity = "7.35, 7.36"
ZipFile = "0.10.0"
julia = "1.6"
7 changes: 6 additions & 1 deletion src/FMI2/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ function fmi2SetReal(c::FMU2Component,

if track
if status == fmi2StatusOK
for j in (c.A, c.B, c.C, c.D)
for j in (c.A, c.B, c.C, c.D, c.E, c.F)
if any(collect(v in j.∂f_refs for v in vr))
FMICore.invalidate!(j)
end
Expand Down Expand Up @@ -1562,6 +1562,8 @@ function fmi2SetTime(c::FMU2Component, time::fmi2Real; soft::Bool=false, track::
FMICore.invalidate!(c.B)
FMICore.invalidate!(c.C)
FMICore.invalidate!(c.D)
FMICore.invalidate!(c.E)
FMICore.invalidate!(c.F)
end
end

Expand Down Expand Up @@ -1620,6 +1622,9 @@ function fmi2SetContinuousStates(c::FMU2Component,

FMICore.invalidate!(c.A)
FMICore.invalidate!(c.C)

FMICore.invalidate!(c.E)
FMICore.invalidate!(c.F)
end
end

Expand Down
20 changes: 20 additions & 0 deletions src/FMI2/convert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using ChainRulesCore: ignore_derivatives
import SciMLSensitivity.ForwardDiff

# ToDo: Replace by multiple dispatch version ...
# Receives one or an array of value references in an arbitrary format (see fmi2ValueReferenceFormat) and converts it into an Array{fmi2ValueReference} (if not already).
function prepareValueReference(md::fmi2ModelDescription, vr::fmi2ValueReferenceFormat)
tvr = typeof(vr)
Expand Down Expand Up @@ -107,6 +108,25 @@ function fmi2ModelVariablesForValueReference(md::fmi2ModelDescription, vr::fmi2V
ar
end

"""
ToDo.
"""
function fmi2DataTypeForValueReference(md::fmi2ModelDescription, vr::fmi2ValueReference)
mv = fmi2ModelVariablesForValueReference(md, vr)[1]
if !isnothing(mv.Real)
return fmi2Real
elseif !isnothing(mv.Integer) || !isnothing(mv.Enumeration)
return fmi2Integer
elseif !isnothing(mv.Boolean)
return fmi2Boolean
elseif !isnothing(mv.String)
return fmi2String
else
@assert false "fmi2TypeForValueReference(...): Unknown data type for value reference `$(vr)`."
end
return nothing
end

"""
fmi2StringToValueReference(md::fmi2ModelDescription, name::String)
Expand Down
21 changes: 19 additions & 2 deletions src/FMI2/ext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,20 @@ Retrieves all the pointers of binary functions.
- FMISpec2.0.2: 2.2.7 Definition of Model Variables (ModelVariables)
"""
function fmi2Load(pathToFMU::String; unpackPath::Union{String, Nothing}=nothing, type::Union{Symbol, fmi2Type, Nothing}=nothing, cleanup::Bool=true, logLevel::FMULogLevel=FMULogLevelWarn)
function fmi2Load(pathToFMU::String; unpackPath::Union{String, Nothing}=nothing, type::Union{Symbol, fmi2Type, Nothing}=nothing, cleanup::Bool=true, logLevel::Union{FMULogLevel, Symbol}=FMULogLevelWarn)
# Create uninitialized FMU

if isa(logLevel, Symbol)
if logLevel == :info
logLevel = FMULogLevelInfo
elseif logLevel == :warn
logLevel = FMULogLevelWarn
elseif logLevel == :error
logLevel = FMULogLevelError
else
@assert false "Unknown logLevel symbol: `$(logLevel)`, supported are `:info`, `:warn` and `:error`."
end
end
fmu = FMU2(logLevel)

if startswith(pathToFMU, "http")
Expand All @@ -149,6 +161,7 @@ function fmi2Load(pathToFMU::String; unpackPath::Union{String, Nothing}=nothing,
# parse modelDescription.xml
fmu.modelDescription = fmi2LoadModelDescription(pathToModelDescription)
fmu.modelName = fmu.modelDescription.modelName
fmu.isZeroState = (length(fmu.modelDescription.stateValueReferences) == 0)

if isa(type, fmi2Type)
fmu.type = type
Expand Down Expand Up @@ -455,6 +468,7 @@ function fmi2Instantiate!(fmu::FMU2;
component.visible = visible
component.jacobianUpdate! = fmi2SampleJacobian!

# setting a jacobian update function dependent on DIrectionalDerivatives-Functionality is present in the FMU
updFct = nothing
if fmi2ProvidesDirectionalDerivative(fmu)
updFct = (jac, ∂f_refs, ∂x_refs) -> fmi2GetJacobian!(jac.mtx, component, ∂f_refs, ∂x_refs)
Expand All @@ -466,6 +480,8 @@ function fmi2Instantiate!(fmu::FMU2;
component.B = FMICore.FMUJacobian{fmi2Real, fmi2ValueReference}(fmu.modelDescription.derivativeValueReferences, fmu.modelDescription.inputValueReferences, updFct)
component.C = FMICore.FMUJacobian{fmi2Real, fmi2ValueReference}(fmu.modelDescription.outputValueReferences, fmu.modelDescription.stateValueReferences, updFct)
component.D = FMICore.FMUJacobian{fmi2Real, fmi2ValueReference}(fmu.modelDescription.outputValueReferences, fmu.modelDescription.inputValueReferences, updFct)
component.E = FMICore.FMUJacobian{fmi2Real, fmi2ValueReference}(fmu.modelDescription.derivativeValueReferences, isnothing(fmu.optim_p_refs) ? Array{fmi2ValueReference,1}() : fmu.optim_p_refs, updFct)
component.F = FMICore.FMUJacobian{fmi2Real, fmi2ValueReference}(fmu.modelDescription.outputValueReferences, isnothing(fmu.optim_p_refs) ? Array{fmi2ValueReference,1}() : fmu.optim_p_refs, updFct)

# register component for current thread
fmu.threadComponents[Threads.threadid()] = component
Expand Down Expand Up @@ -1092,7 +1108,8 @@ function fmi2Set(comp::FMU2Component, vrs::fmi2ValueReferenceFormat, srcArray::A
@assert isa(srcArray[i], String) "fmi2Set(...): Unknown data type for value reference `$(vr)` at index $(i), should be `String`, is `$(typeof(srcArray[i]))`."
retcodes[i] = fmi2SetString(comp, vr, srcArray[i])
elseif mv.Enumeration != nothing
@warn "fmi2Set(...): Currently not implemented for fmi2Enum."
@assert isa(srcArray[i], Union{Real, Integer}) "fmi2Set(...): Unknown data type for value reference `$(vr)` at index $(i), should be `Enumeration` (`Integer`), is `$(typeof(srcArray[i]))`."
retcodes[i] = fmi2SetInteger(comp, vr, Integer(srcArray[i]))
else
@assert false "fmi2Set(...): Unknown data type for value reference `$(vr)` at index $(i), is `$(mv.datatype.datatype)`."
end
Expand Down
10 changes: 5 additions & 5 deletions src/FMI2/prep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function prepareSolveFMU(fmu::FMU2,
#retcode = fmi2SetContinuousStates(c, x0)
#@assert retcode == fmi2StatusOK "fmi2Simulate(...): Setting initial state failed with return code $(retcode)."
retcodes = fmi2Set(c, fmu.modelDescription.stateValueReferences, x0; filter=setBeforeInitialization)
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial inputs failed with return code $(retcode)."
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial states failed with return code $(retcode)."
end

# enter (hard)
Expand All @@ -125,21 +125,21 @@ function prepareSolveFMU(fmu::FMU2,
# parameters
if parameters !== nothing
retcodes = fmi2Set(c, collect(keys(parameters)), collect(values(parameters)); filter=setInInitialization)
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial parameters failed with return code $(retcode)."
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial parameters failed with return code $(retcodes)."
end

# inputs
if inputs !== nothing
retcodes = fmi2Set(c, collect(keys(inputs)), collect(values(inputs)); filter=setInInitialization)
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial inputs failed with return code $(retcode)."
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial inputs failed with return code $(retcodes)."
end

# start state
if x0 !== nothing
#retcode = fmi2SetContinuousStates(c, x0)
#@assert retcode == fmi2StatusOK "fmi2Simulate(...): Setting initial state failed with return code $(retcode)."
retcodes = fmi2Set(c, fmu.modelDescription.stateValueReferences, x0; filter=setInInitialization)
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial inputs failed with return code $(retcode)."
@assert all(retcodes .== fmi2StatusOK) "fmi2Simulate(...): Setting initial inputs failed with return code $(retcodes)."
end

# exit setup (hard)
Expand All @@ -153,7 +153,7 @@ function prepareSolveFMU(fmu::FMU2,

# ME specific
if type == fmi2TypeModelExchange
if x0 == nothing
if x0 == nothing && !c.fmu.isZeroState
x0 = fmi2GetContinuousStates(c)
end

Expand Down
Loading

0 comments on commit 03702f6

Please sign in to comment.