Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.16.0 #98

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
name = "FMIImport"
uuid = "9fcbc62e-52a0-44e9-a616-1359a0008194"
authors = ["TT <[email protected]>", "LM <[email protected]>", "JK <[email protected]>"]
version = "0.15.8"
version = "0.16.0"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
EzXML = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
FMICore = "8af89139-c281-408e-bce2-3005eb87462f"
ForwardDiffChainRules = "c9556dd2-1aed-4cfe-8560-1557cf593001"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea"

[compat]
ChainRulesCore = "1.16"
EzXML = "1.1.0"
FMICore = "0.17.3"
ForwardDiffChainRules = "0.1.1"
SciMLSensitivity = "7.35, 7.36"
FMICore = "0.18.0"
ZipFile = "0.10.0"
julia = "1.6"
69 changes: 43 additions & 26 deletions src/FMI2/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import FMICore: fmi2DoStep, fmi2CancelStep, fmi2GetStatus!, fmi2GetRealStatus!,
import FMICore: fmi2SetTime, fmi2SetContinuousStates, fmi2EnterEventMode, fmi2NewDiscreteStates!, fmi2EnterContinuousTimeMode, fmi2CompletedIntegratorStep!
import FMICore: fmi2GetDerivatives!, fmi2GetEventIndicators!, fmi2GetContinuousStates!, fmi2GetNominalsOfContinuousStates!

using FMICore: invalidate!, check_invalidate!

"""
Source: FMISpec2.0.2[p.21]: 2.1.5 Creation, Destruction and Logging of FMU Instances

Expand Down Expand Up @@ -234,9 +236,10 @@ end

# helper
function checkStatus(c::FMU2Component, status::fmi2Status)
@assert (status != fmi2StatusWarning) || !c.fmu.executionConfig.assertOnWarning "Assert on `fmi2StatusWarning`. See stack for errors."
if status == fmi2StatusWarning
@assert !c.fmu.executionConfig.assertOnWarning "Assert on `fmi2StatusWarning`. See stack for errors."

if status == fmi2StatusError
elseif status == fmi2StatusError
c.state = fmi2ComponentStateError
@assert !c.fmu.executionConfig.assertOnError "Assert on `fmi2StatusError`. See stack for errors."

Expand Down Expand Up @@ -561,6 +564,7 @@ function fmi2GetReal!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, n
return status
end


"""
fmi2SetReal(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::AbstractArray{fmi2Real})

Expand Down Expand Up @@ -597,14 +601,23 @@ function fmi2SetReal(c::FMU2Component,
c.compAddr, vr, nvr, value)
checkStatus(c, status)

if track
if status == fmi2StatusOK
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
end
end
if track && status == fmi2StatusOK
check_invalidate!(vr, c.∂ẋ_∂x)
check_invalidate!(vr, c.∂ẋ_∂u)
check_invalidate!(vr, c.∂ẋ_∂p)

check_invalidate!(vr, c.∂y_∂x)
check_invalidate!(vr, c.∂y_∂u)
check_invalidate!(vr, c.∂y_∂p)

check_invalidate!(vr, c.∂e_∂x)
check_invalidate!(vr, c.∂e_∂u)
check_invalidate!(vr, c.∂e_∂p)

# [NOTE] No need to check for:
# check_invalidate!(vr, c.∂ẋ_∂t)
# check_invalidate!(vr, c.∂y_∂t)
# check_invalidate!(vr, c.∂e_∂t)
end

return status
Expand Down Expand Up @@ -650,6 +663,7 @@ function fmi2GetInteger!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}
return status
end


"""
fmi2SetInteger(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::AbstractArray{fmi2Integer})

Expand Down Expand Up @@ -687,6 +701,7 @@ function fmi2SetInteger(c::FMU2Component, vr::AbstractArray{fmi2ValueReference},
return status
end


"""
fmi2GetBoolean!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::AbstractArray{fmi2Boolean})

Expand Down Expand Up @@ -726,6 +741,7 @@ function fmi2GetBoolean!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}
return status
end


"""
fmi2SetBoolean(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::AbstractArray{fmi2Boolean})

Expand Down Expand Up @@ -761,6 +777,7 @@ function fmi2SetBoolean(c::FMU2Component, vr::AbstractArray{fmi2ValueReference},
return status
end


"""
fmi2GetString!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::Union{AbstractArray{Ptr{Cchar}}, AbstractArray{Ptr{UInt8}}})

