From 39e478d707805c33f407952709bd6a27f7546ef3 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 8 Sep 2022 11:32:41 +0200 Subject: [PATCH 1/4] Use getSpaceLoadParent(SpaceLoad&) and not SpaceLoadInstance SpaceLoadInstance is a SpaceLoad. But SpaceInfiltrationDesignFlowRate is a SpaceLoad, not a SpaceLoadInstance --- src/energyplus/ForwardTranslator.cpp | 3 +-- src/energyplus/ForwardTranslator.hpp | 7 +++---- .../ForwardTranslateElectricEquipment.cpp | 2 +- .../ForwardTranslateElectricEquipmentITEAirCooled.cpp | 2 +- .../ForwardTranslator/ForwardTranslateGasEquipment.cpp | 2 +- .../ForwardTranslateHotWaterEquipment.cpp | 2 +- .../ForwardTranslator/ForwardTranslateLights.cpp | 2 +- .../ForwardTranslator/ForwardTranslateLuminaire.cpp | 2 +- .../ForwardTranslator/ForwardTranslateOtherEquipment.cpp | 2 +- .../ForwardTranslator/ForwardTranslatePeople.cpp | 2 +- .../ForwardTranslator/ForwardTranslateSteamEquipment.cpp | 2 +- 11 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/energyplus/ForwardTranslator.cpp b/src/energyplus/ForwardTranslator.cpp index d82916c140..30ffed6bcd 100644 --- a/src/energyplus/ForwardTranslator.cpp +++ b/src/energyplus/ForwardTranslator.cpp @@ -60,7 +60,6 @@ #include "../model/ConcreteModelObjects.hpp" #include "../model/SpaceLoad.hpp" #include "../model/SpaceLoad_Impl.hpp" -#include "../model/SpaceLoadInstance.hpp" #include "../model/SpaceType.hpp" #include "../model/SpaceInfiltrationDesignFlowRate.hpp" #include "../model/SpaceInfiltrationDesignFlowRate_Impl.hpp" @@ -226,7 +225,7 @@ namespace energyplus { // * m_excludeSpaceTranslation = false: translate and return the IdfObject for Space // * If the load is assigned to a spaceType: // * translateAndMapModelObjec(spaceType) (which will return a ZoneList if m_excludeSpaceTranslation is true, SpaceList otherwise) - IdfObject ForwardTranslator::getSpaceLoadInstanceParent(model::SpaceLoadInstance& sp, bool allowSpaceType) { + IdfObject ForwardTranslator::getSpaceLoadParent(const model::SpaceLoad& sp, bool allowSpaceType) { OptionalIdfObject relatedIdfObject; diff --git a/src/energyplus/ForwardTranslator.hpp b/src/energyplus/ForwardTranslator.hpp index 0ff2d30d07..a4dec8adb6 100644 --- a/src/energyplus/ForwardTranslator.hpp +++ b/src/energyplus/ForwardTranslator.hpp @@ -406,7 +406,7 @@ namespace model { class SizingPlant; class SizingSystem; class SizingZone; - class SpaceLoadInstance; + class SpaceLoad; class StandardGlazing; class StandardOpaqueMaterial; class SimpleGlazing; @@ -593,9 +593,8 @@ namespace energyplus { */ Workspace translateModelPrivate(model::Model& model, bool fullModelTranslation); - // TODO: restrict to SpaceLoadInstance or SpaceLoad? - // Pick up the Zone, ZoneList, Space or SpaceList (if allowSpaceType is true) object for a given SpaceLoadInstance - IdfObject getSpaceLoadInstanceParent(model::SpaceLoadInstance& sp, bool allowSpaceType = true); + // Pick up the Zone, ZoneList, Space or SpaceList (if allowSpaceType is true) object for a given SpaceLoad (or SpaceLoadInstance) + IdfObject getSpaceLoadParent(const model::SpaceLoad& sp, bool allowSpaceType = true); boost::optional translateAndMapModelObject(model::ModelObject& modelObject); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipment.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipment.cpp index 53d21b2c61..54ba4889a9 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipment.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipment.cpp @@ -64,7 +64,7 @@ namespace energyplus { ElectricEquipmentDefinition definition = modelObject.electricEquipmentDefinition(); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(ElectricEquipmentFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipmentITEAirCooled.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipmentITEAirCooled.cpp index af9359f5d0..ab8c52b2c9 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipmentITEAirCooled.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateElectricEquipmentITEAirCooled.cpp @@ -111,7 +111,7 @@ namespace energyplus { // cf https://github.com/NREL/OpenStudio/blob/bf4ffc49d5947f74b139efa5fb1dffec9b1fb013/src/energyplus/ForwardTranslator.cpp#L323-L341 // Assign object to Zone/Space - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject, false); // We do not allow spaceType! + IdfObject parentIdfObject = getSpaceLoadParent(modelObject, false); // We do not allow spaceType! idfObject.setString(ElectricEquipment_ITE_AirCooledFields::ZoneorSpaceName, parentIdfObject.nameString()); // attach the supply air node to zone if there is an available supply air node diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateGasEquipment.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateGasEquipment.cpp index a4b60348b0..d5b5d767d8 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateGasEquipment.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateGasEquipment.cpp @@ -68,7 +68,7 @@ namespace energyplus { idfObject.setString(GasEquipmentFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(GasEquipmentFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateHotWaterEquipment.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateHotWaterEquipment.cpp index 2ffe330ed5..0bd122014f 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateHotWaterEquipment.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateHotWaterEquipment.cpp @@ -68,7 +68,7 @@ namespace energyplus { idfObject.setString(HotWaterEquipmentFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(HotWaterEquipmentFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateLights.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateLights.cpp index 7f133e86da..85de6b1e52 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateLights.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateLights.cpp @@ -56,7 +56,7 @@ namespace energyplus { LightsDefinition definition = modelObject.lightsDefinition(); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(LightsFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateLuminaire.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateLuminaire.cpp index 2352c7ab08..9d410c233d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateLuminaire.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateLuminaire.cpp @@ -68,7 +68,7 @@ namespace energyplus { idfObject.setString(LightsFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(LightsFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateOtherEquipment.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateOtherEquipment.cpp index ae54d29350..3f0284d9c1 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateOtherEquipment.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateOtherEquipment.cpp @@ -68,7 +68,7 @@ namespace energyplus { idfObject.setString(OtherEquipmentFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(OtherEquipmentFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePeople.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePeople.cpp index 37bdfd8134..4499d81a47 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePeople.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePeople.cpp @@ -70,7 +70,7 @@ namespace energyplus { idfObject.setString(PeopleFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(PeopleFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.numberofPeopleSchedule()) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSteamEquipment.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSteamEquipment.cpp index 21814395dd..536da69b06 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSteamEquipment.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSteamEquipment.cpp @@ -68,7 +68,7 @@ namespace energyplus { idfObject.setString(SteamEquipmentFields::Name, modelObject.name().get()); - IdfObject parentIdfObject = getSpaceLoadInstanceParent(modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject); idfObject.setString(SteamEquipmentFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); if (boost::optional schedule = modelObject.schedule()) { From c4adcc45f1059cdb0a432e57ef904e12c169b32c Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 8 Sep 2022 14:34:19 +0200 Subject: [PATCH 2/4] Fix #4645 - Map SpaceInfiltration to Space/SpaceList --- src/energyplus/ForwardTranslator.cpp | 60 +++++++------------ ...anslateSpaceInfiltrationDesignFlowRate.cpp | 32 ++-------- ...eSpaceInfiltrationEffectiveLeakageArea.cpp | 27 ++------- ...nslateSpaceInfiltrationFlowCoefficient.cpp | 26 +------- .../ForwardTranslateSpaceType.cpp | 8 --- 5 files changed, 33 insertions(+), 120 deletions(-) diff --git a/src/energyplus/ForwardTranslator.cpp b/src/energyplus/ForwardTranslator.cpp index 30ffed6bcd..2f59ccfdee 100644 --- a/src/energyplus/ForwardTranslator.cpp +++ b/src/energyplus/ForwardTranslator.cpp @@ -315,48 +315,30 @@ namespace energyplus { thermalZone.combineSpaces(); } } else { - // We're going to have a bunch of troubles with the SpaceInfiltration objects as they cannot live on a Space in E+, they are on the zone - // So we do the same as combineSpaces but only for those infiltration objects: we hard apply them to each individual space, then remove the - // spacetype ones to be safe (make 100% sure they won't get translated) - // TODO: Technically we could just find a smart way to convert the SpaceInfiltration:DesignFlowRate object to a Flow / Zone and use a ZoneList, - // but it gets complicated with little benefit, so not doing it for now + + // The SpaceInfiltration:EffectiveLeakageAreas and FlowCoefficients (unlike the SpaceInfiltration:DesignFlowRate), + // and the ElectricEquipment:ITE:AirCooled only accept a Zone or a Space, not a ZoneList nor a SpaceList + // So we need to put them on the spaces to avoid problems. But we do not need to hardSize() them (they end up going on a Space). + // then remove the spacetype ones to be safe (make 100% sure they won't get translated) + for (auto& sp : model.getConcreteModelObjects()) { - auto spi = sp.spaceInfiltrationDesignFlowRates(); + // auto spi = sp.spaceInfiltrationDesignFlowRates(); auto spiel = sp.spaceInfiltrationEffectiveLeakageAreas(); auto spifc = sp.spaceInfiltrationFlowCoefficients(); - std::vector infiltrations; - infiltrations.reserve(spi.size() + spiel.size() + spifc.size()); - infiltrations.insert(infiltrations.end(), spi.begin(), spi.end()); - infiltrations.insert(infiltrations.end(), spiel.begin(), spiel.end()); - infiltrations.insert(infiltrations.end(), spifc.begin(), spifc.end()); - for (auto& infil : infiltrations) { - for (auto& space : sp.spaces()) { - auto infilClone = infil.clone(model).cast(); - infilClone.setParent(space); - } - infil.remove(); - } - - // The ElectricEquipment:ITE:AirCooled only accepts a Zone or a Space, not a ZoneList nor a SpaceList - // So similarly, we need to put them on the spaces to avoid problems. But we do not need to hardSize() them - for (auto& ite : sp.electricEquipmentITEAirCooled()) { - std::string name = ite.nameString(); - for (auto& space : sp.spaces()) { - auto iteClone = ite.clone(model).cast(); - iteClone.setParent(space); - } - ite.remove(); - } - } - - // We also convert all SpaceInfiltrationDesignFlowRate objects to Flow/Space (Flow/Zone) because these may not be absolute - // That includes the Space ones too. - // SpaceInfiltrationEffectiveLeakageAreas and SpaceInfiltrationFlowCoefficients don't need it, they are always absolute - for (auto& infil : model.getConcreteModelObjects()) { - // technically we only need to hardsize if the space it's assigned to is part of a thermalzone with more than one space - if (!openstudio::istringEqual("Flow/Space", infil.designFlowRateCalculationMethod())) { - if (infil.space() && infil.space()->thermalZone() && infil.space()->thermalZone()->spaces().size() > 1) { - infil.hardSize(); // translates to Flow/Zone + auto ites = sp.electricEquipmentITEAirCooled(); + std::vector loads; + loads.reserve(spiel.size() + spifc.size() + ites.size()); + loads.insert(loads.end(), spiel.begin(), spiel.end()); + loads.insert(loads.end(), spifc.begin(), spifc.end()); + loads.insert(loads.end(), ites.begin(), ites.end()); + + for (auto& infil : loads) { + if (infil.spaceType()) { + for (auto& space : sp.spaces()) { + auto infilClone = infil.clone(model).cast(); + infilClone.setParent(space); + } + infil.remove(); } } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationDesignFlowRate.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationDesignFlowRate.cpp index d9df00c154..f4973623ac 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationDesignFlowRate.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationDesignFlowRate.cpp @@ -55,36 +55,14 @@ namespace openstudio { namespace energyplus { boost::optional ForwardTranslator::translateSpaceInfiltrationDesignFlowRate(SpaceInfiltrationDesignFlowRate& modelObject) { - IdfObject idfObject(openstudio::IddObjectType::ZoneInfiltration_DesignFlowRate); - m_idfObjects.push_back(idfObject); - - idfObject.setString(ZoneInfiltration_DesignFlowRateFields::Name, modelObject.name().get()); - - boost::optional space = modelObject.space(); - boost::optional spaceType = modelObject.spaceType(); - if (space) { - // Note: this can't be mapped to a Space, in E+ it's ZoneInfiltration:DesignFlowRate (so no need to check m_excludeSpaceTranslation) - boost::optional thermalZone = space->thermalZone(); - if (thermalZone) { - idfObject.setString(ZoneInfiltration_DesignFlowRateFields::ZoneorZoneListorSpaceorSpaceListName, thermalZone->name().get()); - } - } else if (spaceType) { - // This is a weird one... we need a ZoneList, not a SpaceList, even if we do translate to E+ spaces. Use the helper to figure the out right name - // We shouldn't get in there, we have hard applied them to the Spaces early in translateModelPrivate - idfObject.setString(ZoneInfiltration_DesignFlowRateFields::ZoneorZoneListorSpaceorSpaceListName, zoneListNameForSpaceType(spaceType.get())); - if (!m_excludeSpaceTranslation) { - OS_ASSERT(false); - } - } else { - // Note: a warning will be issued higher up already - // Object of type 'OS:SpaceInfiltration:FlowCoefficient' and named 'My Infiltration' is not associated with a Space or SpaceType, it will not be translated. - LOG(Warn, modelObject.briefDescription() << " has neither a Space nor a SpaceType attached, it will not be translated."); - return boost::none; - } + + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneInfiltration_DesignFlowRate, modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject, true); // We **do** allow spaceType! + idfObject.setString(ZoneInfiltration_DesignFlowRateFields::ZoneorZoneListorSpaceorSpaceListName, parentIdfObject.nameString()); boost::optional schedule = modelObject.schedule(); if (schedule) { - idfObject.setString(ZoneInfiltration_DesignFlowRateFields::ScheduleName, schedule->name().get()); + idfObject.setString(ZoneInfiltration_DesignFlowRateFields::ScheduleName, schedule->nameString()); } std::string designFlowRateCalculationMethod = modelObject.designFlowRateCalculationMethod(); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationEffectiveLeakageArea.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationEffectiveLeakageArea.cpp index b05c3f60cf..a83d965d54 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationEffectiveLeakageArea.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationEffectiveLeakageArea.cpp @@ -55,29 +55,10 @@ namespace openstudio { namespace energyplus { boost::optional ForwardTranslator::translateSpaceInfiltrationEffectiveLeakageArea(SpaceInfiltrationEffectiveLeakageArea& modelObject) { - IdfObject idfObject(openstudio::IddObjectType::ZoneInfiltration_EffectiveLeakageArea); - m_idfObjects.push_back(idfObject); - - idfObject.setString(ZoneInfiltration_EffectiveLeakageAreaFields::Name, modelObject.name().get()); - - boost::optional space = modelObject.space(); - boost::optional spaceType = modelObject.spaceType(); - if (space) { - // Note: this can't be mapped to a Space, in E+ it's ZoneInfiltration:EffectiveLeakageArea (so no need to check m_excludeSpaceTranslation) - boost::optional thermalZone = space->thermalZone(); - if (thermalZone) { - idfObject.setString(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneorSpaceName, thermalZone->name().get()); - } - } else if (spaceType) { - // TODO: This field is called 'ZoneName' and not 'ZoneorZoneListName'. It **DOES NOT** accept a Zone List - idfObject.setString(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneorSpaceName, zoneListNameForSpaceType(spaceType.get())); - OS_ASSERT(false); - } else { - // Note: a warning will be issued higher up already - // Object of type 'OS:SpaceInfiltration:EffectiveLeakageArea' and named 'My Infiltration' is not associated with a Space or SpaceType, it will not be translated. - LOG(Warn, modelObject.briefDescription() << " has neither a Space nor a SpaceType attached, it will not be translated."); - return boost::none; - } + + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneInfiltration_EffectiveLeakageArea, modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject, false); // We do not allow spaceType! + idfObject.setString(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneorSpaceName, parentIdfObject.nameString()); boost::optional schedule = modelObject.schedule(); if (schedule) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationFlowCoefficient.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationFlowCoefficient.cpp index a7b7bbfd49..0c10563f3d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationFlowCoefficient.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceInfiltrationFlowCoefficient.cpp @@ -56,29 +56,9 @@ namespace energyplus { boost::optional ForwardTranslator::translateSpaceInfiltrationFlowCoefficient(SpaceInfiltrationFlowCoefficient& modelObject) { - IdfObject idfObject(openstudio::IddObjectType::ZoneInfiltration_FlowCoefficient); - idfObject.setString(ZoneInfiltration_FlowCoefficientFields::Name, modelObject.nameString()); - - boost::optional space = modelObject.space(); - boost::optional spaceType = modelObject.spaceType(); - if (space) { - // Note: this can't be mapped to a Space, in E+ it's ZoneInfiltration:FlowCoefficient (so no need to check m_excludeSpaceTranslation) - boost::optional thermalZone = space->thermalZone(); - if (thermalZone) { - idfObject.setString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName, thermalZone->nameString()); - } - } else if (spaceType) { - // TODO: This field is called 'ZoneName' and not 'ZoneorZoneListName'. It **DOES NOT** accept a Zone List - idfObject.setString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName, zoneListNameForSpaceType(spaceType.get())); - OS_ASSERT(false); - } else { - // Note: a warning will be issued higher up already - // Object of type 'OS:SpaceInfiltration:FlowCoefficient' and named 'My Infiltration' is not associated with a Space or SpaceType, it will not be translated. - LOG(Warn, modelObject.briefDescription() << " has neither a Space nor a SpaceType attached, it will not be translated."); - return boost::none; - } - - m_idfObjects.push_back(idfObject); + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneInfiltration_FlowCoefficient, modelObject); + IdfObject parentIdfObject = getSpaceLoadParent(modelObject, false); // We do not allow spaceType! + idfObject.setString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName, parentIdfObject.nameString()); boost::optional schedule_ = modelObject.schedule(); if (!schedule_) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceType.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceType.cpp index f85c34146a..a43a9f2dc1 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSpaceType.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSpaceType.cpp @@ -130,14 +130,6 @@ namespace energyplus { for (const auto& s : spaces) { idfObject->pushExtensibleGroup(std::vector(1, s.nameString())); } - - // Infiltration objects are Space-level in OS, but they are Zone-Level in E+, so we'll **ALSO** need a ZoneList for it... - bool hasAnyInfiltration = (!modelObject.spaceInfiltrationDesignFlowRates().empty() || !modelObject.spaceInfiltrationFlowCoefficients().empty() - || !modelObject.spaceInfiltrationEffectiveLeakageAreas().empty()); - - if (hasAnyInfiltration) { - makeZoneList(false); - } } // Translate all SpaceType loads From be67d329884b024967c02674f167ddb4077f12c9 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 8 Sep 2022 14:34:40 +0200 Subject: [PATCH 3/4] #4645 - Adjust Gtest now that it maps to a Space/SpaceList --- .../SpaceInfiltrationDesignFlowRate_GTest.cpp | 73 ++++++++++++++----- ...InfiltrationEffectiveLeakageArea_GTest.cpp | 33 ++++++++- ...SpaceInfiltrationFlowCoefficient_GTest.cpp | 56 +++++++++++--- 3 files changed, 128 insertions(+), 34 deletions(-) diff --git a/src/energyplus/Test/SpaceInfiltrationDesignFlowRate_GTest.cpp b/src/energyplus/Test/SpaceInfiltrationDesignFlowRate_GTest.cpp index 4a0bad1418..a30a9b700f 100644 --- a/src/energyplus/Test/SpaceInfiltrationDesignFlowRate_GTest.cpp +++ b/src/energyplus/Test/SpaceInfiltrationDesignFlowRate_GTest.cpp @@ -286,34 +286,69 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationDesignFlowRate_Spac EXPECT_EQ(4, w.getObjectsByType(IddObjectType::Space).size()); EXPECT_EQ(2, w.getObjectsByType(IddObjectType::SpaceList).size()); + w.getObjectByTypeAndName(IddObjectType::SpaceList, buildingSpaceType.nameString()); + auto infils = w.getObjectsByType(IddObjectType::ZoneInfiltration_DesignFlowRate); - // I expect infilSpace1, infilSpace3, two infilOffice and two infilBuilding, so 6 total - ASSERT_EQ(6, infils.size()); + // I expect infilSpace1, infilSpace3 which are on the space, and infilOffice and infilBuilding which use SpaceList + ASSERT_EQ(4, infils.size()); - double totalInfiltration = 0.0; // m3/s for (const auto& infil : infils) { auto name = infil.nameString(); - auto z_ = infil.getTarget(ZoneInfiltration_DesignFlowRateFields::ZoneorZoneListorSpaceorSpaceListName); - ASSERT_TRUE(z_); - EXPECT_EQ(zone, z_.get()); - EXPECT_EQ("Flow/Zone", infil.getString(ZoneInfiltration_DesignFlowRateFields::DesignFlowRateCalculationMethod).get()); - double i = infil.getDouble(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate).get(); - totalInfiltration += i; + auto target_ = infil.getTarget(ZoneInfiltration_DesignFlowRateFields::ZoneorZoneListorSpaceorSpaceListName); + ASSERT_TRUE(target_); + if (name.find(infilBuilding.nameString()) != std::string::npos) { - EXPECT_EQ(0.05, i); - EXPECT_EQ(infilBuilding.airChangesperHour().get() * spaceVolume / 3600.0, i); + EXPECT_EQ(target_->iddObject().type(), IddObjectType::SpaceList); + EXPECT_EQ(buildingSpaceType.nameString(), target_->nameString()); + EXPECT_EQ("AirChanges/Hour", infil.getString(ZoneInfiltration_DesignFlowRateFields::DesignFlowRateCalculationMethod).get()); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperFloorArea)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperExteriorSurfaceArea)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate)); + + ASSERT_FALSE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::AirChangesperHour)); + EXPECT_EQ(infilBuilding.airChangesperHour().get(), infil.getDouble(ZoneInfiltration_DesignFlowRateFields::AirChangesperHour).get()); + } else if (name.find(infilOffice.nameString()) != std::string::npos) { - EXPECT_EQ(0.2, i); - EXPECT_EQ(infilOffice.flowperSpaceFloorArea().get() * spaceFloorArea, i); + EXPECT_EQ(target_->iddObject().type(), IddObjectType::SpaceList); + EXPECT_EQ(officeSpaceType.nameString(), target_->nameString()); + + EXPECT_EQ("Flow/Area", infil.getString(ZoneInfiltration_DesignFlowRateFields::DesignFlowRateCalculationMethod).get()); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate)); + + ASSERT_FALSE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperFloorArea)); + EXPECT_EQ(infilOffice.flowperSpaceFloorArea().get(), infil.getDouble(ZoneInfiltration_DesignFlowRateFields::FlowRateperFloorArea).get()); + + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperExteriorSurfaceArea)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::AirChangesperHour)); + } else if (name.find(infilSpace1.nameString()) != std::string::npos) { - EXPECT_EQ(0.015, i); - EXPECT_EQ(infilSpace1.designFlowRate().get(), i); + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space1.nameString(), target_->nameString()); + + EXPECT_EQ("Flow/Zone", infil.getString(ZoneInfiltration_DesignFlowRateFields::DesignFlowRateCalculationMethod).get()); + + ASSERT_FALSE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate)); + EXPECT_EQ(infilSpace1.designFlowRate().get(), infil.getDouble(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate).get()); + + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperFloorArea)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperExteriorSurfaceArea)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::AirChangesperHour)); + } else if (name.find(infilSpace3.nameString()) != std::string::npos) { - EXPECT_DOUBLE_EQ(0.172, i); - EXPECT_DOUBLE_EQ(infilSpace3.flowperExteriorSurfaceArea().get() * innerSpaceExteriorSurfaceArea, i); + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space3.nameString(), target_->nameString()); + + EXPECT_EQ("Flow/ExteriorArea", infil.getString(ZoneInfiltration_DesignFlowRateFields::DesignFlowRateCalculationMethod).get()); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::DesignFlowRate)); + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperFloorArea)); + + ASSERT_FALSE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::FlowRateperExteriorSurfaceArea)); + EXPECT_EQ(infilSpace3.flowperExteriorSurfaceArea().get(), + infil.getDouble(ZoneInfiltration_DesignFlowRateFields::FlowRateperExteriorSurfaceArea).get()); + + EXPECT_TRUE(infil.isEmpty(ZoneInfiltration_DesignFlowRateFields::AirChangesperHour)); } } - - EXPECT_DOUBLE_EQ(0.687, totalInfiltration); } } diff --git a/src/energyplus/Test/SpaceInfiltrationEffectiveLeakageArea_GTest.cpp b/src/energyplus/Test/SpaceInfiltrationEffectiveLeakageArea_GTest.cpp index ba04851182..b972cc3270 100644 --- a/src/energyplus/Test/SpaceInfiltrationEffectiveLeakageArea_GTest.cpp +++ b/src/energyplus/Test/SpaceInfiltrationEffectiveLeakageArea_GTest.cpp @@ -251,32 +251,57 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationEffectiveLeakageAre EXPECT_EQ(2, w.getObjectsByType(IddObjectType::SpaceList).size()); auto infils = w.getObjectsByType(IddObjectType::ZoneInfiltration_EffectiveLeakageArea); - // I expect infilSpace1, infilSpace3, two infilOffice and two infilBuilding, so 6 total + // I expect infilSpace1, infilSpace3, two infilOffice and two infilBuilding, so 6 total. All pointing to a Space ASSERT_EQ(6, infils.size()); + bool foundOfficeSpace1 = false; + bool foundOfficeSpace2 = false; + bool foundBuildingSpace3 = false; + bool foundBuildingSpace4 = false; + double totalInfiltration = 0.0; // cm2 for (const auto& infil : infils) { auto name = infil.nameString(); - auto z_ = infil.getTarget(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneorSpaceName); - ASSERT_TRUE(z_); - EXPECT_EQ(zone, z_.get()); + auto target_ = infil.getTarget(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneorSpaceName); + ASSERT_TRUE(target_); double i = infil.getDouble(ZoneInfiltration_EffectiveLeakageAreaFields::EffectiveAirLeakageArea).get(); totalInfiltration += i; if (name.find(infilSpace1.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space1.nameString(), target_->nameString()); EXPECT_EQ(0.1, i); EXPECT_EQ(infilSpace1.effectiveAirLeakageArea(), i); } else if (name.find(infilSpace3.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space3.nameString(), target_->nameString()); EXPECT_DOUBLE_EQ(0.2, i); EXPECT_DOUBLE_EQ(infilSpace3.effectiveAirLeakageArea(), i); } else if (name.find(infilOffice.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + if (space1.nameString() == target_->nameString()) { + foundOfficeSpace1 = true; + } else if (space2.nameString() == target_->nameString()) { + foundOfficeSpace2 = true; + } EXPECT_EQ(0.3, i); EXPECT_EQ(infilOffice.effectiveAirLeakageArea(), i); } else if (name.find(infilBuilding.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + if (space3.nameString() == target_->nameString()) { + foundBuildingSpace3 = true; + } else if (space4.nameString() == target_->nameString()) { + foundBuildingSpace4 = true; + } EXPECT_EQ(0.4, i); EXPECT_EQ(infilBuilding.effectiveAirLeakageArea(), i); } } + EXPECT_TRUE(foundOfficeSpace1); + EXPECT_TRUE(foundOfficeSpace2); + EXPECT_TRUE(foundBuildingSpace3); + EXPECT_TRUE(foundBuildingSpace4); + EXPECT_DOUBLE_EQ(1.7, totalInfiltration); } } diff --git a/src/energyplus/Test/SpaceInfiltrationFlowCoefficient_GTest.cpp b/src/energyplus/Test/SpaceInfiltrationFlowCoefficient_GTest.cpp index 87fc4f4124..6a0714ea63 100644 --- a/src/energyplus/Test/SpaceInfiltrationFlowCoefficient_GTest.cpp +++ b/src/energyplus/Test/SpaceInfiltrationFlowCoefficient_GTest.cpp @@ -100,12 +100,15 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationFlowCoefficient) { EXPECT_EQ(0u, w.getObjectsByType(IddObjectType::ZoneInfiltration_FlowCoefficient).size()); } - { - ThermalZone zone(model); - zone.setName("Zone1"); - Space space(model); - space.setThermalZone(zone); - infiltration.setSpace(space); + ThermalZone zone(model); + zone.setName("Zone1"); + Space space(model); + space.setName("Space1"); + space.setThermalZone(zone); + infiltration.setSpace(space); + + for (bool excludeSpaceTranslation : {true, false}) { + ft.setExcludeSpaceTranslation(excludeSpaceTranslation); Workspace w = ft.translateModel(model); EXPECT_EQ(0u, ft.errors().size()); @@ -117,7 +120,11 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationFlowCoefficient) { WorkspaceObject idfObject(idfObjs[0]); EXPECT_EQ("My Infiltration", idfObject.getString(ZoneInfiltration_FlowCoefficientFields::Name).get()); - EXPECT_EQ("Zone1", idfObject.getString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName).get()); + if (excludeSpaceTranslation) { + EXPECT_EQ("Zone1", idfObject.getString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName).get()); + } else { + EXPECT_EQ("Space1", idfObject.getString(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName).get()); + } EXPECT_FALSE(infiltration.schedule()); EXPECT_EQ("Always On Discrete", idfObject.getString(ZoneInfiltration_FlowCoefficientFields::ScheduleName).get()); @@ -411,33 +418,55 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationFlowCoefficient_Spa EXPECT_EQ(2, w.getObjectsByType(IddObjectType::SpaceList).size()); auto infils = w.getObjectsByType(IddObjectType::ZoneInfiltration_FlowCoefficient); - // I expect infilSpace1, infilSpace3, two infilOffice and two infilBuilding, so 6 total + // I expect infilSpace1, infilSpace3, two infilOffice and two infilBuilding, so 6 total, all pointing to a Space ASSERT_EQ(6, infils.size()); + bool foundOfficeSpace1 = false; + bool foundOfficeSpace2 = false; + bool foundBuildingSpace3 = false; + bool foundBuildingSpace4 = false; + for (const auto& infil : infils) { auto name = infil.nameString(); - auto z_ = infil.getTarget(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName); - ASSERT_TRUE(z_); - EXPECT_EQ(zone, z_.get()); + auto target_ = infil.getTarget(ZoneInfiltration_FlowCoefficientFields::ZoneorSpaceName); + ASSERT_TRUE(target_); if (name.find(infilSpace1.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space1.nameString(), target_->nameString()); + EXPECT_EQ(infilSpace1.flowCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::FlowCoefficient).get()); EXPECT_EQ(infilSpace1.stackCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::StackCoefficient).get()); EXPECT_EQ(infilSpace1.pressureExponent(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::PressureExponent).get()); EXPECT_EQ(infilSpace1.windCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::WindCoefficient).get()); EXPECT_EQ(infilSpace1.shelterFactor(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::ShelterFactor).get()); } else if (name.find(infilSpace3.nameString()) != std::string::npos) { + EXPECT_EQ(target_->iddObject().type(), IddObjectType::Space); + EXPECT_EQ(space3.nameString(), target_->nameString()); + EXPECT_EQ(infilSpace3.flowCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::FlowCoefficient).get()); EXPECT_EQ(infilSpace3.stackCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::StackCoefficient).get()); EXPECT_EQ(infilSpace3.pressureExponent(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::PressureExponent).get()); EXPECT_EQ(infilSpace3.windCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::WindCoefficient).get()); EXPECT_EQ(infilSpace3.shelterFactor(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::ShelterFactor).get()); } else if (name.find(infilOffice.nameString()) != std::string::npos) { + if (space1.nameString() == target_->nameString()) { + foundOfficeSpace1 = true; + } else if (space2.nameString() == target_->nameString()) { + foundOfficeSpace2 = true; + } + EXPECT_EQ(infilOffice.flowCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::FlowCoefficient).get()); EXPECT_EQ(infilOffice.stackCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::StackCoefficient).get()); EXPECT_EQ(infilOffice.pressureExponent(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::PressureExponent).get()); EXPECT_EQ(infilOffice.windCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::WindCoefficient).get()); EXPECT_EQ(infilOffice.shelterFactor(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::ShelterFactor).get()); } else if (name.find(infilBuilding.nameString()) != std::string::npos) { + if (space3.nameString() == target_->nameString()) { + foundBuildingSpace3 = true; + } else if (space4.nameString() == target_->nameString()) { + foundBuildingSpace4 = true; + } + EXPECT_EQ(infilBuilding.flowCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::FlowCoefficient).get()); EXPECT_EQ(infilBuilding.stackCoefficient(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::StackCoefficient).get()); EXPECT_EQ(infilBuilding.pressureExponent(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::PressureExponent).get()); @@ -445,5 +474,10 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SpaceInfiltrationFlowCoefficient_Spa EXPECT_EQ(infilBuilding.shelterFactor(), infil.getDouble(ZoneInfiltration_FlowCoefficientFields::ShelterFactor).get()); } } + + EXPECT_TRUE(foundOfficeSpace1); + EXPECT_TRUE(foundOfficeSpace2); + EXPECT_TRUE(foundBuildingSpace3); + EXPECT_TRUE(foundBuildingSpace4); } } From 2f7a98f6cd8dd2669e48346ba59c1ebb505d07b4 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 8 Sep 2022 14:43:34 +0200 Subject: [PATCH 4/4] cf #4649 - SwimmingPool:Indoor: field Make-up Water Supply Schedule Name no longer required --- .../ForwardTranslator/ForwardTranslateSwimmingPoolIndoor.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSwimmingPoolIndoor.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSwimmingPoolIndoor.cpp index 1d6973ce4e..9986fda1f6 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSwimmingPoolIndoor.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSwimmingPoolIndoor.cpp @@ -86,9 +86,6 @@ namespace energyplus { Schedule makeupWaterSupplySchedule = modelObject.makeupWaterSupplySchedule(); if (auto _sch = translateAndMapModelObject(makeupWaterSupplySchedule)) { idfObject.setString(SwimmingPool_IndoorFields::MakeupWaterSupplyScheduleName, _sch->nameString()); - } else { - LOG(Error, "Missing required 'Make-up Water Supply Schedule Name' for " << modelObject.briefDescription()); - return boost::none; } // Cover Schedule Name: Required Object