From 5d932f98fb30668b2ac30c4863c88b12cc5f3958 Mon Sep 17 00:00:00 2001 From: Lars Ivar Hatledal Date: Fri, 8 Nov 2024 01:44:23 +0100 Subject: [PATCH] update --- .../examples/BouncingBall/bouncing_ball.cpp | 49 ++++++++++--------- export/include/fmu4cpp/fmu_variable.hpp | 5 +- export/src/fmu4cpp/fmu_base.cpp | 34 +++++++++---- src/model.cpp | 16 ++++-- 4 files changed, 65 insertions(+), 39 deletions(-) diff --git a/export/examples/BouncingBall/bouncing_ball.cpp b/export/examples/BouncingBall/bouncing_ball.cpp index 4f804a4..15dff22 100644 --- a/export/examples/BouncingBall/bouncing_ball.cpp +++ b/export/examples/BouncingBall/bouncing_ball.cpp @@ -12,30 +12,31 @@ class BouncingBall : public fmu_base { register_variable( real( - "height", [this] { return height; }) + "height", [this] { return height_; }) .setCausality(causality_t::OUTPUT) - .setVariability(variability_t::CONTINUOUS)); + .setVariability(variability_t::CONTINUOUS) + .setInitial(initial_t::EXACT)); register_variable( real( - "velocity", [this] { return velocity; }) - .setCausality(causality_t::CALCULATED_PARAMETER) - .setVariability(variability_t::TUNABLE)); + "velocity", [this] { return velocity_; }) + .setCausality(causality_t::LOCAL) + .setVariability(variability_t::CONTINUOUS)); register_variable( real( - "gravity", [this] { return gravity; }, - [this](const auto &input) { gravity = input; }) + "gravity", [this] { return gravity_; }, + [this](const auto &input) { gravity_ = input; }) .setCausality(causality_t::PARAMETER) - .setVariability(variability_t::TUNABLE)); + .setVariability(variability_t::FIXED)); register_variable( real( "bounceFactor", - [this] { return bounceFactor; }, - [this](const auto &input) { bounceFactor = input; }) + [this] { return bounceFactor_; }, + [this](const auto &input) { bounceFactor_ = input; }) .setCausality(causality_t::PARAMETER) - .setVariability(variability_t::TUNABLE)); + .setVariability(variability_t::FIXED)); BouncingBall::reset(); @@ -43,31 +44,31 @@ class BouncingBall : public fmu_base { bool do_step(double currentTime, double dt) override { // Update velocity with gravity - velocity += gravity * dt; + velocity_ += gravity_ * dt; // Update height with current velocity - height += velocity * dt; + height_ += velocity_ * dt; // Check for bounce - if (height <= 0.0f) { - height = 0.0f; // Reset height to ground level - velocity = -velocity * bounceFactor;// Reverse velocity and apply bounce factor + if (height_ <= 0.0f) { + height_ = 0.0f; // Reset height to ground level + velocity_ = -velocity_ * bounceFactor_;// Reverse velocity and apply bounce factor } return true; } void reset() override { - height = 10; - velocity = 0; - gravity = -9.81f; - bounceFactor = 0.6f; + height_ = 10; + velocity_ = 0; + gravity_ = -9.81f; + bounceFactor_ = 0.6f; } private: - double height; // Current height of the ball - double velocity; // Current velocity of the ball - double gravity; // Acceleration due to gravity - double bounceFactor;// Factor to reduce velocity on bounce + double height_; // Current height of the ball + double velocity_; // Current velocity of the ball + double gravity_; // Acceleration due to gravity + double bounceFactor_;// Factor to reduce velocity on bounce }; model_info fmu4cpp::get_model_info() { diff --git a/export/include/fmu4cpp/fmu_variable.hpp b/export/include/fmu4cpp/fmu_variable.hpp index 608935b..786fc21 100644 --- a/export/include/fmu4cpp/fmu_variable.hpp +++ b/export/include/fmu4cpp/fmu_variable.hpp @@ -176,7 +176,10 @@ namespace fmu4cpp { unsigned int vr, size_t index, const std::function &getter, const std::optional> &setter) - : Variable(name, vr, index, getter, setter) {} + : Variable(name, vr, index, getter, setter) { + + variability_ = variability_t::CONTINUOUS; + } [[nodiscard]] std::optional getMin() const { return min_; diff --git a/export/src/fmu4cpp/fmu_base.cpp b/export/src/fmu4cpp/fmu_base.cpp index 0000823..2680ac1 100644 --- a/export/src/fmu4cpp/fmu_base.cpp +++ b/export/src/fmu4cpp/fmu_base.cpp @@ -14,14 +14,14 @@ namespace { - std::vector collect( + std::vector collect( const std::vector &v1, const std::vector &v2, const std::vector &v3, const std::vector &v4, const std::function &predicate = [](auto &v) { return true; }) { - std::vector vars; + std::vector vars; for (const fmu4cpp::VariableBase &v: v1) { if (predicate(v)) { vars.push_back(&v); @@ -96,7 +96,7 @@ namespace fmu4cpp { ss << "\t\n"; auto allVars = collect(integers_, reals_, booleans_, strings_); - std::sort(allVars.begin(), allVars.end(), [](const VariableBase* v1, const VariableBase* v2) { + std::sort(allVars.begin(), allVars.end(), [](const VariableBase *v1, const VariableBase *v2) { return v1->index() < v2->index(); }); @@ -115,12 +115,12 @@ namespace fmu4cpp { ss << " initial=\"" << to_string(*initial) << "\""; } ss << ">\n"; - if (auto i = dynamic_cast(v)) { + if (auto i = dynamic_cast(v)) { ss << "\t\t\tget() << "\""; } - } else if (auto r = dynamic_cast(v)) { + } else if (auto r = dynamic_cast(v)) { ss << "\t\t\tget() << "\""; @@ -130,12 +130,12 @@ namespace fmu4cpp { if (min && max) { ss << " min=\"" << *min << "\" max=\"" << *max << "\""; } - } else if (auto s = dynamic_cast(v)) { + } else if (auto s = dynamic_cast(v)) { ss << "\t\t\tget() << "\""; } - } else if (auto b = dynamic_cast(v)) { + } else if (auto b = dynamic_cast(v)) { ss << "\t\t\tget() << "\""; @@ -150,13 +150,13 @@ namespace fmu4cpp { ss << "\t\n"; - std::vector outputs = collect(integers_, reals_, booleans_, strings_, [](auto &v) { + std::vector unknowns = collect(integers_, reals_, booleans_, strings_, [](auto &v) { return v.causality() == causality_t::OUTPUT; }); - if (!outputs.empty()) { + if (!unknowns.empty()) { ss << "\t\t\n"; - for (const auto &v: outputs) { + for (const auto &v: unknowns) { ss << "\t\t\tindex() << "\""; const auto deps = v->getDependencies(); if (!deps.empty()) { @@ -174,6 +174,20 @@ namespace fmu4cpp { ss << "\t\t\n"; } + + std::vector initialUnknowns = collect(integers_, reals_, booleans_, strings_, [](auto &v) { + return (v.causality() == causality_t::OUTPUT && v.initial() == initial_t::APPROX || v.initial() == initial_t::CALCULATED) || v.causality() == causality_t::CALCULATED_PARAMETER; + }); + if (!initialUnknowns.empty()) { + ss << "\t\t\n"; + for (const auto &v: initialUnknowns) { + ss << "\t\t\tindex() << "\""; + ss << "/>\n"; + } + ss << "\t\t\n"; + } + + ss << "\t\n"; ss << ""; diff --git a/src/model.cpp b/src/model.cpp index 6de0cd3..8fa8d77 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -18,46 +18,54 @@ class Model : public fmu_base { integer( "integerIn", [this] { return integer_; }, [this](int value) { integer_ = value; }) .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE)); + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); register_variable( real( "realIn", [this] { return real_; }, [this](double value) { real_ = value; }) .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE)); + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); register_variable( boolean( "booleanIn", [this] { return boolean_; }, [this](bool value) { boolean_ = value; }) .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE)); + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); register_variable( string( "stringIn", [this] { return string_; }, [this](std::string value) { string_ = std::move(value); }) .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE)); + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); register_variable( integer( "integerOut", [this] { return integer_; }) .setCausality(causality_t::OUTPUT) .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) .setDependencies({get_int_variable("integerIn")->index()})); register_variable( real( "realOut", [this] { return real_; }) .setCausality(causality_t::OUTPUT) .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) .setDependencies({get_real_variable("realIn")->index()})); register_variable( boolean( "booleanOut", [this] { return boolean_; }) .setCausality(causality_t::OUTPUT) .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) .setDependencies({get_bool_variable("booleanIn")->index()})); register_variable( string( "stringOut", [this] { return string_; }) .setCausality(causality_t::OUTPUT) .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) .setDependencies({get_string_variable("stringIn")->index()})); Model::reset();