From aea2a219e37cf5d03024555bfb2ffecb09f90603 Mon Sep 17 00:00:00 2001 From: Kyle Benne Date: Mon, 11 Oct 2021 17:35:03 -0500 Subject: [PATCH] Enable output for _QLat_flow ref lbl-srg/modelica-buildings#2602 --- lib/spawn.cpp | 13 ++ lib/spawn.hpp | 1 + lib/variables.cpp | 3 - test/CMakeLists.txt | 2 +- test/test_single_family_house.cpp | 146 ++++++++++++++++++ ...est_single_family_house_lights_control.cpp | 127 --------------- 6 files changed, 161 insertions(+), 131 deletions(-) create mode 100644 test/test_single_family_house.cpp delete mode 100644 test/test_single_family_house_lights_control.cpp diff --git a/lib/spawn.cpp b/lib/spawn.cpp index 65c54742..abaa6041 100644 --- a/lib/spawn.cpp +++ b/lib/spawn.cpp @@ -325,6 +325,12 @@ void Spawn::updateZoneTemperatures(bool skipConnectedZones) { prevWarmupFlag = sim_state.dataGlobal->WarmupFlag; } +void Spawn::updateLatentGains() { + for (int zonei = 1; zonei <= sim_state.dataGlobal->NumOfZones; ++zonei) { + EnergyPlus::InternalHeatGains::SumAllInternalLatentGains(sim_state, zonei, sim_state.dataHeatBalFanSys->ZoneLatentGain(zonei)); + } +} + double Spawn::zoneHeatTransfer(const int zonenum) { const auto & sums = zoneSums(zonenum); // Refer to @@ -536,6 +542,7 @@ void Spawn::exchange(const bool force) EnergyPlus::HVACManager::ReportAirHeatBalance(sim_state); EnergyPlus::InternalHeatGains::InitInternalHeatGains(sim_state); EnergyPlus::ScheduleManager::UpdateScheduleValues(sim_state); + updateLatentGains(); // Now update the outputs for( auto & varmap : variables ) { @@ -566,6 +573,12 @@ void Spawn::exchange(const bool force) var.setValue(zoneHeatTransfer( varZoneNum ), spawn::units::UnitSystem::EP); break; } + case VariableType::QLAT_FLOW: { + const auto varZoneNum = zoneNum(var.name); + const auto value = sim_state.dataHeatBalFanSys->ZoneLatentGain( varZoneNum ); + var.setValue(sim_state.dataHeatBalFanSys->ZoneLatentGain( varZoneNum ), spawn::units::UnitSystem::EP); + break; + } case VariableType::SENSOR: { var.setValue(getSensorValue(var), spawn::units::UnitSystem::EP); break; diff --git a/lib/spawn.hpp b/lib/spawn.hpp index d157c9dc..5013eb8c 100644 --- a/lib/spawn.hpp +++ b/lib/spawn.hpp @@ -168,6 +168,7 @@ class Spawn { double zoneTemperature(const int zonenum); void updateZoneTemperature(const int zonenum, const double & dt); void updateZoneTemperatures(bool skipConnectedZones = false); + void updateLatentGains(); void initZoneEquip(); // Time in seconds of the last zone temperature update // This is required for computing the dt in the diff --git a/lib/variables.cpp b/lib/variables.cpp index c4e3f211..a03942e9 100644 --- a/lib/variables.cpp +++ b/lib/variables.cpp @@ -260,9 +260,6 @@ std::map parseVariables(const spawn::Input & input) { var.real_attributes.emplace_back("relativeQuantity","false"); var.real_attributes.emplace_back("unit",spawn::units::toString(var.mounittype)); - // TODO exchange this variable with real EnergyPlus data - var.setValue(0.0, spawn::units::UnitSystem::MO); - result.emplace(i,std::move(var)); } ++i; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f9612336..a6ad0a24 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,7 +24,7 @@ add_executable(tests test_temp_directory.cpp test_unzip_file.cpp test_floating_zone.cpp - test_single_family_house_lights_control.cpp + test_single_family_house.cpp test_fmi.cpp test_mbl_idf.cpp test_infiltration.cpp diff --git a/test/test_single_family_house.cpp b/test/test_single_family_house.cpp new file mode 100644 index 00000000..0ceda70f --- /dev/null +++ b/test/test_single_family_house.cpp @@ -0,0 +1,146 @@ +#include "../fmu/fmu.hpp" +#include "../fmu/modeldescription.hpp" +#include "../fmu/logger.h" +#include "../util/filesystem.hpp" +#include "../util/math.hpp" +#include "paths.hpp" +#include "create_epfmu.hpp" +#include +#include +#include + +using json = nlohmann::json; + +TEST_CASE("Test SingleFamilyHouse") +{ + std::string spawn_input_string = fmt::format( + R"( + {{ + "version": "0.1", + "EnergyPlus": {{ + "idf": "{idfpath}", + "weather": "{epwpath}", + "relativeSurfaceTolerance": 1.0e-10 + }}, + "fmu": {{ + "name": "MyBuilding.fmu", + "version": "2.0", + "kind" : "ME" + }}, + "model": {{ + "zones": [ + {{ "name": "LIVING ZONE" }} + ], + "emsActuators": [ + {{ + "variableName" : "LIVING ZONE People", + "componentType" : "People", + "controlType" : "Number of People", + "unit" : "1", + "fmiName" : "living zone people" + }} + ], + "schedules": [ + {{ + "name": "HOUSE LIGHTING", + "unit": "1", + "fmiName": "lighting input" + }} + ], + "outputVariables": [ + {{ + "name": "Lights Electricity Rate", + "key": "LIVING ZONE Lights", + "fmiName": "lighting output" + }} + ] + }} + }} + )", fmt::arg("idfpath", single_family_house_idf_path().generic_string()), fmt::arg("epwpath", chicago_epw_path().generic_string())); + + const auto fmu_file_path = create_epfmu(spawn_input_string); + spawn::fmu::FMU fmu{fmu_file_path, false}; // don't require all symbols + REQUIRE(fmu.fmi.fmi2GetVersion() == std::string("2.0")); + + const auto resource_path = (fmu.extractedFilesPath() / "resources").string(); + fmi2CallbackFunctions callbacks = {fmuNothingLogger, calloc, free, NULL, NULL}; // called by the model during simulation + const auto comp = fmu.fmi.fmi2Instantiate("test-instance", fmi2ModelExchange, "abc-guid", resource_path.c_str(), &callbacks, false, true); + + fmi2Status status; + + status = fmu.fmi.fmi2SetupExperiment(comp, false, 0.0, 0.0, false, 0.0); + REQUIRE(status == fmi2OK); + + const auto model_description_path = fmu.extractedFilesPath() / fmu.modelDescriptionPath(); + spawn::fmu::ModelDescription modelDescription(model_description_path); + + // Begin test lighting + const auto lighting_input_ref = modelDescription.valueReference("lighting input"); + const auto lighting_output_ref = modelDescription.valueReference("lighting output"); + + const std::array lighting_input_refs = {lighting_input_ref}; + const std::array lighting_output_refs = {lighting_output_ref}; + + status = fmu.fmi.fmi2ExitInitializationMode(comp); + REQUIRE(status == fmi2OK); + + std::array lighting_output_values; + std::array lighting_input_values; + + lighting_input_values[0] = 0.0; + status = fmu.fmi.fmi2SetReal(comp, lighting_input_refs.data(), lighting_input_refs.size(), lighting_input_values.data()); + CHECK(status == fmi2OK); + + status = fmu.fmi.fmi2GetReal(comp, lighting_output_refs.data(), lighting_output_refs.size(), lighting_output_values.data()); + CHECK(status == fmi2OK); + CHECK( lighting_output_values[0] == Approx(0.0) ); + + lighting_input_values[0] = 1.0; + status = fmu.fmi.fmi2SetReal(comp, lighting_input_refs.data(), lighting_input_refs.size(), lighting_input_values.data()); + CHECK(status == fmi2OK); + + status = fmu.fmi.fmi2GetReal(comp, lighting_output_refs.data(), lighting_output_refs.size(), lighting_output_values.data()); + CHECK(status == fmi2OK); + CHECK( lighting_output_values[0] == Approx(1000.0) ); + + lighting_input_values[0] = 0.5; + status = fmu.fmi.fmi2SetReal(comp, lighting_input_refs.data(), lighting_input_refs.size(), lighting_input_values.data()); + CHECK(status == fmi2OK); + + status = fmu.fmi.fmi2GetReal(comp, lighting_output_refs.data(), lighting_output_refs.size(), lighting_output_values.data()); + CHECK(status == fmi2OK); + CHECK( lighting_output_values[0] == Approx(500.0) ); + + lighting_input_values[0] = 0.0; + status = fmu.fmi.fmi2SetReal(comp, lighting_input_refs.data(), lighting_input_refs.size(), lighting_input_values.data()); + CHECK(status == fmi2OK); + + status = fmu.fmi.fmi2GetReal(comp, lighting_output_refs.data(), lighting_output_refs.size(), lighting_output_values.data()); + CHECK(status == fmi2OK); + CHECK( lighting_output_values[0] == Approx(0.0) ); + + // Begin test latent heat + const auto qlat_flow_ref = modelDescription.valueReference("LIVING ZONE_QLat_flow"); + const auto people_input_ref = modelDescription.valueReference("living zone people"); + const std::array latent_output_refs = {qlat_flow_ref}; + const std::array latent_input_refs = {people_input_ref}; + + std::array latent_output_values; + std::array latent_input_values; + + status = fmu.fmi.fmi2GetReal(comp, latent_output_refs.data(), latent_output_refs.size(), latent_output_values.data()); + CHECK(status == fmi2OK); + CHECK( latent_output_values[0] == Approx(0.0) ); + + latent_input_values[0] = 5.0; + status = fmu.fmi.fmi2SetReal(comp, latent_input_refs.data(), latent_input_refs.size(), latent_input_values.data()); + CHECK(status == fmi2OK); + + status = fmu.fmi.fmi2GetReal(comp, latent_output_refs.data(), latent_output_refs.size(), latent_output_values.data()); + CHECK(status == fmi2OK); + CHECK( latent_output_values[0] > 10.0 ); + + status = fmu.fmi.fmi2Terminate(comp); + REQUIRE(status == fmi2OK); +} + diff --git a/test/test_single_family_house_lights_control.cpp b/test/test_single_family_house_lights_control.cpp deleted file mode 100644 index e1655c96..00000000 --- a/test/test_single_family_house_lights_control.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "../fmu/fmu.hpp" -#include "../fmu/modeldescription.hpp" -#include "../fmu/logger.h" -#include "../util/filesystem.hpp" -#include "../util/math.hpp" -#include "paths.hpp" -#include "create_epfmu.hpp" -#include -#include -#include - -using json = nlohmann::json; - -TEST_CASE("Test SingleFamilyHouse Lights") -{ - std::string spawn_input_string = fmt::format( - R"( - {{ - "version": "0.1", - "EnergyPlus": {{ - "idf": "{idfpath}", - "weather": "{epwpath}", - "relativeSurfaceTolerance": 1.0e-10 - }}, - "fmu": {{ - "name": "MyBuilding.fmu", - "version": "2.0", - "kind" : "ME" - }}, - "model": {{ - "zones": [ - {{ "name": "LIVING ZONE" }} - ], - "schedules": [ - {{ - "name": "HOUSE LIGHTING", - "unit": "1", - "fmiName": "lighting input" - }} - ], - "outputVariables": [ - {{ - "name": "Lights Electricity Rate", - "key": "LIVING ZONE Lights", - "fmiName": "lighting output" - }} - ] - }} - }} - )", fmt::arg("idfpath", single_family_house_idf_path().generic_string()), fmt::arg("epwpath", chicago_epw_path().generic_string())); - - const auto fmu_file_path = create_epfmu(spawn_input_string); - spawn::fmu::FMU fmu{fmu_file_path, false}; // don't require all symbols - REQUIRE(fmu.fmi.fmi2GetVersion() == std::string("2.0")); - - const auto resource_path = (fmu.extractedFilesPath() / "resources").string(); - fmi2CallbackFunctions callbacks = {fmuNothingLogger, calloc, free, NULL, NULL}; // called by the model during simulation - const auto comp = fmu.fmi.fmi2Instantiate("test-instance", fmi2ModelExchange, "abc-guid", resource_path.c_str(), &callbacks, false, true); - - fmi2Status status; - - status = fmu.fmi.fmi2SetupExperiment(comp, false, 0.0, 0.0, false, 0.0); - REQUIRE(status == fmi2OK); - - const auto model_description_path = fmu.extractedFilesPath() / fmu.modelDescriptionPath(); - spawn::fmu::ModelDescription modelDescription(model_description_path); - - constexpr std::array variable_names{ - "LIVING ZONE_T", - "LIVING ZONE_QConSen_flow", - "lighting input", - "lighting output" - }; - - std::map variable_refs; - for (const auto name : variable_names) { - variable_refs[name] = modelDescription.valueReference(name); - } - - const auto lighting_input_ref = modelDescription.valueReference("lighting input"); - const auto lighting_output_ref = modelDescription.valueReference("lighting output"); - - const std::array input_refs = {lighting_input_ref}; - const std::array output_refs = {lighting_output_ref}; - - status = fmu.fmi.fmi2ExitInitializationMode(comp); - REQUIRE(status == fmi2OK); - - std::array output_values; - std::array input_values; - - input_values[0] = 0.0; - status = fmu.fmi.fmi2SetReal(comp, input_refs.data(), input_refs.size(), input_values.data()); - CHECK(status == fmi2OK); - - status = fmu.fmi.fmi2GetReal(comp, output_refs.data(), output_refs.size(), output_values.data()); - CHECK(status == fmi2OK); - CHECK( output_values[0] == Approx(0.0) ); - - input_values[0] = 1.0; - status = fmu.fmi.fmi2SetReal(comp, input_refs.data(), input_refs.size(), input_values.data()); - CHECK(status == fmi2OK); - - status = fmu.fmi.fmi2GetReal(comp, output_refs.data(), output_refs.size(), output_values.data()); - CHECK(status == fmi2OK); - CHECK( output_values[0] == Approx(1000.0) ); - - input_values[0] = 0.5; - status = fmu.fmi.fmi2SetReal(comp, input_refs.data(), input_refs.size(), input_values.data()); - CHECK(status == fmi2OK); - - status = fmu.fmi.fmi2GetReal(comp, output_refs.data(), output_refs.size(), output_values.data()); - CHECK(status == fmi2OK); - CHECK( output_values[0] == Approx(500.0) ); - - input_values[0] = 0.0; - status = fmu.fmi.fmi2SetReal(comp, input_refs.data(), input_refs.size(), input_values.data()); - CHECK(status == fmi2OK); - - status = fmu.fmi.fmi2GetReal(comp, output_refs.data(), output_refs.size(), output_values.data()); - CHECK(status == fmi2OK); - CHECK( output_values[0] == Approx(0.0) ); - - status = fmu.fmi.fmi2Terminate(comp); - REQUIRE(status == fmi2OK); -} -