Skip to content

Commit

Permalink
Added functions for getting FMU metadata (#17)
Browse files Browse the repository at this point in the history
* Added functions for getting inp, out, state names

* added tests for checking values

* changed fmi2GetVariableUnits to default nothing

* updated fmi2GetVariableDescriptions

* returns dict instead of list of dict

* added tests for checking units and start values

Co-authored-by: sathvikbhagavan <sathvikbhagavan@@gmail.com>
  • Loading branch information
sathvikbhagavan and sathvikbhagavan authored May 25, 2022
1 parent aa9af79 commit 94d8184
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 1 deletion.
158 changes: 158 additions & 0 deletions src/FMI2_md.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using FMICore: fmi2ModelDescriptionModelExchange, fmi2ModelDescriptionCoSimulati
using FMICore: fmi2ModelDescriptionReal, fmi2ModelDescriptionBoolean, fmi2ModelDescriptionInteger, fmi2ModelDescriptionString, fmi2ModelDescriptionEnumeration
using FMICore: fmi2ModelDescriptionModelStructure
using FMICore: fmi2DependencyKind
using FMICore: FMU2

######################################
# [Sec. 1a] fmi2LoadModelDescription #
Expand Down Expand Up @@ -761,4 +762,161 @@ Returns true, if the FMU provides directional derivatives
"""
function fmi2ProvidesDirectionalDerivative(md::fmi2ModelDescription)
return (md.coSimulation != nothing && md.coSimulation.providesDirectionalDerivative) || (md.modelExchange != nothing && md.modelExchange.providesDirectionalDerivative)
end


"""
Returns a dictionary of names to their value references
"""
function fmi2GetNamesToValueReference(md::fmi2ModelDescription)
md.stringValueReferences
end

function fmi2GetNamesToValueReference(fmu::FMU2)
fmi2GetNamesToValueReference(fmu.modelDescription)
end


"""
Returns a dictionary of value references to their names
"""
function fmi2GetValueRefenceToName(md::fmi2ModelDescription)
value_reference_to_name = Dict()
for (key, value) in md.stringValueReferences
if haskey(value_reference_to_name, value)
push!(value_reference_to_name[value], key)
else
value_reference_to_name[value] = [key]
end
end
value_reference_to_name
end

function fmi2GetValueRefenceToName(fmu::FMU2)
fmi2GetValueRefenceToName(fmu.modelDescription)
end


"""
Returns names of inputs
"""
function fmi2GetInputNames(md::fmi2ModelDescription)
value_reference_to_name = fmi2GetValueRefenceToName(md)
input_names = []
for i in md.inputValueReferences
append!(input_names, value_reference_to_name[i])
end
input_names
end

function fmi2GetInputNames(fmu::FMU2)
fmi2GetInputNames(fmu.modelDescription)
end


"""
Returns names of outputs
"""
function fmi2GetOutputNames(md::fmi2ModelDescription)
value_reference_to_name = fmi2GetValueRefenceToName(md)
output_names = []
for i in md.outputValueReferences
append!(output_names, value_reference_to_name[i])
end
output_names
end

function fmi2GetOutputNames(fmu::FMU2)
fmi2GetOutputNames(fmu.modelDescription)
end


"""
Returns names of parameters
"""
function fmi2GetParameterNames(md::fmi2ModelDescription)
value_reference_to_name = fmi2GetValueRefenceToName(md)
parameter_names = []
for i in md.parameterValueReferences
append!(parameter_names, value_reference_to_name[i])
end
parameter_names
end

function fmi2GetParameterNames(fmu::FMU2)
fmi2GetParameterNames(fmu.modelDescription)
end

"""
Returns names of states
"""
function fmi2GetStateNames(md::fmi2ModelDescription)
value_reference_to_name = fmi2GetValueRefenceToName(md)
state_names = []
for i in md.stateValueReferences
append!(state_names, value_reference_to_name[i])
end
state_names
end

function fmi2GetStateNames(fmu::FMU2)
fmi2GetStateNames(fmu.modelDescription)
end



"""
Returns names of derivatives
"""
function fmi2GetDerivateNames(md::fmi2ModelDescription)
value_reference_to_name = fmi2GetValueRefenceToName(md)
derivative_names = []
for i in md.derivativeValueReferences
for j in value_reference_to_name[i]
if startswith(j, "der(")
push!(derivative_names, j)
end
end
end
derivative_names
end

function fmi2GetDerivateNames(fmu::FMU2)
fmi2GetDerivateNames(fmu.modelDescription)
end


"""
Returns a dictionary of variables with their descriptions
"""
function fmi2GetVariableDescriptions(md::fmi2ModelDescription)
Dict(md.modelVariables[i].name => md.modelVariables[i].description for i = 1:length(md.modelVariables))
end

function fmi2GetVariableDescriptions(fmu::FMU2)
fmi2GetVariableDescriptions(fmu.modelDescription)
end


"""
Returns a dictionary of variables with their units
"""
function fmi2GetVariableUnits(md::fmi2ModelDescription)
Dict(md.modelVariables[i].name => md.modelVariables[i]._Real !== nothing ? md.modelVariables[i]._Real.unit : nothing for i = 1:length(md.modelVariables))
end

function fmi2GetVariableUnits(fmu::FMU2)
fmi2GetVariableUnits(fmu.modelDescription)
end


"""
Returns a dictionary of variables with their starting values
"""
function fmi2GetStartValues(md::fmi2ModelDescription)
Dict(md.modelVariables[i].name => md.modelVariables[i].initial for i = 1:length(md.modelVariables))
end

function fmi2GetStartValues(fmu::FMU2)
fmi2GetStartValues(fmu.modelDescription)
end
1 change: 1 addition & 0 deletions src/FMIImport.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export fmi2LoadModelDescription
export fmi2GetDefaultStartTime, fmi2GetDefaultStopTime, fmi2GetDefaultTolerance, fmi2GetDefaultStepSize
export fmi2GetModelName, fmi2GetGUID, fmi2GetGenerationTool, fmi2GetGenerationDateAndTime, fmi2GetVariableNamingConvention, fmi2GetNumberOfEventIndicators, fmi2GetNumberOfStates, fmi2IsCoSimulation, fmi2IsModelExchange
export fmi2DependenciesSupported, fmi2GetModelIdentifier, fmi2CanGetSetState, fmi2CanSerializeFMUstate, fmi2ProvidesDirectionalDerivative
export fmi2GetNamesToValueReference, fmi2GetValueRefenceToName, fmi2GetInputNames, fmi2GetOutputNames, fmi2GetParameterNames, fmi2GetStateNames, fmi2GetDerivateNames, fmi2GetVariableDescriptions, fmi2GetVariableUnits, fmi2GetStartValues

# FMI2_fmu_to_md.jl
# everything exported in `FMI2_md.jl`
Expand Down
42 changes: 41 additions & 1 deletion test/model_description.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,44 @@ myFMU.executionConfig.assertOnWarning = true
@test fmi2GetDefaultTolerance(myFMU.modelDescription) 1e-4
@test fmi2GetDefaultStepSize(myFMU.modelDescription) === nothing

fmi2Unload(myFMU)
@test length(fmi2GetNamesToValueReference(myFMU.modelDescription)) == 50
@test length(fmi2GetNamesToValueReference(myFMU)) == 50

@test length(fmi2GetValueRefenceToName(myFMU.modelDescription)) == 42
@test length(fmi2GetValueRefenceToName(myFMU)) == 42

@test length(fmi2GetInputNames(myFMU.modelDescription)) == 0
@test length(fmi2GetInputNames(myFMU)) == 0

@test length(fmi2GetOutputNames(myFMU.modelDescription)) == 0
@test length(fmi2GetOutputNames(myFMU)) == 0

@test length(fmi2GetParameterNames(myFMU.modelDescription)) == 0
@test length(fmi2GetParameterNames(myFMU)) == 0

@test length(fmi2GetStateNames(myFMU.modelDescription)) == 3
@test length(fmi2GetStateNames(myFMU)) == 3
@test fmi2GetStateNames(myFMU) == ["mass.s", "mass.v", "mass.v_relfric"]

@test length(fmi2GetDerivateNames(myFMU.modelDescription)) == 2
@test length(fmi2GetDerivateNames(myFMU)) == 2
@test fmi2GetDerivateNames(myFMU) == ["der(mass.s)", "der(mass.v)"]

@test length(fmi2GetVariableDescriptions(myFMU.modelDescription)) == 50
@test length(fmi2GetVariableDescriptions(myFMU)) == 50


@test length(fmi2GetVariableUnits(myFMU.modelDescription)) == 50
@test length(fmi2GetVariableUnits(myFMU)) == 50
@test fmi2GetVariableUnits(myFMU)["der(mass.s)"] == "m/s"
@test fmi2GetVariableUnits(myFMU)["mass.F_prop"] == "N.s/m"
@test fmi2GetVariableUnits(myFMU)["mass.fexp"] == "s/m"
@test fmi2GetVariableUnits(myFMU)["der(mass.v)"] == "m/s2"

@test length(fmi2GetStartValues(myFMU.modelDescription)) == 50
@test length(fmi2GetStartValues(myFMU)) == 50
@test fmi2GetStartValues(myFMU)["mass.startForward"] == 0
@test fmi2GetStartValues(myFMU)["mass.startBackward"] == 0
@test fmi2GetStartValues(myFMU)["mass.locked"] == 1

fmi2Unload(myFMU)
46 changes: 46 additions & 0 deletions test/model_description_io.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using FMIImport.FMICore: fmi2VariableNamingConventionStructured

myFMU = fmi2Load("IO", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"])
myFMU.executionConfig.assertOnWarning = true

@test length(fmi2GetNamesToValueReference(myFMU.modelDescription)) == 11
@test length(fmi2GetNamesToValueReference(myFMU)) == 11

@test length(fmi2GetValueRefenceToName(myFMU.modelDescription)) == 11
@test length(fmi2GetValueRefenceToName(myFMU)) == 11

@test length(fmi2GetInputNames(myFMU.modelDescription)) == 3
@test length(fmi2GetInputNames(myFMU)) == 3
@test fmi2GetInputNames(myFMU.modelDescription) == ["u_real", "u_boolean", "u_integer"]
@test fmi2GetInputNames(myFMU) == ["u_real", "u_boolean", "u_integer"]

@test length(fmi2GetOutputNames(myFMU.modelDescription)) == 3
@test length(fmi2GetOutputNames(myFMU)) == 3
@test fmi2GetOutputNames(myFMU.modelDescription) == ["y_real", "y_boolean", "y_integer"]
@test fmi2GetOutputNames(myFMU) == ["y_real", "y_boolean", "y_integer"]

@test length(fmi2GetParameterNames(myFMU.modelDescription)) == 0
@test length(fmi2GetParameterNames(myFMU)) == 0

@test length(fmi2GetStateNames(myFMU.modelDescription)) == 0
@test length(fmi2GetStateNames(myFMU)) == 0

@test length(fmi2GetDerivateNames(myFMU.modelDescription)) == 0
@test length(fmi2GetDerivateNames(myFMU)) == 0

@test length(fmi2GetVariableDescriptions(myFMU.modelDescription)) == 11
@test length(fmi2GetVariableDescriptions(myFMU)) == 11

@test length(fmi2GetVariableUnits(myFMU.modelDescription)) == 11
@test length(fmi2GetVariableUnits(myFMU)) == 11

@test length(fmi2GetStartValues(myFMU.modelDescription)) == 11
@test length(fmi2GetStartValues(myFMU)) == 11


fmi2Unload(myFMU)

0 comments on commit 94d8184

Please sign in to comment.