Skip to content

Commit

Permalink
Remove check from fmi3GetAdjointDerivative! (#74)
Browse files Browse the repository at this point in the history
* add eventIndicatorValueReferences to ModelDescription stuct

* Update Project.toml

* remove wrong redundant check

* formatting

* Update Project.toml

---------

Co-authored-by: ThummeTo <[email protected]>
  • Loading branch information
halentin and ThummeTo authored Sep 17, 2024
1 parent e23fa7a commit 73dbcb4
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 120 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "FMICore"
uuid = "8af89139-c281-408e-bce2-3005eb87462f"
authors = ["TT <[email protected]>", "LM <[email protected]>", "JK <[email protected]>"]
version = "1.1.0"
version = "1.1.1"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
21 changes: 16 additions & 5 deletions src/FMI2/cfunc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,22 @@ Source: FMISpec2.0.2[p.22]: 2.1.5 Creation, Destruction and Logging of FMU Insta
The function controls debug logging that is output via the logger function callback. If loggingOn = fmi2True, debug logging is enabled, otherwise it is switched off.
"""
function fmi2SetDebugLogging(cfunc::Ptr{Cvoid}, c::fmi2Component, loggingOn::fmi2Boolean, nCategories::Csize_t, categories::Union{Ptr{fmi2String}, AbstractArray{fmi2String}})
status = ccall(cfunc,
fmi2Status,
(fmi2Component, fmi2Boolean, Csize_t, Ptr{fmi2String}),
c, loggingOn, nCategories, categories)
function fmi2SetDebugLogging(
cfunc::Ptr{Cvoid},
c::fmi2Component,
loggingOn::fmi2Boolean,
nCategories::Csize_t,
categories::Union{Ptr{fmi2String},AbstractArray{fmi2String}},
)
status = ccall(
cfunc,
fmi2Status,
(fmi2Component, fmi2Boolean, Csize_t, Ptr{fmi2String}),
c,
loggingOn,
nCategories,
categories,
)
@debug "fmi2SetDebugLogging(c: $(c), loggingOn: $(loggingOn), nCategories: $(nCategories), categories: $(categories)) → $(status)"
return status
end
Expand Down
4 changes: 1 addition & 3 deletions src/FMI3/cfunc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1682,9 +1682,7 @@ function fmi3GetAdjointDerivative!(
sensitivity::AbstractArray{fmi3Float64},
nSensitivity::Csize_t,
)::fmi3Status
@assert fmi3ProvidesAdjointDerivatives(c.fmu) [
"fmi3GetAdjointDerivative!(...): This FMU does not support build-in adjoint derivatives!",
]

status = ccall(
cfunc,
fmi3Status,
Expand Down
129 changes: 105 additions & 24 deletions test/FMI2/CS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,149 @@
using Libdl, Suppressor

function test_CS(lib, cblibpath)
component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_cs"), fmi2TypeCoSimulation, pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))

component = fmi2Instantiate(
dlsym(lib, :fmi2Instantiate),
pointer("test_cs"),
fmi2TypeCoSimulation,
pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"),
pointer("file:///"),
Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))),
fmi2Boolean(false),
fmi2Boolean(false),
)

startpoint = fmi2Real(0.0)
@test fmi2StatusOK == fmi2SetupExperiment(dlsym(lib, :fmi2SetupExperiment),component, fmi2Boolean(true), fmi2Real(0.01), startpoint, fmi2Boolean(false), fmi2Real(1.0))
@test fmi2StatusOK == fmi2SetupExperiment(
dlsym(lib, :fmi2SetupExperiment),
component,
fmi2Boolean(true),
fmi2Real(0.01),
startpoint,
fmi2Boolean(false),
fmi2Real(1.0),
)



fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)
if Sys.WORD_SIZE == 64
@test fmi2StatusOK == fmi2DoStep(dlsym(lib, :fmi2DoStep), component, fmi2Real(0.0), fmi2Real(0.01), fmi2False)
@test fmi2StatusOK == fmi2DoStep(
dlsym(lib, :fmi2DoStep),
component,
fmi2Real(0.0),
fmi2Real(0.01),
fmi2False,
)
end


status = fmi2Real(0.0)
statusptr = pointer([status])
@test fmi2StatusOK == fmi2GetRealStatus!(dlsym(lib, :fmi2GetRealStatus), component, fmi2StatusKindLastSuccessfulTime, Ptr{fmi2Real}(statusptr))
@test fmi2StatusOK == fmi2GetRealStatus!(
dlsym(lib, :fmi2GetRealStatus),
component,
fmi2StatusKindLastSuccessfulTime,
Ptr{fmi2Real}(statusptr),
)

@suppress begin
# Suppressing the IllegalFunctionCall Warnings, as they are expected here
# Suppressing the IllegalFunctionCall Warnings, as they are expected here
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
status = fmi2Status(fmi2StatusOK)
statusptr = pointer([status])
@test fmi2StatusDiscard == fmi2GetStatus!(dlsym(lib, :fmi2GetStatus), component, fmi2StatusKindDoStepStatus, Ptr{fmi2Status}(statusptr))


@test fmi2StatusDiscard == fmi2GetStatus!(
dlsym(lib, :fmi2GetStatus),
component,
fmi2StatusKindDoStepStatus,
Ptr{fmi2Status}(statusptr),
)


status = fmi2Integer(0)
statusptr = pointer([status])
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetIntegerStatus!(dlsym(lib, :fmi2GetIntegerStatus), component, Cuint(2), Ptr{fmi2Integer}(statusptr))

@test fmi2StatusDiscard == fmi2GetIntegerStatus!(
dlsym(lib, :fmi2GetIntegerStatus),
component,
Cuint(2),
Ptr{fmi2Integer}(statusptr),
)

status = fmi2Boolean(false)
statusptr = pointer([status])
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetBooleanStatus!(dlsym(lib, :fmi2GetBooleanStatus), component, Cuint(2), Ptr{fmi2Boolean}(statusptr))
@test fmi2StatusDiscard == fmi2GetBooleanStatus!(
dlsym(lib, :fmi2GetBooleanStatus),
component,
Cuint(2),
Ptr{fmi2Boolean}(statusptr),
)

status = "test"
statusptr = pointer(status)
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetStringStatus!(dlsym(lib, :fmi2GetStringStatus), component, Cuint(2), Ptr{fmi2String}(statusptr))
@test fmi2StatusDiscard == fmi2GetStringStatus!(
dlsym(lib, :fmi2GetStringStatus),
component,
Cuint(2),
Ptr{fmi2String}(statusptr),
)
end

fmi2Terminate(dlsym(lib, :fmi2Terminate), component)

end

function test_CS_IO(lib, cblibpath)
component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_generic_io"), fmi2TypeCoSimulation, pointer("{95a6399d-38c5-4504-b3f3-98319bd94ce6}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))
component = fmi2Instantiate(
dlsym(lib, :fmi2Instantiate),
pointer("test_generic_io"),
fmi2TypeCoSimulation,
pointer("{95a6399d-38c5-4504-b3f3-98319bd94ce6}"),
pointer("file:///"),
Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))),
fmi2Boolean(false),
fmi2Boolean(false),
)
@test component != C_NULL
@test fmi2StatusOK == fmi2SetupExperiment(dlsym(lib, :fmi2SetupExperiment),component, fmi2Boolean(false), fmi2Real(0.0), fmi2Real(0.0), fmi2Boolean(false), fmi2Real(1.0))
@test fmi2StatusOK == fmi2SetupExperiment(
dlsym(lib, :fmi2SetupExperiment),
component,
fmi2Boolean(false),
fmi2Real(0.0),
fmi2Real(0.0),
fmi2Boolean(false),
fmi2Real(1.0),
)

@test fmi2StatusOK == fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
@test fmi2StatusOK == fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)
@test fmi2StatusOK ==
fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
@test fmi2StatusOK ==
fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)


fmireference = [fmi2ValueReference(352321536)]
@test fmi2StatusOK == fmi2SetRealInputDerivatives(dlsym(lib, :fmi2SetRealInputDerivatives), component, fmireference, Csize_t(1), [fmi2Integer(1)], fmi2Real.([1.0]))
@test fmi2StatusOK == fmi2SetRealInputDerivatives(
dlsym(lib, :fmi2SetRealInputDerivatives),
component,
fmireference,
Csize_t(1),
[fmi2Integer(1)],
fmi2Real.([1.0]),
)

fmireference = [fmi2ValueReference(335544320)]
values = zeros(fmi2Real, 1)
@test fmi2StatusOK == fmi2GetRealOutputDerivatives!(dlsym(lib, :fmi2GetRealOutputDerivatives), component, fmireference, Csize_t(1), [fmi2Integer(1)], values)
@test fmi2StatusOK == fmi2GetRealOutputDerivatives!(
dlsym(lib, :fmi2GetRealOutputDerivatives),
component,
fmireference,
Csize_t(1),
[fmi2Integer(1)],
values,
)




end

end
69 changes: 56 additions & 13 deletions test/FMI2/ME.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,93 @@
using Libdl

function test_ME(lib, cblibpath)
component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_me"), fmi2TypeModelExchange, pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))
component = fmi2Instantiate(
dlsym(lib, :fmi2Instantiate),
pointer("test_me"),
fmi2TypeModelExchange,
pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"),
pointer("file:///"),
Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))),
fmi2Boolean(false),
fmi2Boolean(false),
)
@test component != C_NULL

fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)

@test fmi2StatusOK == fmi2EnterEventMode(dlsym(lib, :fmi2Instantiate), component)

eventInfo = fmi2EventInfo()
eventInfo = fmi2EventInfo()
ptr = Ptr{fmi2EventInfo}(pointer_from_objref(eventInfo))

@test fmi2StatusOK == fmi2NewDiscreteStates!(dlsym(lib, :fmi2NewDiscreteStates), component, ptr)

@test fmi2StatusOK == fmi2EnterContinuousTimeMode(dlsym(lib, :fmi2EnterContinuousTimeMode), component)
@test fmi2StatusOK ==
fmi2NewDiscreteStates!(dlsym(lib, :fmi2NewDiscreteStates), component, ptr)

@test fmi2StatusOK ==
fmi2EnterContinuousTimeMode(dlsym(lib, :fmi2EnterContinuousTimeMode), component)

enterEventMode = fmi2Boolean(false)
terminateSimulation = fmi2Boolean(false)
@test fmi2StatusOK == fmi2CompletedIntegratorStep!(dlsym(lib, :fmi2CompletedIntegratorStep), component, fmi2Boolean(false), pointer([enterEventMode]), pointer([terminateSimulation]))
@test fmi2StatusOK == fmi2CompletedIntegratorStep!(
dlsym(lib, :fmi2CompletedIntegratorStep),
component,
fmi2Boolean(false),
pointer([enterEventMode]),
pointer([terminateSimulation]),
)

@test fmi2StatusOK == fmi2SetTime(dlsym(lib, :fmi2SetTime), component, fmi2Real(0.0))

n_states = Csize_t(2)
state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetContinuousStates!(dlsym(lib, :fmi2GetContinuousStates), component,state_arr, n_states)
@test fmi2StatusOK == fmi2GetContinuousStates!(
dlsym(lib, :fmi2GetContinuousStates),
component,
state_arr,
n_states,
)

state_arr[2] = 2.0
@test fmi2StatusOK == fmi2SetContinuousStates(dlsym(lib, :fmi2SetContinuousStates), component,state_arr, n_states)
@test fmi2StatusOK == fmi2SetContinuousStates(
dlsym(lib, :fmi2SetContinuousStates),
component,
state_arr,
n_states,
)

state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetContinuousStates!(dlsym(lib, :fmi2GetContinuousStates), component,state_arr, n_states)
@test fmi2StatusOK == fmi2GetContinuousStates!(
dlsym(lib, :fmi2GetContinuousStates),
component,
state_arr,
n_states,
)
@test state_arr[2] == 2.0

n_indicators = Csize_t(2)
indicator_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetEventIndicators!(dlsym(lib, :fmi2GetEventIndicators), component,indicator_arr, n_indicators)
@test fmi2StatusOK == fmi2GetEventIndicators!(
dlsym(lib, :fmi2GetEventIndicators),
component,
indicator_arr,
n_indicators,
)

nom_state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetNominalsOfContinuousStates!(dlsym(lib, :fmi2GetNominalsOfContinuousStates), component, nom_state_arr, n_states)
@test fmi2StatusOK == fmi2GetNominalsOfContinuousStates!(
dlsym(lib, :fmi2GetNominalsOfContinuousStates),
component,
nom_state_arr,
n_states,
)

der_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetDerivatives!(dlsym(lib, :fmi2GetDerivatives), component,der_arr, n_states)
@test fmi2StatusOK ==
fmi2GetDerivatives!(dlsym(lib, :fmi2GetDerivatives), component, der_arr, n_states)
# Acceleration should be equal to Gravity in this FMU
if Sys.WORD_SIZE == 64
# on 32 Bit this returns 9.81 * 10^16 which is not equal to -9.81
# on 32 Bit this returns 9.81 * 10^16 which is not equal to -9.81
@test der_arr[2] -9.81
end

Expand Down
30 changes: 22 additions & 8 deletions test/FMI2/cfunc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,27 @@ if binarypath != ""
lib = dlopen(binarypath)
libio = dlopen(iopath)
# Missing Tests for fmi2<Set, Get><Boolean, String> because the FMU we are testing with doesnt variables of these types
@testset "Generic Functions in ME Mode" begin test_generic(lib,cblibpath, fmi2TypeModelExchange) end
@testset "Generic Functions in ME Mode with IO FMU" begin test_generic_io(libio,iocblibpath, fmi2TypeModelExchange) end
@testset "Generic Functions in CS Mode with IO FMU" begin test_generic_io(libio,iocblibpath, fmi2TypeCoSimulation) end
@testset "Generic Functions in CS Mode" begin test_generic(lib,cblibpath, fmi2TypeCoSimulation) end
@testset "ME-specific Functions" begin test_ME(lib, cblibpath) end
@testset "CS-specific Functions" begin test_CS(lib, cblibpath) end
@testset "CS-specific Functions with IO FMU" begin test_CS_IO(libio, iocblibpath) end
@testset "Generic Functions in ME Mode" begin
test_generic(lib, cblibpath, fmi2TypeModelExchange)
end
@testset "Generic Functions in ME Mode with IO FMU" begin
test_generic_io(libio, iocblibpath, fmi2TypeModelExchange)
end
@testset "Generic Functions in CS Mode with IO FMU" begin
test_generic_io(libio, iocblibpath, fmi2TypeCoSimulation)
end
@testset "Generic Functions in CS Mode" begin
test_generic(lib, cblibpath, fmi2TypeCoSimulation)
end
@testset "ME-specific Functions" begin
test_ME(lib, cblibpath)
end
@testset "CS-specific Functions" begin
test_CS(lib, cblibpath)
end
@testset "CS-specific Functions with IO FMU" begin
test_CS_IO(libio, iocblibpath)
end
else
@warn "No valid FMU binaries found for this OS. Skipping tests."
end
end
Loading

2 comments on commit 73dbcb4

@ThummeTo
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/115335

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.1 -m "<description of version>" 73dbcb4d1f4b0a5d736bae1ce69d354554648de3
git push origin v1.1.1

Please sign in to comment.