Skip to content

Commit

Permalink
Merge pull request #87 from dnv-opensource/fix/86-outputs-in-generate…
Browse files Browse the repository at this point in the history
…d-model-description

Fix outputs in generated `modelDescription.xml`
  • Loading branch information
StephanieKemna authored Dec 19, 2024
2 parents b716bf3 + e35f12c commit 6a42062
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 11 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
All notable changes to the [mlfmu] project will be documented in this file.<br>
The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

### Changed

* Generation of modelDescription.xml file to correctly generate tags for each output with 1-indexed indexes and InitialUnknowns tags
* Generation of modelDescription.xml adds the variables (inputs, parameters and outputs) in the orderer of their valueReference. This is for the indexing to work correctly

## [1.0.2]

### Changed
Expand Down
18 changes: 15 additions & 3 deletions src/mlfmu/utils/fmi_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,16 @@ def generate_model_description(fmu_model: FmiModel) -> ElementTree:
# <ModelStructure> tag with <Outputs> tab inside --> Append all outputs
model_structure = SubElement(root, "ModelStructure")
outputs = SubElement(model_structure, "Outputs")
initial_unknowns = SubElement(model_structure, "InitialUnknowns")

for var in fmu_model.get_fmi_model_variables():
# Get all variables to add them inside the <ModelVariables> tag
model_variables = fmu_model.get_fmi_model_variables()

# The variables needs to be added in the order of their valueReference
sorted_model_variables = sorted(model_variables, key=lambda x: x.variable_reference)

# Add each variable inside the <ModelVariables> tag
for var in sorted_model_variables:
# XML variable attributes
var_attrs = {
"name": var.name,
Expand All @@ -95,9 +103,13 @@ def generate_model_description(fmu_model: FmiModel) -> ElementTree:
# FMI variable type element
_ = SubElement(var_elem, var.type.value.capitalize(), var_type_attrs)

# Appending output to <Outputs> inside <ModelStructure>
# Adding outputs inside <ModelStructure>
if var.causality == FmiCausality.OUTPUT:
_ = SubElement(outputs, "Unknown", {"index": str(var.variable_reference)})
# Index is 1-indexed for <Unknown> tag
unknown_attributes = {"index": str(var.variable_reference + 1)}
# For each output create an <Unknown> tag inside both <Outputs> and <InitialUnknowns>
_ = SubElement(outputs, "Unknown", unknown_attributes)
_ = SubElement(initial_unknowns, "Unknown", unknown_attributes)

# Create XML tree containing root element and pretty format its contents
xml_tree = ElementTree(root)
Expand Down
18 changes: 10 additions & 8 deletions tests/utils/test_modelDescription_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ def test_generate_model_description_with_internal_state_params():
variables = xml_structure.findall(".//ScalarVariable")

assert xml_structure.getroot().tag == "fmiModelDescription"
assert variables[0].attrib["name"] == "state1"
assert variables[0].attrib["causality"] == "parameter"
assert variables[0][0].tag == "Real"
assert variables[0][0].attrib["start"] == "0.0"

assert variables[1].attrib["name"] == "output1"
assert variables[1].attrib["causality"] == "output"
assert variables[0].attrib["name"] == "output1"
assert variables[0].attrib["causality"] == "output"

assert variables[1].attrib["name"] == "state1"
assert variables[1].attrib["causality"] == "parameter"
assert variables[1][0].tag == "Real"
assert variables[1][0].attrib["start"] == "0.0"


def test_generate_vector_ports():
Expand Down Expand Up @@ -193,5 +194,6 @@ def test_generate_model_description_output():
output_variables = [var for var in variables if var.attrib.get("causality") == "output"]
outputs_registered = xml_structure.findall(".//Outputs/Unknown")

assert output_variables[0].attrib["valueReference"] == outputs_registered[0].attrib["index"]
assert output_variables[1].attrib["valueReference"] == outputs_registered[1].attrib["index"]
# The index should be the valueReference + 1
assert int(output_variables[0].attrib["valueReference"]) + 1 == int(outputs_registered[0].attrib["index"])
assert int(output_variables[1].attrib["valueReference"]) + 1 == int(outputs_registered[1].attrib["index"])

0 comments on commit 6a42062

Please sign in to comment.