diff --git a/include/fmi4cpp/fmi2/fmu.hpp b/include/fmi4cpp/fmi2/fmu.hpp index 7526486..54fe8bb 100644 --- a/include/fmi4cpp/fmi2/fmu.hpp +++ b/include/fmi4cpp/fmi2/fmu.hpp @@ -26,7 +26,7 @@ class fmu : public virtual fmu_provider std::shared_ptr modelDescription_; public: - explicit fmu(const fs::path& fmuPath); + explicit fmu(const fs::path& fmuPath, bool unzipFmu = true); [[nodiscard]] std::string get_model_description_xml() const; [[nodiscard]] std::shared_ptr get_model_description() const override; diff --git a/src/fmi4cpp/fmi2/fmu.cpp b/src/fmi4cpp/fmi2/fmu.cpp index ae4ed46..6267af8 100644 --- a/src/fmi4cpp/fmi2/fmu.cpp +++ b/src/fmi4cpp/fmi2/fmu.cpp @@ -11,34 +11,38 @@ using namespace fmi4cpp; using namespace fmi4cpp::fmi2; -fmu::fmu(const fs::path& fmuPath) +fmu::fmu(const fs::path& fmuPath, bool unzipFmu) { - - if (!exists(fmuPath)) { - const auto err = "No such file '" + absolute(fmuPath).string() + "'!"; - MLOG_FATAL(err); - throw std::runtime_error(err); - } - - const std::string fmuName = fmuPath.stem().string(); - fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); - - if (!create_directories(tmpPath)) { - const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; - MLOG_FATAL(err); - throw std::runtime_error(err); + if (unzipFmu) { + if (!exists(fmuPath)) { + const auto err = "No such file '" + absolute(fmuPath).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + const std::string fmuName = fmuPath.stem().string(); + fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); + + if (!create_directories(tmpPath)) { + const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); + + if (!unzip(fmuPath, tmpPath.string())) { + const auto err = "Failed to extract FMU '" + absolute(fmuPath).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + resource_ = std::make_shared(tmpPath); + modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); + } else { + resource_ = std::make_shared(fmuPath); + modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); } - - MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); - - if (!unzip(fmuPath, tmpPath.string())) { - const auto err = "Failed to extract FMU '" + absolute(fmuPath).string() + "'!"; - MLOG_FATAL(err); - throw std::runtime_error(err); - } - - resource_ = std::make_shared(tmpPath); - modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); } std::string fmu::get_model_description_xml() const diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6e8ad93..3fd03c6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,8 @@ add_executable(test_controlled_temperature test_controlled_temperature.cpp) -target_link_libraries(test_controlled_temperature PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2) +target_link_libraries(test_controlled_temperature PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2 libzip::libzip) add_test(NAME test_controlled_temperature COMMAND test_controlled_temperature) +target_include_directories(test_controlled_temperature PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) add_executable(test_model_description1 test_modeldescription1.cpp) target_link_libraries(test_model_description1 PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2) diff --git a/tests/test_controlled_temperature.cpp b/tests/test_controlled_temperature.cpp index f8f4cdd..b015de0 100644 --- a/tests/test_controlled_temperature.cpp +++ b/tests/test_controlled_temperature.cpp @@ -1,5 +1,10 @@ #include +#include +#include +#include +#include +#include #define CATCH_CONFIG_MAIN #include @@ -37,5 +42,57 @@ TEST_CASE("ControlledTemperature_test1") CHECK(298.15 == Approx(ref)); + CHECK(slave->terminate()); +} + + +TEST_CASE("ControlledTemperature_test2") +{ + const std::string fmu_path = "../resources/fmus/2.0/cs/20sim/4.6.4.8004/" + "ControlledTemperature/ControlledTemperature.fmu"; + namespace fs = std::filesystem; + if (!fs::exists(fmu_path)) { + const auto err = "No such file '" + fs::absolute(fmu_path).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + const std::string fmuName = fs::path(fmu_path).stem().string(); + fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); + + if (!fs::create_directories(tmpPath)) { + const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); + + if (!unzip(fmu_path, tmpPath.string())) { + const auto err = "Failed to extract FMU '" + fs::absolute(fs::path(fmu_path)).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + auto fmu = fmi2::fmu(tmpPath,false).as_cs_fmu(); + + size_t numOutputs = 0; + for (const auto& v : *fmu->get_model_description()->model_variables) { + if (v.causality == fmi2::causality::output) { + numOutputs++; + } + } + CHECK(2 == numOutputs); + + auto slave = fmu->new_instance(); + CHECK(slave->setup_experiment()); + CHECK(slave->enter_initialization_mode()); + CHECK(slave->exit_initialization_mode()); + + double ref; + CHECK(slave->step(step_size)); + CHECK(slave->read_real(vr, ref)); + + CHECK(298.15 == Approx(ref)); + CHECK(slave->terminate()); } \ No newline at end of file