From e50c99d455b893d4e626e2ea558d396cf3f0b180 Mon Sep 17 00:00:00 2001 From: Lars Ivar Hatledal Date: Thu, 26 Sep 2019 22:53:46 +0200 Subject: [PATCH] Use enums and add test --- .../modeldescription/fmi2/Fmi2Causality.java | 56 +++ .../modeldescription/fmi2/Fmi2Initial.java | 28 ++ .../fmi2/Fmi2ScalarVariable.java | 43 +- .../fmi2/Fmi2Variability.java | 45 ++ .../fmi2/FmiModelDescription.java | 4 + .../fmi2/TestFmiModeldescription.java | 31 ++ .../modelDescription.xml | 386 ++++++++++++++++++ .../fmi2/JaxbScalarVariable.kt | 13 +- 8 files changed, 575 insertions(+), 31 deletions(-) create mode 100644 fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Causality.java create mode 100644 fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Initial.java create mode 100644 fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Variability.java create mode 100644 fmi-md/src/test/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/TestFmiModeldescription.java create mode 100644 fmi-md/src/test/resources/fmi2/ControlledTemperature/modelDescription.xml diff --git a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Causality.java b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Causality.java new file mode 100644 index 00000000..4f9021b3 --- /dev/null +++ b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Causality.java @@ -0,0 +1,56 @@ +package no.ntnu.ihb.fmi4j.modeldescription.fmi2; + +public enum Fmi2Causality { + + /** + * Independent parameter (a data value that is constant during the + * simulation and is provided by the environment and cannot be used in + * connections). variability must be "fixed" or "tunable". initial must be + * exact or not present (meaning exact). + */ + parameter, + + /** + * A data value that is constant during the simulation and is computed + * during initialization or when tunable parameters change. variability must + * be "fixed" or "tunable". initial must be "approx", "calculated" or not + * present (meaning calculated). + */ + calculated_parameter, + + /** + * The variable value can be provided from another model or slave. It is not + * allowed to define initial. + */ + input, + + /** + * The variable value can be used by another model or slave. The algebraic + * relationship to the inputs is defined via the dependencies attribute of + * . + */ + output, + + /** + * Local variable that is calculated from other categories or is a + * continuous time state (see section 2.2.8). It is not allowed to use the + * variable value in another model or slave. + */ + local, + + /** + * The independent variable (usually "time"). All variables are a + * function of this independent variable. variability must be "continuous". At + * most one ScalarVariable of an FMU can be defined as "independent". If no + * variable is defined as "independent", it is implicitly present with name = "time" + * and unit = "s". If one variable is defined as "independent", it must be defined as + * "Real" without a "start" attribute. It is not allowed to call function fmi2SetReal + * on an "independent" variable. Instead, its value is initialized with + * fmi2SetupExperiment and after initialization set by fmi2SetTime for + * ModelExchange and by arguments currentCommunicationPoint and + * communicationStepSize of fmi2DoStep for CoSimulation. [The actual value can + * be inquired with fmi2GetReal.] + */ + independent; + +} diff --git a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Initial.java b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Initial.java new file mode 100644 index 00000000..be1019ca --- /dev/null +++ b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Initial.java @@ -0,0 +1,28 @@ +package no.ntnu.ihb.fmi4j.modeldescription.fmi2; + +public enum Fmi2Initial { + + /** + * The variable is initialized with the start value (provided under Real, + * Integer, Boolean, String or Enumeration). + */ + exact, + + /** + * The variable is an iteration variable of an algebraic loop and the + * iteration at initialization starts with the start value. + */ + approx, + + /** + * The variable is calculated from other categories during initialization. It + * is not allowed to provide a "start" value. + */ + calculated, + + /** + * Undefined unknown + */ + undefined; + +} diff --git a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2ScalarVariable.java b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2ScalarVariable.java index 900558b2..0614ca27 100644 --- a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2ScalarVariable.java +++ b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2ScalarVariable.java @@ -155,14 +155,11 @@ public class Fmi2ScalarVariable { @XmlAttribute(name = "description") protected java.lang.String description; @XmlAttribute(name = "causality") - @XmlJavaTypeAdapter(NormalizedStringAdapter.class) - protected java.lang.String causality; + protected Fmi2Causality causality; @XmlAttribute(name = "variability") - @XmlJavaTypeAdapter(NormalizedStringAdapter.class) - protected java.lang.String variability; + protected Fmi2Variability variability; @XmlAttribute(name = "initial") - @XmlJavaTypeAdapter(NormalizedStringAdapter.class) - protected java.lang.String initial; + protected Fmi2Initial initial; @XmlAttribute(name = "canHandleMultipleSetPerTimeInstant") protected java.lang.Boolean canHandleMultipleSetPerTimeInstant; @@ -379,12 +376,12 @@ public void setDescription(java.lang.String value) { * * @return * possible object is - * {@link java.lang.String } + * {@link Fmi2Causality } * */ - public java.lang.String getCausality() { + public Fmi2Causality getCausality() { if (causality == null) { - return "local"; + return Fmi2Causality.local; } else { return causality; } @@ -395,10 +392,10 @@ public java.lang.String getCausality() { * * @param value * allowed object is - * {@link java.lang.String } + * {@link Fmi2Causality } * */ - public void setCausality(java.lang.String value) { + public void setCausality(Fmi2Causality value) { this.causality = value; } @@ -407,12 +404,12 @@ public void setCausality(java.lang.String value) { * * @return * possible object is - * {@link java.lang.String } + * {@link Fmi2Variability } * */ - public java.lang.String getVariability() { + public Fmi2Variability getVariability() { if (variability == null) { - return "continuous"; + return Fmi2Variability.continuous; } else { return variability; } @@ -423,10 +420,10 @@ public java.lang.String getVariability() { * * @param value * allowed object is - * {@link java.lang.String } + * {@link Fmi2Variability } * */ - public void setVariability(java.lang.String value) { + public void setVariability(Fmi2Variability value) { this.variability = value; } @@ -435,11 +432,15 @@ public void setVariability(java.lang.String value) { * * @return * possible object is - * {@link java.lang.String } + * {@link Fmi2Initial } * */ - public java.lang.String getInitial() { - return initial; + public Fmi2Initial getInitial() { + if (initial == null) { + return Fmi2Initial.undefined; + } else { + return initial; + } } /** @@ -447,10 +448,10 @@ public java.lang.String getInitial() { * * @param value * allowed object is - * {@link java.lang.String } + * {@link Fmi2Initial } * */ - public void setInitial(java.lang.String value) { + public void setInitial(Fmi2Initial value) { this.initial = value; } diff --git a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Variability.java b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Variability.java new file mode 100644 index 00000000..d28581aa --- /dev/null +++ b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/Fmi2Variability.java @@ -0,0 +1,45 @@ +package no.ntnu.ihb.fmi4j.modeldescription.fmi2; + +public enum Fmi2Variability { + + /** + * The value of the variable never changes. + */ + constant, + + /** + * The value of the variable is fixed after initialization, in other words + * after fmi2ExitInitializationMode was called the variable value does not + * change anymore. + */ + fixed, + + /** + * The value of the variable is constant between external events + * (ModelExchange) and between Communication Points (CoSimulation) due to + * changing categories with causality = "parameter" or "input" and + * variability = "tunable". Whenever a parameter or input signal with + * variability = "tunable" changes, then an event is triggered externally + * (ModelExchange) or the change is performed at the next Communication + * Point (CoSimulation) and the categories with variability = "tunable" and + * causality = "calculatedParameter" or "output" must be newly computed. + */ + tunable, + + /** + * ModelExchange: The value of the variable is constant between external and + * internal events (= time, state, step events defined implicitly in the + * FMU). CoSimulation: By convention, the variable is from a "realAttribute" sampled + * data system and its value is only changed at Communication Points (also + * inside the slave). + */ + discrete, + + /** + * Only a variable of type = "Real" can be "continuous". ModelExchange: No + * restrictions on value changes. CoSimulation: By convention, the variable + * is from a differential + */ + continuous; + +} diff --git a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/FmiModelDescription.java b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/FmiModelDescription.java index 8b9afa02..f8c44e08 100644 --- a/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/FmiModelDescription.java +++ b/fmi-md/src/main/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/FmiModelDescription.java @@ -319,6 +319,10 @@ public CoSimulation getCoSimulation() { return this.coSimulation; } + public void setCoSimulation(CoSimulation coSimulation) { + this.coSimulation = coSimulation; + } + /** * Gets the value of the unitDefinitions property. * diff --git a/fmi-md/src/test/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/TestFmiModeldescription.java b/fmi-md/src/test/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/TestFmiModeldescription.java new file mode 100644 index 00000000..e6a91a5d --- /dev/null +++ b/fmi-md/src/test/java/no/ntnu/ihb/fmi4j/modeldescription/fmi2/TestFmiModeldescription.java @@ -0,0 +1,31 @@ +package no.ntnu.ihb.fmi4j.modeldescription.fmi2; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.xml.bind.JAXB; + +public class TestFmiModeldescription { + + private static FmiModelDescription md; + + @BeforeAll + static void setup() { + md = JAXB.unmarshal(TestFmiModeldescription.class.getClassLoader() + .getResource("fmi2/ControlledTemperature/modelDescription.xml"), FmiModelDescription.class); + } + + @Test + void testCausality() { + Fmi2ScalarVariable var1 = md.getModelVariables().getScalarVariable().stream().filter(v -> v.valueReference == 0).findFirst().get(); + Assertions.assertEquals(Fmi2Causality.parameter, var1.causality); + } + + @Test + void testVariability() { + Fmi2ScalarVariable var = md.getModelVariables().getScalarVariable().stream().filter(v -> v.valueReference == 18).findFirst().get(); + Assertions.assertEquals(Fmi2Variability.fixed, var.variability); + } + +} diff --git a/fmi-md/src/test/resources/fmi2/ControlledTemperature/modelDescription.xml b/fmi-md/src/test/resources/fmi2/ControlledTemperature/modelDescription.xml new file mode 100644 index 00000000..c371fca4 --- /dev/null +++ b/fmi-md/src/test/resources/fmi2/ControlledTemperature/modelDescription.xml @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fmi-model/src/main/kotlin/no/ntnu/ihb/fmi4j/modeldescription/fmi2/JaxbScalarVariable.kt b/fmi-model/src/main/kotlin/no/ntnu/ihb/fmi4j/modeldescription/fmi2/JaxbScalarVariable.kt index 3deaddaf..e1553fc6 100644 --- a/fmi-model/src/main/kotlin/no/ntnu/ihb/fmi4j/modeldescription/fmi2/JaxbScalarVariable.kt +++ b/fmi-model/src/main/kotlin/no/ntnu/ihb/fmi4j/modeldescription/fmi2/JaxbScalarVariable.kt @@ -37,18 +37,11 @@ class JaxbScalarVariable internal constructor( override val description: String? get() = v.description override val causality: Causality? - get() = v.causality?.let { - var causalityString = it - val upperCaseIndex = it.indexOfFirst { it.isUpperCase() } - if (upperCaseIndex != -1) { - causalityString = causalityString.substring(0, upperCaseIndex) + "_" + causalityString.substring(upperCaseIndex, causalityString.length) - } - Causality.valueOf(causalityString.toUpperCase()) - } + get() = v.causality?.let { Causality.valueOf(it.name.toUpperCase()) } override val variability: Variability? - get() = v.variability?.let { Variability.valueOf(it.toUpperCase()) } + get() = v.variability?.let { Variability.valueOf(it.name.toUpperCase()) } override val initial: Initial? - get() = v.initial?.let { Initial.valueOf(it.toUpperCase()) } + get() = v.initial?.let { Initial.valueOf(it.name.toUpperCase()) } /** * Return a typed version of this variable.