Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 22 additions & 41 deletions src/energyplus/ForwardTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -316,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<SpaceType>()) {
auto spi = sp.spaceInfiltrationDesignFlowRates();
// auto spi = sp.spaceInfiltrationDesignFlowRates();
auto spiel = sp.spaceInfiltrationEffectiveLeakageAreas();
auto spifc = sp.spaceInfiltrationFlowCoefficients();
std::vector<SpaceLoad> 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<SpaceLoad>();
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<SpaceLoad>();
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<SpaceInfiltrationDesignFlowRate>()) {
// 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<SpaceLoad> 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<SpaceLoad>();
infilClone.setParent(space);
}
infil.remove();
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/energyplus/ForwardTranslator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ namespace model {
class SizingPlant;
class SizingSystem;
class SizingZone;
class SpaceLoadInstance;
class SpaceLoad;
class StandardGlazing;
class StandardOpaqueMaterial;
class SimpleGlazing;
Expand Down Expand Up @@ -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<IdfObject> translateAndMapModelObject(model::ModelObject& modelObject);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.numberofPeopleSchedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,36 +55,14 @@ namespace openstudio {
namespace energyplus {

boost::optional<IdfObject> 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> space = modelObject.space();
boost::optional<SpaceType> 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> 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> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,10 @@ namespace openstudio {
namespace energyplus {

boost::optional<IdfObject> 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> space = modelObject.space();
boost::optional<SpaceType> 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> 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> schedule = modelObject.schedule();
if (schedule) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,9 @@ namespace energyplus {

boost::optional<IdfObject> ForwardTranslator::translateSpaceInfiltrationFlowCoefficient(SpaceInfiltrationFlowCoefficient& modelObject) {

IdfObject idfObject(openstudio::IddObjectType::ZoneInfiltration_FlowCoefficient);
idfObject.setString(ZoneInfiltration_FlowCoefficientFields::Name, modelObject.nameString());

boost::optional<Space> space = modelObject.space();
boost::optional<SpaceType> 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> 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> schedule_ = modelObject.schedule();
if (!schedule_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,6 @@ namespace energyplus {
for (const auto& s : spaces) {
idfObject->pushExtensibleGroup(std::vector<std::string>(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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> schedule = modelObject.schedule()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading