diff --git a/include/fmi4cpp/fmi2/xml/model_description.hpp b/include/fmi4cpp/fmi2/xml/model_description.hpp index 1474992..a9f4792 100644 --- a/include/fmi4cpp/fmi2/xml/model_description.hpp +++ b/include/fmi4cpp/fmi2/xml/model_description.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ struct model_description_base std::shared_ptr model_structure; std::optional default_experiment; + std::optional unit_definitions; size_t number_of_event_indicators; [[nodiscard]] size_t number_of_continuous_states() const; diff --git a/include/fmi4cpp/fmi2/xml/unit_definitions.hpp b/include/fmi4cpp/fmi2/xml/unit_definitions.hpp new file mode 100644 index 0000000..14b1df6 --- /dev/null +++ b/include/fmi4cpp/fmi2/xml/unit_definitions.hpp @@ -0,0 +1,54 @@ +/* + * File Name: unit_definitions.h + * Description: Defines structures for handling physical units and their conversions, including base units, display units, and unit definitions. + * Author: weilong.wen + * Email: weilong.wen.mail@gmail.com + * Created: 2025-02-03 + */ + +#ifndef FMI4CPP_UNITDEFINITIONS_HPP +#define FMI4CPP_UNITDEFINITIONS_HPP + +#include +#include +#include + +namespace fmi4cpp::fmi2 +{ + +struct base_unit +{ + std::optional kg = 0; + std::optional m = 0; + std::optional s = 0; + std::optional A = 0; + std::optional K = 0; + std::optional mol = 0; + std::optional cd = 0; + std::optional rad = 0; + std::optional factor = 1.0; + std::optional offset = 0.0; +}; + +struct display_unit +{ + std::string name; + double factor = 1.0; + double offset = 0.0; +}; + +struct unit +{ + std::string name; + base_unit base_unit; + std::vector display_units; +}; + +struct unit_definitions +{ + std::vector units; +}; + +} // namespace fmi4cpp::fmi2 + +#endif // FMI4CPP_UNITDEFINITIONS_HPP diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d087f8..2806919 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,6 +33,7 @@ set(publicHeaders "fmi4cpp/fmi2/xml/enums.hpp" "fmi4cpp/fmi2/xml/source_files.hpp" + "fmi4cpp/fmi2/xml/unit_definitions.hpp" "fmi4cpp/fmi2/xml/default_experiment.hpp" "fmi4cpp/fmi2/xml/fmu_attributes.hpp" diff --git a/src/fmi4cpp/fmi2/xml/model_description_parser.cpp b/src/fmi4cpp/fmi2/xml/model_description_parser.cpp index ad9902e..ec4db1a 100644 --- a/src/fmi4cpp/fmi2/xml/model_description_parser.cpp +++ b/src/fmi4cpp/fmi2/xml/model_description_parser.cpp @@ -148,6 +148,59 @@ std::unique_ptr parse_model_structure(const pugi::xml_nod return std::make_unique(outputs, derivatives, initial_unknowns); } +base_unit parse_base_unit(const pugi::xml_node& node) +{ + base_unit baseUnit; + baseUnit.kg = parse_attribute(node, "kg"); + baseUnit.m = parse_attribute(node, "m"); + baseUnit.s = parse_attribute(node, "s"); + baseUnit.A = parse_attribute(node, "A"); + baseUnit.K = parse_attribute(node, "K"); + baseUnit.mol = parse_attribute(node, "mol"); + baseUnit.cd = parse_attribute(node, "cd"); + baseUnit.rad = parse_attribute(node, "rad"); + baseUnit.factor = parse_attribute(node, "factor"); + baseUnit.offset = parse_attribute(node, "offset"); + + return baseUnit; +} + +display_unit parse_display_unit(const pugi::xml_node& node) +{ + display_unit displayUnit; + displayUnit.name = parse_attribute(node, "name"); + displayUnit.factor = parse_attribute(node, "factor"); + displayUnit.offset = parse_attribute(node, "offset"); + + return displayUnit; +} + +unit parse_unit(const pugi::xml_node& node) +{ + unit Unit; + for (const pugi::xml_node& v : node) { + if (std::string("BaseUnit") == v.name()) { + Unit.base_unit = parse_base_unit(v); + } else if (std::string("DisplayUnit") == v.name()) { + Unit.display_units.push_back(parse_display_unit(v)); + } + } + Unit.name = parse_attribute(node, "name"); + + return Unit; +} + +unit_definitions parse_unit_definitions(const pugi::xml_node& node) +{ + unit_definitions unitDefs; + for (const pugi::xml_node& v : node) { + if (std::string("Unit") == v.name()) { + unitDefs.units.push_back(parse_unit(v)); + } + } + return unitDefs; +} + fmu_attributes parse_fmu_attributes(const pugi::xml_node& node) { @@ -322,6 +375,8 @@ std::unique_ptr fmi4cpp::fmi2::parse_model_description( base.model_variables = std::move(parse_model_variables(v)); } else if (std::string("ModelStructure") == v.name()) { base.model_structure = std::move(parse_model_structure(v)); + } else if (std::string("UnitDefinitions") == v.name()) { + base.unit_definitions = std::move(parse_unit_definitions(v)); } }