Expand Down Expand Up @@ -800,6 +817,7 @@ function fmi2GetString!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference},
return status
end


"""
fmi2SetString(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, value::Union{AbstractArray{Ptr{Cchar}}, AbstractArray{Ptr{UInt8}}})

Expand Down Expand Up @@ -837,6 +855,7 @@ function fmi2SetString(c::FMU2Component, vr::AbstractArray{fmi2ValueReference},
return status
end


"""
fmi2GetFMUstate!(c::FMU2Component, FMUstate::Ref{fmi2FMUstate})

Expand Down Expand Up @@ -1015,6 +1034,7 @@ function fmi2SerializeFMUstate!(c::FMU2Component, FMUstate::fmi2FMUstate, serial
return status
end


"""
fmi2DeSerializeFMUstate!(c::FMU2Component, serializedState::AbstractArray{fmi2Byte}, size::Csize_t, FMUstate::Ref{fmi2FMUstate})

Expand Down Expand Up @@ -1054,6 +1074,7 @@ function fmi2DeSerializeFMUstate!(c::FMU2Component, serializedState::AbstractArr
return status
end


"""
fmi2GetDirectionalDerivative!(c::FMU2Component,
vUnknown_ref::AbstractArray{fmi2ValueReference},
Expand Down Expand Up @@ -1156,14 +1177,15 @@ More detailed:

See also [`fmi2SetRealInputDerivatives`](@ref).
"""
function fmi2SetRealInputDerivatives(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, order::AbstractArray{fmi2Integer}, value::AbstractArray{fmi2Real})
function fmi2SetRealInputDerivatives(c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, order::Array{fmi2Integer}, value::Array{fmi2Real})

status = fmi2SetRealInputDerivatives(c.fmu.cSetRealInputDerivatives,
c.compAddr, vr, nvr, order, value)
checkStatus(c, status)
return status
end


"""
fmi2GetRealOutputDerivatives!(c::FMU2Component,
vr::AbstractArray{fmi2ValueReference},
Expand Down Expand Up @@ -1195,14 +1217,15 @@ More detailed:
- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions
- FMISpec2.0.2[p.104]: 4.2.1 Transfer of Input / Output Values and Parameters
"""
function fmi2GetRealOutputDerivatives!(c::FMU2Component, vr::AbstractArray{fmi2ValueReference}, nvr::Csize_t, order::AbstractArray{fmi2Integer}, value::AbstractArray{fmi2Real})
function fmi2GetRealOutputDerivatives!(c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, order::Array{fmi2Integer}, value::Array{fmi2Real})

status = fmi2GetRealOutputDerivatives!(c.fmu.cGetRealOutputDerivatives,
c.compAddr, vr, nvr, order, value)
checkStatus(c, status)
return status
end


"""
fmi2DoStep(c::FMU2Component,
currentCommunicationPoint::fmi2Real,
Expand Down Expand Up @@ -1491,7 +1514,6 @@ function fmi2GetStringStatus!(c::FMU2Component, s::fmi2StatusKind, value::fmi2St
end

# Model Exchange specific Functions
#TOD0
"""
fmi2SetTime(c::FMU2Component,
time::fmi2Real;
Expand Down Expand Up @@ -1558,19 +1580,15 @@ function fmi2SetTime(c::FMU2Component, time::fmi2Real; soft::Bool=false, track::
if status == fmi2StatusOK
c.t = time

FMICore.invalidate!(c.A)
FMICore.invalidate!(c.B)
FMICore.invalidate!(c.C)
FMICore.invalidate!(c.D)
FMICore.invalidate!(c.E)
FMICore.invalidate!(c.F)
invalidate!(c.∂ẋ_∂t)
invalidate!(c.∂y_∂t)
invalidate!(c.∂e_∂t)
end
end

return status
end

#TODO
"""
fmi2SetContinuousStates(c::FMU2Component,
x::AbstractArray{fmi2Real},
Expand Down Expand Up @@ -1618,13 +1636,11 @@ function fmi2SetContinuousStates(c::FMU2Component,

if track
if status == fmi2StatusOK
c.x = copy(x)
isnothing(c.x) ? (c.x = copy(x);) : copyto!(c.x, x)

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

FMICore.invalidate!(c.E)
FMICore.invalidate!(c.F)
invalidate!(c.∂ẋ_∂x)
invalidate!(c.∂y_∂x)
invalidate!(c.∂e_∂x)
end
end

Expand Down Expand Up @@ -1857,6 +1873,7 @@ function fmi2GetDerivatives!(c::FMU2Component,
status = fmi2GetDerivatives!(c.fmu.cGetDerivatives,
c.compAddr, derivatives, nx)
checkStatus(c, status)

return status
end

Expand Down
79 changes: 33 additions & 46 deletions src/FMI2/convert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,32 @@
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using ChainRulesCore: ignore_derivatives
import SciMLSensitivity.ForwardDiff
# ToDo: Fix this: 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)
if isa(vr, AbstractArray{fmi2ValueReference,1})
return vr
elseif tvr == fmi2ValueReference
return [vr]
elseif tvr == String
return [fmi2StringToValueReference(md, vr)]
elseif isa(vr, AbstractArray{String,1})
return fmi2StringToValueReference(md, vr)
elseif tvr == Int64
return [fmi2ValueReference(vr)]
elseif isa(vr, AbstractArray{Int64,1})
return fmi2ValueReference.(vr)
elseif tvr == Nothing
prepareValueReference(md::fmi2ModelDescription, vr::AbstractVector{fmi2ValueReference}) = vr
prepareValueReference(md::fmi2ModelDescription, vr::fmi2ValueReference) = [vr]
prepareValueReference(md::fmi2ModelDescription, vr::String) = [fmi2StringToValueReference(md, vr)]
prepareValueReference(md::fmi2ModelDescription, vr::AbstractVector{String}) = fmi2StringToValueReference(md, vr)
prepareValueReference(md::fmi2ModelDescription, vr::AbstractVector{<:Integer}) = fmi2ValueReference.(vr)
prepareValueReference(md::fmi2ModelDescription, vr::Integer) = [fmi2ValueReference(vr)]
prepareValueReference(md::fmi2ModelDescription, vr::Nothing) = fmi2ValueReference[]
function prepareValueReference(md::fmi2ModelDescription, vr::Symbol)
if vr == :states
return md.stateValueReferences
elseif vr == :derivatives
return md.derivativeValueReferences
elseif vr == :inputs
return md.inputValueReferences
elseif vr == :outputs
return md.outputValueReferences
elseif vr == :all
return md.valueReferences
elseif vr == :none
return Array{fmi2ValueReference,1}()
elseif tvr == Symbol
if vr == :states
return md.stateValueReferences
elseif vr == :derivatives
return md.derivativeValueReferences
elseif vr == :inputs
return md.inputValueReferences
elseif vr == :outputs
return md.outputValueReferences
elseif vr == :all
return md.valueReferences
elseif vr == :none
return Array{fmi2ValueReference,1}()
else
@assert false "Unknwon symbol `$vr`, can't convert to value reference."
end
else
@assert false "Unknwon symbol `$vr`, can't convert to value reference."
end

@assert false "prepareValueReference(...): Unknown value reference structure `$tvr`."
end
function prepareValueReference(fmu::FMU2, vr::fmi2ValueReferenceFormat)
prepareValueReference(fmu.modelDescription, vr)
Expand All @@ -69,16 +55,17 @@ Returns an array of ValueReferences coresponding to the variable names.
See also [`fmi2StringToValueReference`](@ref).
"""
function fmi2StringToValueReference(md::fmi2ModelDescription, names::AbstractArray{String})
vr = Array{fmi2ValueReference}(undef,0)
for name in names
reference = fmi2StringToValueReference(md, name)
if reference == nothing
@warn "Value reference for variable '$name' not found, skipping."
else
push!(vr, reference)
end
end
vr
# vr = Array{fmi2ValueReference}(undef,0)
# for name in names
# reference = fmi2StringToValueReference(md, name)
# if reference == nothing
# @warn "Value reference for variable '$name' not found, skipping."
# else
# push!(vr, reference)
# end
# end
# vr
return broadcast(fmi2StringToValueReference, (md,), names)
end

"""
Expand Down
Loading