From ccd75316f7dbeee58131a2b3c06aeaa3c624c32b Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 12:59:47 +0200 Subject: [PATCH 01/24] Naive IDD add Chiller:Electric:ASHRAE205 --- resources/energyplus/ProposedEnergy+.idd | 121 ++++++++++++++++++++++ resources/model/OpenStudio.idd | 124 +++++++++++++++++++++++ 2 files changed, 245 insertions(+) diff --git a/resources/energyplus/ProposedEnergy+.idd b/resources/energyplus/ProposedEnergy+.idd index 00a56b4725..a7aedd13f3 100644 --- a/resources/energyplus/ProposedEnergy+.idd +++ b/resources/energyplus/ProposedEnergy+.idd @@ -42357,6 +42357,127 @@ Boiler:Steam, \retaincase \default General +Chiller:Electric:ASHRAE205, + \min-fields 11 + \memo This chiller model utilizes ASHRAE Standard 205 compliant representations + \memo for chillers (Representation Specification RS0001). + A1, \field Name + \type alpha + \reference Chillers + \required-field + \reference-class-name validPlantEquipmentTypes + \reference validPlantEquipmentNames + \reference-class-name validBranchEquipmentTypes + \reference validBranchEquipmentNames + A2, \field Representation File Name + \note The name of the ASHRAE205 RS0001 (chiller) representation file + \type alpha + \retaincase + \required-field + A3, \field Performance Interpolation Method + \type choice + \key Linear + \key Cubic + \default Linear + N1, \field Rated Capacity + \note Not yet implemented / reserved for future use. Full load capacity at AHRI 550/590 test conditions. + \note Used to scale representation data. + \type real + \units W + \minimum> 0.0 + \autosizable + \default autosize + N2, \field Sizing Factor + \note Multiplies the autosized flow rates. + \type real + \minimum> 0.0 + \default 1.0 + A4 , \field Ambient Temperature Indicator + \note Used to determine standby losses + \required-field + \type choice + \key Schedule + \key Zone + \key Outdoors + A5 , \field Ambient Temperature Schedule Name + \type object-list + \object-list ScheduleNames + A6, \field Ambient Temperature Zone Name + \note Any energy imbalance on the chiller results in heat added to this zone. + \type object-list + \object-list ZoneNames + A7, \field Ambient Temperature Outdoor Air Node Name + \type node + \note required for Ambient Temperature Indicator=Outdoors + A8, \field Chilled Water Inlet Node Name + \type node + \required-field + A9, \field Chilled Water Outlet Node Name + \type node + \required-field + A10, \field Chilled Water Maximum Requested Flow Rate + \type real + \units m3/s + \minimum> 0 + \autosizable + \ip-units gal/min + \default autosize + A11, \field Condenser Inlet Node Name + \type node + A12, \field Condenser Outlet Node Name + \type node + A13, \field Condenser Maximum Requested Flow Rate + \type real + \units m3/s + \minimum> 0 + \autosizable + \ip-units gal/min + \default autosize + A14, \field Chiller Flow Mode + \note Select operating mode for fluid flow through the chiller. "NotModulated" is for + \note either variable or constant pumping with flow controlled by the external plant system. + \note "ConstantFlow" is for constant pumping with flow controlled by chiller to operate at + \note full design flow rate. "LeavingSetpointModulated" is for variable pumping with flow + \note controlled by chiller to vary flow to target a leaving temperature setpoint. + \type choice + \key ConstantFlow + \key LeavingSetpointModulated + \key NotModulated + \default NotModulated + A15, \field Oil Cooler Inlet Node Name + \note Use if the oil cooler uses an external cooling loop, otherwise the oil cooler will add + \note heat to the ambient conditions (i.e., it is air cooled). + \type node + A16, \field Oil Cooler Outlet Node Name + \type node + A17, \field Oil Cooler Design Flow Rate + \type real + \units m3/s + \minimum> 0 + \ip-units gal/min + A18, \field Auxiliary Inlet Node Name + \note Use if the auxiliary components of the chiller use an external cooling loop, otherwise + \note the auxiliary components will add heat to the ambient conditions (i.e., they are air cooled). + \type node + A19, \field Auxiliary Outlet Node Name + \type node + A20, \field Auxiliary Cooling Design Flow Rate + \type real + \units m3/s + \minimum> 0 + \ip-units gal/min + A21, \field Heat Recovery Inlet Node Name + \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. + \type node + A21, \field Heat Recovery Outlet Node Name + \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. + \type node + A23; \field End-Use Subcategory + \note Any text may be used here to categorize the end-uses in the ABUPS End Uses by Subcategory table. + \type alpha + \retaincase + \default General + Chiller:Electric:EIR, \min-fields 23 \memo This chiller model is the empirical model from the DOE-2 building Energy diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index 0629c730b7..d406a94e81 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -13813,6 +13813,130 @@ OS:Chiller:Electric:ReformulatedEIR, \retaincase \default General +OS:Chiller:Electric:ASHRAE205, + \min-fields 12 + \memo This chiller model utilizes ASHRAE Standard 205 compliant representations + \memo for chillers (Representation Specification RS0001). + A1, \field Handle + \type handle + \required-field + A2, \field Name + \type alpha + \reference Chillers + \required-field + \reference-class-name validPlantEquipmentTypes + \reference validPlantEquipmentNames + \reference-class-name validBranchEquipmentTypes + \reference validBranchEquipmentNames + A3, \field Representation File Name + \note The name of the ASHRAE205 RS0001 (chiller) representation file + \type alpha + \retaincase + \required-field + A4, \field Performance Interpolation Method + \type choice + \key Linear + \key Cubic + \default Linear + N1, \field Rated Capacity + \note Not yet implemented / reserved for future use. Full load capacity at AHRI 550/590 test conditions. + \note Used to scale representation data. + \type real + \units W + \minimum> 0.0 + \autosizable + \default autosize + N2, \field Sizing Factor + \note Multiplies the autosized flow rates. + \type real + \minimum> 0.0 + \default 1.0 + A5 , \field Ambient Temperature Indicator + \note Used to determine standby losses + \required-field + \type choice + \key Schedule + \key Zone + \key Outdoors + A6 , \field Ambient Temperature Schedule Name + \type object-list + \object-list ScheduleNames + A7, \field Ambient Temperature Zone Name + \note Any energy imbalance on the chiller results in heat added to this zone. + \type object-list + \object-list ZoneNames + A8, \field Ambient Temperature Outdoor Air Node Name + \type node + \note required for Ambient Temperature Indicator=Outdoors + A9, \field Chilled Water Inlet Node Name + \type node + \required-field + A10, \field Chilled Water Outlet Node Name + \type node + \required-field + A11, \field Chilled Water Maximum Requested Flow Rate + \type real + \units m3/s + \minimum> 0 + \autosizable + \ip-units gal/min + \default autosize + A12, \field Condenser Inlet Node Name + \type node + A13, \field Condenser Outlet Node Name + \type node + A14, \field Condenser Maximum Requested Flow Rate + \type real + \units m3/s + \minimum> 0 + \autosizable + \ip-units gal/min + \default autosize + A15, \field Chiller Flow Mode + \note Select operating mode for fluid flow through the chiller. "NotModulated" is for + \note either variable or constant pumping with flow controlled by the external plant system. + \note "ConstantFlow" is for constant pumping with flow controlled by chiller to operate at + \note full design flow rate. "LeavingSetpointModulated" is for variable pumping with flow + \note controlled by chiller to vary flow to target a leaving temperature setpoint. + \type choice + \key ConstantFlow + \key LeavingSetpointModulated + \key NotModulated + \default NotModulated + A16, \field Oil Cooler Inlet Node Name + \note Use if the oil cooler uses an external cooling loop, otherwise the oil cooler will add + \note heat to the ambient conditions (i.e., it is air cooled). + \type node + A17, \field Oil Cooler Outlet Node Name + \type node + A18, \field Oil Cooler Design Flow Rate + \type real + \units m3/s + \minimum> 0 + \ip-units gal/min + A19, \field Auxiliary Inlet Node Name + \note Use if the auxiliary components of the chiller use an external cooling loop, otherwise + \note the auxiliary components will add heat to the ambient conditions (i.e., they are air cooled). + \type node + A20, \field Auxiliary Outlet Node Name + \type node + A21, \field Auxiliary Cooling Design Flow Rate + \type real + \units m3/s + \minimum> 0 + \ip-units gal/min + A22, \field Heat Recovery Inlet Node Name + \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. + \type node + A22, \field Heat Recovery Outlet Node Name + \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. + \type node + A24; \field End-Use Subcategory + \note Any text may be used here to categorize the end-uses in the ABUPS End Uses by Subcategory table. + \type alpha + \retaincase + \default General + OS:CentralHeatPumpSystem, A1, \field Handle \type handle From 22b2099daeaaab732f7fd949c6d15605174883a9 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 13:03:10 +0200 Subject: [PATCH 02/24] Adjust for ConnectionObject + ExternalFileNames --- resources/model/OpenStudio.idd | 44 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index d406a94e81..7e6d607a29 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -13824,14 +13824,11 @@ OS:Chiller:Electric:ASHRAE205, \type alpha \reference Chillers \required-field - \reference-class-name validPlantEquipmentTypes - \reference validPlantEquipmentNames - \reference-class-name validBranchEquipmentTypes - \reference validBranchEquipmentNames + \reference ConnectionObject A3, \field Representation File Name \note The name of the ASHRAE205 RS0001 (chiller) representation file - \type alpha - \retaincase + \type object-list + \object-list ExternalFileNames \required-field A4, \field Performance Interpolation Method \type choice @@ -13864,15 +13861,18 @@ OS:Chiller:Electric:ASHRAE205, A7, \field Ambient Temperature Zone Name \note Any energy imbalance on the chiller results in heat added to this zone. \type object-list - \object-list ZoneNames + \object-list ThermalZoneNames A8, \field Ambient Temperature Outdoor Air Node Name - \type node + \type object-list + \object-list ConnectionNames \note required for Ambient Temperature Indicator=Outdoors A9, \field Chilled Water Inlet Node Name - \type node + \type object-list + \object-list ConnectionNames \required-field A10, \field Chilled Water Outlet Node Name - \type node + \type object-list + \object-list ConnectionNames \required-field A11, \field Chilled Water Maximum Requested Flow Rate \type real @@ -13882,9 +13882,11 @@ OS:Chiller:Electric:ASHRAE205, \ip-units gal/min \default autosize A12, \field Condenser Inlet Node Name - \type node + \type object-list + \object-list ConnectionNames A13, \field Condenser Outlet Node Name - \type node + \type object-list + \object-list ConnectionNames A14, \field Condenser Maximum Requested Flow Rate \type real \units m3/s @@ -13906,9 +13908,11 @@ OS:Chiller:Electric:ASHRAE205, A16, \field Oil Cooler Inlet Node Name \note Use if the oil cooler uses an external cooling loop, otherwise the oil cooler will add \note heat to the ambient conditions (i.e., it is air cooled). - \type node + \type object-list + \object-list ConnectionNames A17, \field Oil Cooler Outlet Node Name - \type node + \type object-list + \object-list ConnectionNames A18, \field Oil Cooler Design Flow Rate \type real \units m3/s @@ -13917,9 +13921,11 @@ OS:Chiller:Electric:ASHRAE205, A19, \field Auxiliary Inlet Node Name \note Use if the auxiliary components of the chiller use an external cooling loop, otherwise \note the auxiliary components will add heat to the ambient conditions (i.e., they are air cooled). - \type node + \type object-list + \object-list ConnectionNames A20, \field Auxiliary Outlet Node Name - \type node + \type object-list + \object-list ConnectionNames A21, \field Auxiliary Cooling Design Flow Rate \type real \units m3/s @@ -13927,10 +13933,12 @@ OS:Chiller:Electric:ASHRAE205, \ip-units gal/min A22, \field Heat Recovery Inlet Node Name \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. - \type node + \type object-list + \object-list ConnectionNames A22, \field Heat Recovery Outlet Node Name \note Not yet implemented / reserved for future use. Heat recovery is not yet within scope of ASHRAE Stanard 205. - \type node + \type object-list + \object-list ConnectionNames A24; \field End-Use Subcategory \note Any text may be used here to categorize the end-uses in the ABUPS End Uses by Subcategory table. \type alpha From 75b23163cec974fa65aed998824975f5b14ad676 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 13:07:21 +0200 Subject: [PATCH 03/24] Make everything rquired-field where appropriate --- resources/model/OpenStudio.idd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index 7e6d607a29..af5090ad23 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -13834,7 +13834,7 @@ OS:Chiller:Electric:ASHRAE205, \type choice \key Linear \key Cubic - \default Linear + \required-field N1, \field Rated Capacity \note Not yet implemented / reserved for future use. Full load capacity at AHRI 550/590 test conditions. \note Used to scale representation data. @@ -13842,12 +13842,12 @@ OS:Chiller:Electric:ASHRAE205, \units W \minimum> 0.0 \autosizable - \default autosize + \required-field N2, \field Sizing Factor \note Multiplies the autosized flow rates. \type real \minimum> 0.0 - \default 1.0 + \required-field A5 , \field Ambient Temperature Indicator \note Used to determine standby losses \required-field @@ -13880,7 +13880,7 @@ OS:Chiller:Electric:ASHRAE205, \minimum> 0 \autosizable \ip-units gal/min - \default autosize + \required-field A12, \field Condenser Inlet Node Name \type object-list \object-list ConnectionNames @@ -13893,7 +13893,7 @@ OS:Chiller:Electric:ASHRAE205, \minimum> 0 \autosizable \ip-units gal/min - \default autosize + \required-field A15, \field Chiller Flow Mode \note Select operating mode for fluid flow through the chiller. "NotModulated" is for \note either variable or constant pumping with flow controlled by the external plant system. @@ -13904,7 +13904,7 @@ OS:Chiller:Electric:ASHRAE205, \key ConstantFlow \key LeavingSetpointModulated \key NotModulated - \default NotModulated + \required-field A16, \field Oil Cooler Inlet Node Name \note Use if the oil cooler uses an external cooling loop, otherwise the oil cooler will add \note heat to the ambient conditions (i.e., it is air cooled). From 7f278fcaa5ba6a3d582e1e0d8f2b77fa517ff567 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 14:33:50 +0200 Subject: [PATCH 04/24] Commit stub files ``` $os_build3/Products/openstudio GenerateClass.rb -c "ChillerElectricASHRAE205" -b "WaterToWaterComponent" -i "OS:Chiller:Electric:ASHRAE205" -s model -o /media/DataExt4/Software/Others/OpenStudio3/src/model/ -p -f -r ``` --- ...rwardTranslateChillerElectricASHRAE205.cpp | 222 +++++ ...verseTranslateChillerElectricASHRAE205.cpp | 298 ++++++ src/model/ChillerElectricASHRAE205.cpp | 861 ++++++++++++++++++ src/model/ChillerElectricASHRAE205.hpp | 292 ++++++ src/model/ChillerElectricASHRAE205_Impl.hpp | 290 ++++++ .../test/ChillerElectricASHRAE205_GTest.cpp | 270 ++++++ 6 files changed, 2233 insertions(+) create mode 100644 src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp create mode 100644 src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp create mode 100644 src/model/ChillerElectricASHRAE205.cpp create mode 100644 src/model/ChillerElectricASHRAE205.hpp create mode 100644 src/model/ChillerElectricASHRAE205_Impl.hpp create mode 100644 src/model/test/ChillerElectricASHRAE205_GTest.cpp diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp new file mode 100644 index 0000000000..3def4feb58 --- /dev/null +++ b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp @@ -0,0 +1,222 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include "../ForwardTranslator.hpp" +#include "../../model/Model.hpp" + +#include "../../model/ChillerElectricASHRAE205.hpp" + +// TODO: Check the following class names against object getters and setters. +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" + +#include "../../model/Zone.hpp" +#include "../../model/Zone_Impl.hpp" + +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" + +#include +// #include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + + boost::optional ForwardTranslator::translateChillerElectricASHRAE205(model::ChillerElectricASHRAE205& modelObject) { + boost::optional result; + boost::optional _wo; + boost::optional _mo; + + // Instantiate an IdfObject of the class to store the values + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Chiller_Electric_ASHRAE205, modelObject); + // If it doesn't have a name, or if you aren't sure you are going to want to return it + // IdfObject idfObject( openstudio::IddObjectType::Chiller_Electric_ASHRAE205 ); + // m_idfObjects.push_back(idfObject); + + // TODO: Note JM 2018-10-17 + // You are responsible for implementing any additional logic based on choice fields, etc. + // The ForwardTranslator generator script is meant to facilitate your work, not get you 100% of the way + + // TODO: If you keep createRegisterAndNameIdfObject above, you don't need this. + // But in some cases, you'll want to handle failure without pushing to the map + // Name + if (boost::optional moName = modelObject.name()) { + idfObject.setName(*moName); + } + + // Representation File Name: Required String + std::string representationFileName = modelObject.representationFileName(); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, representationFileName); + + // Performance Interpolation Method: Optional String + std::string performanceInterpolationMethod = modelObject.performanceInterpolationMethod(); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); + + if (modelObject.isRatedCapacityAutosized()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "Autosize"); + } else { + // Rated Capacity: boost::optional + if (boost::optional _ratedCapacity = modelObject.ratedCapacity()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::RatedCapacity, _ratedCapacity.get()); + } + } + + // Sizing Factor: Optional Double + double sizingFactor = modelObject.sizingFactor(); + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor, sizingFactor); + + // Ambient Temperature Indicator: Required String + std::string ambientTemperatureIndicator = modelObject.ambientTemperatureIndicator(); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, ambientTemperatureIndicator); + + // Ambient Temperature Schedule Name: Optional Object + if (boost::optional _ambientTemperatureSchedule = modelObject.ambientTemperatureSchedule()) { + if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureSchedule.get())) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, _owo->nameString()); + } + } + + // Ambient Temperature Zone Name: Optional Object + if (boost::optional _ambientTemperatureZone = modelObject.ambientTemperatureZone()) { + if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureZone.get())) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, _owo->nameString()); + } + } + + // Ambient Temperature Outdoor Air Node Name: Optional Node + Node ambientTemperatureOutdoorAirNodeName = modelObject.ambientTemperatureOutdoorAirNodeName(); + if (boost::optional _owo = translateAndMapModelObject(ambientTemperatureOutdoorAirNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, _owo->nameString()); + } + + // Chilled Water Inlet Node Name: Required Node + Node chilledWaterInletNodeName = modelObject.chilledWaterInletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(chilledWaterInletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, _owo->nameString()); + } + + // Chilled Water Outlet Node Name: Required Node + Node chilledWaterOutletNodeName = modelObject.chilledWaterOutletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(chilledWaterOutletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, _owo->nameString()); + } + + if (modelObject.isChilledWaterMaximumRequestedFlowRateAutosized()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "Autosize"); + } else { + // Chilled Water Maximum Requested Flow Rate: boost::optional + if (boost::optional _chilledWaterMaximumRequestedFlowRate = modelObject.chilledWaterMaximumRequestedFlowRate()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, _chilledWaterMaximumRequestedFlowRate.get()); + } + } + + // Condenser Inlet Node Name: Optional Node + Node condenserInletNodeName = modelObject.condenserInletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(condenserInletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, _owo->nameString()); + } + + // Condenser Outlet Node Name: Optional Node + Node condenserOutletNodeName = modelObject.condenserOutletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(condenserOutletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, _owo->nameString()); + } + + if (modelObject.isCondenserMaximumRequestedFlowRateAutosized()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "Autosize"); + } else { + // Condenser Maximum Requested Flow Rate: boost::optional + if (boost::optional _condenserMaximumRequestedFlowRate = modelObject.condenserMaximumRequestedFlowRate()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, _condenserMaximumRequestedFlowRate.get()); + } + } + + // Chiller Flow Mode: Optional String + std::string chillerFlowMode = modelObject.chillerFlowMode(); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, chillerFlowMode); + + // Oil Cooler Inlet Node Name: Optional Node + Node oilCoolerInletNodeName = modelObject.oilCoolerInletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(oilCoolerInletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, _owo->nameString()); + } + + // Oil Cooler Outlet Node Name: Optional Node + Node oilCoolerOutletNodeName = modelObject.oilCoolerOutletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(oilCoolerOutletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, _owo->nameString()); + } + + // Oil Cooler Design Flow Rate: boost::optional + if (boost::optional _oilCoolerDesignFlowRate = modelObject.oilCoolerDesignFlowRate()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, _oilCoolerDesignFlowRate.get()); + } + + // Auxiliary Inlet Node Name: Optional Node + Node auxiliaryInletNodeName = modelObject.auxiliaryInletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(auxiliaryInletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, _owo->nameString()); + } + + // Auxiliary Outlet Node Name: Optional Node + Node auxiliaryOutletNodeName = modelObject.auxiliaryOutletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(auxiliaryOutletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, _owo->nameString()); + } + + // Auxiliary Cooling Design Flow Rate: boost::optional + if (boost::optional _auxiliaryCoolingDesignFlowRate = modelObject.auxiliaryCoolingDesignFlowRate()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, _auxiliaryCoolingDesignFlowRate.get()); + } + + // Heat Recovery Inlet Node Name: Optional Node + Node heatRecoveryInletNodeName = modelObject.heatRecoveryInletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(heatRecoveryInletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, _owo->nameString()); + } + + // Heat Recovery Outlet Node Name: Optional Node + Node heatRecoveryOutletNodeName = modelObject.heatRecoveryOutletNodeName(); + if (boost::optional _owo = translateAndMapModelObject(heatRecoveryOutletNodeName)) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, _owo->nameString()); + } + + // End-Use Subcategory: Optional String + std::string endUseSubcategory = modelObject.endUseSubcategory(); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, endUseSubcategory); + + return idfObject; + } // End of translate function + +} // end namespace energyplus +} // end namespace openstudio \ No newline at end of file diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp new file mode 100644 index 0000000000..6d17b3af63 --- /dev/null +++ b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp @@ -0,0 +1,298 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/ChillerElectricASHRAE205.hpp" + +// TODO: Check the following class names against object getters and setters. +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" + +#include "../../model/Zone.hpp" +#include "../../model/Zone_Impl.hpp" + +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" + +#include +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + + boost::optional ReverseTranslator::translateChillerElectricASHRAE205(const WorkspaceObject& workspaceObject) { + boost::optional result; + boost::optional _wo; + boost::optional _mo; + + // Instantiate an object of the class to store the values, + // but we don't return it until we know it's ok + // TODO: check constructor, it might need other objects + openstudio::model::ChillerElectricASHRAE205 modelObject(m_model); + + // TODO: Note JM 2018-10-17 + // You are responsible for implementing any additional logic based on choice fields, etc. + // The ReverseTranslator generator script is meant to facilitate your work, not get you 100% of the way + + // Name + if (boost::optional _name = workspaceObject.name()) { + modelObject.setName(_name.get()); + } + + // Representation File Name: Required String + if (boost::optional _representationFileName = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName)) { + modelObject.setRepresentationFileName(_representationFileName.get()); + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required property 'Representation File Name'"); + return result; + } + + // Performance Interpolation Method: Optional String + if (boost::optional _performanceInterpolationMethod = + workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod)) { + modelObject.setPerformanceInterpolationMethod(_performanceInterpolationMethod.get()); + } + + // Rated Capacity: Optional Double + if (boost::optional _ratedCapacity = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::RatedCapacity)) { + modelObject.setRatedCapacity(_ratedCapacity.get()); + } + + // Sizing Factor: Optional Double + if (boost::optional _sizingFactor = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor)) { + modelObject.setSizingFactor(_sizingFactor.get()); + } + + // Ambient Temperature Indicator: Required String + if (boost::optional _ambientTemperatureIndicator = + workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator)) { + modelObject.setAmbientTemperatureIndicator(_ambientTemperatureIndicator.get()); + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required property 'Ambient Temperature Indicator'"); + return result; + } + + // Ambient Temperature Schedule Name: Optional Object + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _ambientTemperatureSchedule = _mo->optionalCast()) { + modelObject.setAmbientTemperatureSchedule(_ambientTemperatureSchedule.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Schedule Name'"); + } + } + } + // Ambient Temperature Zone Name: Optional Object + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _ambientTemperatureZone = _mo->optionalCast()) { + modelObject.setAmbientTemperatureZone(_ambientTemperatureZone.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Zone Name'"); + } + } + } + // Ambient Temperature Outdoor Air Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _ambientTemperatureOutdoorAirNodeName = _mo->optionalCast()) { + modelObject.setAmbientTemperatureOutdoorAirNodeName(_ambientTemperatureOutdoorAirNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Outdoor Air Node Name'"); + } + } + } + // Chilled Water Inlet Node Name: Required Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _chilledWaterInletNodeName = _mo->optionalCast()) { + modelObject.setChilledWaterInletNodeName(_chilledWaterInletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Chilled Water Inlet Node Name'"); + } + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot reverse translate required object 'Chilled Water Inlet Node Name'"); + return result; + } + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required object 'Chilled Water Inlet Node Name'"); + return result; + } + // Chilled Water Outlet Node Name: Required Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _chilledWaterOutletNodeName = _mo->optionalCast()) { + modelObject.setChilledWaterOutletNodeName(_chilledWaterOutletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Chilled Water Outlet Node Name'"); + } + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot reverse translate required object 'Chilled Water Outlet Node Name'"); + return result; + } + } else { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required object 'Chilled Water Outlet Node Name'"); + return result; + } + // Chilled Water Maximum Requested Flow Rate: Optional Double + if (boost::optional _chilledWaterMaximumRequestedFlowRate = + workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate)) { + modelObject.setChilledWaterMaximumRequestedFlowRate(_chilledWaterMaximumRequestedFlowRate.get()); + } + + // Condenser Inlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _condenserInletNodeName = _mo->optionalCast()) { + modelObject.setCondenserInletNodeName(_condenserInletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Condenser Inlet Node Name'"); + } + } + } + // Condenser Outlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _condenserOutletNodeName = _mo->optionalCast()) { + modelObject.setCondenserOutletNodeName(_condenserOutletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Condenser Outlet Node Name'"); + } + } + } + // Condenser Maximum Requested Flow Rate: Optional Double + if (boost::optional _condenserMaximumRequestedFlowRate = + workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate)) { + modelObject.setCondenserMaximumRequestedFlowRate(_condenserMaximumRequestedFlowRate.get()); + } + + // Chiller Flow Mode: Optional String + if (boost::optional _chillerFlowMode = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode)) { + modelObject.setChillerFlowMode(_chillerFlowMode.get()); + } + + // Oil Cooler Inlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _oilCoolerInletNodeName = _mo->optionalCast()) { + modelObject.setOilCoolerInletNodeName(_oilCoolerInletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Oil Cooler Inlet Node Name'"); + } + } + } + // Oil Cooler Outlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _oilCoolerOutletNodeName = _mo->optionalCast()) { + modelObject.setOilCoolerOutletNodeName(_oilCoolerOutletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Oil Cooler Outlet Node Name'"); + } + } + } + // Oil Cooler Design Flow Rate: Optional Double + if (boost::optional _oilCoolerDesignFlowRate = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate)) { + modelObject.setOilCoolerDesignFlowRate(_oilCoolerDesignFlowRate.get()); + } + + // Auxiliary Inlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _auxiliaryInletNodeName = _mo->optionalCast()) { + modelObject.setAuxiliaryInletNodeName(_auxiliaryInletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Auxiliary Inlet Node Name'"); + } + } + } + // Auxiliary Outlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _auxiliaryOutletNodeName = _mo->optionalCast()) { + modelObject.setAuxiliaryOutletNodeName(_auxiliaryOutletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Auxiliary Outlet Node Name'"); + } + } + } + // Auxiliary Cooling Design Flow Rate: Optional Double + if (boost::optional _auxiliaryCoolingDesignFlowRate = + workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate)) { + modelObject.setAuxiliaryCoolingDesignFlowRate(_auxiliaryCoolingDesignFlowRate.get()); + } + + // Heat Recovery Inlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _heatRecoveryInletNodeName = _mo->optionalCast()) { + modelObject.setHeatRecoveryInletNodeName(_heatRecoveryInletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Heat Recovery Inlet Node Name'"); + } + } + } + // Heat Recovery Outlet Node Name: Optional Node + if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName))) { + if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { + // TODO: check return types + if (boost::optional _heatRecoveryOutletNodeName = _mo->optionalCast()) { + modelObject.setHeatRecoveryOutletNodeName(_heatRecoveryOutletNodeName.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Heat Recovery Outlet Node Name'"); + } + } + } + // End-Use Subcategory: Optional String + if (boost::optional _endUseSubcategory = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory)) { + modelObject.setEndUseSubcategory(_endUseSubcategory.get()); + } + + result = modelObject; + return result; + } // End of translate function + +} // end namespace energyplus +} // end namespace openstudio \ No newline at end of file diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp new file mode 100644 index 0000000000..7f5463120e --- /dev/null +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -0,0 +1,861 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include "ChillerElectricASHRAE205.hpp" +#include "ChillerElectricASHRAE205_Impl.hpp" + +// TODO: Check the following class names against object getters and setters. +#include "ExternalFile.hpp" +#include "ExternalFile_Impl.hpp" +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "ThermalZone.hpp" +#include "ThermalZone_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "Connection.hpp" +#include "Connection_Impl.hpp" +#include "ScheduleTypeLimits.hpp" +#include "ScheduleTypeRegistry.hpp" + +#include +#include +#include + +#include "../utilities/units/Unit.hpp" + +#include "../utilities/core/Assert.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + ChillerElectricASHRAE205_Impl::ChillerElectricASHRAE205_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : WaterToWaterComponent_Impl(idfObject, model, keepHandle) { + OS_ASSERT(idfObject.iddObject().type() == ChillerElectricASHRAE205::iddObjectType()); + } + + ChillerElectricASHRAE205_Impl::ChillerElectricASHRAE205_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, + bool keepHandle) + : WaterToWaterComponent_Impl(other, model, keepHandle) { + OS_ASSERT(other.iddObject().type() == ChillerElectricASHRAE205::iddObjectType()); + } + + ChillerElectricASHRAE205_Impl::ChillerElectricASHRAE205_Impl(const ChillerElectricASHRAE205_Impl& other, Model_Impl* model, bool keepHandle) + : WaterToWaterComponent_Impl(other, model, keepHandle) {} + + const std::vector& ChillerElectricASHRAE205_Impl::outputVariableNames() const { + static std::vector result; + if (result.empty()) { + } + return result; + } + + IddObjectType ChillerElectricASHRAE205_Impl::iddObjectType() const { + return ChillerElectricASHRAE205::iddObjectType(); + } + + std::vector ChillerElectricASHRAE205_Impl::getScheduleTypeKeys(const Schedule& schedule) const { + // TODO: Check schedule display names. + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()), e(fieldIndices.end()); + if (std::find(b, e, OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName) != e) { + result.push_back(ScheduleTypeKey("ChillerElectricASHRAE205", "Ambient Temperature")); + } + return result; + } + + ExternalFile ChillerElectricASHRAE205_Impl::representationFile() const { + boost::optional value = optionalRepresentationFile(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Representation File attached."); + } + return value.get(); + } + + std::string ChillerElectricASHRAE205_Impl::performanceInterpolationMethod() const { + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional ChillerElectricASHRAE205_Impl::ratedCapacity() const { + return getDouble(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, true); + } + + bool ChillerElectricASHRAE205_Impl::isRatedCapacityAutosized() const { + bool result = false; + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + boost::optional ChillerElectricASHRAE205_Impl::autosizedRatedCapacity() { + return getAutosizedValue("TODO_CHECK_SQL Rated Capacity", "W"); + } + + double ChillerElectricASHRAE205_Impl::sizingFactor() const { + boost::optional value = getDouble(OS_Chiller_Electric_ASHRAE205Fields::SizingFactor, true); + OS_ASSERT(value); + return value.get(); + } + + std::string ChillerElectricASHRAE205_Impl::ambientTemperatureIndicator() const { + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureSchedule() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName); + } + + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureZone() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName); + } + + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureOutdoorAirNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName); + } + + Connection ChillerElectricASHRAE205_Impl::chilledWaterInletNode() const { + boost::optional value = optionalChilledWaterInletNode(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Chilled Water Inlet Node attached."); + } + return value.get(); + } + + Connection ChillerElectricASHRAE205_Impl::chilledWaterOutletNode() const { + boost::optional value = optionalChilledWaterOutletNode(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Chilled Water Outlet Node attached."); + } + return value.get(); + } + + boost::optional ChillerElectricASHRAE205_Impl::chilledWaterMaximumRequestedFlowRate() const { + return getDouble(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, true); + } + + bool ChillerElectricASHRAE205_Impl::isChilledWaterMaximumRequestedFlowRateAutosized() const { + bool result = false; + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + boost::optional ChillerElectricASHRAE205_Impl::autosizedChilledWaterMaximumRequestedFlowRate() { + return getAutosizedValue("TODO_CHECK_SQL Chilled Water Maximum Requested Flow Rate", "m3/s"); + } + + boost::optional ChillerElectricASHRAE205_Impl::condenserInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::condenserOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::condenserMaximumRequestedFlowRate() const { + return getDouble(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, true); + } + + bool ChillerElectricASHRAE205_Impl::isCondenserMaximumRequestedFlowRateAutosized() const { + bool result = false; + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + boost::optional ChillerElectricASHRAE205_Impl::autosizedCondenserMaximumRequestedFlowRate() { + return getAutosizedValue("TODO_CHECK_SQL Condenser Maximum Requested Flow Rate", "m3/s"); + } + + std::string ChillerElectricASHRAE205_Impl::chillerFlowMode() const { + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerDesignFlowRate() const { + return getDouble(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, true); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryCoolingDesignFlowRate() const { + return getDouble(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, true); + } + + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName); + } + + std::string ChillerElectricASHRAE205_Impl::endUseSubcategory() const { + boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, true); + OS_ASSERT(value); + return value.get(); + } + + bool ChillerElectricASHRAE205_Impl::isEndUseSubcategoryDefaulted() const { + return isEmpty(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory); + } + + bool ChillerElectricASHRAE205_Impl::setRepresentationFile(const ExternalFile& externalFile) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName, externalFile.handle()); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setRatedCapacity(double ratedCapacity) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, ratedCapacity); + return result; + } + + void ChillerElectricASHRAE205_Impl::autosizeRatedCapacity() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, "autosize"); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setSizingFactor(double sizingFactor) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::SizingFactor, sizingFactor); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, ambientTemperatureIndicator); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureSchedule(Schedule& schedule) { + bool result = + setSchedule(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, "ChillerElectricASHRAE205", "Ambient Temperature", schedule); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureSchedule() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureZone(const ThermalZone& thermalZone) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, thermalZone.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureZone() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureOutdoorAirNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureOutdoorAirNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setChilledWaterInletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, connection.handle()); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setChilledWaterOutletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, connection.handle()); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, chilledWaterMaximumRequestedFlowRate); + return result; + } + + void ChillerElectricASHRAE205_Impl::autosizeChilledWaterMaximumRequestedFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "autosize"); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setCondenserInletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetCondenserInletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setCondenserOutletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetCondenserOutletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, condenserMaximumRequestedFlowRate); + return result; + } + + void ChillerElectricASHRAE205_Impl::autosizeCondenserMaximumRequestedFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "autosize"); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setChillerFlowMode(const std::string& chillerFlowMode) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, chillerFlowMode); + return result; + } + + bool ChillerElectricASHRAE205_Impl::setOilCoolerInletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetOilCoolerInletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setOilCoolerOutletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetOilCoolerOutletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, oilCoolerDesignFlowRate); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetOilCoolerDesignFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setAuxiliaryInletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAuxiliaryInletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setAuxiliaryOutletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAuxiliaryOutletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, auxiliaryCoolingDesignFlowRate); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAuxiliaryCoolingDesignFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setHeatRecoveryInletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetHeatRecoveryInletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setHeatRecoveryOutletNode(const Connection& connection) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, connection.handle()); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetHeatRecoveryOutletNode() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, ""); + OS_ASSERT(result); + } + + bool ChillerElectricASHRAE205_Impl::setEndUseSubcategory(const std::string& endUseSubcategory) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, endUseSubcategory); + OS_ASSERT(result); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetEndUseSubcategory() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, ""); + OS_ASSERT(result); + } + + void ChillerElectricASHRAE205_Impl::autosize() { + autosizeRatedCapacity(); + autosizeChilledWaterMaximumRequestedFlowRate(); + autosizeCondenserMaximumRequestedFlowRate(); + } + + void ChillerElectricASHRAE205_Impl::applySizingValues() { + boost::optional val; + val = autosizedRatedCapacity(); + if (val) { + setRatedCapacity(val.get()); + } + + val = autosizedChilledWaterMaximumRequestedFlowRate(); + if (val) { + setChilledWaterMaximumRequestedFlowRate(val.get()); + } + + val = autosizedCondenserMaximumRequestedFlowRate(); + if (val) { + setCondenserMaximumRequestedFlowRate(val.get()); + } + } + + boost::optional ChillerElectricASHRAE205_Impl::optionalRepresentationFile() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName); + } + + boost::optional ChillerElectricASHRAE205_Impl::optionalChilledWaterInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::optionalChilledWaterOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName); + } + + } // namespace detail + + ChillerElectricASHRAE205::ChillerElectricASHRAE205(const Model& model) : WaterToWaterComponent(ChillerElectricASHRAE205::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + // TODO: Appropriately handle the following required object-list fields. + // OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName + // OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName + // OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName + bool ok = true; + // ok = setRepresentationFile(); + OS_ASSERT(ok); + // ok = setPerformanceInterpolationMethod(); + OS_ASSERT(ok); + // ok = setRatedCapacity(); + OS_ASSERT(ok); + // ok = setSizingFactor(); + OS_ASSERT(ok); + // ok = setAmbientTemperatureIndicator(); + OS_ASSERT(ok); + // ok = setChilledWaterInletNode(); + OS_ASSERT(ok); + // ok = setChilledWaterOutletNode(); + OS_ASSERT(ok); + // ok = setChilledWaterMaximumRequestedFlowRate(); + OS_ASSERT(ok); + // ok = setCondenserMaximumRequestedFlowRate(); + OS_ASSERT(ok); + // ok = setChillerFlowMode(); + OS_ASSERT(ok); + } + + IddObjectType ChillerElectricASHRAE205::iddObjectType() { + return IddObjectType(IddObjectType::OS_Chiller_Electric_ASHRAE205); + } + + std::vector ChillerElectricASHRAE205::performanceInterpolationMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod); + } + + std::vector ChillerElectricASHRAE205::ambientTemperatureIndicatorValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator); + } + + std::vector ChillerElectricASHRAE205::chillerFlowModeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_Chiller_Electric_ASHRAE205Fields::ChillerFlowMode); + } + + ExternalFile ChillerElectricASHRAE205::representationFile() const { + return getImpl()->representationFile(); + } + + std::string ChillerElectricASHRAE205::performanceInterpolationMethod() const { + return getImpl()->performanceInterpolationMethod(); + } + + boost::optional ChillerElectricASHRAE205::ratedCapacity() const { + return getImpl()->ratedCapacity(); + } + + bool ChillerElectricASHRAE205::isRatedCapacityAutosized() const { + return getImpl()->isRatedCapacityAutosized(); + } + + boost::optional ChillerElectricASHRAE205::autosizedRatedCapacity() { + return getImpl()->autosizedRatedCapacity(); + } + + double ChillerElectricASHRAE205::sizingFactor() const { + return getImpl()->sizingFactor(); + } + + std::string ChillerElectricASHRAE205::ambientTemperatureIndicator() const { + return getImpl()->ambientTemperatureIndicator(); + } + + boost::optional ChillerElectricASHRAE205::ambientTemperatureSchedule() const { + return getImpl()->ambientTemperatureSchedule(); + } + + boost::optional ChillerElectricASHRAE205::ambientTemperatureZone() const { + return getImpl()->ambientTemperatureZone(); + } + + boost::optional ChillerElectricASHRAE205::ambientTemperatureOutdoorAirNode() const { + return getImpl()->ambientTemperatureOutdoorAirNode(); + } + + Connection ChillerElectricASHRAE205::chilledWaterInletNode() const { + return getImpl()->chilledWaterInletNode(); + } + + Connection ChillerElectricASHRAE205::chilledWaterOutletNode() const { + return getImpl()->chilledWaterOutletNode(); + } + + boost::optional ChillerElectricASHRAE205::chilledWaterMaximumRequestedFlowRate() const { + return getImpl()->chilledWaterMaximumRequestedFlowRate(); + } + + bool ChillerElectricASHRAE205::isChilledWaterMaximumRequestedFlowRateAutosized() const { + return getImpl()->isChilledWaterMaximumRequestedFlowRateAutosized(); + } + + boost::optional ChillerElectricASHRAE205::autosizedChilledWaterMaximumRequestedFlowRate() { + return getImpl()->autosizedChilledWaterMaximumRequestedFlowRate(); + } + + boost::optional ChillerElectricASHRAE205::condenserInletNode() const { + return getImpl()->condenserInletNode(); + } + + boost::optional ChillerElectricASHRAE205::condenserOutletNode() const { + return getImpl()->condenserOutletNode(); + } + + boost::optional ChillerElectricASHRAE205::condenserMaximumRequestedFlowRate() const { + return getImpl()->condenserMaximumRequestedFlowRate(); + } + + bool ChillerElectricASHRAE205::isCondenserMaximumRequestedFlowRateAutosized() const { + return getImpl()->isCondenserMaximumRequestedFlowRateAutosized(); + } + + boost::optional ChillerElectricASHRAE205::autosizedCondenserMaximumRequestedFlowRate() { + return getImpl()->autosizedCondenserMaximumRequestedFlowRate(); + } + + std::string ChillerElectricASHRAE205::chillerFlowMode() const { + return getImpl()->chillerFlowMode(); + } + + boost::optional ChillerElectricASHRAE205::oilCoolerInletNode() const { + return getImpl()->oilCoolerInletNode(); + } + + boost::optional ChillerElectricASHRAE205::oilCoolerOutletNode() const { + return getImpl()->oilCoolerOutletNode(); + } + + boost::optional ChillerElectricASHRAE205::oilCoolerDesignFlowRate() const { + return getImpl()->oilCoolerDesignFlowRate(); + } + + boost::optional ChillerElectricASHRAE205::auxiliaryInletNode() const { + return getImpl()->auxiliaryInletNode(); + } + + boost::optional ChillerElectricASHRAE205::auxiliaryOutletNode() const { + return getImpl()->auxiliaryOutletNode(); + } + + boost::optional ChillerElectricASHRAE205::auxiliaryCoolingDesignFlowRate() const { + return getImpl()->auxiliaryCoolingDesignFlowRate(); + } + + boost::optional ChillerElectricASHRAE205::heatRecoveryInletNode() const { + return getImpl()->heatRecoveryInletNode(); + } + + boost::optional ChillerElectricASHRAE205::heatRecoveryOutletNode() const { + return getImpl()->heatRecoveryOutletNode(); + } + + std::string ChillerElectricASHRAE205::endUseSubcategory() const { + return getImpl()->endUseSubcategory(); + } + + bool ChillerElectricASHRAE205::isEndUseSubcategoryDefaulted() const { + return getImpl()->isEndUseSubcategoryDefaulted(); + } + + bool ChillerElectricASHRAE205::setRepresentationFile(const ExternalFile& externalFile) { + return getImpl()->setRepresentationFile(externalFile); + } + + bool ChillerElectricASHRAE205::setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod) { + return getImpl()->setPerformanceInterpolationMethod(performanceInterpolationMethod); + } + + bool ChillerElectricASHRAE205::setRatedCapacity(double ratedCapacity) { + return getImpl()->setRatedCapacity(ratedCapacity); + } + + void ChillerElectricASHRAE205::autosizeRatedCapacity() { + getImpl()->autosizeRatedCapacity(); + } + + bool ChillerElectricASHRAE205::setSizingFactor(double sizingFactor) { + return getImpl()->setSizingFactor(sizingFactor); + } + + bool ChillerElectricASHRAE205::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { + return getImpl()->setAmbientTemperatureIndicator(ambientTemperatureIndicator); + } + + bool ChillerElectricASHRAE205::setAmbientTemperatureSchedule(Schedule& schedule) { + return getImpl()->setAmbientTemperatureSchedule(schedule); + } + + void ChillerElectricASHRAE205::resetAmbientTemperatureSchedule() { + getImpl()->resetAmbientTemperatureSchedule(); + } + + bool ChillerElectricASHRAE205::setAmbientTemperatureZone(const ThermalZone& thermalZone) { + return getImpl()->setAmbientTemperatureZone(thermalZone); + } + + void ChillerElectricASHRAE205::resetAmbientTemperatureZone() { + getImpl()->resetAmbientTemperatureZone(); + } + + bool ChillerElectricASHRAE205::setAmbientTemperatureOutdoorAirNode(const Connection& connection) { + return getImpl()->setAmbientTemperatureOutdoorAirNode(connection); + } + + void ChillerElectricASHRAE205::resetAmbientTemperatureOutdoorAirNode() { + getImpl()->resetAmbientTemperatureOutdoorAirNode(); + } + + bool ChillerElectricASHRAE205::setChilledWaterInletNode(const Connection& connection) { + return getImpl()->setChilledWaterInletNode(connection); + } + + bool ChillerElectricASHRAE205::setChilledWaterOutletNode(const Connection& connection) { + return getImpl()->setChilledWaterOutletNode(connection); + } + + bool ChillerElectricASHRAE205::setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate) { + return getImpl()->setChilledWaterMaximumRequestedFlowRate(chilledWaterMaximumRequestedFlowRate); + } + + void ChillerElectricASHRAE205::autosizeChilledWaterMaximumRequestedFlowRate() { + getImpl()->autosizeChilledWaterMaximumRequestedFlowRate(); + } + + bool ChillerElectricASHRAE205::setCondenserInletNode(const Connection& connection) { + return getImpl()->setCondenserInletNode(connection); + } + + void ChillerElectricASHRAE205::resetCondenserInletNode() { + getImpl()->resetCondenserInletNode(); + } + + bool ChillerElectricASHRAE205::setCondenserOutletNode(const Connection& connection) { + return getImpl()->setCondenserOutletNode(connection); + } + + void ChillerElectricASHRAE205::resetCondenserOutletNode() { + getImpl()->resetCondenserOutletNode(); + } + + bool ChillerElectricASHRAE205::setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate) { + return getImpl()->setCondenserMaximumRequestedFlowRate(condenserMaximumRequestedFlowRate); + } + + void ChillerElectricASHRAE205::autosizeCondenserMaximumRequestedFlowRate() { + getImpl()->autosizeCondenserMaximumRequestedFlowRate(); + } + + bool ChillerElectricASHRAE205::setChillerFlowMode(const std::string& chillerFlowMode) { + return getImpl()->setChillerFlowMode(chillerFlowMode); + } + + bool ChillerElectricASHRAE205::setOilCoolerInletNode(const Connection& connection) { + return getImpl()->setOilCoolerInletNode(connection); + } + + void ChillerElectricASHRAE205::resetOilCoolerInletNode() { + getImpl()->resetOilCoolerInletNode(); + } + + bool ChillerElectricASHRAE205::setOilCoolerOutletNode(const Connection& connection) { + return getImpl()->setOilCoolerOutletNode(connection); + } + + void ChillerElectricASHRAE205::resetOilCoolerOutletNode() { + getImpl()->resetOilCoolerOutletNode(); + } + + bool ChillerElectricASHRAE205::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { + return getImpl()->setOilCoolerDesignFlowRate(oilCoolerDesignFlowRate); + } + + void ChillerElectricASHRAE205::resetOilCoolerDesignFlowRate() { + getImpl()->resetOilCoolerDesignFlowRate(); + } + + bool ChillerElectricASHRAE205::setAuxiliaryInletNode(const Connection& connection) { + return getImpl()->setAuxiliaryInletNode(connection); + } + + void ChillerElectricASHRAE205::resetAuxiliaryInletNode() { + getImpl()->resetAuxiliaryInletNode(); + } + + bool ChillerElectricASHRAE205::setAuxiliaryOutletNode(const Connection& connection) { + return getImpl()->setAuxiliaryOutletNode(connection); + } + + void ChillerElectricASHRAE205::resetAuxiliaryOutletNode() { + getImpl()->resetAuxiliaryOutletNode(); + } + + bool ChillerElectricASHRAE205::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { + return getImpl()->setAuxiliaryCoolingDesignFlowRate(auxiliaryCoolingDesignFlowRate); + } + + void ChillerElectricASHRAE205::resetAuxiliaryCoolingDesignFlowRate() { + getImpl()->resetAuxiliaryCoolingDesignFlowRate(); + } + + bool ChillerElectricASHRAE205::setHeatRecoveryInletNode(const Connection& connection) { + return getImpl()->setHeatRecoveryInletNode(connection); + } + + void ChillerElectricASHRAE205::resetHeatRecoveryInletNode() { + getImpl()->resetHeatRecoveryInletNode(); + } + + bool ChillerElectricASHRAE205::setHeatRecoveryOutletNode(const Connection& connection) { + return getImpl()->setHeatRecoveryOutletNode(connection); + } + + void ChillerElectricASHRAE205::resetHeatRecoveryOutletNode() { + getImpl()->resetHeatRecoveryOutletNode(); + } + + bool ChillerElectricASHRAE205::setEndUseSubcategory(const std::string& endUseSubcategory) { + return getImpl()->setEndUseSubcategory(endUseSubcategory); + } + + void ChillerElectricASHRAE205::resetEndUseSubcategory() { + getImpl()->resetEndUseSubcategory(); + } + + /// @cond + ChillerElectricASHRAE205::ChillerElectricASHRAE205(std::shared_ptr impl) + : WaterToWaterComponent(std::move(impl)) {} + /// @endcond + +} // namespace model +} // namespace openstudio diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp new file mode 100644 index 0000000000..abb78b19c2 --- /dev/null +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -0,0 +1,292 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#ifndef MODEL_CHILLERELECTRICASHRAE205_HPP +#define MODEL_CHILLERELECTRICASHRAE205_HPP + +#include +#include "WaterToWaterComponent.hpp" + +namespace openstudio { + +namespace model { + + // TODO: Check the following class names against object getters and setters. + class ExternalFile; + class Schedule; + class ThermalZone; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + + namespace detail { + + class ChillerElectricASHRAE205_Impl; + + } // namespace detail + + /** ChillerElectricASHRAE205 is a WaterToWaterComponent that wraps the OpenStudio IDD object 'OS:Chiller:Electric:ASHRAE205'. */ + class MODEL_API ChillerElectricASHRAE205 : public WaterToWaterComponent + { + public: + /** @name Constructors and Destructors */ + //@{ + + explicit ChillerElectricASHRAE205(const Model& model); + + virtual ~ChillerElectricASHRAE205() = default; + + //@} + + static IddObjectType iddObjectType(); + + static std::vector performanceInterpolationMethodValues(); + + static std::vector ambientTemperatureIndicatorValues(); + + static std::vector chillerFlowModeValues(); + + /** @name Getters */ + //@{ + + // TODO: Check return type. From object lists, some candidates are: ExternalFile. + ExternalFile representationFile() const; + + std::string performanceInterpolationMethod() const; + + boost::optional ratedCapacity() const; + + bool isRatedCapacityAutosized() const; + + boost::optional autosizedRatedCapacity(); + + double sizingFactor() const; + + std::string ambientTemperatureIndicator() const; + + // TODO: Check return type. From object lists, some candidates are: Schedule. + boost::optional ambientTemperatureSchedule() const; + + // TODO: Check return type. From object lists, some candidates are: ThermalZone. + boost::optional ambientTemperatureZone() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional ambientTemperatureOutdoorAirNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + Connection chilledWaterInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + Connection chilledWaterOutletNode() const; + + boost::optional chilledWaterMaximumRequestedFlowRate() const; + + bool isChilledWaterMaximumRequestedFlowRateAutosized() const; + + boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional condenserInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional condenserOutletNode() const; + + boost::optional condenserMaximumRequestedFlowRate() const; + + bool isCondenserMaximumRequestedFlowRateAutosized() const; + + boost::optional autosizedCondenserMaximumRequestedFlowRate(); + + std::string chillerFlowMode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional oilCoolerInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional oilCoolerOutletNode() const; + + boost::optional oilCoolerDesignFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional auxiliaryInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional auxiliaryOutletNode() const; + + boost::optional auxiliaryCoolingDesignFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional heatRecoveryInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional heatRecoveryOutletNode() const; + + std::string endUseSubcategory() const; + + bool isEndUseSubcategoryDefaulted() const; + + //@} + /** @name Setters */ + //@{ + + // TODO: Check argument type. From object lists, some candidates are: ExternalFile. + bool setRepresentationFile(const ExternalFile& externalFile); + + bool setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod); + + bool setRatedCapacity(double ratedCapacity); + + void autosizeRatedCapacity(); + + bool setSizingFactor(double sizingFactor); + + bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); + + // TODO: Check argument type. From object lists, some candidates are: Schedule. + // Note Schedules are passed by reference, not const reference. + bool setAmbientTemperatureSchedule(Schedule& schedule); + + void resetAmbientTemperatureSchedule(); + + // TODO: Check argument type. From object lists, some candidates are: ThermalZone. + bool setAmbientTemperatureZone(const ThermalZone& thermalZone); + + void resetAmbientTemperatureZone(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAmbientTemperatureOutdoorAirNode(const Connection& connection); + + void resetAmbientTemperatureOutdoorAirNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setChilledWaterInletNode(const Connection& connection); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setChilledWaterOutletNode(const Connection& connection); + + bool setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate); + + void autosizeChilledWaterMaximumRequestedFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setCondenserInletNode(const Connection& connection); + + void resetCondenserInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setCondenserOutletNode(const Connection& connection); + + void resetCondenserOutletNode(); + + bool setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate); + + void autosizeCondenserMaximumRequestedFlowRate(); + + bool setChillerFlowMode(const std::string& chillerFlowMode); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setOilCoolerInletNode(const Connection& connection); + + void resetOilCoolerInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setOilCoolerOutletNode(const Connection& connection); + + void resetOilCoolerOutletNode(); + + bool setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate); + + void resetOilCoolerDesignFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAuxiliaryInletNode(const Connection& connection); + + void resetAuxiliaryInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAuxiliaryOutletNode(const Connection& connection); + + void resetAuxiliaryOutletNode(); + + bool setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate); + + void resetAuxiliaryCoolingDesignFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setHeatRecoveryInletNode(const Connection& connection); + + void resetHeatRecoveryInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setHeatRecoveryOutletNode(const Connection& connection); + + void resetHeatRecoveryOutletNode(); + + bool setEndUseSubcategory(const std::string& endUseSubcategory); + + void resetEndUseSubcategory(); + + //@} + /** @name Other */ + //@{ + + //@} + protected: + /// @cond + using ImplType = detail::ChillerElectricASHRAE205_Impl; + + explicit ChillerElectricASHRAE205(std::shared_ptr impl); + + friend class detail::ChillerElectricASHRAE205_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.ChillerElectricASHRAE205"); + }; + + /** \relates ChillerElectricASHRAE205*/ + using OptionalChillerElectricASHRAE205 = boost::optional; + + /** \relates ChillerElectricASHRAE205*/ + using ChillerElectricASHRAE205Vector = std::vector; + +} // namespace model +} // namespace openstudio + +#endif // MODEL_CHILLERELECTRICASHRAE205_HPP diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp new file mode 100644 index 0000000000..4b5e740ac5 --- /dev/null +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -0,0 +1,290 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#ifndef MODEL_CHILLERELECTRICASHRAE205_IMPL_HPP +#define MODEL_CHILLERELECTRICASHRAE205_IMPL_HPP + +#include +#include "WaterToWaterComponent_Impl.hpp" + +namespace openstudio { +namespace model { + + // TODO: Check the following class names against object getters and setters. + class ExternalFile; + class Schedule; + class ThermalZone; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + class Connection; + + namespace detail { + + /** ChillerElectricASHRAE205_Impl is a WaterToWaterComponent_Impl that is the implementation class for ChillerElectricASHRAE205.*/ + class MODEL_API ChillerElectricASHRAE205_Impl : public WaterToWaterComponent_Impl + { + public: + /** @name Constructors and Destructors */ + //@{ + + ChillerElectricASHRAE205_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + ChillerElectricASHRAE205_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle); + + ChillerElectricASHRAE205_Impl(const ChillerElectricASHRAE205_Impl& other, Model_Impl* model, bool keepHandle); + + virtual ~ChillerElectricASHRAE205_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const override; + + virtual IddObjectType iddObjectType() const override; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + //@} + /** @name Getters */ + //@{ + + // TODO: Check return type. From object lists, some candidates are: ExternalFile. + ExternalFile representationFile() const; + + std::string performanceInterpolationMethod() const; + + boost::optional ratedCapacity() const; + + bool isRatedCapacityAutosized() const; + + boost::optional autosizedRatedCapacity(); + + double sizingFactor() const; + + std::string ambientTemperatureIndicator() const; + + // TODO: Check return type. From object lists, some candidates are: Schedule. + boost::optional ambientTemperatureSchedule() const; + + // TODO: Check return type. From object lists, some candidates are: ThermalZone. + boost::optional ambientTemperatureZone() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional ambientTemperatureOutdoorAirNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + Connection chilledWaterInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + Connection chilledWaterOutletNode() const; + + boost::optional chilledWaterMaximumRequestedFlowRate() const; + + bool isChilledWaterMaximumRequestedFlowRateAutosized() const; + + boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional condenserInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional condenserOutletNode() const; + + boost::optional condenserMaximumRequestedFlowRate() const; + + bool isCondenserMaximumRequestedFlowRateAutosized() const; + + boost::optional autosizedCondenserMaximumRequestedFlowRate(); + + std::string chillerFlowMode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional oilCoolerInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional oilCoolerOutletNode() const; + + boost::optional oilCoolerDesignFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional auxiliaryInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional auxiliaryOutletNode() const; + + boost::optional auxiliaryCoolingDesignFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional heatRecoveryInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + boost::optional heatRecoveryOutletNode() const; + + std::string endUseSubcategory() const; + + bool isEndUseSubcategoryDefaulted() const; + + //@} + /** @name Setters */ + //@{ + + // TODO: Check argument type. From object lists, some candidates are: ExternalFile. + bool setRepresentationFile(const ExternalFile& externalFile); + + bool setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod); + + bool setRatedCapacity(double ratedCapacity); + + void autosizeRatedCapacity(); + + bool setSizingFactor(double sizingFactor); + + bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); + + // TODO: Check argument type. From object lists, some candidates are: Schedule. + // Note Schedules are passed by reference, not const reference. + bool setAmbientTemperatureSchedule(Schedule& schedule); + + void resetAmbientTemperatureSchedule(); + + // TODO: Check argument type. From object lists, some candidates are: ThermalZone. + bool setAmbientTemperatureZone(const ThermalZone& thermalZone); + + void resetAmbientTemperatureZone(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAmbientTemperatureOutdoorAirNode(const Connection& connection); + + void resetAmbientTemperatureOutdoorAirNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setChilledWaterInletNode(const Connection& connection); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setChilledWaterOutletNode(const Connection& connection); + + bool setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate); + + void autosizeChilledWaterMaximumRequestedFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setCondenserInletNode(const Connection& connection); + + void resetCondenserInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setCondenserOutletNode(const Connection& connection); + + void resetCondenserOutletNode(); + + bool setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate); + + void autosizeCondenserMaximumRequestedFlowRate(); + + bool setChillerFlowMode(const std::string& chillerFlowMode); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setOilCoolerInletNode(const Connection& connection); + + void resetOilCoolerInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setOilCoolerOutletNode(const Connection& connection); + + void resetOilCoolerOutletNode(); + + bool setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate); + + void resetOilCoolerDesignFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAuxiliaryInletNode(const Connection& connection); + + void resetAuxiliaryInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setAuxiliaryOutletNode(const Connection& connection); + + void resetAuxiliaryOutletNode(); + + bool setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate); + + void resetAuxiliaryCoolingDesignFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setHeatRecoveryInletNode(const Connection& connection); + + void resetHeatRecoveryInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + bool setHeatRecoveryOutletNode(const Connection& connection); + + void resetHeatRecoveryOutletNode(); + + bool setEndUseSubcategory(const std::string& endUseSubcategory); + + void resetEndUseSubcategory(); + + virtual void autosize() override; + + virtual void applySizingValues() override; + + //@} + /** @name Other */ + //@{ + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.ChillerElectricASHRAE205"); + + // TODO: Check the return types of these methods. + // Optional getters for use by methods like children() so can remove() if the constructor fails. + // There are other ways for the public versions of these getters to fail--perhaps all required + // objects should be returned as boost::optionals + boost::optional optionalRepresentationFile() const; + boost::optional optionalChilledWaterInletNode() const; + boost::optional optionalChilledWaterOutletNode() const; + }; + + } // namespace detail + +} // namespace model +} // namespace openstudio + +#endif // MODEL_CHILLERELECTRICASHRAE205_IMPL_HPP diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp new file mode 100644 index 0000000000..340c848d21 --- /dev/null +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -0,0 +1,270 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include "ModelFixture.hpp" + +#include "../ChillerElectricASHRAE205.hpp" +#include "../ChillerElectricASHRAE205_Impl.hpp" + +// TODO: Check the following class names against object getters and setters. +#include "../ExternalFile.hpp" +#include "../ExternalFile_Impl.hpp" + +#include "../Schedule.hpp" +#include "../Schedule_Impl.hpp" + +#include "../ThermalZone.hpp" +#include "../ThermalZone_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +#include "../Connection.hpp" +#include "../Connection_Impl.hpp" + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, ChillerElectricASHRAE205_GettersSetters) { + Model m; + // TODO: Check regular Ctor arguments + ChillerElectricASHRAE205 chillerElectricASHRAE205(m); + // TODO: Or if a UniqueModelObject (and make sure _Impl is included) + // ChillerElectricASHRAE205 chillerElectricASHRAE205 = m.getUniqueModelObject(); + + chillerElectricASHRAE205.setName("My ChillerElectricASHRAE205"); + + // Representation File Name: Required Object + ExternalFile obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setRepresentationFile(obj)); + EXPECT_EQ(obj, chillerElectricASHRAE205.representationFile()); + + // Performance Interpolation Method: Required String + EXPECT_TRUE(chillerElectricASHRAE205.setPerformanceInterpolationMethod("Linear")); + EXPECT_EQ("Linear", chillerElectricASHRAE205.performanceInterpolationMethod()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setPerformanceInterpolationMethod("BADENUM")); + EXPECT_EQ("Linear", chillerElectricASHRAE205.performanceInterpolationMethod()); + + // Rated Capacity: Required Double + // Autosize + chillerElectricASHRAE205.autosizeRatedCapacity(); + EXPECT_TRUE(chillerElectricASHRAE205.isRatedCapacityAutosized()); + // Set + EXPECT_TRUE(chillerElectricASHRAE205.setRatedCapacity(0.5)); + ASSERT_TRUE(chillerElectricASHRAE205.ratedCapacity()); + EXPECT_EQ(0.5, chillerElectricASHRAE205.ratedCapacity().get()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setRatedCapacity(-10.0)); + ASSERT_TRUE(chillerElectricASHRAE205.ratedCapacity()); + EXPECT_EQ(0.5, chillerElectricASHRAE205.ratedCapacity().get()); + EXPECT_FALSE(chillerElectricASHRAE205.isRatedCapacityAutosized()); + + // Sizing Factor: Required Double + EXPECT_TRUE(chillerElectricASHRAE205.setSizingFactor(0.6)); + EXPECT_EQ(0.6, chillerElectricASHRAE205.sizingFactor()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setSizingFactor(-10.0)); + EXPECT_EQ(0.6, chillerElectricASHRAE205.sizingFactor()); + + // Ambient Temperature Indicator: Required String + EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureIndicator("Schedule")); + EXPECT_EQ("Schedule", chillerElectricASHRAE205.ambientTemperatureIndicator()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setAmbientTemperatureIndicator("BADENUM")); + EXPECT_EQ("Schedule", chillerElectricASHRAE205.ambientTemperatureIndicator()); + + // Ambient Temperature Schedule Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureSchedule(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureSchedule()); + EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureSchedule().get()); + + // Ambient Temperature Zone Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureZone(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureZone()); + EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureZone().get()); + + // Ambient Temperature Outdoor Air Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureOutdoorAirNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureOutdoorAirNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureOutdoorAirNode().get()); + + // Chilled Water Inlet Node Name: Required Object + Connection obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterInletNode(obj)); + EXPECT_EQ(obj, chillerElectricASHRAE205.chilledWaterInletNode()); + + // Chilled Water Outlet Node Name: Required Object + Connection obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterOutletNode(obj)); + EXPECT_EQ(obj, chillerElectricASHRAE205.chilledWaterOutletNode()); + + // Chilled Water Maximum Requested Flow Rate: Required Double + // Autosize + chillerElectricASHRAE205.autosizeChilledWaterMaximumRequestedFlowRate(); + EXPECT_TRUE(chillerElectricASHRAE205.isChilledWaterMaximumRequestedFlowRateAutosized()); + // Set + EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterMaximumRequestedFlowRate(1.3)); + ASSERT_TRUE(chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate()); + EXPECT_EQ(1.3, chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate().get()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setChilledWaterMaximumRequestedFlowRate(-10.0)); + ASSERT_TRUE(chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate()); + EXPECT_EQ(1.3, chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate().get()); + EXPECT_FALSE(chillerElectricASHRAE205.isChilledWaterMaximumRequestedFlowRateAutosized()); + + // Condenser Inlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setCondenserInletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.condenserInletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.condenserInletNode().get()); + + // Condenser Outlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setCondenserOutletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.condenserOutletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.condenserOutletNode().get()); + + // Condenser Maximum Requested Flow Rate: Required Double + // Autosize + chillerElectricASHRAE205.autosizeCondenserMaximumRequestedFlowRate(); + EXPECT_TRUE(chillerElectricASHRAE205.isCondenserMaximumRequestedFlowRateAutosized()); + // Set + EXPECT_TRUE(chillerElectricASHRAE205.setCondenserMaximumRequestedFlowRate(1.6)); + ASSERT_TRUE(chillerElectricASHRAE205.condenserMaximumRequestedFlowRate()); + EXPECT_EQ(1.6, chillerElectricASHRAE205.condenserMaximumRequestedFlowRate().get()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setCondenserMaximumRequestedFlowRate(-10.0)); + ASSERT_TRUE(chillerElectricASHRAE205.condenserMaximumRequestedFlowRate()); + EXPECT_EQ(1.6, chillerElectricASHRAE205.condenserMaximumRequestedFlowRate().get()); + EXPECT_FALSE(chillerElectricASHRAE205.isCondenserMaximumRequestedFlowRateAutosized()); + + // Chiller Flow Mode: Required String + EXPECT_TRUE(chillerElectricASHRAE205.setChillerFlowMode("ConstantFlow")); + EXPECT_EQ("ConstantFlow", chillerElectricASHRAE205.chillerFlowMode()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setChillerFlowMode("BADENUM")); + EXPECT_EQ("ConstantFlow", chillerElectricASHRAE205.chillerFlowMode()); + + // Oil Cooler Inlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerInletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerInletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.oilCoolerInletNode().get()); + + // Oil Cooler Outlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerOutletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerOutletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.oilCoolerOutletNode().get()); + + // Oil Cooler Design Flow Rate: Optional Double + EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerDesignFlowRate(2.0)); + ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerDesignFlowRate()); + EXPECT_EQ(2.0, chillerElectricASHRAE205.oilCoolerDesignFlowRate().get()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setOilCoolerDesignFlowRate(-10.0)); + ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerDesignFlowRate()); + EXPECT_EQ(2.0, chillerElectricASHRAE205.oilCoolerDesignFlowRate().get()); + + // Auxiliary Inlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryInletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryInletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.auxiliaryInletNode().get()); + + // Auxiliary Outlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryOutletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryOutletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.auxiliaryOutletNode().get()); + + // Auxiliary Cooling Design Flow Rate: Optional Double + EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryCoolingDesignFlowRate(2.3)); + ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate()); + EXPECT_EQ(2.3, chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate().get()); + // Bad Value + EXPECT_FALSE(chillerElectricASHRAE205.setAuxiliaryCoolingDesignFlowRate(-10.0)); + ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate()); + EXPECT_EQ(2.3, chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate().get()); + + // Heat Recovery Inlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setHeatRecoveryInletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.heatRecoveryInletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.heatRecoveryInletNode().get()); + + // Heat Recovery Outlet Node Name: Optional Object + boost::optional obj(m); + EXPECT_TRUE(chillerElectricASHRAE205.setHeatRecoveryOutletNode(obj)); + ASSERT_TRUE(chillerElectricASHRAE205.heatRecoveryOutletNode()); + EXPECT_EQ(obj, chillerElectricASHRAE205.heatRecoveryOutletNode().get()); + + // End-Use Subcategory: Optional String + // Default value from IDD + EXPECT_TRUE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); + EXPECT_EQ("General", chillerElectricASHRAE205.endUseSubcategory()); + // Set + EXPECT_TRUE(chillerElectricASHRAE205.setEndUseSubcategory()); + EXPECT_EQ(, chillerElectricASHRAE205.endUseSubcategory()); + EXPECT_FALSE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); + // Reset + chillerElectricASHRAE205.resetEndUseSubcategory(); + EXPECT_TRUE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); +} From 65b57af39debc060a3af550092d83dd02fff6c5e Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 14:58:58 +0200 Subject: [PATCH 05/24] Switch the Ambient Temperature Outdoor Air Node Name to an alpha, not a Node OutdoorAir:Node isn't wrapped in OS SDK --- resources/model/OpenStudio.idd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index af5090ad23..e10cb6c024 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -13863,8 +13863,7 @@ OS:Chiller:Electric:ASHRAE205, \type object-list \object-list ThermalZoneNames A8, \field Ambient Temperature Outdoor Air Node Name - \type object-list - \object-list ConnectionNames + \type alpha \note required for Ambient Temperature Indicator=Outdoors A9, \field Chilled Water Inlet Node Name \type object-list From 4a9d4c4c593ade9c7926fee7d0350dc949b131a1 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 16:35:35 +0200 Subject: [PATCH 06/24] First pass a model implementation for ChillerElectricASHRAE205 --- src/model/CMakeLists.txt | 4 + src/model/ChillerElectricASHRAE205.cpp | 705 +++++++++----------- src/model/ChillerElectricASHRAE205.hpp | 161 ++--- src/model/ChillerElectricASHRAE205_Impl.hpp | 189 ++---- src/model/ConcreteModelObjects.hpp | 2 + src/model/Model.cpp | 2 + src/model/ModelHVAC.i | 2 + src/model/ScheduleTypeRegistry.cpp | 1 + 8 files changed, 438 insertions(+), 628 deletions(-) diff --git a/src/model/CMakeLists.txt b/src/model/CMakeLists.txt index 30e15e8c4b..c73cb7d6b8 100644 --- a/src/model/CMakeLists.txt +++ b/src/model/CMakeLists.txt @@ -281,6 +281,9 @@ set(${target_name}_src ChillerAbsorptionIndirect.hpp ChillerAbsorptionIndirect_Impl.hpp ChillerAbsorptionIndirect.cpp + ChillerElectricASHRAE205.hpp + ChillerElectricASHRAE205_Impl.hpp + ChillerElectricASHRAE205.cpp ChillerElectricEIR.hpp ChillerElectricEIR_Impl.hpp ChillerElectricEIR.cpp @@ -1891,6 +1894,7 @@ set(${target_name}_test_src # test/CentralHeatPumpSystemModule_GTest.cpp => Included in the above test/ChillerAbsorption_GTest.cpp test/ChillerAbsorptionIndirect_GTest.cpp + test/ChillerElectricASHRAE205_GTest.cpp test/ChillerElectricEIR_GTest.cpp test/ChillerElectricReformulatedEIR_GTest.cpp test/ChillerHeaterPerformanceElectricEIR_GTest.cpp diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 7f5463120e..6a3b11465e 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -30,35 +30,17 @@ #include "ChillerElectricASHRAE205.hpp" #include "ChillerElectricASHRAE205_Impl.hpp" -// TODO: Check the following class names against object getters and setters. #include "ExternalFile.hpp" #include "ExternalFile_Impl.hpp" #include "Schedule.hpp" #include "Schedule_Impl.hpp" +#include "Node.hpp" +#include "Node_Impl.hpp" +#include "PlantLoop.hpp" #include "ThermalZone.hpp" #include "ThermalZone_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" -#include "Connection.hpp" -#include "Connection_Impl.hpp" +#include "Model.hpp" + #include "ScheduleTypeLimits.hpp" #include "ScheduleTypeRegistry.hpp" @@ -90,9 +72,29 @@ namespace model { : WaterToWaterComponent_Impl(other, model, keepHandle) {} const std::vector& ChillerElectricASHRAE205_Impl::outputVariableNames() const { - static std::vector result; - if (result.empty()) { - } + static std::vector result{"Chiller Part Load Ratio", + "Chiller Cycling Ratio", + "Minimum Part Load Ratio", + "Chiller Electricity Rate", + "Chiller Electricity Energy", + "Chiller Evaporator Cooling Rate", + "Chiller Evaporator Cooling Energy", + "Chiller Evaporator Inlet Temperature", + "Chiller Evaporator Outlet Temperature", + "Chiller Evaporator Mass Flow Rate", + "Chiller Condenser Heat Transfer Rate", + "Chiller Condenser Heat Transfer Energy", + "Chiller COP", + "Chiller Condenser Inlet Temperature", + "Chiller Condenser Outlet Temperature", + "Chiller Condenser Mass Flow Rate", + "Chiller Effective Heat Rejection Temperature", + "Chiller Zone Heat Gain Rate", + "Chiller Zone Heat Gain Energy", + "Oil Cooler Heat Transfer Rate", + "Oil Cooler Heat Transfer Energy", + "Auxiliary Heat Transfer Rate", + "Auxiliary Heat Transfer Energy"}; return result; } @@ -101,30 +103,44 @@ namespace model { } std::vector ChillerElectricASHRAE205_Impl::getScheduleTypeKeys(const Schedule& schedule) const { - // TODO: Check schedule display names. std::vector result; UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); - UnsignedVector::const_iterator b(fieldIndices.begin()), e(fieldIndices.end()); + UnsignedVector::const_iterator b(fieldIndices.begin()); + UnsignedVector::const_iterator e(fieldIndices.end()); if (std::find(b, e, OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName) != e) { - result.push_back(ScheduleTypeKey("ChillerElectricASHRAE205", "Ambient Temperature")); + result.emplace_back("ChillerElectricASHRAE205", "Ambient Temperature"); } return result; } + boost::optional ChillerElectricASHRAE205_Impl::optionalRepresentationFile() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName); + } + ExternalFile ChillerElectricASHRAE205_Impl::representationFile() const { boost::optional value = optionalRepresentationFile(); if (!value) { - LOG_AND_THROW(briefDescription() << " does not have an Representation File attached."); + LOG_AND_THROW(briefDescription() << " does not have a Representation File attached."); } return value.get(); } + bool ChillerElectricASHRAE205_Impl::setRepresentationFile(const ExternalFile& externalFile) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName, externalFile.handle()); + return result; + } + std::string ChillerElectricASHRAE205_Impl::performanceInterpolationMethod() const { boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, true); OS_ASSERT(value); return value.get(); } + bool ChillerElectricASHRAE205_Impl::setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); + return result; + } + boost::optional ChillerElectricASHRAE205_Impl::ratedCapacity() const { return getDouble(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, true); } @@ -133,13 +149,19 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, true); if (value) { - result = openstudio::istringEqual(value.get(), "autosize"); + result = openstudio::istringEqual(value.get(), "AutoSize"); } return result; } - boost::optional ChillerElectricASHRAE205_Impl::autosizedRatedCapacity() { - return getAutosizedValue("TODO_CHECK_SQL Rated Capacity", "W"); + bool ChillerElectricASHRAE205_Impl::setRatedCapacity(double ratedCapacity) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, ratedCapacity); + return result; + } + + void ChillerElectricASHRAE205_Impl::autosizeRatedCapacity() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, "AutoSize"); + OS_ASSERT(result); } double ChillerElectricASHRAE205_Impl::sizingFactor() const { @@ -148,38 +170,79 @@ namespace model { return value.get(); } + bool ChillerElectricASHRAE205_Impl::setSizingFactor(double sizingFactor) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::SizingFactor, sizingFactor); + return result; + } + std::string ChillerElectricASHRAE205_Impl::ambientTemperatureIndicator() const { boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, true); OS_ASSERT(value); return value.get(); } + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, ambientTemperatureIndicator); + return result; + } + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureSchedule() const { return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName); } + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureSchedule(Schedule& schedule) { + bool result = + setSchedule(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, "ChillerElectricASHRAE205", "Ambient Temperature", schedule); + if (result) { + bool ok = setAmbientTemperatureIndicator("Schedule"); + OS_ASSERT(ok); + } + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureSchedule() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, ""); + OS_ASSERT(result); + result = setAmbientTemperatureIndicator("Outdoors"); + OS_ASSERT(result); + } + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureZone() const { return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName); } - boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureOutdoorAirNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName); + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureZone(const ThermalZone& thermalZone) { + bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, thermalZone.handle()); + if (result) { + bool ok = setAmbientTemperatureIndicator("Zone"); + OS_ASSERT(ok); + } + return result; } - Connection ChillerElectricASHRAE205_Impl::chilledWaterInletNode() const { - boost::optional value = optionalChilledWaterInletNode(); - if (!value) { - LOG_AND_THROW(briefDescription() << " does not have an Chilled Water Inlet Node attached."); - } - return value.get(); + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureZone() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, ""); + OS_ASSERT(result); + result = setAmbientTemperatureIndicator("Outdoors"); + OS_ASSERT(result); } - Connection ChillerElectricASHRAE205_Impl::chilledWaterOutletNode() const { - boost::optional value = optionalChilledWaterOutletNode(); - if (!value) { - LOG_AND_THROW(briefDescription() << " does not have an Chilled Water Outlet Node attached."); + boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureOutdoorAirNodeName() const { + return getString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, false, true); + } + + bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureOutdoorAirNodeName(const std::string& ambientTemperatureOutdoorAirNodeName) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, ambientTemperatureOutdoorAirNodeName); + if (result) { + bool ok = setAmbientTemperatureIndicator("Outdoors"); + OS_ASSERT(ok); } - return value.get(); + return result; + } + + void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureOutdoorAirNodeName() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, ""); + OS_ASSERT(result); } boost::optional ChillerElectricASHRAE205_Impl::chilledWaterMaximumRequestedFlowRate() const { @@ -190,21 +253,19 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, true); if (value) { - result = openstudio::istringEqual(value.get(), "autosize"); + result = openstudio::istringEqual(value.get(), "AutoSize"); } return result; } - boost::optional ChillerElectricASHRAE205_Impl::autosizedChilledWaterMaximumRequestedFlowRate() { - return getAutosizedValue("TODO_CHECK_SQL Chilled Water Maximum Requested Flow Rate", "m3/s"); - } - - boost::optional ChillerElectricASHRAE205_Impl::condenserInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName); + bool ChillerElectricASHRAE205_Impl::setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, chilledWaterMaximumRequestedFlowRate); + return result; } - boost::optional ChillerElectricASHRAE205_Impl::condenserOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName); + void ChillerElectricASHRAE205_Impl::autosizeChilledWaterMaximumRequestedFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "AutoSize"); + OS_ASSERT(result); } boost::optional ChillerElectricASHRAE205_Impl::condenserMaximumRequestedFlowRate() const { @@ -215,13 +276,19 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, true); if (value) { - result = openstudio::istringEqual(value.get(), "autosize"); + result = openstudio::istringEqual(value.get(), "AutoSize"); } return result; } - boost::optional ChillerElectricASHRAE205_Impl::autosizedCondenserMaximumRequestedFlowRate() { - return getAutosizedValue("TODO_CHECK_SQL Condenser Maximum Requested Flow Rate", "m3/s"); + bool ChillerElectricASHRAE205_Impl::setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, condenserMaximumRequestedFlowRate); + return result; + } + + void ChillerElectricASHRAE205_Impl::autosizeCondenserMaximumRequestedFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "AutoSize"); + OS_ASSERT(result); } std::string ChillerElectricASHRAE205_Impl::chillerFlowMode() const { @@ -230,36 +297,37 @@ namespace model { return value.get(); } - boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); - } - - boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); + bool ChillerElectricASHRAE205_Impl::setChillerFlowMode(const std::string& chillerFlowMode) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, chillerFlowMode); + return result; } boost::optional ChillerElectricASHRAE205_Impl::oilCoolerDesignFlowRate() const { return getDouble(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, true); } - boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); + bool ChillerElectricASHRAE205_Impl::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, oilCoolerDesignFlowRate); + return result; } - boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); + void ChillerElectricASHRAE205_Impl::resetOilCoolerDesignFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, ""); + OS_ASSERT(result); } boost::optional ChillerElectricASHRAE205_Impl::auxiliaryCoolingDesignFlowRate() const { return getDouble(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, true); } - boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName); + bool ChillerElectricASHRAE205_Impl::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { + bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, auxiliaryCoolingDesignFlowRate); + return result; } - boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName); + void ChillerElectricASHRAE205_Impl::resetAuxiliaryCoolingDesignFlowRate() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, ""); + OS_ASSERT(result); } std::string ChillerElectricASHRAE205_Impl::endUseSubcategory() const { @@ -272,283 +340,214 @@ namespace model { return isEmpty(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory); } - bool ChillerElectricASHRAE205_Impl::setRepresentationFile(const ExternalFile& externalFile) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName, externalFile.handle()); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod) { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setRatedCapacity(double ratedCapacity) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, ratedCapacity); - return result; - } - - void ChillerElectricASHRAE205_Impl::autosizeRatedCapacity() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, "autosize"); - OS_ASSERT(result); - } - - bool ChillerElectricASHRAE205_Impl::setSizingFactor(double sizingFactor) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::SizingFactor, sizingFactor); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, ambientTemperatureIndicator); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureSchedule(Schedule& schedule) { - bool result = - setSchedule(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, "ChillerElectricASHRAE205", "Ambient Temperature", schedule); - return result; - } - - void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureSchedule() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, ""); - OS_ASSERT(result); - } - - bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureZone(const ThermalZone& thermalZone) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, thermalZone.handle()); - return result; - } - - void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureZone() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, ""); + bool ChillerElectricASHRAE205_Impl::setEndUseSubcategory(const std::string& endUseSubcategory) { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, endUseSubcategory); OS_ASSERT(result); - } - - bool ChillerElectricASHRAE205_Impl::setAmbientTemperatureOutdoorAirNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, connection.handle()); return result; } - void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureOutdoorAirNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, ""); + void ChillerElectricASHRAE205_Impl::resetEndUseSubcategory() { + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, ""); OS_ASSERT(result); } - bool ChillerElectricASHRAE205_Impl::setChilledWaterInletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, connection.handle()); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setChilledWaterOutletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, connection.handle()); - return result; - } - - bool ChillerElectricASHRAE205_Impl::setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, chilledWaterMaximumRequestedFlowRate); - return result; - } - - void ChillerElectricASHRAE205_Impl::autosizeChilledWaterMaximumRequestedFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "autosize"); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::autosizedRatedCapacity() { + return getAutosizedValue("Design Size Rated Capacity", "W"); } - bool ChillerElectricASHRAE205_Impl::setCondenserInletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, connection.handle()); - return result; + boost::optional ChillerElectricASHRAE205_Impl::autosizedChilledWaterMaximumRequestedFlowRate() { + return getAutosizedValue("Design Size Chilled Water Maximum Requested Flow Rate", "m3/s"); } - void ChillerElectricASHRAE205_Impl::resetCondenserInletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::autosizedCondenserMaximumRequestedFlowRate() { + return getAutosizedValue("Design Size Condenser Maximum Requested Flow Rate", "m3/s"); } - bool ChillerElectricASHRAE205_Impl::setCondenserOutletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, connection.handle()); - return result; + void ChillerElectricASHRAE205_Impl::autosize() { + autosizeRatedCapacity(); + autosizeChilledWaterMaximumRequestedFlowRate(); + autosizeCondenserMaximumRequestedFlowRate(); } - void ChillerElectricASHRAE205_Impl::resetCondenserOutletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, ""); - OS_ASSERT(result); - } + void ChillerElectricASHRAE205_Impl::applySizingValues() { + boost::optional val; + val = autosizedRatedCapacity(); + if (val) { + setRatedCapacity(val.get()); + } - bool ChillerElectricASHRAE205_Impl::setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, condenserMaximumRequestedFlowRate); - return result; - } + val = autosizedChilledWaterMaximumRequestedFlowRate(); + if (val) { + setChilledWaterMaximumRequestedFlowRate(val.get()); + } - void ChillerElectricASHRAE205_Impl::autosizeCondenserMaximumRequestedFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "autosize"); - OS_ASSERT(result); + val = autosizedCondenserMaximumRequestedFlowRate(); + if (val) { + setCondenserMaximumRequestedFlowRate(val.get()); + } } - bool ChillerElectricASHRAE205_Impl::setChillerFlowMode(const std::string& chillerFlowMode) { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, chillerFlowMode); - return result; + // Primary: Chiller Water + unsigned ChillerElectricASHRAE205_Impl::supplyInletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName; } - bool ChillerElectricASHRAE205_Impl::setOilCoolerInletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, connection.handle()); - return result; + unsigned ChillerElectricASHRAE205_Impl::supplyOutletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName; } - void ChillerElectricASHRAE205_Impl::resetOilCoolerInletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::chilledWaterLoop() const { + return WaterToWaterComponent_Impl::plantLoop(); } - bool ChillerElectricASHRAE205_Impl::setOilCoolerOutletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, connection.handle()); - return result; + boost::optional ChillerElectricASHRAE205_Impl::chilledWaterInletNode() const { + if (auto mo_ = supplyInletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - void ChillerElectricASHRAE205_Impl::resetOilCoolerOutletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::chilledWaterOutletNode() const { + if (auto mo_ = supplyOutletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - bool ChillerElectricASHRAE205_Impl::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, oilCoolerDesignFlowRate); - return result; - } + // Secondary: Condenser Loop - void ChillerElectricASHRAE205_Impl::resetOilCoolerDesignFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, ""); - OS_ASSERT(result); + unsigned ChillerElectricASHRAE205_Impl::demandInletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName; } - bool ChillerElectricASHRAE205_Impl::setAuxiliaryInletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, connection.handle()); - return result; + unsigned ChillerElectricASHRAE205_Impl::demandOutletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName; } - void ChillerElectricASHRAE205_Impl::resetAuxiliaryInletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::condenserWaterLoop() const { + return WaterToWaterComponent_Impl::secondaryPlantLoop(); } - bool ChillerElectricASHRAE205_Impl::setAuxiliaryOutletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, connection.handle()); - return result; + boost::optional ChillerElectricASHRAE205_Impl::condenserInletNode() const { + if (auto mo_ = demandInletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - void ChillerElectricASHRAE205_Impl::resetAuxiliaryOutletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::condenserOutletNode() const { + if (auto mo_ = demandOutletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - bool ChillerElectricASHRAE205_Impl::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { - bool result = setDouble(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, auxiliaryCoolingDesignFlowRate); - return result; + // Tertiary: Heat Recovery + unsigned ChillerElectricASHRAE205_Impl::tertiaryInletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName; } - void ChillerElectricASHRAE205_Impl::resetAuxiliaryCoolingDesignFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, ""); - OS_ASSERT(result); + unsigned ChillerElectricASHRAE205_Impl::tertiaryOutletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName; } - bool ChillerElectricASHRAE205_Impl::setHeatRecoveryInletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, connection.handle()); - return result; + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryLoop() const { + return WaterToWaterComponent_Impl::tertiaryPlantLoop(); } - void ChillerElectricASHRAE205_Impl::resetHeatRecoveryInletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryInletNode() const { + if (auto mo_ = tertiaryInletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - bool ChillerElectricASHRAE205_Impl::setHeatRecoveryOutletNode(const Connection& connection) { - bool result = setPointer(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, connection.handle()); - return result; + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryOutletNode() const { + if (auto mo_ = tertiaryOutletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - void ChillerElectricASHRAE205_Impl::resetHeatRecoveryOutletNode() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); } - bool ChillerElectricASHRAE205_Impl::setEndUseSubcategory(const std::string& endUseSubcategory) { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, endUseSubcategory); - OS_ASSERT(result); - return result; + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); } - void ChillerElectricASHRAE205_Impl::resetEndUseSubcategory() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, ""); - OS_ASSERT(result); + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); } - void ChillerElectricASHRAE205_Impl::autosize() { - autosizeRatedCapacity(); - autosizeChilledWaterMaximumRequestedFlowRate(); - autosizeCondenserMaximumRequestedFlowRate(); + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); } - void ChillerElectricASHRAE205_Impl::applySizingValues() { - boost::optional val; - val = autosizedRatedCapacity(); - if (val) { - setRatedCapacity(val.get()); - } + bool ChillerElectricASHRAE205_Impl::addToNode(Node& node) { + boost::optional t_plantLoop = node.plantLoop(); - val = autosizedChilledWaterMaximumRequestedFlowRate(); - if (val) { - setChilledWaterMaximumRequestedFlowRate(val.get()); + // If trying to add to a node that is on the supply side of a plant loop + if (t_plantLoop) { + if (t_plantLoop->supplyComponent(node.handle())) { + // If there is already a cooling Plant Loop + boost::optional coolingPlant = this->chilledWaterLoop(); + if (coolingPlant) { + // And it's not the same as the node's loop + if (t_plantLoop.get() != coolingPlant.get()) { + // And if there is no Heat Recovery (tertiary) + boost::optional heatingPlant = this->heatRecoveryLoop(); + if (!heatingPlant) { + // Then try to add it to the tertiary one + LOG(Warn, "Calling addToTertiaryNode to connect it to the tertiary (=Heat Recovery) loop for " << briefDescription()); + return this->addToTertiaryNode(node); + } + } + } + } } - val = autosizedCondenserMaximumRequestedFlowRate(); - if (val) { - setCondenserMaximumRequestedFlowRate(val.get()); - } + // All other cases, call the base class implementation + return WaterToWaterComponent_Impl::addToNode(node); } - boost::optional ChillerElectricASHRAE205_Impl::optionalRepresentationFile() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName); - } + bool ChillerElectricASHRAE205_Impl::addToTertiaryNode(Node& node) { + auto _model = node.model(); + auto t_plantLoop = node.plantLoop(); - boost::optional ChillerElectricASHRAE205_Impl::optionalChilledWaterInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName); - } - - boost::optional ChillerElectricASHRAE205_Impl::optionalChilledWaterOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName); + // Only accept adding to a node that is on a demand side of a plant loop + // Since tertiary here = heat recovery loop (heating) + if (t_plantLoop) { + if (t_plantLoop->demandComponent(node.handle())) { + // Call base class method which accepts both supply and demand + return WaterToWaterComponent_Impl::addToTertiaryNode(node); + } else { + LOG(Info, + "Tertiary Loop (Heat Recovery Loop) connections can only be placed on the Demand side (of a Heating Loop), for " << briefDescription()); + } + } + return false; } } // namespace detail - ChillerElectricASHRAE205::ChillerElectricASHRAE205(const Model& model) : WaterToWaterComponent(ChillerElectricASHRAE205::iddObjectType(), model) { + ChillerElectricASHRAE205::ChillerElectricASHRAE205(const ExternalFile& representationFile) + : WaterToWaterComponent(ChillerElectricASHRAE205::iddObjectType(), representationFile.model()) { OS_ASSERT(getImpl()); - // TODO: Appropriately handle the following required object-list fields. - // OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName - // OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName - // OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName - bool ok = true; - // ok = setRepresentationFile(); - OS_ASSERT(ok); - // ok = setPerformanceInterpolationMethod(); - OS_ASSERT(ok); - // ok = setRatedCapacity(); - OS_ASSERT(ok); - // ok = setSizingFactor(); - OS_ASSERT(ok); - // ok = setAmbientTemperatureIndicator(); - OS_ASSERT(ok); - // ok = setChilledWaterInletNode(); - OS_ASSERT(ok); - // ok = setChilledWaterOutletNode(); - OS_ASSERT(ok); - // ok = setChilledWaterMaximumRequestedFlowRate(); - OS_ASSERT(ok); - // ok = setCondenserMaximumRequestedFlowRate(); - OS_ASSERT(ok); - // ok = setChillerFlowMode(); - OS_ASSERT(ok); + setPerformanceInterpolationMethod("Linear"); + autosizeRatedCapacity(); + setSizingFactor(1.0); + setAmbientTemperatureIndicator("Outdoors"); + autosizeChilledWaterMaximumRequestedFlowRate(); + autosizeCondenserMaximumRequestedFlowRate(); + setChillerFlowMode("NotModulated"); + setEndUseSubcategory("General"); } IddObjectType ChillerElectricASHRAE205::iddObjectType() { - return IddObjectType(IddObjectType::OS_Chiller_Electric_ASHRAE205); + return {IddObjectType::OS_Chiller_Electric_ASHRAE205}; } std::vector ChillerElectricASHRAE205::performanceInterpolationMethodValues() { @@ -600,16 +599,8 @@ namespace model { return getImpl()->ambientTemperatureZone(); } - boost::optional ChillerElectricASHRAE205::ambientTemperatureOutdoorAirNode() const { - return getImpl()->ambientTemperatureOutdoorAirNode(); - } - - Connection ChillerElectricASHRAE205::chilledWaterInletNode() const { - return getImpl()->chilledWaterInletNode(); - } - - Connection ChillerElectricASHRAE205::chilledWaterOutletNode() const { - return getImpl()->chilledWaterOutletNode(); + boost::optional ChillerElectricASHRAE205::ambientTemperatureOutdoorAirNodeName() const { + return getImpl()->ambientTemperatureOutdoorAirNodeName(); } boost::optional ChillerElectricASHRAE205::chilledWaterMaximumRequestedFlowRate() const { @@ -624,14 +615,6 @@ namespace model { return getImpl()->autosizedChilledWaterMaximumRequestedFlowRate(); } - boost::optional ChillerElectricASHRAE205::condenserInletNode() const { - return getImpl()->condenserInletNode(); - } - - boost::optional ChillerElectricASHRAE205::condenserOutletNode() const { - return getImpl()->condenserOutletNode(); - } - boost::optional ChillerElectricASHRAE205::condenserMaximumRequestedFlowRate() const { return getImpl()->condenserMaximumRequestedFlowRate(); } @@ -648,38 +631,14 @@ namespace model { return getImpl()->chillerFlowMode(); } - boost::optional ChillerElectricASHRAE205::oilCoolerInletNode() const { - return getImpl()->oilCoolerInletNode(); - } - - boost::optional ChillerElectricASHRAE205::oilCoolerOutletNode() const { - return getImpl()->oilCoolerOutletNode(); - } - boost::optional ChillerElectricASHRAE205::oilCoolerDesignFlowRate() const { return getImpl()->oilCoolerDesignFlowRate(); } - boost::optional ChillerElectricASHRAE205::auxiliaryInletNode() const { - return getImpl()->auxiliaryInletNode(); - } - - boost::optional ChillerElectricASHRAE205::auxiliaryOutletNode() const { - return getImpl()->auxiliaryOutletNode(); - } - boost::optional ChillerElectricASHRAE205::auxiliaryCoolingDesignFlowRate() const { return getImpl()->auxiliaryCoolingDesignFlowRate(); } - boost::optional ChillerElectricASHRAE205::heatRecoveryInletNode() const { - return getImpl()->heatRecoveryInletNode(); - } - - boost::optional ChillerElectricASHRAE205::heatRecoveryOutletNode() const { - return getImpl()->heatRecoveryOutletNode(); - } - std::string ChillerElectricASHRAE205::endUseSubcategory() const { return getImpl()->endUseSubcategory(); } @@ -728,20 +687,12 @@ namespace model { getImpl()->resetAmbientTemperatureZone(); } - bool ChillerElectricASHRAE205::setAmbientTemperatureOutdoorAirNode(const Connection& connection) { - return getImpl()->setAmbientTemperatureOutdoorAirNode(connection); - } - - void ChillerElectricASHRAE205::resetAmbientTemperatureOutdoorAirNode() { - getImpl()->resetAmbientTemperatureOutdoorAirNode(); + bool ChillerElectricASHRAE205::setAmbientTemperatureOutdoorAirNodeName(const std::string& ambientTemperatureOutdoorAirNodeName) { + return getImpl()->setAmbientTemperatureOutdoorAirNodeName(ambientTemperatureOutdoorAirNodeName); } - bool ChillerElectricASHRAE205::setChilledWaterInletNode(const Connection& connection) { - return getImpl()->setChilledWaterInletNode(connection); - } - - bool ChillerElectricASHRAE205::setChilledWaterOutletNode(const Connection& connection) { - return getImpl()->setChilledWaterOutletNode(connection); + void ChillerElectricASHRAE205::resetAmbientTemperatureOutdoorAirNodeName() { + getImpl()->resetAmbientTemperatureOutdoorAirNodeName(); } bool ChillerElectricASHRAE205::setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate) { @@ -752,22 +703,6 @@ namespace model { getImpl()->autosizeChilledWaterMaximumRequestedFlowRate(); } - bool ChillerElectricASHRAE205::setCondenserInletNode(const Connection& connection) { - return getImpl()->setCondenserInletNode(connection); - } - - void ChillerElectricASHRAE205::resetCondenserInletNode() { - getImpl()->resetCondenserInletNode(); - } - - bool ChillerElectricASHRAE205::setCondenserOutletNode(const Connection& connection) { - return getImpl()->setCondenserOutletNode(connection); - } - - void ChillerElectricASHRAE205::resetCondenserOutletNode() { - getImpl()->resetCondenserOutletNode(); - } - bool ChillerElectricASHRAE205::setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate) { return getImpl()->setCondenserMaximumRequestedFlowRate(condenserMaximumRequestedFlowRate); } @@ -780,76 +715,82 @@ namespace model { return getImpl()->setChillerFlowMode(chillerFlowMode); } - bool ChillerElectricASHRAE205::setOilCoolerInletNode(const Connection& connection) { - return getImpl()->setOilCoolerInletNode(connection); + bool ChillerElectricASHRAE205::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { + return getImpl()->setOilCoolerDesignFlowRate(oilCoolerDesignFlowRate); } - void ChillerElectricASHRAE205::resetOilCoolerInletNode() { - getImpl()->resetOilCoolerInletNode(); + void ChillerElectricASHRAE205::resetOilCoolerDesignFlowRate() { + getImpl()->resetOilCoolerDesignFlowRate(); } - bool ChillerElectricASHRAE205::setOilCoolerOutletNode(const Connection& connection) { - return getImpl()->setOilCoolerOutletNode(connection); + bool ChillerElectricASHRAE205::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { + return getImpl()->setAuxiliaryCoolingDesignFlowRate(auxiliaryCoolingDesignFlowRate); } - void ChillerElectricASHRAE205::resetOilCoolerOutletNode() { - getImpl()->resetOilCoolerOutletNode(); + void ChillerElectricASHRAE205::resetAuxiliaryCoolingDesignFlowRate() { + getImpl()->resetAuxiliaryCoolingDesignFlowRate(); } - bool ChillerElectricASHRAE205::setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate) { - return getImpl()->setOilCoolerDesignFlowRate(oilCoolerDesignFlowRate); + bool ChillerElectricASHRAE205::setEndUseSubcategory(const std::string& endUseSubcategory) { + return getImpl()->setEndUseSubcategory(endUseSubcategory); } - void ChillerElectricASHRAE205::resetOilCoolerDesignFlowRate() { - getImpl()->resetOilCoolerDesignFlowRate(); + void ChillerElectricASHRAE205::resetEndUseSubcategory() { + getImpl()->resetEndUseSubcategory(); } - bool ChillerElectricASHRAE205::setAuxiliaryInletNode(const Connection& connection) { - return getImpl()->setAuxiliaryInletNode(connection); + // Convenience getters + + boost::optional ChillerElectricASHRAE205::chilledWaterLoop() const { + return getImpl()->chilledWaterLoop(); } - void ChillerElectricASHRAE205::resetAuxiliaryInletNode() { - getImpl()->resetAuxiliaryInletNode(); + boost::optional ChillerElectricASHRAE205::chilledWaterInletNode() const { + return getImpl()->chilledWaterInletNode(); } - bool ChillerElectricASHRAE205::setAuxiliaryOutletNode(const Connection& connection) { - return getImpl()->setAuxiliaryOutletNode(connection); + boost::optional ChillerElectricASHRAE205::chilledWaterOutletNode() const { + return getImpl()->chilledWaterOutletNode(); } - void ChillerElectricASHRAE205::resetAuxiliaryOutletNode() { - getImpl()->resetAuxiliaryOutletNode(); + boost::optional ChillerElectricASHRAE205::condenserWaterLoop() const { + return getImpl()->condenserWaterLoop(); } - bool ChillerElectricASHRAE205::setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate) { - return getImpl()->setAuxiliaryCoolingDesignFlowRate(auxiliaryCoolingDesignFlowRate); + boost::optional ChillerElectricASHRAE205::condenserInletNode() const { + return getImpl()->condenserInletNode(); } - void ChillerElectricASHRAE205::resetAuxiliaryCoolingDesignFlowRate() { - getImpl()->resetAuxiliaryCoolingDesignFlowRate(); + boost::optional ChillerElectricASHRAE205::condenserOutletNode() const { + return getImpl()->condenserOutletNode(); } - bool ChillerElectricASHRAE205::setHeatRecoveryInletNode(const Connection& connection) { - return getImpl()->setHeatRecoveryInletNode(connection); + boost::optional ChillerElectricASHRAE205::heatRecoveryLoop() const { + return getImpl()->heatRecoveryLoop(); } - void ChillerElectricASHRAE205::resetHeatRecoveryInletNode() { - getImpl()->resetHeatRecoveryInletNode(); + boost::optional ChillerElectricASHRAE205::heatRecoveryInletNode() const { + return getImpl()->heatRecoveryInletNode(); } - bool ChillerElectricASHRAE205::setHeatRecoveryOutletNode(const Connection& connection) { - return getImpl()->setHeatRecoveryOutletNode(connection); + boost::optional ChillerElectricASHRAE205::heatRecoveryOutletNode() const { + return getImpl()->heatRecoveryOutletNode(); } - void ChillerElectricASHRAE205::resetHeatRecoveryOutletNode() { - getImpl()->resetHeatRecoveryOutletNode(); + boost::optional ChillerElectricASHRAE205::oilCoolerInletNode() const { + return getImpl()->oilCoolerInletNode(); } - bool ChillerElectricASHRAE205::setEndUseSubcategory(const std::string& endUseSubcategory) { - return getImpl()->setEndUseSubcategory(endUseSubcategory); + boost::optional ChillerElectricASHRAE205::oilCoolerOutletNode() const { + return getImpl()->oilCoolerOutletNode(); } - void ChillerElectricASHRAE205::resetEndUseSubcategory() { - getImpl()->resetEndUseSubcategory(); + boost::optional ChillerElectricASHRAE205::auxiliaryInletNode() const { + return getImpl()->auxiliaryInletNode(); + } + + boost::optional ChillerElectricASHRAE205::auxiliaryOutletNode() const { + return getImpl()->auxiliaryOutletNode(); } /// @cond diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index abb78b19c2..b5f7439665 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -37,21 +37,10 @@ namespace openstudio { namespace model { - // TODO: Check the following class names against object getters and setters. class ExternalFile; - class Schedule; + class Node; class ThermalZone; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; + class Schedule; namespace detail { @@ -66,7 +55,7 @@ namespace model { /** @name Constructors and Destructors */ //@{ - explicit ChillerElectricASHRAE205(const Model& model); + explicit ChillerElectricASHRAE205(const ExternalFile& representationFile); virtual ~ChillerElectricASHRAE205() = default; @@ -83,186 +72,117 @@ namespace model { /** @name Getters */ //@{ - // TODO: Check return type. From object lists, some candidates are: ExternalFile. ExternalFile representationFile() const; std::string performanceInterpolationMethod() const; boost::optional ratedCapacity() const; - bool isRatedCapacityAutosized() const; - boost::optional autosizedRatedCapacity(); - double sizingFactor() const; std::string ambientTemperatureIndicator() const; - // TODO: Check return type. From object lists, some candidates are: Schedule. boost::optional ambientTemperatureSchedule() const; - // TODO: Check return type. From object lists, some candidates are: ThermalZone. boost::optional ambientTemperatureZone() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional ambientTemperatureOutdoorAirNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - Connection chilledWaterInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - Connection chilledWaterOutletNode() const; + boost::optional ambientTemperatureOutdoorAirNodeName() const; boost::optional chilledWaterMaximumRequestedFlowRate() const; - bool isChilledWaterMaximumRequestedFlowRateAutosized() const; - boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional condenserInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional condenserOutletNode() const; - boost::optional condenserMaximumRequestedFlowRate() const; - bool isCondenserMaximumRequestedFlowRateAutosized() const; - boost::optional autosizedCondenserMaximumRequestedFlowRate(); - std::string chillerFlowMode() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional oilCoolerInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional oilCoolerOutletNode() const; - boost::optional oilCoolerDesignFlowRate() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional auxiliaryInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional auxiliaryOutletNode() const; - boost::optional auxiliaryCoolingDesignFlowRate() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional heatRecoveryInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional heatRecoveryOutletNode() const; - std::string endUseSubcategory() const; - bool isEndUseSubcategoryDefaulted() const; //@} /** @name Setters */ //@{ - // TODO: Check argument type. From object lists, some candidates are: ExternalFile. bool setRepresentationFile(const ExternalFile& externalFile); bool setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod); bool setRatedCapacity(double ratedCapacity); - void autosizeRatedCapacity(); bool setSizingFactor(double sizingFactor); bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); - // TODO: Check argument type. From object lists, some candidates are: Schedule. - // Note Schedules are passed by reference, not const reference. + /** This will make the Ambient Temperature Indicator = 'Schedule' */ bool setAmbientTemperatureSchedule(Schedule& schedule); - + /** This will reset the Ambient Temperature Indicator = 'Outdoors' */ void resetAmbientTemperatureSchedule(); - // TODO: Check argument type. From object lists, some candidates are: ThermalZone. + /** This will make the Ambient Temperature Indicator = 'Zone' */ bool setAmbientTemperatureZone(const ThermalZone& thermalZone); - + /** This will reset the Ambient Temperature Indicator = 'Outdoors' */ void resetAmbientTemperatureZone(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAmbientTemperatureOutdoorAirNode(const Connection& connection); - - void resetAmbientTemperatureOutdoorAirNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setChilledWaterInletNode(const Connection& connection); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setChilledWaterOutletNode(const Connection& connection); + /** This will make the Ambient Temperature Indicator = 'Outdoors' */ + bool setAmbientTemperatureOutdoorAirNodeName(const std::string& ambientTemperatureOutdoorAirNodeName); + /** This will reset the Ambient Temperature Indicator = 'Outdoors'. A default Outdoor Air Node Name will be used in the ForwardTranslator */ + void resetAmbientTemperatureOutdoorAirNodeName(); bool setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate); - void autosizeChilledWaterMaximumRequestedFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setCondenserInletNode(const Connection& connection); - - void resetCondenserInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setCondenserOutletNode(const Connection& connection); - - void resetCondenserOutletNode(); - bool setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate); - void autosizeCondenserMaximumRequestedFlowRate(); bool setChillerFlowMode(const std::string& chillerFlowMode); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setOilCoolerInletNode(const Connection& connection); - - void resetOilCoolerInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setOilCoolerOutletNode(const Connection& connection); - - void resetOilCoolerOutletNode(); - bool setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate); - void resetOilCoolerDesignFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAuxiliaryInletNode(const Connection& connection); - - void resetAuxiliaryInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAuxiliaryOutletNode(const Connection& connection); + bool setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate); + void resetAuxiliaryCoolingDesignFlowRate(); - void resetAuxiliaryOutletNode(); + bool setEndUseSubcategory(const std::string& endUseSubcategory); + void resetEndUseSubcategory(); - bool setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate); + //@} + /** @name Other */ + //@{ - void resetAuxiliaryCoolingDesignFlowRate(); + boost::optional autosizedRatedCapacity(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setHeatRecoveryInletNode(const Connection& connection); + boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); - void resetHeatRecoveryInletNode(); + boost::optional autosizedCondenserMaximumRequestedFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setHeatRecoveryOutletNode(const Connection& connection); + /** Convenience Function to return the Chilled Water Loop (chiller on supply) **/ + boost::optional chilledWaterLoop() const; + // Same as supplyInletModelObject, but cast to a Node + boost::optional chilledWaterInletNode() const; + boost::optional chilledWaterOutletNode() const; - void resetHeatRecoveryOutletNode(); + /** Convenience Function to return the Condenser Water Loop (chiller on demand side) **/ + boost::optional condenserWaterLoop() const; + boost::optional condenserInletNode() const; + boost::optional condenserOutletNode() const; - bool setEndUseSubcategory(const std::string& endUseSubcategory); + // Not implemented in E+ 22.2.0, but reserved as a Tertiary Loop for now + boost::optional heatRecoveryLoop() const; + boost::optional heatRecoveryInletNode() const; + boost::optional heatRecoveryOutletNode() const; - void resetEndUseSubcategory(); + // TODO: how to deal with these? That's 5 plant loop total in the end + boost::optional oilCoolerInletNode() const; + boost::optional oilCoolerOutletNode() const; - //@} - /** @name Other */ - //@{ + boost::optional auxiliaryInletNode() const; + boost::optional auxiliaryOutletNode() const; //@} protected: @@ -290,3 +210,4 @@ namespace model { } // namespace openstudio #endif // MODEL_CHILLERELECTRICASHRAE205_HPP + diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp index 4b5e740ac5..12347cbd1b 100644 --- a/src/model/ChillerElectricASHRAE205_Impl.hpp +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -36,21 +36,10 @@ namespace openstudio { namespace model { - // TODO: Check the following class names against object getters and setters. class ExternalFile; - class Schedule; + class Node; class ThermalZone; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; - class Connection; + class Schedule; namespace detail { @@ -67,7 +56,7 @@ namespace model { ChillerElectricASHRAE205_Impl(const ChillerElectricASHRAE205_Impl& other, Model_Impl* model, bool keepHandle); - virtual ~ChillerElectricASHRAE205_Impl() {} + virtual ~ChillerElectricASHRAE205_Impl() = default; //@} /** @name Virtual Methods */ @@ -79,207 +68,155 @@ namespace model { virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + // chilledWaterLoop + virtual unsigned supplyInletPort() const override; + virtual unsigned supplyOutletPort() const override; + + // condenserWaterLoop + virtual unsigned demandInletPort() const override; + virtual unsigned demandOutletPort() const override; + + // heatRecoveryLoop + virtual unsigned tertiaryInletPort() const override; + virtual unsigned tertiaryOutletPort() const override; + + /** This function will perform a check if trying to add it to a node that is on the demand side of a plant loop. + * If: + * - the node is on the demand side of a loop + * - the node isn't on the current condenser water loop itself + * - the chiller doesn't already have a heat recovery (tertiary) loop, + * then it tries to add it to the Tertiary loop. + * In all other cases, it will call the base class' method WaterToWaterComponent_Impl::addToNode() + * If this is connecting to the demand side of a loop (not tertiary), will set the chiller condenserType to WaterCooled + */ + virtual bool addToNode(Node& node) override; + + /* Restricts addToTertiaryNode to a node that is on the demand side of a plant loop (tertiary = Heat Recovery Loop) */ + virtual bool addToTertiaryNode(Node& node) override; + + virtual void autosize() override; + + virtual void applySizingValues() override; + //@} /** @name Getters */ //@{ - // TODO: Check return type. From object lists, some candidates are: ExternalFile. ExternalFile representationFile() const; std::string performanceInterpolationMethod() const; boost::optional ratedCapacity() const; - bool isRatedCapacityAutosized() const; - boost::optional autosizedRatedCapacity(); - double sizingFactor() const; std::string ambientTemperatureIndicator() const; - // TODO: Check return type. From object lists, some candidates are: Schedule. boost::optional ambientTemperatureSchedule() const; - // TODO: Check return type. From object lists, some candidates are: ThermalZone. boost::optional ambientTemperatureZone() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional ambientTemperatureOutdoorAirNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - Connection chilledWaterInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - Connection chilledWaterOutletNode() const; + boost::optional ambientTemperatureOutdoorAirNodeName() const; boost::optional chilledWaterMaximumRequestedFlowRate() const; - bool isChilledWaterMaximumRequestedFlowRateAutosized() const; - boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional condenserInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional condenserOutletNode() const; - boost::optional condenserMaximumRequestedFlowRate() const; - bool isCondenserMaximumRequestedFlowRateAutosized() const; - boost::optional autosizedCondenserMaximumRequestedFlowRate(); - std::string chillerFlowMode() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional oilCoolerInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional oilCoolerOutletNode() const; - boost::optional oilCoolerDesignFlowRate() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional auxiliaryInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional auxiliaryOutletNode() const; - boost::optional auxiliaryCoolingDesignFlowRate() const; - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional heatRecoveryInletNode() const; - - // TODO: Check return type. From object lists, some candidates are: Connection. - boost::optional heatRecoveryOutletNode() const; - std::string endUseSubcategory() const; - bool isEndUseSubcategoryDefaulted() const; //@} /** @name Setters */ //@{ - // TODO: Check argument type. From object lists, some candidates are: ExternalFile. bool setRepresentationFile(const ExternalFile& externalFile); bool setPerformanceInterpolationMethod(const std::string& performanceInterpolationMethod); bool setRatedCapacity(double ratedCapacity); - void autosizeRatedCapacity(); bool setSizingFactor(double sizingFactor); bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); - // TODO: Check argument type. From object lists, some candidates are: Schedule. - // Note Schedules are passed by reference, not const reference. bool setAmbientTemperatureSchedule(Schedule& schedule); - void resetAmbientTemperatureSchedule(); - // TODO: Check argument type. From object lists, some candidates are: ThermalZone. bool setAmbientTemperatureZone(const ThermalZone& thermalZone); - void resetAmbientTemperatureZone(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAmbientTemperatureOutdoorAirNode(const Connection& connection); - - void resetAmbientTemperatureOutdoorAirNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setChilledWaterInletNode(const Connection& connection); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setChilledWaterOutletNode(const Connection& connection); + bool setAmbientTemperatureOutdoorAirNodeName(const std::string& ambientTemperatureOutdoorAirNodeName); + void resetAmbientTemperatureOutdoorAirNodeName(); bool setChilledWaterMaximumRequestedFlowRate(double chilledWaterMaximumRequestedFlowRate); - void autosizeChilledWaterMaximumRequestedFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setCondenserInletNode(const Connection& connection); - - void resetCondenserInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setCondenserOutletNode(const Connection& connection); - - void resetCondenserOutletNode(); - bool setCondenserMaximumRequestedFlowRate(double condenserMaximumRequestedFlowRate); - void autosizeCondenserMaximumRequestedFlowRate(); bool setChillerFlowMode(const std::string& chillerFlowMode); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setOilCoolerInletNode(const Connection& connection); - - void resetOilCoolerInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setOilCoolerOutletNode(const Connection& connection); - - void resetOilCoolerOutletNode(); - bool setOilCoolerDesignFlowRate(double oilCoolerDesignFlowRate); - void resetOilCoolerDesignFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAuxiliaryInletNode(const Connection& connection); - - void resetAuxiliaryInletNode(); - - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setAuxiliaryOutletNode(const Connection& connection); - - void resetAuxiliaryOutletNode(); - bool setAuxiliaryCoolingDesignFlowRate(double auxiliaryCoolingDesignFlowRate); - void resetAuxiliaryCoolingDesignFlowRate(); - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setHeatRecoveryInletNode(const Connection& connection); + bool setEndUseSubcategory(const std::string& endUseSubcategory); + void resetEndUseSubcategory(); - void resetHeatRecoveryInletNode(); + //@} + /** @name Other */ + //@{ - // TODO: Check argument type. From object lists, some candidates are: Connection. - bool setHeatRecoveryOutletNode(const Connection& connection); + boost::optional autosizedRatedCapacity(); - void resetHeatRecoveryOutletNode(); + boost::optional autosizedChilledWaterMaximumRequestedFlowRate(); - bool setEndUseSubcategory(const std::string& endUseSubcategory); + boost::optional autosizedCondenserMaximumRequestedFlowRate(); - void resetEndUseSubcategory(); + /** Convenience Function to return the Chilled Water Loop (chiller on supply) **/ + boost::optional chilledWaterLoop() const; + // Same as supplyInletModelObject, but cast to a Node + boost::optional chilledWaterInletNode() const; + boost::optional chilledWaterOutletNode() const; - virtual void autosize() override; + /** Convenience Function to return the Condenser Water Loop (chiller on demand side) **/ + boost::optional condenserWaterLoop() const; + boost::optional condenserInletNode() const; + boost::optional condenserOutletNode() const; - virtual void applySizingValues() override; + // Not implemented in E+ 22.2.0, but reserved as a Tertiary Loop for now + boost::optional heatRecoveryLoop() const; + boost::optional heatRecoveryInletNode() const; + boost::optional heatRecoveryOutletNode() const; - //@} - /** @name Other */ - //@{ + // TODO: how to deal with these? That's 5 plant loop total in the end + boost::optional oilCoolerInletNode() const; + boost::optional oilCoolerOutletNode() const; + + boost::optional auxiliaryInletNode() const; + boost::optional auxiliaryOutletNode() const; //@} protected: private: REGISTER_LOGGER("openstudio.model.ChillerElectricASHRAE205"); - // TODO: Check the return types of these methods. // Optional getters for use by methods like children() so can remove() if the constructor fails. // There are other ways for the public versions of these getters to fail--perhaps all required // objects should be returned as boost::optionals boost::optional optionalRepresentationFile() const; - boost::optional optionalChilledWaterInletNode() const; - boost::optional optionalChilledWaterOutletNode() const; }; } // namespace detail diff --git a/src/model/ConcreteModelObjects.hpp b/src/model/ConcreteModelObjects.hpp index b3e0264348..ee8f6ce1fd 100644 --- a/src/model/ConcreteModelObjects.hpp +++ b/src/model/ConcreteModelObjects.hpp @@ -106,6 +106,7 @@ #include "ClimateZones.hpp" #include "ChillerAbsorption.hpp" #include "ChillerAbsorptionIndirect.hpp" +#include "ChillerElectricASHRAE205.hpp" #include "ChillerElectricEIR.hpp" #include "ChillerElectricReformulatedEIR.hpp" #include "ChillerHeaterPerformanceElectricEIR.hpp" @@ -639,6 +640,7 @@ #include "CFactorUndergroundWallConstruction_Impl.hpp" #include "ChillerAbsorption_Impl.hpp" #include "ChillerAbsorptionIndirect_Impl.hpp" +#include "ChillerElectricASHRAE205_Impl.hpp" #include "ChillerElectricEIR_Impl.hpp" #include "ChillerElectricReformulatedEIR_Impl.hpp" #include "ChillerHeaterPerformanceElectricEIR_Impl.hpp" diff --git a/src/model/Model.cpp b/src/model/Model.cpp index db96379c9c..6df76e2d05 100644 --- a/src/model/Model.cpp +++ b/src/model/Model.cpp @@ -3873,6 +3873,7 @@ namespace model { REGISTER_CONSTRUCTOR(CFactorUndergroundWallConstruction); REGISTER_CONSTRUCTOR(ChillerAbsorption); REGISTER_CONSTRUCTOR(ChillerAbsorptionIndirect); + REGISTER_CONSTRUCTOR(ChillerElectricASHRAE205); REGISTER_CONSTRUCTOR(ChillerElectricEIR); REGISTER_CONSTRUCTOR(ChillerElectricReformulatedEIR); REGISTER_CONSTRUCTOR(ChillerHeaterPerformanceElectricEIR); @@ -4428,6 +4429,7 @@ namespace model { REGISTER_COPYCONSTRUCTORS(ClimateZones); REGISTER_COPYCONSTRUCTORS(ChillerAbsorption); REGISTER_COPYCONSTRUCTORS(ChillerAbsorptionIndirect); + REGISTER_COPYCONSTRUCTORS(ChillerElectricASHRAE205); REGISTER_COPYCONSTRUCTORS(ChillerElectricEIR); REGISTER_COPYCONSTRUCTORS(ChillerElectricReformulatedEIR); REGISTER_COPYCONSTRUCTORS(ChillerHeaterPerformanceElectricEIR); diff --git a/src/model/ModelHVAC.i b/src/model/ModelHVAC.i index 91590c33dd..bb855885ff 100644 --- a/src/model/ModelHVAC.i +++ b/src/model/ModelHVAC.i @@ -164,6 +164,7 @@ MODELOBJECT_TEMPLATES(AirTerminalDualDuctVAVOutdoorAir); MODELOBJECT_TEMPLATES(CentralHeatPumpSystem); MODELOBJECT_TEMPLATES(CentralHeatPumpSystemModule); MODELOBJECT_TEMPLATES(ChillerHeaterPerformanceElectricEIR); +MODELOBJECT_TEMPLATES(ChillerElectricASHRAE205); MODELOBJECT_TEMPLATES(ChillerElectricEIR); MODELOBJECT_TEMPLATES(ChillerElectricReformulatedEIR); MODELOBJECT_TEMPLATES(CoilCoolingDXMultiSpeedStageData); @@ -285,6 +286,7 @@ SWIG_MODELOBJECT(AirTerminalDualDuctVAVOutdoorAir, 1); SWIG_MODELOBJECT(CentralHeatPumpSystem, 1); SWIG_MODELOBJECT(CentralHeatPumpSystemModule, 1); SWIG_MODELOBJECT(ChillerHeaterPerformanceElectricEIR, 1); +SWIG_MODELOBJECT(ChillerElectricASHRAE205, 1); SWIG_MODELOBJECT(ChillerElectricEIR, 1); SWIG_MODELOBJECT(ChillerElectricReformulatedEIR, 1); SWIG_MODELOBJECT(CoilCoolingDXMultiSpeedStageData, 1); diff --git a/src/model/ScheduleTypeRegistry.cpp b/src/model/ScheduleTypeRegistry.cpp index c53bd048a0..9796e72845 100644 --- a/src/model/ScheduleTypeRegistry.cpp +++ b/src/model/ScheduleTypeRegistry.cpp @@ -171,6 +171,7 @@ namespace model { {"AvailabilityManagerScheduledOff", "Availability Manager Scheduled Off", "schedule", false, "Availability", 0.0, 1.0}, {"CentralHeatPumpSystem", "Ancillary Operation", "ancillaryOperationSchedule", false, "Availability", 0.0, 1.0}, {"CentralHeatPumpSystemModule", "Chiller Heater Modules Control", "chillerHeaterModulesControlSchedule", false, "Availability", 0.0, 1.0}, + {"ChillerElectricASHRAE205", "Ambient Temperature", "ambientTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble()}, {"ChillerElectricEIR", "Basin Heater Operating", "basinHeaterSchedule", false, "Availability", 0.0, 1.0}, {"ChillerElectricEIR", "Heat Recovery Inlet High Temperature Limit", "heatRecoveryInletHighTemperatureLimitSchedule", true, "Temperature", OptionalDouble(), OptionalDouble()}, From c599454ce9856c3d1a8c45dd0f373185ee08eafc Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 15 Sep 2022 16:42:03 +0200 Subject: [PATCH 07/24] Progress on model implementation + Gtest --- resources/CMakeLists.txt | 1 + .../model/A205ExampleChiller.RS0001.a205.cbor | Bin 0 -> 6964 bytes src/model/ChillerElectricASHRAE205.cpp | 98 +++- src/model/ChillerElectricASHRAE205.hpp | 9 +- src/model/ChillerElectricASHRAE205_Impl.hpp | 5 +- src/model/ExternalFile.cpp | 22 +- src/model/ExternalFile.hpp | 3 + src/model/ExternalFile_Impl.hpp | 3 + .../test/ChillerElectricASHRAE205_GTest.cpp | 468 +++++++++++------- 9 files changed, 400 insertions(+), 209 deletions(-) create mode 100644 resources/model/A205ExampleChiller.RS0001.a205.cbor diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 10271e10aa..a7b682aebd 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -162,6 +162,7 @@ set(model_resources_src model/offset_tests.osm model/ParkUnder_Retail_Office_C2.osm model/ASHRAECourthouse.osm + model/A205ExampleChiller.RS0001.a205.cbor ) diff --git a/resources/model/A205ExampleChiller.RS0001.a205.cbor b/resources/model/A205ExampleChiller.RS0001.a205.cbor new file mode 100644 index 0000000000000000000000000000000000000000..7f8e55453f6d5405867a23649de37bde9def1fd6 GIT binary patch literal 6964 zcmeI1X;@R|w#NZc9D1a!LoHr4QV>*vVID-g85|GuAR^irk{z-k$xil8FdVc_SO=UH ztwWJPtyo1=1Q7~coUk&911RFa5kaMD700dh{DY=)Z@u?<&N2kqVJCG)y26I4Iw~6DE)h zOVLVFVDD%zh?kJ8n4we}Sae!9djU^FEA4oW_O8x6-=JWgKc&`E626$G<)nmX8%(p5 zhDsoLeiW;ci^QaYRBA@@d}WkePBOe05eqL`$$P7T=OM6n;5!N&Jb2y`38|E56+D|5 zi49MzWiSRyYIrujHZhb$XXPPvbaHcYAo;EiPR@L12WLlqjI)!3@8RL#;o{=%>Ln%mBBT}ez7LEc(N4~&~@94&JaP@R>@^pr7SAmnehrHAE-Aaw)JKwRimJySz z4;9Pv7eNlg3!|l)IUu{`|^Jp5-9l^PkTp~O6qQo@taB+FCM z8XiNc7?Q=(VNT?!WQi;#7Rh-khL&i>8rGhK6UpjaeEyYqbWKSH`)*7jrIgZ)LZr{r zPPsy))JjESjg}!9)w@`Sg$4U|2Amet3cWm*W`vqV6)6q#4Gr@5XXKr!6n2S)%ok}5 zW@wdekc`#{V@0emCQ&6~SN!D;en>J|R>Aix}@P3>L$E{m`iM#rzj@r*g_CN;oaZKO$g) z78g-KEcyRDukOn(E0)q)Ii-vh>LX7x+*{d3M!G@o#r;n%L%QUIRgt7bh`s zoNrKI_>{nipolPqLZqVyVkl9JoMd+ z6p;(LuR|uAt!+3}ue1L19dc5XppS`$RA6F}z9N%3LLIzgO2>|=fYlBBMGf|Vs?YQ< zj$r!W%9JNM>-RzX-zSf{=-04#@9q!Wpsy(A1Cw8SHz%VqORYZS%@M4z>+cpT!vX81 zc*W{0x~79vqc+8)P^neKkW8|%NjFoKoTlTos`t^#j;E9=t>$f3z9%?hk<+rs2Vs{u zV(W4K)x$eYIb#2o&FN;QtsGHoYoGpn+#!xg4oMiA^Qw>|ez;*WtTt555xGk=!=k-= za73wc*{n}`RB^=8;C=JD9XP=e8CJcoxa4Pjw8x@9vWEa{{u&?@O`#6 zyksp$WCev#Ygatsh$GQV?^grOIO0TbYhzxD5A-BiRCYW+#Sz==;uM1%y*MK0FR#*{ z_5THWHnp0bn2`oO1@d*0@^3jJO?$s@`o0wCX_#5IRs4b@%6eE@q|UMBh-EJ3@zT{; zV8+=;i$+g}=EDb!3WKkfLr-DU3eV|Ej#z0fdm(r}k0W+wd@;_b`Z!1ApX=G@yX7xY zu6dIZ8wNjso};&L2SU)vqK`ivFv05^1 zel4 zBkZ!7#3GeQOlcDJm38#5ztx?Te9aLR2B>p?@=gCfV>qJ0U?~`7nc<)u%@L;!a89`8 zdCTYN98qtu9GUhsAaOuH%xQpHWA|egHPsw((O@}LC$HZ=9R*cxfXcC1zHv)b98qVm z6h)RUE2mI3XAN*+Va@J!HA6X~(O@~|IXPh6n&%wxiviC6l<&zOjf%KpupEtNA9{tw zV_gQQ3*OYhACJ0jFj$V<^HG%_z6{L zE9N?FfOFdxbY#geSG~bfd~RU&>btJcV}Og>Yu}6>vj=(%mZIXIXsam|&|`oLRb!K* z-KIg0!BY5i)ZNsHXi{eka9)=_=0Qg(^cXA!-)2YNynY3G3~(;(jq#n>ThQ~?lAy1w z_pP;SVI5l^({w!W7)0!hTpitj(!JPj8`}R~B}ZJ3c%9UZ-NzAyc_E}(05k{F!;F(cTb2EIppE#5W3sj(I^Sc@Vq9+N;BCLL3w%OWJ1~|?7JT=n?*f0b42ye{+CGl6zaft zjc4w`0*<&jzIf-0GSqJIIhX4twv*x0tA{zcYdO|=vnnp^1WN7Z(0%)r*0`&P8PJq% z?SuqeQ>{Hcaw&YgA}tqcvA`R*KAo|z6uq=iF=kC$-5spG-!j6abp=OUvN~MPW<%XJc!Z3O1Nk?lb0yTI(@$%f4NJxT|BYJB_pEh~_>kD*J?^WtBux^H*g%b41Ph zv8S4I8sXFH!lR~g$hg^J%GrlqhvqlA>FHPfp;@u=xygo^SQizQb<&%JPmcRn_5E6) z*{m(F)x;5+5C8ph!j*z%u~++PrvUhPZ6Px@^@kph+1pP3_&fCQ)7jahuVSvH=Kh5# zub^l6ud7^S5ML5i>aXA<@--WGOk^b!;q#Za-8G>I_{}@zy=|@2py&C8wlOc!rK`mu zWfc$cS<^79-Qm~OJ>ioz+4W>DCO!7bd2!EtT&hf;mt-~))m-n-qf-O)daTphtlUR_ z=yBmgAHez+rjG4Xq+Wg(Fi&T9UxR3?H{42#7mfn#4KZ(t)0g{lx_SGmtwa%nn_BtDolJ|3#T?1f;bam5AGl1xK?@QZv z0@zs|N4LBNBo{ku-5d$nGDzXIHi1{TsQ;d8qp-;p{lX0J^7g!f;$iqxcc%>*h)d0N#MJ-5wpBmhKrgoa377hYrxiQv09FI4 zo)D1AjOaCSQ*a*uQStq%Y3O%M^wPV@Gu;3Qlf05*PzH>3PvNH0IKcQ*zpQpfoio#y zxGdQl0bqR7=M6(nnXh6RhF*IC7@Jg-#-enYu#G#0_A&v)?_cyo8uG;qACzmKQwVTv zjW6jp7vP_76QD!cFfqx^SDQ?AR`2`QyGO$hJY{y)*@H0C(p|_0V?2D{=FQ1~0iJcX zX3qe2sg|n)9|IPc`L|BJ2UxfGNZEG+z^-+pe3JAkfA%wt@WWd~+XLg*`r^(S3&AxzSXi9rp=B{F|54 zy4)O$Z2H1SmvR&^xYxPRH|+ptS)^B%KEVs01@I@MaWJXzc15@B06)!r;W%0^_2k4k zlTP2ofS=Fs(Ka>%to>GXKZsbfV+p$>f#raR%_{nFcR*%%uZgw20ePY4c_pg=XPTS8 z8Hydn-b#*;HHx6;k-*hWf}&)4w44dsKm&$6&5AgLzRbAKUQqnm7Qmu=ae;m70Gq@2 zOn7+&kTdJ`kE}W1jO8G)7Hxv<7rHE;-vO|3F^4RzW1z@OMbmAzq8^*n6 zJzIu-2t7NFP?dnqks0%Z(*QX#E6X7Pt;)ai>)uB|7(NE!pACX;#GhK)$4dLSr~VJN5=~R`&Lbb3l*veu z2EEI0PW2J=+xBBL{>dOHMOqytr$kKR$AbD;KKkwRZ|@xPx?XXtpO qGJ#@frT#}Ip#%jOqm{>WJ!)Qvhr&?(k*@SlC$ ChillerElectricASHRAE205_Impl::ambientTemperatureZone() const { @@ -223,8 +225,10 @@ namespace model { void ChillerElectricASHRAE205_Impl::resetAmbientTemperatureZone() { bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, ""); OS_ASSERT(result); - result = setAmbientTemperatureIndicator("Outdoors"); - OS_ASSERT(result); + if (openstudio::istringEqual("Zone", ambientTemperatureIndicator())) { + result = setAmbientTemperatureIndicator("Outdoors"); + OS_ASSERT(result); + } } boost::optional ChillerElectricASHRAE205_Impl::ambientTemperatureOutdoorAirNodeName() const { @@ -469,22 +473,6 @@ namespace model { return boost::none; } - boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); - } - - boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); - } - - boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); - } - - boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); - } - bool ChillerElectricASHRAE205_Impl::addToNode(Node& node) { boost::optional t_plantLoop = node.plantLoop(); @@ -530,16 +518,61 @@ namespace model { return false; } + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerLoop() const { + if (boost::optional n_ = oilCoolerInletNode()) { + return n_->plantLoop(); + } + return boost::none; + } + + bool ChillerElectricASHRAE205_Impl::addToOilCoolerLoopNode(Node& node) { + LOG_AND_THROW("NOT IMPLEMENTED YET"); + } + + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryLoop() const { + if (boost::optional n_ = auxiliaryInletNode()) { + return n_->plantLoop(); + } + return boost::none; + } + + bool ChillerElectricASHRAE205_Impl::addToAuxiliaryLoopNode(Node& node) { + LOG_AND_THROW("NOT IMPLEMENTED YET"); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { + return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); + } + } // namespace detail ChillerElectricASHRAE205::ChillerElectricASHRAE205(const ExternalFile& representationFile) : WaterToWaterComponent(ChillerElectricASHRAE205::iddObjectType(), representationFile.model()) { OS_ASSERT(getImpl()); + auto filePath = representationFile.filePath(); + bool ok = (toString(filePath.extension()) == ".cbor"); + if (!ok) { + remove(); + LOG_AND_THROW("External file must have a .cbor extension, got externalfile='" << filePath << "'."); + } + setPerformanceInterpolationMethod("Linear"); autosizeRatedCapacity(); setSizingFactor(1.0); - setAmbientTemperatureIndicator("Outdoors"); + getImpl()->setAmbientTemperatureIndicator("Outdoors"); autosizeChilledWaterMaximumRequestedFlowRate(); autosizeCondenserMaximumRequestedFlowRate(); setChillerFlowMode("NotModulated"); @@ -667,9 +700,10 @@ namespace model { return getImpl()->setSizingFactor(sizingFactor); } - bool ChillerElectricASHRAE205::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { - return getImpl()->setAmbientTemperatureIndicator(ambientTemperatureIndicator); - } + // Done via the other setAmbientXXX + // bool ChillerElectricASHRAE205::setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator) { + // return getImpl()->setAmbientTemperatureIndicator(ambientTemperatureIndicator); + // } bool ChillerElectricASHRAE205::setAmbientTemperatureSchedule(Schedule& schedule) { return getImpl()->setAmbientTemperatureSchedule(schedule); @@ -777,6 +811,14 @@ namespace model { return getImpl()->heatRecoveryOutletNode(); } + boost::optional ChillerElectricASHRAE205::oilCoolerLoop() const { + return getImpl()->oilCoolerLoop(); + } + + bool ChillerElectricASHRAE205::addToOilCoolerLoopNode(Node& node) { + return getImpl()->addToOilCoolerLoopNode(node); + } + boost::optional ChillerElectricASHRAE205::oilCoolerInletNode() const { return getImpl()->oilCoolerInletNode(); } @@ -785,6 +827,14 @@ namespace model { return getImpl()->oilCoolerOutletNode(); } + boost::optional ChillerElectricASHRAE205::auxiliaryLoop() const { + return getImpl()->auxiliaryLoop(); + } + + bool ChillerElectricASHRAE205::addToAuxiliaryLoopNode(Node& node) { + return getImpl()->addToAuxiliaryLoopNode(node); + } + boost::optional ChillerElectricASHRAE205::auxiliaryInletNode() const { return getImpl()->auxiliaryInletNode(); } diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index b5f7439665..e70470175b 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -117,7 +117,8 @@ namespace model { bool setSizingFactor(double sizingFactor); - bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); + // This is done via the setAmbientXXX methods + // bool setAmbientTemperatureIndicator(const std::string& ambientTemperatureIndicator); /** This will make the Ambient Temperature Indicator = 'Schedule' */ bool setAmbientTemperatureSchedule(Schedule& schedule); @@ -177,10 +178,13 @@ namespace model { boost::optional heatRecoveryInletNode() const; boost::optional heatRecoveryOutletNode() const; - // TODO: how to deal with these? That's 5 plant loop total in the end + boost::optional oilCoolerLoop() const; + bool addToOilCoolerLoopNode(Node& node); boost::optional oilCoolerInletNode() const; boost::optional oilCoolerOutletNode() const; + bool addToAuxiliaryLoopNode(Node& node); + boost::optional auxiliaryLoop() const; boost::optional auxiliaryInletNode() const; boost::optional auxiliaryOutletNode() const; @@ -210,4 +214,3 @@ namespace model { } // namespace openstudio #endif // MODEL_CHILLERELECTRICASHRAE205_HPP - diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp index 12347cbd1b..816241fc68 100644 --- a/src/model/ChillerElectricASHRAE205_Impl.hpp +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -201,10 +201,13 @@ namespace model { boost::optional heatRecoveryInletNode() const; boost::optional heatRecoveryOutletNode() const; - // TODO: how to deal with these? That's 5 plant loop total in the end + boost::optional oilCoolerLoop() const; + bool addToOilCoolerLoopNode(Node& node); boost::optional oilCoolerInletNode() const; boost::optional oilCoolerOutletNode() const; + bool addToAuxiliaryLoopNode(Node& node); + boost::optional auxiliaryLoop() const; boost::optional auxiliaryInletNode() const; boost::optional auxiliaryOutletNode() const; diff --git a/src/model/ExternalFile.cpp b/src/model/ExternalFile.cpp index a9af885da4..9d3b4d4d4a 100644 --- a/src/model/ExternalFile.cpp +++ b/src/model/ExternalFile.cpp @@ -33,6 +33,9 @@ #include "Model.hpp" #include "ScheduleFile.hpp" #include "PythonPluginInstance.hpp" +#include "PythonPluginInstance_Impl.hpp" +#include "ChillerElectricASHRAE205.hpp" +#include "ChillerElectricASHRAE205_Impl.hpp" #include #include @@ -45,7 +48,6 @@ #include #include "ScheduleFile_Impl.hpp" -#include "PythonPluginInstance_Impl.hpp" namespace openstudio { namespace model { @@ -114,6 +116,13 @@ namespace model { tmp.insert(tmp.end(), tmp2.begin(), tmp2.end()); } + // ChillerElectricASHRAE205 + std::vector chs = chillerElectricASHRAE205s(); + for (auto& ch : chs) { + std::vector tmp2 = ch.remove(); + tmp.insert(tmp.end(), tmp2.begin(), tmp2.end()); + } + std::vector idfObjects = ModelObject_Impl::remove(); idfObjects.insert(idfObjects.end(), tmp.begin(), tmp.end()); @@ -192,6 +201,11 @@ namespace model { return result; } + std::vector ExternalFile_Impl::chillerElectricASHRAE205s() const { + std::vector result = getObject().getModelObjectSources(); + return result; + } + } // namespace detail boost::optional ExternalFile::getExternalFile(const Model& model, const std::string& filename) { @@ -313,8 +327,12 @@ namespace model { return getImpl()->pythonPluginInstances(); } + std::vector ExternalFile::chillerElectricASHRAE205s() const { + return getImpl()->chillerElectricASHRAE205s(); + } + /// @cond - ExternalFile::ExternalFile(std::shared_ptr impl) : ResourceObject(impl) {} + ExternalFile::ExternalFile(std::shared_ptr impl) : ResourceObject(std::move(impl)) {} /// @endcond } // namespace model diff --git a/src/model/ExternalFile.hpp b/src/model/ExternalFile.hpp index 8f6e525a6b..399928aaeb 100644 --- a/src/model/ExternalFile.hpp +++ b/src/model/ExternalFile.hpp @@ -41,6 +41,7 @@ namespace model { class ScheduleFile; class PythonPluginInstance; + class ChillerElectricASHRAE205; namespace detail { @@ -94,6 +95,8 @@ namespace model { std::vector pythonPluginInstances() const; + std::vector chillerElectricASHRAE205s() const; + //@} protected: /// @cond diff --git a/src/model/ExternalFile_Impl.hpp b/src/model/ExternalFile_Impl.hpp index cfcf53cada..3f12981e6e 100644 --- a/src/model/ExternalFile_Impl.hpp +++ b/src/model/ExternalFile_Impl.hpp @@ -40,6 +40,7 @@ namespace model { class ExternalFile; class ScheduleFile; class PythonPluginInstance; + class ChillerElectricASHRAE205; namespace detail { @@ -101,6 +102,8 @@ namespace model { std::vector pythonPluginInstances() const; + std::vector chillerElectricASHRAE205s() const; + //@} protected: bool setFileName(const std::string& fileName); diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index 340c848d21..62584a2ada 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -32,239 +32,349 @@ #include "../ChillerElectricASHRAE205.hpp" #include "../ChillerElectricASHRAE205_Impl.hpp" -// TODO: Check the following class names against object getters and setters. #include "../ExternalFile.hpp" #include "../ExternalFile_Impl.hpp" -#include "../Schedule.hpp" -#include "../Schedule_Impl.hpp" - #include "../ThermalZone.hpp" #include "../ThermalZone_Impl.hpp" +#include "../PlantLoop.hpp" +#include "../PlantLoop_Impl.hpp" +#include "../Node.hpp" +#include "../Node_Impl.hpp" +#include "../Schedule.hpp" +#include "../ScheduleConstant.hpp" -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" - -#include "../Connection.hpp" -#include "../Connection_Impl.hpp" +#include "../../utilities/core/PathHelpers.hpp" using namespace openstudio; using namespace openstudio::model; TEST_F(ModelFixture, ChillerElectricASHRAE205_GettersSetters) { Model m; - // TODO: Check regular Ctor arguments - ChillerElectricASHRAE205 chillerElectricASHRAE205(m); - // TODO: Or if a UniqueModelObject (and make sure _Impl is included) - // ChillerElectricASHRAE205 chillerElectricASHRAE205 = m.getUniqueModelObject(); - chillerElectricASHRAE205.setName("My ChillerElectricASHRAE205"); + EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + + openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); + EXPECT_TRUE(exists(p)); + + openstudio::path expectedDestDir; + std::vector absoluteFilePaths = m.workflowJSON().absoluteFilePaths(); + if (absoluteFilePaths.empty()) { + expectedDestDir = m.workflowJSON().absoluteRootDir(); + } else { + expectedDestDir = absoluteFilePaths[0]; + } + + if (exists(expectedDestDir)) { + removeDirectory(expectedDestDir); + } + ASSERT_FALSE(exists(expectedDestDir)); + + boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); + ASSERT_TRUE(representationFile); + EXPECT_EQ(1u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0u, representationFile->chillerElectricASHRAE205s().size()); + EXPECT_EQ(openstudio::toString(p.filename()), representationFile->fileName()); + EXPECT_TRUE(equivalent(expectedDestDir / representationFile->fileName(), representationFile->filePath())); + EXPECT_TRUE(exists(representationFile->filePath())); + EXPECT_NE(p, representationFile->filePath()); + + ChillerElectricASHRAE205 ch(representationFile.get()); + EXPECT_EQ(1u, m.getConcreteModelObjects().size()); + EXPECT_EQ(1u, representationFile->chillerElectricASHRAE205s().size()); + EXPECT_EQ(representationFile->handle(), ch.representationFile().handle()); // Representation File Name: Required Object - ExternalFile obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setRepresentationFile(obj)); - EXPECT_EQ(obj, chillerElectricASHRAE205.representationFile()); + // ExternalFile obj(m); + // EXPECT_TRUE(ch.setRepresentationFile(obj)); + // EXPECT_EQ(obj, ch.representationFile()); // Performance Interpolation Method: Required String - EXPECT_TRUE(chillerElectricASHRAE205.setPerformanceInterpolationMethod("Linear")); - EXPECT_EQ("Linear", chillerElectricASHRAE205.performanceInterpolationMethod()); + // Ctor default + EXPECT_EQ("Linear", ch.performanceInterpolationMethod()); + EXPECT_TRUE(ch.setPerformanceInterpolationMethod("Cubic")); + EXPECT_EQ("Cubic", ch.performanceInterpolationMethod()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setPerformanceInterpolationMethod("BADENUM")); - EXPECT_EQ("Linear", chillerElectricASHRAE205.performanceInterpolationMethod()); + EXPECT_FALSE(ch.setPerformanceInterpolationMethod("BADENUM")); + EXPECT_EQ("Cubic", ch.performanceInterpolationMethod()); // Rated Capacity: Required Double // Autosize - chillerElectricASHRAE205.autosizeRatedCapacity(); - EXPECT_TRUE(chillerElectricASHRAE205.isRatedCapacityAutosized()); + ch.autosizeRatedCapacity(); + EXPECT_TRUE(ch.isRatedCapacityAutosized()); // Set - EXPECT_TRUE(chillerElectricASHRAE205.setRatedCapacity(0.5)); - ASSERT_TRUE(chillerElectricASHRAE205.ratedCapacity()); - EXPECT_EQ(0.5, chillerElectricASHRAE205.ratedCapacity().get()); + EXPECT_TRUE(ch.setRatedCapacity(0.5)); + ASSERT_TRUE(ch.ratedCapacity()); + EXPECT_EQ(0.5, ch.ratedCapacity().get()); + EXPECT_FALSE(ch.isRatedCapacityAutosized()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setRatedCapacity(-10.0)); - ASSERT_TRUE(chillerElectricASHRAE205.ratedCapacity()); - EXPECT_EQ(0.5, chillerElectricASHRAE205.ratedCapacity().get()); - EXPECT_FALSE(chillerElectricASHRAE205.isRatedCapacityAutosized()); + EXPECT_FALSE(ch.setRatedCapacity(-10.0)); + ASSERT_TRUE(ch.ratedCapacity()); + EXPECT_EQ(0.5, ch.ratedCapacity().get()); + EXPECT_FALSE(ch.isRatedCapacityAutosized()); // Sizing Factor: Required Double - EXPECT_TRUE(chillerElectricASHRAE205.setSizingFactor(0.6)); - EXPECT_EQ(0.6, chillerElectricASHRAE205.sizingFactor()); + // Ctor default + EXPECT_EQ(1.0, ch.sizingFactor()); + EXPECT_TRUE(ch.setSizingFactor(0.6)); + EXPECT_EQ(0.6, ch.sizingFactor()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setSizingFactor(-10.0)); - EXPECT_EQ(0.6, chillerElectricASHRAE205.sizingFactor()); + EXPECT_FALSE(ch.setSizingFactor(-10.0)); + EXPECT_EQ(0.6, ch.sizingFactor()); // Ambient Temperature Indicator: Required String - EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureIndicator("Schedule")); - EXPECT_EQ("Schedule", chillerElectricASHRAE205.ambientTemperatureIndicator()); - // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setAmbientTemperatureIndicator("BADENUM")); - EXPECT_EQ("Schedule", chillerElectricASHRAE205.ambientTemperatureIndicator()); + EXPECT_EQ("Outdoors", ch.ambientTemperatureIndicator()); + + // EXPECT_TRUE(ch.setAmbientTemperatureIndicator("Schedule")); + // EXPECT_EQ("Schedule", ch.ambientTemperatureIndicator()); + // // Bad Value + // EXPECT_FALSE(ch.setAmbientTemperatureIndicator("BADENUM")); + // EXPECT_EQ("Schedule", ch.ambientTemperatureIndicator()); // Ambient Temperature Schedule Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureSchedule(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureSchedule()); - EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureSchedule().get()); + ScheduleConstant tempSch(m); + EXPECT_TRUE(ch.setAmbientTemperatureSchedule(tempSch)); + ASSERT_TRUE(ch.ambientTemperatureSchedule()); + EXPECT_EQ(tempSch, ch.ambientTemperatureSchedule().get()); + EXPECT_EQ("Schedule", ch.ambientTemperatureIndicator()); + ch.resetAmbientTemperatureOutdoorAirNodeName(); + EXPECT_EQ("Schedule", ch.ambientTemperatureIndicator()); + ch.resetAmbientTemperatureSchedule(); + EXPECT_EQ("Outdoors", ch.ambientTemperatureIndicator()); // Ambient Temperature Zone Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureZone(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureZone()); - EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureZone().get()); + ThermalZone z(m); + EXPECT_TRUE(ch.setAmbientTemperatureZone(z)); + ASSERT_TRUE(ch.ambientTemperatureZone()); + EXPECT_EQ(z, ch.ambientTemperatureZone().get()); + EXPECT_EQ("Zone", ch.ambientTemperatureIndicator()); + ch.resetAmbientTemperatureSchedule(); + EXPECT_EQ("Zone", ch.ambientTemperatureIndicator()); + ch.resetAmbientTemperatureZone(); + EXPECT_EQ("Outdoors", ch.ambientTemperatureIndicator()); + + EXPECT_TRUE(ch.setAmbientTemperatureZone(z)); + EXPECT_EQ("Zone", ch.ambientTemperatureIndicator()); + ch.resetAmbientTemperatureOutdoorAirNodeName(); + EXPECT_EQ("Zone", ch.ambientTemperatureIndicator()); // Ambient Temperature Outdoor Air Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setAmbientTemperatureOutdoorAirNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.ambientTemperatureOutdoorAirNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.ambientTemperatureOutdoorAirNode().get()); - - // Chilled Water Inlet Node Name: Required Object - Connection obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterInletNode(obj)); - EXPECT_EQ(obj, chillerElectricASHRAE205.chilledWaterInletNode()); - - // Chilled Water Outlet Node Name: Required Object - Connection obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterOutletNode(obj)); - EXPECT_EQ(obj, chillerElectricASHRAE205.chilledWaterOutletNode()); + EXPECT_TRUE(ch.setAmbientTemperatureOutdoorAirNodeName("My Outdoor Air Node Name")); + ASSERT_TRUE(ch.ambientTemperatureOutdoorAirNodeName()); + EXPECT_EQ("My Outdoor Air Node Name", ch.ambientTemperatureOutdoorAirNodeName().get()); + EXPECT_EQ("Outdoors", ch.ambientTemperatureIndicator()); // Chilled Water Maximum Requested Flow Rate: Required Double - // Autosize - chillerElectricASHRAE205.autosizeChilledWaterMaximumRequestedFlowRate(); - EXPECT_TRUE(chillerElectricASHRAE205.isChilledWaterMaximumRequestedFlowRateAutosized()); + // Ctor default + EXPECT_TRUE(ch.isChilledWaterMaximumRequestedFlowRateAutosized()); // Set - EXPECT_TRUE(chillerElectricASHRAE205.setChilledWaterMaximumRequestedFlowRate(1.3)); - ASSERT_TRUE(chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate()); - EXPECT_EQ(1.3, chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate().get()); + EXPECT_TRUE(ch.setChilledWaterMaximumRequestedFlowRate(1.3)); + ASSERT_TRUE(ch.chilledWaterMaximumRequestedFlowRate()); + EXPECT_EQ(1.3, ch.chilledWaterMaximumRequestedFlowRate().get()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setChilledWaterMaximumRequestedFlowRate(-10.0)); - ASSERT_TRUE(chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate()); - EXPECT_EQ(1.3, chillerElectricASHRAE205.chilledWaterMaximumRequestedFlowRate().get()); - EXPECT_FALSE(chillerElectricASHRAE205.isChilledWaterMaximumRequestedFlowRateAutosized()); - - // Condenser Inlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setCondenserInletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.condenserInletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.condenserInletNode().get()); - - // Condenser Outlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setCondenserOutletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.condenserOutletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.condenserOutletNode().get()); + EXPECT_FALSE(ch.setChilledWaterMaximumRequestedFlowRate(-10.0)); + ASSERT_TRUE(ch.chilledWaterMaximumRequestedFlowRate()); + EXPECT_EQ(1.3, ch.chilledWaterMaximumRequestedFlowRate().get()); + EXPECT_FALSE(ch.isChilledWaterMaximumRequestedFlowRateAutosized()); + // Autosize + ch.autosizeChilledWaterMaximumRequestedFlowRate(); + EXPECT_TRUE(ch.isChilledWaterMaximumRequestedFlowRateAutosized()); // Condenser Maximum Requested Flow Rate: Required Double - // Autosize - chillerElectricASHRAE205.autosizeCondenserMaximumRequestedFlowRate(); - EXPECT_TRUE(chillerElectricASHRAE205.isCondenserMaximumRequestedFlowRateAutosized()); + // Ctor default + EXPECT_TRUE(ch.isCondenserMaximumRequestedFlowRateAutosized()); // Set - EXPECT_TRUE(chillerElectricASHRAE205.setCondenserMaximumRequestedFlowRate(1.6)); - ASSERT_TRUE(chillerElectricASHRAE205.condenserMaximumRequestedFlowRate()); - EXPECT_EQ(1.6, chillerElectricASHRAE205.condenserMaximumRequestedFlowRate().get()); + EXPECT_TRUE(ch.setCondenserMaximumRequestedFlowRate(1.6)); + ASSERT_TRUE(ch.condenserMaximumRequestedFlowRate()); + EXPECT_EQ(1.6, ch.condenserMaximumRequestedFlowRate().get()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setCondenserMaximumRequestedFlowRate(-10.0)); - ASSERT_TRUE(chillerElectricASHRAE205.condenserMaximumRequestedFlowRate()); - EXPECT_EQ(1.6, chillerElectricASHRAE205.condenserMaximumRequestedFlowRate().get()); - EXPECT_FALSE(chillerElectricASHRAE205.isCondenserMaximumRequestedFlowRateAutosized()); + EXPECT_FALSE(ch.setCondenserMaximumRequestedFlowRate(-10.0)); + ASSERT_TRUE(ch.condenserMaximumRequestedFlowRate()); + EXPECT_EQ(1.6, ch.condenserMaximumRequestedFlowRate().get()); + EXPECT_FALSE(ch.isCondenserMaximumRequestedFlowRateAutosized()); + // Autosize + ch.autosizeCondenserMaximumRequestedFlowRate(); + EXPECT_TRUE(ch.isCondenserMaximumRequestedFlowRateAutosized()); // Chiller Flow Mode: Required String - EXPECT_TRUE(chillerElectricASHRAE205.setChillerFlowMode("ConstantFlow")); - EXPECT_EQ("ConstantFlow", chillerElectricASHRAE205.chillerFlowMode()); + EXPECT_TRUE(ch.setChillerFlowMode("ConstantFlow")); + EXPECT_EQ("ConstantFlow", ch.chillerFlowMode()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setChillerFlowMode("BADENUM")); - EXPECT_EQ("ConstantFlow", chillerElectricASHRAE205.chillerFlowMode()); - - // Oil Cooler Inlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerInletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerInletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.oilCoolerInletNode().get()); - - // Oil Cooler Outlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerOutletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerOutletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.oilCoolerOutletNode().get()); + EXPECT_FALSE(ch.setChillerFlowMode("BADENUM")); + EXPECT_EQ("ConstantFlow", ch.chillerFlowMode()); // Oil Cooler Design Flow Rate: Optional Double - EXPECT_TRUE(chillerElectricASHRAE205.setOilCoolerDesignFlowRate(2.0)); - ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerDesignFlowRate()); - EXPECT_EQ(2.0, chillerElectricASHRAE205.oilCoolerDesignFlowRate().get()); + EXPECT_TRUE(ch.setOilCoolerDesignFlowRate(2.0)); + ASSERT_TRUE(ch.oilCoolerDesignFlowRate()); + EXPECT_EQ(2.0, ch.oilCoolerDesignFlowRate().get()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setOilCoolerDesignFlowRate(-10.0)); - ASSERT_TRUE(chillerElectricASHRAE205.oilCoolerDesignFlowRate()); - EXPECT_EQ(2.0, chillerElectricASHRAE205.oilCoolerDesignFlowRate().get()); - - // Auxiliary Inlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryInletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryInletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.auxiliaryInletNode().get()); - - // Auxiliary Outlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryOutletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryOutletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.auxiliaryOutletNode().get()); + EXPECT_FALSE(ch.setOilCoolerDesignFlowRate(-10.0)); + ASSERT_TRUE(ch.oilCoolerDesignFlowRate()); + EXPECT_EQ(2.0, ch.oilCoolerDesignFlowRate().get()); // Auxiliary Cooling Design Flow Rate: Optional Double - EXPECT_TRUE(chillerElectricASHRAE205.setAuxiliaryCoolingDesignFlowRate(2.3)); - ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate()); - EXPECT_EQ(2.3, chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate().get()); + EXPECT_TRUE(ch.setAuxiliaryCoolingDesignFlowRate(2.3)); + ASSERT_TRUE(ch.auxiliaryCoolingDesignFlowRate()); + EXPECT_EQ(2.3, ch.auxiliaryCoolingDesignFlowRate().get()); // Bad Value - EXPECT_FALSE(chillerElectricASHRAE205.setAuxiliaryCoolingDesignFlowRate(-10.0)); - ASSERT_TRUE(chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate()); - EXPECT_EQ(2.3, chillerElectricASHRAE205.auxiliaryCoolingDesignFlowRate().get()); - - // Heat Recovery Inlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setHeatRecoveryInletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.heatRecoveryInletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.heatRecoveryInletNode().get()); - - // Heat Recovery Outlet Node Name: Optional Object - boost::optional obj(m); - EXPECT_TRUE(chillerElectricASHRAE205.setHeatRecoveryOutletNode(obj)); - ASSERT_TRUE(chillerElectricASHRAE205.heatRecoveryOutletNode()); - EXPECT_EQ(obj, chillerElectricASHRAE205.heatRecoveryOutletNode().get()); + EXPECT_FALSE(ch.setAuxiliaryCoolingDesignFlowRate(-10.0)); + ASSERT_TRUE(ch.auxiliaryCoolingDesignFlowRate()); + EXPECT_EQ(2.3, ch.auxiliaryCoolingDesignFlowRate().get()); // End-Use Subcategory: Optional String // Default value from IDD - EXPECT_TRUE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); - EXPECT_EQ("General", chillerElectricASHRAE205.endUseSubcategory()); + EXPECT_EQ("General", ch.endUseSubcategory()); // Set - EXPECT_TRUE(chillerElectricASHRAE205.setEndUseSubcategory()); - EXPECT_EQ(, chillerElectricASHRAE205.endUseSubcategory()); - EXPECT_FALSE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); + EXPECT_TRUE(ch.setEndUseSubcategory("Chiller")); + EXPECT_EQ("Chiller", ch.endUseSubcategory()); + EXPECT_FALSE(ch.isEndUseSubcategoryDefaulted()); // Reset - chillerElectricASHRAE205.resetEndUseSubcategory(); - EXPECT_TRUE(chillerElectricASHRAE205.isEndUseSubcategoryDefaulted()); + ch.resetEndUseSubcategory(); + EXPECT_TRUE(ch.isEndUseSubcategoryDefaulted()); + EXPECT_EQ("General", ch.endUseSubcategory()); +} + +TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { + Model m; + + EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + + openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); + EXPECT_TRUE(exists(p)); + + openstudio::path expectedDestDir; + std::vector absoluteFilePaths = m.workflowJSON().absoluteFilePaths(); + if (absoluteFilePaths.empty()) { + expectedDestDir = m.workflowJSON().absoluteRootDir(); + } else { + expectedDestDir = absoluteFilePaths[0]; + } + + if (exists(expectedDestDir)) { + removeDirectory(expectedDestDir); + } + ASSERT_FALSE(exists(expectedDestDir)); + + boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); + ASSERT_TRUE(representationFile); + EXPECT_EQ(1u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0u, representationFile->chillerElectricASHRAE205s().size()); + EXPECT_EQ(openstudio::toString(p.filename()), representationFile->fileName()); + EXPECT_TRUE(equivalent(expectedDestDir / representationFile->fileName(), representationFile->filePath())); + EXPECT_TRUE(exists(representationFile->filePath())); + EXPECT_NE(p, representationFile->filePath()); + + ChillerElectricASHRAE205 ch(representationFile.get()); + EXPECT_FALSE(ch.chilledWaterLoop()); + EXPECT_FALSE(ch.chilledWaterInletNode()); + EXPECT_FALSE(ch.chilledWaterOutletNode()); + + EXPECT_FALSE(ch.condenserWaterLoop()); + EXPECT_FALSE(ch.condenserInletNode()); + EXPECT_FALSE(ch.condenserOutletNode()); + + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + PlantLoop chwLoop(m); + PlantLoop cndLoop(m); + PlantLoop hrLoop(m); + PlantLoop ocLoop(m); + PlantLoop auxLoop(m); + + // Chilled Water Inlet Node Name: Required Object + + EXPECT_TRUE(chwLoop.addSupplyBranchForComponent(ch)); + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + + EXPECT_FALSE(ch.condenserWaterLoop()); + EXPECT_FALSE(ch.condenserInletNode()); + EXPECT_FALSE(ch.condenserOutletNode()); + + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Condenser + EXPECT_TRUE(cndLoop.addDemandBranchForComponent(ch)); + ASSERT_TRUE(ch.chilledWaterLoop()); + EXPECT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Heat Recovery + EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch)); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + // TODO + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); } From 180ec11f2c2d2000fdb40456c81a38699adc91df Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 09:05:29 +0200 Subject: [PATCH 08/24] Fixup model / tests + add a clone gtest --- src/model/ChillerElectricASHRAE205.cpp | 18 +-- .../test/ChillerElectricASHRAE205_GTest.cpp | 114 ++++++++++++++++-- 2 files changed, 114 insertions(+), 18 deletions(-) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 463112b69f..a09ed7b26a 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -476,17 +476,17 @@ namespace model { bool ChillerElectricASHRAE205_Impl::addToNode(Node& node) { boost::optional t_plantLoop = node.plantLoop(); - // If trying to add to a node that is on the supply side of a plant loop + // If trying to add to a node that is on the demand side of a plant loop if (t_plantLoop) { - if (t_plantLoop->supplyComponent(node.handle())) { - // If there is already a cooling Plant Loop - boost::optional coolingPlant = this->chilledWaterLoop(); - if (coolingPlant) { + if (t_plantLoop->demandComponent(node.handle())) { + // If there is already a another loop where it's on the demand side (condenser Plant Loop) + boost::optional cndLoop_ = this->condenserWaterLoop(); + if (cndLoop_) { // And it's not the same as the node's loop - if (t_plantLoop.get() != coolingPlant.get()) { + if (t_plantLoop.get() != cndLoop_.get()) { // And if there is no Heat Recovery (tertiary) - boost::optional heatingPlant = this->heatRecoveryLoop(); - if (!heatingPlant) { + if (!this->heatRecoveryLoop().is_initialized()) { + ; // Then try to add it to the tertiary one LOG(Warn, "Calling addToTertiaryNode to connect it to the tertiary (=Heat Recovery) loop for " << briefDescription()); return this->addToTertiaryNode(node); @@ -568,6 +568,8 @@ namespace model { remove(); LOG_AND_THROW("External file must have a .cbor extension, got externalfile='" << filePath << "'."); } + ok = setPointer(OS_Chiller_Electric_ASHRAE205Fields::RepresentationFileName, representationFile.handle()); + OS_ASSERT(ok); setPerformanceInterpolationMethod("Linear"); autosizeRatedCapacity(); diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index 62584a2ada..3c982a1447 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -52,8 +52,8 @@ using namespace openstudio::model; TEST_F(ModelFixture, ChillerElectricASHRAE205_GettersSetters) { Model m; - EXPECT_EQ(0u, m.getConcreteModelObjects().size()); - EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); EXPECT_TRUE(exists(p)); @@ -70,19 +70,21 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_GettersSetters) { removeDirectory(expectedDestDir); } ASSERT_FALSE(exists(expectedDestDir)); + EXPECT_TRUE(exists(p)); boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); ASSERT_TRUE(representationFile); - EXPECT_EQ(1u, m.getConcreteModelObjects().size()); - EXPECT_EQ(0u, representationFile->chillerElectricASHRAE205s().size()); + + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, representationFile->chillerElectricASHRAE205s().size()); EXPECT_EQ(openstudio::toString(p.filename()), representationFile->fileName()); EXPECT_TRUE(equivalent(expectedDestDir / representationFile->fileName(), representationFile->filePath())); EXPECT_TRUE(exists(representationFile->filePath())); EXPECT_NE(p, representationFile->filePath()); ChillerElectricASHRAE205 ch(representationFile.get()); - EXPECT_EQ(1u, m.getConcreteModelObjects().size()); - EXPECT_EQ(1u, representationFile->chillerElectricASHRAE205s().size()); + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(1, representationFile->chillerElectricASHRAE205s().size()); EXPECT_EQ(representationFile->handle(), ch.representationFile().handle()); // Representation File Name: Required Object @@ -233,13 +235,25 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_GettersSetters) { ch.resetEndUseSubcategory(); EXPECT_TRUE(ch.isEndUseSubcategoryDefaulted()); EXPECT_EQ("General", ch.endUseSubcategory()); + + // Removing the ExternalFile removes the Chiller + openstudio::path dstPath = representationFile->filePath(); + EXPECT_TRUE(exists(p)); + EXPECT_TRUE(exists(dstPath)); + + representationFile->remove(); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); + + EXPECT_TRUE(exists(p)); + EXPECT_FALSE(exists(dstPath)); } TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { Model m; - EXPECT_EQ(0u, m.getConcreteModelObjects().size()); - EXPECT_EQ(0u, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); EXPECT_TRUE(exists(p)); @@ -256,11 +270,13 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { removeDirectory(expectedDestDir); } ASSERT_FALSE(exists(expectedDestDir)); + EXPECT_TRUE(exists(p)); boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); ASSERT_TRUE(representationFile); - EXPECT_EQ(1u, m.getConcreteModelObjects().size()); - EXPECT_EQ(0u, representationFile->chillerElectricASHRAE205s().size()); + + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, representationFile->chillerElectricASHRAE205s().size()); EXPECT_EQ(openstudio::toString(p.filename()), representationFile->fileName()); EXPECT_TRUE(equivalent(expectedDestDir / representationFile->fileName(), representationFile->filePath())); EXPECT_TRUE(exists(representationFile->filePath())); @@ -377,4 +393,82 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryLoop()); EXPECT_FALSE(ch.auxiliaryInletNode()); EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Removing the Chiller doesn't remove the ExternalFile + openstudio::path dstPath = representationFile->filePath(); + EXPECT_TRUE(exists(p)); + EXPECT_TRUE(exists(dstPath)); + + ch.remove(); + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(0, m.getConcreteModelObjects().size()); + + EXPECT_TRUE(exists(p)); + EXPECT_TRUE(exists(dstPath)); +} + +TEST_F(ModelFixture, ChillerElectricASHRAE205_NotCBORFile) { + Model model; + + path p = resourcesPath() / toPath("model/7-7_Windows_Complete.osm"); + EXPECT_TRUE(exists(p)); + + boost::optional representationFile = ExternalFile::getExternalFile(model, openstudio::toString(p)); + ASSERT_TRUE(representationFile); + + ASSERT_THROW(ChillerElectricASHRAE205{representationFile.get()}, openstudio::Exception); +} + +TEST_F(ModelFixture, ChillerElectricASHRAE205_Clone) { + Model m; + + openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); + EXPECT_TRUE(exists(p)); + + openstudio::path expectedDestDir; + std::vector absoluteFilePaths = m.workflowJSON().absoluteFilePaths(); + if (absoluteFilePaths.empty()) { + expectedDestDir = m.workflowJSON().absoluteRootDir(); + } else { + expectedDestDir = absoluteFilePaths[0]; + } + + if (exists(expectedDestDir)) { + removeDirectory(expectedDestDir); + } + ASSERT_FALSE(exists(expectedDestDir)); + EXPECT_TRUE(exists(p)); + + boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); + ASSERT_TRUE(representationFile); + + ChillerElectricASHRAE205 ch(representationFile.get()); + + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(representationFile->handle(), ch.representationFile().handle()); + EXPECT_EQ(1, representationFile->chillerElectricASHRAE205s().size()); + + { + // Another model first, so we don't mess the original one + Model m2; + auto ch2 = ch.clone(m2).cast(); + + ASSERT_EQ(1, m2.getConcreteModelObjects().size()); + auto representationFile2 = m2.getConcreteModelObjects().front(); + EXPECT_EQ(1, m2.getConcreteModelObjects().size()); + EXPECT_EQ(representationFile2.handle(), ch2.representationFile().handle()); + EXPECT_NE(representationFile->handle(), ch2.representationFile().handle()); + EXPECT_EQ(1, representationFile2.chillerElectricASHRAE205s().size()); + } + + { + // Same Model, should point to the same ExternaFile + auto ch2 = ch.clone(m).cast(); + EXPECT_EQ(1, m.getConcreteModelObjects().size()); + EXPECT_EQ(2, m.getConcreteModelObjects().size()); + EXPECT_EQ(representationFile->handle(), ch.representationFile().handle()); + EXPECT_EQ(representationFile->handle(), ch2.representationFile().handle()); + EXPECT_EQ(2, representationFile->chillerElectricASHRAE205s().size()); + } } From dcb6cf19078dd2cbc8a0211f15d513aae5f67d58 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 10:51:18 +0200 Subject: [PATCH 09/24] Start implementing connection to Oil Cooler / Auxiliary Loop --- src/model/ChillerElectricASHRAE205.cpp | 218 ++++++++++++++++-- src/model/ChillerElectricASHRAE205.hpp | 18 +- src/model/ChillerElectricASHRAE205_Impl.hpp | 13 ++ src/model/WaterToWaterComponent.cpp | 4 +- src/model/WaterToWaterComponent_Impl.hpp | 2 +- .../test/ChillerElectricASHRAE205_GTest.cpp | 103 ++++++++- 6 files changed, 321 insertions(+), 37 deletions(-) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index a09ed7b26a..9b0f0e0572 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -501,7 +501,6 @@ namespace model { } bool ChillerElectricASHRAE205_Impl::addToTertiaryNode(Node& node) { - auto _model = node.model(); auto t_plantLoop = node.plantLoop(); // Only accept adding to a node that is on a demand side of a plant loop @@ -518,42 +517,177 @@ namespace model { return false; } - boost::optional ChillerElectricASHRAE205_Impl::oilCoolerLoop() const { - if (boost::optional n_ = oilCoolerInletNode()) { - return n_->plantLoop(); + boost::optional ChillerElectricASHRAE205_Impl::plantLoop() const { + if (boost::optional mo_ = supplyOutletModelObject()) { + if (boost::optional n_ = mo_->optionalCast()) { + return n_->plantLoop(); + } } return boost::none; } - bool ChillerElectricASHRAE205_Impl::addToOilCoolerLoopNode(Node& node) { - LOG_AND_THROW("NOT IMPLEMENTED YET"); + boost::optional ChillerElectricASHRAE205_Impl::secondaryPlantLoop() const { + if (boost::optional mo_ = demandOutletModelObject()) { + if (boost::optional n_ = mo_->optionalCast()) { + return n_->plantLoop(); + } + } + return boost::none; + } + + boost::optional ChillerElectricASHRAE205_Impl::tertiaryPlantLoop() const { + if (boost::optional mo_ = tertiaryOutletModelObject()) { + if (boost::optional n_ = mo_->optionalCast()) { + return n_->plantLoop(); + } + } + return boost::none; + } + + // Extra loops + + /// Oil Cooler Loop + + unsigned ChillerElectricASHRAE205_Impl::oilCoolerInletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName; + } + + OptionalModelObject ChillerElectricASHRAE205_Impl::oilCoolerInletModelObject() const { + return connectedObject(ChillerElectricASHRAE205_Impl::oilCoolerInletPort()); } boost::optional ChillerElectricASHRAE205_Impl::oilCoolerInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName); + if (auto mo_ = oilCoolerInletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; + } + + unsigned ChillerElectricASHRAE205_Impl::oilCoolerOutletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName; + } + + OptionalModelObject ChillerElectricASHRAE205_Impl::oilCoolerOutletModelObject() const { + return connectedObject(ChillerElectricASHRAE205_Impl::oilCoolerOutletPort()); } boost::optional ChillerElectricASHRAE205_Impl::oilCoolerOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName); + if (auto mo_ = oilCoolerOutletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; } - boost::optional ChillerElectricASHRAE205_Impl::auxiliaryLoop() const { - if (boost::optional n_ = auxiliaryInletNode()) { + boost::optional ChillerElectricASHRAE205_Impl::oilCoolerLoop() const { + if (boost::optional n_ = oilCoolerOutletNode()) { return n_->plantLoop(); } return boost::none; } - bool ChillerElectricASHRAE205_Impl::addToAuxiliaryLoopNode(Node& node) { - LOG_AND_THROW("NOT IMPLEMENTED YET"); + bool ChillerElectricASHRAE205_Impl::removeFromOilCoolerLoop() { + if (auto plant = oilCoolerLoop()) { + return HVACComponent_Impl::removeFromLoop(plant->demandInletNode(), plant->demandOutletNode(), oilCoolerInletPort(), oilCoolerOutletPort()); + } + + return false; + } + + bool ChillerElectricASHRAE205_Impl::addToOilCoolerLoopNode(Node& node) { + + if (node.getImpl()->isConnected(getObject())) { + return false; + } + + auto plantLoop_ = node.plantLoop(); + if (!plantLoop_) { + LOG(Warn, "For " << briefDescription() << ", Oil Cooler Loop can only be connected to a PlantLoop"); + return false; + } + + if (!plantLoop_->demandComponent(node.handle())) { + LOG(Warn, "For " << briefDescription() << ", Oil Cooler Loop can only be connected to a PlantLoop on the demand side"); + return false; + } + + HVACComponent systemStartComponent = plantLoop_->demandInletNode(); + HVACComponent systemEndComponent = plantLoop_->demandOutletNode(); + + removeFromOilCoolerLoop(); + + return HVACComponent_Impl::addToNode(node, systemStartComponent, systemEndComponent, oilCoolerInletPort(), oilCoolerOutletPort()); + } + + /// Auxiliary Loop + + unsigned ChillerElectricASHRAE205_Impl::auxiliaryInletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName; + } + + OptionalModelObject ChillerElectricASHRAE205_Impl::auxiliaryInletModelObject() const { + return connectedObject(ChillerElectricASHRAE205_Impl::auxiliaryInletPort()); } boost::optional ChillerElectricASHRAE205_Impl::auxiliaryInletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName); + if (auto mo_ = auxiliaryInletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; + } + + unsigned ChillerElectricASHRAE205_Impl::auxiliaryOutletPort() const { + return OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName; + } + + OptionalModelObject ChillerElectricASHRAE205_Impl::auxiliaryOutletModelObject() const { + return connectedObject(ChillerElectricASHRAE205_Impl::auxiliaryOutletPort()); } boost::optional ChillerElectricASHRAE205_Impl::auxiliaryOutletNode() const { - return getObject().getModelObjectTarget(OS_Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName); + if (auto mo_ = auxiliaryOutletModelObject()) { + return mo_->optionalCast(); + } + return boost::none; + } + + boost::optional ChillerElectricASHRAE205_Impl::auxiliaryLoop() const { + if (boost::optional n_ = auxiliaryOutletNode()) { + return n_->plantLoop(); + } + return boost::none; + } + + bool ChillerElectricASHRAE205_Impl::removeFromAuxiliaryLoop() { + if (auto plant = auxiliaryLoop()) { + return HVACComponent_Impl::removeFromLoop(plant->demandInletNode(), plant->demandOutletNode(), auxiliaryInletPort(), auxiliaryOutletPort()); + } + + return false; + } + + bool ChillerElectricASHRAE205_Impl::addToAuxiliaryLoopNode(Node& node) { + + if (node.getImpl()->isConnected(getObject())) { + return false; + } + + auto plantLoop_ = node.plantLoop(); + if (!plantLoop_) { + LOG(Warn, "For " << briefDescription() << ", Oil Cooler Loop can only be connected to a PlantLoop"); + return false; + } + + if (!plantLoop_->demandComponent(node.handle())) { + LOG(Warn, "For " << briefDescription() << ", Oil Cooler Loop can only be connected to a PlantLoop on the demand side"); + return false; + } + + HVACComponent systemStartComponent = plantLoop_->demandInletNode(); + HVACComponent systemEndComponent = plantLoop_->demandOutletNode(); + + removeFromAuxiliaryLoop(); + + return HVACComponent_Impl::addToNode(node, systemStartComponent, systemEndComponent, auxiliaryInletPort(), auxiliaryOutletPort()); } } // namespace detail @@ -813,38 +947,74 @@ namespace model { return getImpl()->heatRecoveryOutletNode(); } - boost::optional ChillerElectricASHRAE205::oilCoolerLoop() const { - return getImpl()->oilCoolerLoop(); - } + // Oil Cooler Loop - bool ChillerElectricASHRAE205::addToOilCoolerLoopNode(Node& node) { - return getImpl()->addToOilCoolerLoopNode(node); + unsigned ChillerElectricASHRAE205::oilCoolerInletPort() const { + return getImpl()->oilCoolerInletPort(); + } + boost::optional ChillerElectricASHRAE205::oilCoolerInletModelObject() const { + return getImpl()->oilCoolerInletModelObject(); } - boost::optional ChillerElectricASHRAE205::oilCoolerInletNode() const { return getImpl()->oilCoolerInletNode(); } + unsigned ChillerElectricASHRAE205::oilCoolerOutletPort() const { + return getImpl()->oilCoolerOutletPort(); + } + boost::optional ChillerElectricASHRAE205::oilCoolerOutletModelObject() const { + return getImpl()->oilCoolerOutletModelObject(); + } boost::optional ChillerElectricASHRAE205::oilCoolerOutletNode() const { return getImpl()->oilCoolerOutletNode(); } - boost::optional ChillerElectricASHRAE205::auxiliaryLoop() const { - return getImpl()->auxiliaryLoop(); + boost::optional ChillerElectricASHRAE205::oilCoolerLoop() const { + return getImpl()->oilCoolerLoop(); } - bool ChillerElectricASHRAE205::addToAuxiliaryLoopNode(Node& node) { - return getImpl()->addToAuxiliaryLoopNode(node); + bool ChillerElectricASHRAE205::addToOilCoolerLoopNode(Node& node) { + return getImpl()->addToOilCoolerLoopNode(node); } + bool ChillerElectricASHRAE205::removeFromOilCoolerLoop() { + return getImpl()->removeFromOilCoolerLoop(); + } + + // Auxiliary Loop + + unsigned ChillerElectricASHRAE205::auxiliaryInletPort() const { + return getImpl()->auxiliaryInletPort(); + } + boost::optional ChillerElectricASHRAE205::auxiliaryInletModelObject() const { + return getImpl()->auxiliaryInletModelObject(); + } boost::optional ChillerElectricASHRAE205::auxiliaryInletNode() const { return getImpl()->auxiliaryInletNode(); } + unsigned ChillerElectricASHRAE205::auxiliaryOutletPort() const { + return getImpl()->auxiliaryOutletPort(); + } + boost::optional ChillerElectricASHRAE205::auxiliaryOutletModelObject() const { + return getImpl()->auxiliaryOutletModelObject(); + } boost::optional ChillerElectricASHRAE205::auxiliaryOutletNode() const { return getImpl()->auxiliaryOutletNode(); } + boost::optional ChillerElectricASHRAE205::auxiliaryLoop() const { + return getImpl()->auxiliaryLoop(); + } + + bool ChillerElectricASHRAE205::addToAuxiliaryLoopNode(Node& node) { + return getImpl()->addToAuxiliaryLoopNode(node); + } + + bool ChillerElectricASHRAE205::removeFromAuxiliaryLoop() { + return getImpl()->removeFromAuxiliaryLoop(); + } + /// @cond ChillerElectricASHRAE205::ChillerElectricASHRAE205(std::shared_ptr impl) : WaterToWaterComponent(std::move(impl)) {} diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index e70470175b..46173e645f 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -178,15 +178,25 @@ namespace model { boost::optional heatRecoveryInletNode() const; boost::optional heatRecoveryOutletNode() const; - boost::optional oilCoolerLoop() const; - bool addToOilCoolerLoopNode(Node& node); + unsigned oilCoolerInletPort() const; + boost::optional oilCoolerInletModelObject() const; boost::optional oilCoolerInletNode() const; + unsigned oilCoolerOutletPort() const; + boost::optional oilCoolerOutletModelObject() const; boost::optional oilCoolerOutletNode() const; + boost::optional oilCoolerLoop() const; + bool addToOilCoolerLoopNode(Node& node); + bool removeFromOilCoolerLoop(); - bool addToAuxiliaryLoopNode(Node& node); - boost::optional auxiliaryLoop() const; + unsigned auxiliaryInletPort() const; + boost::optional auxiliaryInletModelObject() const; boost::optional auxiliaryInletNode() const; + unsigned auxiliaryOutletPort() const; + boost::optional auxiliaryOutletModelObject() const; boost::optional auxiliaryOutletNode() const; + bool addToAuxiliaryLoopNode(Node& node); + bool removeFromAuxiliaryLoop(); + boost::optional auxiliaryLoop() const; //@} protected: diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp index 816241fc68..0f325af7ec 100644 --- a/src/model/ChillerElectricASHRAE205_Impl.hpp +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -69,14 +69,17 @@ namespace model { virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; // chilledWaterLoop + virtual boost::optional plantLoop() const override; virtual unsigned supplyInletPort() const override; virtual unsigned supplyOutletPort() const override; // condenserWaterLoop + virtual boost::optional secondaryPlantLoop() const override; virtual unsigned demandInletPort() const override; virtual unsigned demandOutletPort() const override; // heatRecoveryLoop + virtual boost::optional tertiaryPlantLoop() const override; virtual unsigned tertiaryInletPort() const override; virtual unsigned tertiaryOutletPort() const override; @@ -201,12 +204,22 @@ namespace model { boost::optional heatRecoveryInletNode() const; boost::optional heatRecoveryOutletNode() const; + /*static*/ unsigned oilCoolerInletPort() const; + boost::optional oilCoolerInletModelObject() const; + /*static*/ unsigned oilCoolerOutletPort() const; + boost::optional oilCoolerOutletModelObject() const; boost::optional oilCoolerLoop() const; bool addToOilCoolerLoopNode(Node& node); + bool removeFromOilCoolerLoop(); boost::optional oilCoolerInletNode() const; boost::optional oilCoolerOutletNode() const; + /*static*/ unsigned auxiliaryInletPort() const; + boost::optional auxiliaryInletModelObject() const; + /*static*/ unsigned auxiliaryOutletPort() const; + boost::optional auxiliaryOutletModelObject() const; bool addToAuxiliaryLoopNode(Node& node); + bool removeFromAuxiliaryLoop(); boost::optional auxiliaryLoop() const; boost::optional auxiliaryInletNode() const; boost::optional auxiliaryOutletNode() const; diff --git a/src/model/WaterToWaterComponent.cpp b/src/model/WaterToWaterComponent.cpp index f0a8b6969a..3aaba52581 100644 --- a/src/model/WaterToWaterComponent.cpp +++ b/src/model/WaterToWaterComponent.cpp @@ -256,8 +256,8 @@ namespace model { if (m_secondaryPlantLoop) { return m_secondaryPlantLoop; } else { - // JM: Same comment as for plantLoop() above, though as of 2018-01-03 I can't think of an actual object - // that could be on the demand side of two plant loops + // JM: Same comment as for plantLoop() above + // Any WaterToWaterComponent that has an Heat Recovery loop could be on the demand side of two plant loops boost::optional tertiaryPlantLoop = this->tertiaryPlantLoop(); std::vector plantLoops = this->model().getConcreteModelObjects(); diff --git a/src/model/WaterToWaterComponent_Impl.hpp b/src/model/WaterToWaterComponent_Impl.hpp index a643d93e84..461e75afa6 100644 --- a/src/model/WaterToWaterComponent_Impl.hpp +++ b/src/model/WaterToWaterComponent_Impl.hpp @@ -109,7 +109,7 @@ namespace model { * This method checks for presence of the WaterToWaterComponent on either the supply or demand side of plantLoops * and does an extra check for actual node: the tertiaryOutletModelObject has to be on the plant loop too */ - boost::optional tertiaryPlantLoop() const; + virtual boost::optional tertiaryPlantLoop() const; virtual bool removeFromTertiaryPlantLoop(); diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index 3c982a1447..2d9a1a25cc 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -43,8 +43,11 @@ #include "../Node_Impl.hpp" #include "../Schedule.hpp" #include "../ScheduleConstant.hpp" +#include "../Mixer.hpp" +#include "../Splitter.hpp" #include "../../utilities/core/PathHelpers.hpp" +#include using namespace openstudio; using namespace openstudio::model; @@ -303,11 +306,24 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryInletNode()); EXPECT_FALSE(ch.auxiliaryOutletNode()); - PlantLoop chwLoop(m); - PlantLoop cndLoop(m); - PlantLoop hrLoop(m); - PlantLoop ocLoop(m); - PlantLoop auxLoop(m); + auto createLoop = [&m](const std::string& prefix) { + PlantLoop p(m); + static constexpr std::array compNames = { + "Supply Inlet", "Supply Splitter", "Supply Connection Node", "Supply Mixer", "Supply Outlet", + "Demand Inlet", "Demand Splitter", "Demand Connection Node", "Demand Mixer", "Demand Outlet", + }; + p.setName(prefix); + for (size_t i = 0; auto& comp : p.components()) { + comp.setName(prefix + " " + std::string{compNames[i++]}); + } + return p; + }; + + auto chwLoop = createLoop("chwLoop"); + auto cndLoop = createLoop("cndLoop"); + auto hrLoop = createLoop("hrLoop"); + auto ocLoop = createLoop("ocLoop"); + auto auxLoop = createLoop("auxLoop"); // Chilled Water Inlet Node Name: Required Object @@ -385,7 +401,6 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.heatRecoveryOutletNode()); EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - // TODO EXPECT_FALSE(ch.oilCoolerLoop()); EXPECT_FALSE(ch.oilCoolerInletNode()); EXPECT_FALSE(ch.oilCoolerOutletNode()); @@ -394,6 +409,82 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryInletNode()); EXPECT_FALSE(ch.auxiliaryOutletNode()); + // Oil Cooler Loop + auto ocDemandConnectionNodes = ocLoop.supplyComponents(ocLoop.demandSplitter(), ocLoop.demandMixer(), IddObjectType::OS_Node); + ASSERT_EQ(1, ocDemandConnectionNodes.size()); + auto ocDemandConnectionNode = ocDemandConnectionNodes[0].cast(); + EXPECT_TRUE(ch.addToOilCoolerLoopNode(ocDemandConnectionNode)); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Auxiliary Loop + auto auxDemandConnectionNodes = ocLoop.supplyComponents(auxLoop.demandSplitter(), auxLoop.demandMixer(), IddObjectType::OS_Node); + ASSERT_EQ(1, auxDemandConnectionNodes.size()); + auto auxDemandConnectionNode = auxDemandConnectionNodes[0].cast(); + EXPECT_TRUE(ch.addToAuxiliaryLoopNode(auxDemandConnectionNode)); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + ASSERT_TRUE(ch.plantLoop()); + ASSERT_EQ(chwLoop, ch.plantLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.secondaryPlantLoop()); + ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + // Removing the Chiller doesn't remove the ExternalFile openstudio::path dstPath = representationFile->filePath(); EXPECT_TRUE(exists(p)); From e4a2fc4423cce88424b17988176fcb17cc267a15 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 11:18:41 +0200 Subject: [PATCH 10/24] Add `addDemandBranchOnOilCoolerLoop` + Need to override the clone method to reset the oil /auxiliary ports too --- src/model/ChillerElectricASHRAE205.cpp | 57 +++++++++++++++++++++ src/model/ChillerElectricASHRAE205.hpp | 1 + src/model/ChillerElectricASHRAE205_Impl.hpp | 3 ++ 3 files changed, 61 insertions(+) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 9b0f0e0572..8d2102417b 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -40,6 +40,8 @@ #include "ThermalZone.hpp" #include "ThermalZone_Impl.hpp" #include "Model.hpp" +#include "Mixer.hpp" +#include "Splitter.hpp" #include "ScheduleTypeLimits.hpp" #include "ScheduleTypeRegistry.hpp" @@ -593,6 +595,46 @@ namespace model { return false; } + bool ChillerElectricASHRAE205_Impl::addDemandBranchOnOilCoolerLoop(PlantLoop& plantLoop) { + Model _model = this->model(); + + if (plantLoop.model() != _model) { + return false; + } + + Splitter splitter = plantLoop.demandSplitter(); + Mixer mixer = plantLoop.demandMixer(); + + if (splitter.outletModelObjects().size() == 1u) { + if (boost::optional mo = splitter.lastOutletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + if ((node->outletModelObject().get() == mixer) && (node->inletModelObject().get() == splitter)) { + + return addToOilCoolerLoopNode(node.get()); + } + } + } + } + + unsigned nextOutletPort = splitter.nextOutletPort(); + unsigned nextInletPort = mixer.nextInletPort(); + + Node node(_model); + + _model.connect(splitter, nextOutletPort, node, node.inletPort()); + _model.connect(node, node.outletPort(), mixer, nextInletPort); + + if (addToOilCoolerLoopNode(node)) { + return true; + } + + _model.disconnect(node, node.outletPort()); + _model.disconnect(node, node.inletPort()); + node.remove(); + + return false; + } + bool ChillerElectricASHRAE205_Impl::addToOilCoolerLoopNode(Node& node) { if (node.getImpl()->isConnected(getObject())) { @@ -690,6 +732,17 @@ namespace model { return HVACComponent_Impl::addToNode(node, systemStartComponent, systemEndComponent, auxiliaryInletPort(), auxiliaryOutletPort()); } + ModelObject ChillerElectricASHRAE205_Impl::clone(Model model) const { + // WaterToWaterComponent resets the supply, demand and tertiary ports + auto mo = WaterToWaterComponent_Impl::clone(model); + + mo.setString(oilCoolerInletPort(), ""); + mo.setString(oilCoolerOutletPort(), ""); + mo.setString(auxiliaryInletPort(), ""); + mo.setString(auxiliaryOutletPort(), ""); + return mo; + } + } // namespace detail ChillerElectricASHRAE205::ChillerElectricASHRAE205(const ExternalFile& representationFile) @@ -973,6 +1026,10 @@ namespace model { return getImpl()->oilCoolerLoop(); } + bool ChillerElectricASHRAE205::addDemandBranchOnOilCoolerLoop(PlantLoop& plantLoop) { + return getImpl()->addDemandBranchOnOilCoolerLoop(plantLoop); + } + bool ChillerElectricASHRAE205::addToOilCoolerLoopNode(Node& node) { return getImpl()->addToOilCoolerLoopNode(node); } diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index 46173e645f..04c5065c57 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -185,6 +185,7 @@ namespace model { boost::optional oilCoolerOutletModelObject() const; boost::optional oilCoolerOutletNode() const; boost::optional oilCoolerLoop() const; + bool addDemandBranchOnOilCoolerLoop(PlantLoop& plantLoop); bool addToOilCoolerLoopNode(Node& node); bool removeFromOilCoolerLoop(); diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp index 0f325af7ec..8de0b7ecd8 100644 --- a/src/model/ChillerElectricASHRAE205_Impl.hpp +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -97,6 +97,8 @@ namespace model { /* Restricts addToTertiaryNode to a node that is on the demand side of a plant loop (tertiary = Heat Recovery Loop) */ virtual bool addToTertiaryNode(Node& node) override; + virtual ModelObject clone(Model model) const override; + virtual void autosize() override; virtual void applySizingValues() override; @@ -209,6 +211,7 @@ namespace model { /*static*/ unsigned oilCoolerOutletPort() const; boost::optional oilCoolerOutletModelObject() const; boost::optional oilCoolerLoop() const; + bool addDemandBranchOnOilCoolerLoop(PlantLoop& plantLoop); bool addToOilCoolerLoopNode(Node& node); bool removeFromOilCoolerLoop(); boost::optional oilCoolerInletNode() const; From 15f5ec51018e6c4903a42e42e75419f859b44060 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 14:37:55 +0200 Subject: [PATCH 11/24] Need to override edges too for the oil cooler and aux loops... --- src/model/ChillerElectricASHRAE205.cpp | 86 ++++++++++ src/model/ChillerElectricASHRAE205.hpp | 1 + src/model/ChillerElectricASHRAE205_Impl.hpp | 3 + src/model/Loop.cpp | 10 +- .../test/ChillerElectricASHRAE205_GTest.cpp | 149 +++++++++++++++++- 5 files changed, 245 insertions(+), 4 deletions(-) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 8d2102417b..5e5a41d176 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -519,6 +519,48 @@ namespace model { return false; } + std::vector ChillerElectricASHRAE205_Impl::edges(const boost::optional& prev) { + // This handles supply, demand, and tertiary connections + std::vector edges = WaterToWaterComponent_Impl::edges(prev); + + auto pushOilCoolerOutletModelObject = [&]() { + if (auto edgeModelObject = oilCoolerOutletModelObject()) { + auto edgeHVACComponent = edgeModelObject->optionalCast(); + OS_ASSERT(edgeHVACComponent); + edges.push_back(edgeHVACComponent.get()); + } + }; + + auto pushAuxiliaryOutletModelObject = [&]() { + if (auto edgeModelObject = auxiliaryOutletModelObject()) { + auto edgeHVACComponent = edgeModelObject->optionalCast(); + OS_ASSERT(edgeHVACComponent); + edges.push_back(edgeHVACComponent.get()); + } + }; + + if (prev) { + if (auto inletModelObject = oilCoolerInletModelObject()) { + if (prev.get() == inletModelObject.get()) { + pushOilCoolerOutletModelObject(); + return edges; + } + } + if (auto inletModelObject = auxiliaryInletModelObject()) { + if (prev.get() == inletModelObject.get()) { + pushAuxiliaryOutletModelObject(); + return edges; + } + } + } else { + pushOilCoolerOutletModelObject(); + pushAuxiliaryOutletModelObject(); + return edges; + } + + return edges; + } + boost::optional ChillerElectricASHRAE205_Impl::plantLoop() const { if (boost::optional mo_ = supplyOutletModelObject()) { if (boost::optional n_ = mo_->optionalCast()) { @@ -707,6 +749,46 @@ namespace model { return false; } + bool ChillerElectricASHRAE205_Impl::addDemandBranchOnAuxiliaryLoop(PlantLoop& plantLoop) { + Model _model = this->model(); + + if (plantLoop.model() != _model) { + return false; + } + + Splitter splitter = plantLoop.demandSplitter(); + Mixer mixer = plantLoop.demandMixer(); + + if (splitter.outletModelObjects().size() == 1u) { + if (boost::optional mo = splitter.lastOutletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + if ((node->outletModelObject().get() == mixer) && (node->inletModelObject().get() == splitter)) { + + return addToAuxiliaryLoopNode(node.get()); + } + } + } + } + + unsigned nextOutletPort = splitter.nextOutletPort(); + unsigned nextInletPort = mixer.nextInletPort(); + + Node node(_model); + + _model.connect(splitter, nextOutletPort, node, node.inletPort()); + _model.connect(node, node.outletPort(), mixer, nextInletPort); + + if (addToAuxiliaryLoopNode(node)) { + return true; + } + + _model.disconnect(node, node.outletPort()); + _model.disconnect(node, node.inletPort()); + node.remove(); + + return false; + } + bool ChillerElectricASHRAE205_Impl::addToAuxiliaryLoopNode(Node& node) { if (node.getImpl()->isConnected(getObject())) { @@ -1064,6 +1146,10 @@ namespace model { return getImpl()->auxiliaryLoop(); } + bool ChillerElectricASHRAE205::addDemandBranchOnAuxiliaryLoop(PlantLoop& plantLoop) { + return getImpl()->addDemandBranchOnAuxiliaryLoop(plantLoop); + } + bool ChillerElectricASHRAE205::addToAuxiliaryLoopNode(Node& node) { return getImpl()->addToAuxiliaryLoopNode(node); } diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index 04c5065c57..de7a069403 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -195,6 +195,7 @@ namespace model { unsigned auxiliaryOutletPort() const; boost::optional auxiliaryOutletModelObject() const; boost::optional auxiliaryOutletNode() const; + bool addDemandBranchOnAuxiliaryLoop(PlantLoop& plantLoop); bool addToAuxiliaryLoopNode(Node& node); bool removeFromAuxiliaryLoop(); boost::optional auxiliaryLoop() const; diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp index 8de0b7ecd8..002ba8d49d 100644 --- a/src/model/ChillerElectricASHRAE205_Impl.hpp +++ b/src/model/ChillerElectricASHRAE205_Impl.hpp @@ -83,6 +83,8 @@ namespace model { virtual unsigned tertiaryInletPort() const override; virtual unsigned tertiaryOutletPort() const override; + virtual std::vector edges(const boost::optional& prev) override; + /** This function will perform a check if trying to add it to a node that is on the demand side of a plant loop. * If: * - the node is on the demand side of a loop @@ -221,6 +223,7 @@ namespace model { boost::optional auxiliaryInletModelObject() const; /*static*/ unsigned auxiliaryOutletPort() const; boost::optional auxiliaryOutletModelObject() const; + bool addDemandBranchOnAuxiliaryLoop(PlantLoop& plantLoop); bool addToAuxiliaryLoopNode(Node& node); bool removeFromAuxiliaryLoop(); boost::optional auxiliaryLoop() const; diff --git a/src/model/Loop.cpp b/src/model/Loop.cpp index 576d7ff195..d9287f57bd 100644 --- a/src/model/Loop.cpp +++ b/src/model/Loop.cpp @@ -39,6 +39,8 @@ #include "Splitter_Impl.hpp" #include "Mixer.hpp" #include "Mixer_Impl.hpp" +#include "HVACComponent.hpp" +#include "HVACComponent_Impl.hpp" #include "StraightComponent.hpp" #include "StraightComponent_Impl.hpp" #include "WaterToAirComponent.hpp" @@ -106,7 +108,9 @@ namespace model { } boost::optional prev; - if (visited.size() >= 2u) prev = visited.rbegin()[1]; + if (visited.size() >= 2u) { + prev = visited.rbegin()[1]; + } std::vector nodes = hvacComponent.getImpl()->edges(prev); @@ -200,7 +204,9 @@ namespace model { void findModelObjects(const HVACComponent& sink, std::vector& visited, std::vector& paths, bool isDemandComponents) { boost::optional prev; - if (visited.size() >= 2u) prev = visited.rbegin()[1]; + if (visited.size() >= 2u) { + prev = visited.rbegin()[1]; + } std::vector nodes = visited.back().getImpl()->edges(prev); diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index 2d9a1a25cc..c81c1647ee 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -410,10 +410,80 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryOutletNode()); // Oil Cooler Loop - auto ocDemandConnectionNodes = ocLoop.supplyComponents(ocLoop.demandSplitter(), ocLoop.demandMixer(), IddObjectType::OS_Node); + auto ocDemandConnectionNodes = ocLoop.demandComponents(ocLoop.demandSplitter(), ocLoop.demandMixer(), IddObjectType::OS_Node); ASSERT_EQ(1, ocDemandConnectionNodes.size()); auto ocDemandConnectionNode = ocDemandConnectionNodes[0].cast(); + EXPECT_EQ(5, ocLoop.demandComponents().size()); EXPECT_TRUE(ch.addToOilCoolerLoopNode(ocDemandConnectionNode)); + EXPECT_EQ(7, ocLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Try removeFromLoop + ch.removeFromOilCoolerLoop(); + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Try addDemandBranchOnLoop + EXPECT_EQ(5, ocLoop.demandComponents().size()); + ch.addDemandBranchOnOilCoolerLoop(ocLoop); + EXPECT_EQ(7, ocLoop.demandComponents().size()); ASSERT_TRUE(ch.chilledWaterLoop()); ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); @@ -448,10 +518,85 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryOutletNode()); // Auxiliary Loop - auto auxDemandConnectionNodes = ocLoop.supplyComponents(auxLoop.demandSplitter(), auxLoop.demandMixer(), IddObjectType::OS_Node); + auto auxDemandConnectionNodes = auxLoop.demandComponents(auxLoop.demandSplitter(), auxLoop.demandMixer(), IddObjectType::OS_Node); ASSERT_EQ(1, auxDemandConnectionNodes.size()); auto auxDemandConnectionNode = auxDemandConnectionNodes[0].cast(); + EXPECT_EQ(5, auxLoop.demandComponents().size()); EXPECT_TRUE(ch.addToAuxiliaryLoopNode(auxDemandConnectionNode)); + EXPECT_EQ(7, auxLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + ASSERT_TRUE(ch.plantLoop()); + ASSERT_EQ(chwLoop, ch.plantLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.secondaryPlantLoop()); + ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + // Try removeFromLoop + ch.removeFromAuxiliaryLoop(); + EXPECT_EQ(5, auxLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + // Try addDemandBranchOnLoop + EXPECT_EQ(5, auxLoop.demandComponents().size()); + ch.addDemandBranchOnAuxiliaryLoop(ocLoop); + EXPECT_EQ(7, auxLoop.demandComponents().size()); ASSERT_TRUE(ch.chilledWaterLoop()); ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); From 201491a1b4e884bac3fded81d24d6bf4b7eac33a Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 17:18:25 +0200 Subject: [PATCH 12/24] Wrap up the model side! --- src/model/ChillerElectricASHRAE205.cpp | 23 +- .../test/ChillerElectricASHRAE205_GTest.cpp | 615 +++++++++--------- 2 files changed, 331 insertions(+), 307 deletions(-) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 5e5a41d176..3632dc8d94 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -402,10 +402,6 @@ namespace model { return OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName; } - boost::optional ChillerElectricASHRAE205_Impl::chilledWaterLoop() const { - return WaterToWaterComponent_Impl::plantLoop(); - } - boost::optional ChillerElectricASHRAE205_Impl::chilledWaterInletNode() const { if (auto mo_ = supplyInletModelObject()) { return mo_->optionalCast(); @@ -430,10 +426,6 @@ namespace model { return OS_Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName; } - boost::optional ChillerElectricASHRAE205_Impl::condenserWaterLoop() const { - return WaterToWaterComponent_Impl::secondaryPlantLoop(); - } - boost::optional ChillerElectricASHRAE205_Impl::condenserInletNode() const { if (auto mo_ = demandInletModelObject()) { return mo_->optionalCast(); @@ -457,10 +449,6 @@ namespace model { return OS_Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName; } - boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryLoop() const { - return WaterToWaterComponent_Impl::tertiaryPlantLoop(); - } - boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryInletNode() const { if (auto mo_ = tertiaryInletModelObject()) { return mo_->optionalCast(); @@ -588,6 +576,17 @@ namespace model { return boost::none; } + boost::optional ChillerElectricASHRAE205_Impl::chilledWaterLoop() const { + return plantLoop(); + } + + boost::optional ChillerElectricASHRAE205_Impl::condenserWaterLoop() const { + return secondaryPlantLoop(); + } + boost::optional ChillerElectricASHRAE205_Impl::heatRecoveryLoop() const { + return tertiaryPlantLoop(); + } + // Extra loops /// Oil Cooler Loop diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index c81c1647ee..9817714b29 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -48,6 +48,7 @@ #include "../../utilities/core/PathHelpers.hpp" #include +#include using namespace openstudio; using namespace openstudio::model; @@ -325,310 +326,334 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { auto ocLoop = createLoop("ocLoop"); auto auxLoop = createLoop("auxLoop"); - // Chilled Water Inlet Node Name: Required Object - - EXPECT_TRUE(chwLoop.addSupplyBranchForComponent(ch)); - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - - EXPECT_FALSE(ch.condenserWaterLoop()); - EXPECT_FALSE(ch.condenserInletNode()); - EXPECT_FALSE(ch.condenserOutletNode()); - - EXPECT_FALSE(ch.heatRecoveryLoop()); - EXPECT_FALSE(ch.heatRecoveryInletNode()); - EXPECT_FALSE(ch.heatRecoveryOutletNode()); - - EXPECT_FALSE(ch.oilCoolerLoop()); - EXPECT_FALSE(ch.oilCoolerInletNode()); - EXPECT_FALSE(ch.oilCoolerOutletNode()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); + // Chilled Water + { + EXPECT_TRUE(chwLoop.addSupplyBranchForComponent(ch)); + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + + EXPECT_FALSE(ch.condenserWaterLoop()); + EXPECT_FALSE(ch.condenserInletNode()); + EXPECT_FALSE(ch.condenserOutletNode()); + + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + } // Condenser - EXPECT_TRUE(cndLoop.addDemandBranchForComponent(ch)); - ASSERT_TRUE(ch.chilledWaterLoop()); - EXPECT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - EXPECT_FALSE(ch.heatRecoveryLoop()); - EXPECT_FALSE(ch.heatRecoveryInletNode()); - EXPECT_FALSE(ch.heatRecoveryOutletNode()); - - EXPECT_FALSE(ch.oilCoolerLoop()); - EXPECT_FALSE(ch.oilCoolerInletNode()); - EXPECT_FALSE(ch.oilCoolerOutletNode()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); + { + EXPECT_TRUE(cndLoop.addDemandBranchForComponent(ch)); + ASSERT_TRUE(ch.chilledWaterLoop()); + EXPECT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + } // Heat Recovery - EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch)); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - EXPECT_FALSE(ch.oilCoolerLoop()); - EXPECT_FALSE(ch.oilCoolerInletNode()); - EXPECT_FALSE(ch.oilCoolerOutletNode()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); + { + EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch)); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + } // Oil Cooler Loop - auto ocDemandConnectionNodes = ocLoop.demandComponents(ocLoop.demandSplitter(), ocLoop.demandMixer(), IddObjectType::OS_Node); - ASSERT_EQ(1, ocDemandConnectionNodes.size()); - auto ocDemandConnectionNode = ocDemandConnectionNodes[0].cast(); - EXPECT_EQ(5, ocLoop.demandComponents().size()); - EXPECT_TRUE(ch.addToOilCoolerLoopNode(ocDemandConnectionNode)); - EXPECT_EQ(7, ocLoop.demandComponents().size()); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - ASSERT_TRUE(ch.oilCoolerLoop()); - EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); - ASSERT_TRUE(ch.oilCoolerInletNode()); - EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); - ASSERT_TRUE(ch.oilCoolerOutletNode()); - EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); - - // Try removeFromLoop - ch.removeFromOilCoolerLoop(); - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - EXPECT_FALSE(ch.oilCoolerLoop()); - EXPECT_FALSE(ch.oilCoolerInletNode()); - EXPECT_FALSE(ch.oilCoolerOutletNode()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); - - // Try addDemandBranchOnLoop - EXPECT_EQ(5, ocLoop.demandComponents().size()); - ch.addDemandBranchOnOilCoolerLoop(ocLoop); - EXPECT_EQ(7, ocLoop.demandComponents().size()); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - ASSERT_TRUE(ch.oilCoolerLoop()); - EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); - ASSERT_TRUE(ch.oilCoolerInletNode()); - EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); - ASSERT_TRUE(ch.oilCoolerOutletNode()); - EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + { + auto ocDemandConnectionNodes = ocLoop.demandComponents(ocLoop.demandSplitter(), ocLoop.demandMixer(), IddObjectType::OS_Node); + + // addToNode + { + ASSERT_EQ(1, ocDemandConnectionNodes.size()); + auto ocDemandConnectionNode = ocDemandConnectionNodes[0].cast(); + EXPECT_EQ(5, ocLoop.demandComponents().size()); + EXPECT_TRUE(ch.addToOilCoolerLoopNode(ocDemandConnectionNode)); + EXPECT_EQ(7, ocLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + } - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); + // Try removeFromLoop + { + ch.removeFromOilCoolerLoop(); + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + + EXPECT_EQ(5, ocLoop.demandComponents().size()); + } + // Try addDemandBranchOnLoop + { + + EXPECT_TRUE(ch.addDemandBranchOnOilCoolerLoop(ocLoop)); + EXPECT_EQ(7, ocLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + } + } // Auxiliary Loop - auto auxDemandConnectionNodes = auxLoop.demandComponents(auxLoop.demandSplitter(), auxLoop.demandMixer(), IddObjectType::OS_Node); - ASSERT_EQ(1, auxDemandConnectionNodes.size()); - auto auxDemandConnectionNode = auxDemandConnectionNodes[0].cast(); - EXPECT_EQ(5, auxLoop.demandComponents().size()); - EXPECT_TRUE(ch.addToAuxiliaryLoopNode(auxDemandConnectionNode)); - EXPECT_EQ(7, auxLoop.demandComponents().size()); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - ASSERT_TRUE(ch.plantLoop()); - ASSERT_EQ(chwLoop, ch.plantLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.secondaryPlantLoop()); - ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - ASSERT_TRUE(ch.oilCoolerLoop()); - EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); - ASSERT_TRUE(ch.oilCoolerInletNode()); - EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); - ASSERT_TRUE(ch.oilCoolerOutletNode()); - EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); - - // Try removeFromLoop - ch.removeFromAuxiliaryLoop(); - EXPECT_EQ(5, auxLoop.demandComponents().size()); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - ASSERT_TRUE(ch.oilCoolerLoop()); - EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); - ASSERT_TRUE(ch.oilCoolerInletNode()); - EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); - ASSERT_TRUE(ch.oilCoolerOutletNode()); - EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); - - EXPECT_FALSE(ch.auxiliaryLoop()); - EXPECT_FALSE(ch.auxiliaryInletNode()); - EXPECT_FALSE(ch.auxiliaryOutletNode()); + { + // AddToNode + { + auto auxDemandConnectionNodes = auxLoop.demandComponents(auxLoop.demandSplitter(), auxLoop.demandMixer(), IddObjectType::OS_Node); + ASSERT_EQ(1, auxDemandConnectionNodes.size()); + auto auxDemandConnectionNode = auxDemandConnectionNodes[0].cast(); + EXPECT_EQ(5, auxLoop.demandComponents().size()); + EXPECT_TRUE(ch.addToAuxiliaryLoopNode(auxDemandConnectionNode)); + EXPECT_EQ(7, auxLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + ASSERT_TRUE(ch.plantLoop()); + ASSERT_EQ(chwLoop, ch.plantLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.secondaryPlantLoop()); + ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + } + { + // Try removeFromLoop + ch.removeFromAuxiliaryLoop(); + EXPECT_EQ(5, auxLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); + EXPECT_EQ(5, auxLoop.demandComponents().size()); + } - // Try addDemandBranchOnLoop - EXPECT_EQ(5, auxLoop.demandComponents().size()); - ch.addDemandBranchOnAuxiliaryLoop(ocLoop); - EXPECT_EQ(7, auxLoop.demandComponents().size()); - - ASSERT_TRUE(ch.chilledWaterLoop()); - ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); - ASSERT_TRUE(ch.plantLoop()); - ASSERT_EQ(chwLoop, ch.plantLoop().get()); - EXPECT_TRUE(ch.chilledWaterInletNode()); - EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); - EXPECT_TRUE(ch.chilledWaterOutletNode()); - EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); - - ASSERT_TRUE(ch.condenserWaterLoop()); - EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); - ASSERT_TRUE(ch.secondaryPlantLoop()); - ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); - ASSERT_TRUE(ch.condenserInletNode()); - EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); - ASSERT_TRUE(ch.condenserOutletNode()); - EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); - - ASSERT_TRUE(ch.oilCoolerLoop()); - EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); - ASSERT_TRUE(ch.oilCoolerInletNode()); - EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); - ASSERT_TRUE(ch.oilCoolerOutletNode()); - EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + { + // Try addDemandBranchOnLoop + EXPECT_TRUE(ch.addDemandBranchOnAuxiliaryLoop(auxLoop)); + EXPECT_EQ(7, auxLoop.demandComponents().size()); + + ASSERT_TRUE(ch.chilledWaterLoop()); + ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); + ASSERT_TRUE(ch.plantLoop()); + ASSERT_EQ(chwLoop, ch.plantLoop().get()); + EXPECT_TRUE(ch.chilledWaterInletNode()); + EXPECT_EQ(ch.supplyInletModelObject()->handle(), ch.chilledWaterInletNode()->handle()); + EXPECT_TRUE(ch.chilledWaterOutletNode()); + EXPECT_EQ(ch.supplyOutletModelObject()->handle(), ch.chilledWaterOutletNode()->handle()); + + ASSERT_TRUE(ch.condenserWaterLoop()); + EXPECT_EQ(cndLoop, ch.condenserWaterLoop().get()); + ASSERT_TRUE(ch.secondaryPlantLoop()); + ASSERT_EQ(cndLoop, ch.secondaryPlantLoop().get()); + ASSERT_TRUE(ch.condenserInletNode()); + EXPECT_EQ(ch.demandInletModelObject()->handle(), ch.condenserInletNode()->handle()); + ASSERT_TRUE(ch.condenserOutletNode()); + EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + + ASSERT_TRUE(ch.oilCoolerLoop()); + EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); + ASSERT_TRUE(ch.oilCoolerInletNode()); + EXPECT_EQ(ch.oilCoolerInletModelObject()->handle(), ch.oilCoolerInletNode()->handle()); + ASSERT_TRUE(ch.oilCoolerOutletNode()); + EXPECT_EQ(ch.oilCoolerOutletModelObject()->handle(), ch.oilCoolerOutletNode()->handle()); + } + } // Removing the Chiller doesn't remove the ExternalFile openstudio::path dstPath = representationFile->filePath(); @@ -646,7 +671,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { TEST_F(ModelFixture, ChillerElectricASHRAE205_NotCBORFile) { Model model; - path p = resourcesPath() / toPath("model/7-7_Windows_Complete.osm"); + openstudio::path p = resourcesPath() / toPath("model/7-7_Windows_Complete.osm"); EXPECT_TRUE(exists(p)); boost::optional representationFile = ExternalFile::getExternalFile(model, openstudio::toString(p)); From 1a7147bb4e8be1ff2899a8222fa12ff8f178b491 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 17:21:22 +0200 Subject: [PATCH 13/24] Write FT + FT test --- src/energyplus/CMakeLists.txt | 2 + src/energyplus/ForwardTranslator.cpp | 5 + src/energyplus/ForwardTranslator.hpp | 3 + ...rwardTranslateChillerElectricASHRAE205.cpp | 205 +++++++------ ...ranslatePlantEquipmentOperationSchemes.cpp | 15 +- .../ForwardTranslatePlantLoop.cpp | 28 +- .../ForwardTranslateSizingPlant.cpp | 3 + .../Test/ChillerElectricASHRAE205_GTest.cpp | 269 ++++++++++++++++++ 8 files changed, 416 insertions(+), 114 deletions(-) create mode 100644 src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index 39f2dd9788..49b5c032f0 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -62,6 +62,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateCFactorUndergroundWallConstruction.cpp ForwardTranslator/ForwardTranslateChillerAbsorption.cpp ForwardTranslator/ForwardTranslateChillerAbsorptionIndirect.cpp + ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp ForwardTranslator/ForwardTranslateChillerElectricEIR.cpp ForwardTranslator/ForwardTranslateChillerElectricReformulatedEIR.cpp ForwardTranslator/ForwardTranslateChillerHeaterPerformanceElectricEIR.cpp @@ -659,6 +660,7 @@ set(${target_name}_test_src Test/AvailabilityManagerNightCycle_GTest.cpp Test/AvailabilityManagerHybridVentilation_GTest.cpp Test/Building_GTest.cpp + Test/ChillerElectricASHRAE205_GTest.cpp Test/CentralHeatPumpSystem_GTest.cpp Test/CoilCoolingDX_GTest.cpp Test/CoilCoolingDXCurveFitPerformance_GTest.cpp diff --git a/src/energyplus/ForwardTranslator.cpp b/src/energyplus/ForwardTranslator.cpp index 3c4855de9b..bdbce99d3b 100644 --- a/src/energyplus/ForwardTranslator.cpp +++ b/src/energyplus/ForwardTranslator.cpp @@ -937,6 +937,11 @@ namespace energyplus { retVal = translateChillerAbsorptionIndirect(mo); break; } + case openstudio::IddObjectType::OS_Chiller_Electric_ASHRAE205: { + auto mo = modelObject.cast(); + retVal = translateChillerElectricASHRAE205(mo); + break; + } case openstudio::IddObjectType::OS_Chiller_Electric_EIR: { model::ChillerElectricEIR chiller = modelObject.cast(); retVal = translateChillerElectricEIR(chiller); diff --git a/src/energyplus/ForwardTranslator.hpp b/src/energyplus/ForwardTranslator.hpp index 0ad5dc5302..9e574f5c24 100644 --- a/src/energyplus/ForwardTranslator.hpp +++ b/src/energyplus/ForwardTranslator.hpp @@ -121,6 +121,7 @@ namespace model { class CFactorUndergroundWallConstruction; class ChillerAbsorption; class ChillerAbsorptionIndirect; + class ChillerElectricASHRAE205; class ChillerElectricEIR; class ChillerElectricReformulatedEIR; class ChillerHeaterPerformanceElectricEIR; @@ -747,6 +748,8 @@ namespace energyplus { boost::optional translateChillerAbsorptionIndirect(model::ChillerAbsorptionIndirect& modelObject); + boost::optional translateChillerElectricASHRAE205(model::ChillerElectricASHRAE205& modelObject); + boost::optional translateChillerElectricEIR(model::ChillerElectricEIR& modelObject); boost::optional translateChillerElectricReformulatedEIR(model::ChillerElectricReformulatedEIR& modelObject); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp index 3def4feb58..3a2f320935 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp @@ -32,12 +32,9 @@ #include "../../model/ChillerElectricASHRAE205.hpp" -// TODO: Check the following class names against object getters and setters. #include "../../model/Schedule.hpp" -#include "../../model/Schedule_Impl.hpp" - -#include "../../model/Zone.hpp" -#include "../../model/Zone_Impl.hpp" +#include "../../model/ExternalFile.hpp" +#include "../../model/ThermalZone.hpp" #include "../../model/Node.hpp" #include "../../model/Node_Impl.hpp" @@ -53,107 +50,133 @@ namespace openstudio { namespace energyplus { boost::optional ForwardTranslator::translateChillerElectricASHRAE205(model::ChillerElectricASHRAE205& modelObject) { - boost::optional result; - boost::optional _wo; - boost::optional _mo; - // Instantiate an IdfObject of the class to store the values - IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Chiller_Electric_ASHRAE205, modelObject); - // If it doesn't have a name, or if you aren't sure you are going to want to return it - // IdfObject idfObject( openstudio::IddObjectType::Chiller_Electric_ASHRAE205 ); - // m_idfObjects.push_back(idfObject); + path filePath = modelObject.representationFile().filePath(); + if (!openstudio::filesystem::exists(filePath)) { + LOG(Warn, modelObject.briefDescription() << "will not be translated, cannot find the representation file '" << filePath << "'"); + return boost::none; + } - // TODO: Note JM 2018-10-17 - // You are responsible for implementing any additional logic based on choice fields, etc. - // The ForwardTranslator generator script is meant to facilitate your work, not get you 100% of the way + // make the path correct for this system + filePath = openstudio::filesystem::system_complete(filePath); - // TODO: If you keep createRegisterAndNameIdfObject above, you don't need this. - // But in some cases, you'll want to handle failure without pushing to the map - // Name - if (boost::optional moName = modelObject.name()) { - idfObject.setName(*moName); + if (!modelObject.chilledWaterLoop()) { + LOG(Warn, modelObject.briefDescription() << "will not be translated, it not on a Chilled Water Loop."); + return boost::none; } + // Instantiate an IdfObject of the class to store the values + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Chiller_Electric_ASHRAE205, modelObject); + // Representation File Name: Required String - std::string representationFileName = modelObject.representationFileName(); - idfObject.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, representationFileName); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, openstudio::toString(filePath.filename())); - // Performance Interpolation Method: Optional String + // Performance Interpolation Method std::string performanceInterpolationMethod = modelObject.performanceInterpolationMethod(); idfObject.setString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); if (modelObject.isRatedCapacityAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "Autosize"); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "AutoSize"); } else { - // Rated Capacity: boost::optional - if (boost::optional _ratedCapacity = modelObject.ratedCapacity()) { - idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::RatedCapacity, _ratedCapacity.get()); - } + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::RatedCapacity, modelObject.ratedCapacity().get()); } // Sizing Factor: Optional Double - double sizingFactor = modelObject.sizingFactor(); - idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor, sizingFactor); + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor, modelObject.sizingFactor()); // Ambient Temperature Indicator: Required String std::string ambientTemperatureIndicator = modelObject.ambientTemperatureIndicator(); + bool ambientTempOk = false; + + if (openstudio::istringEqual("Schedule", ambientTemperatureIndicator)) { + // Ambient Temperature Schedule Name: Optional Object + if (boost::optional _ambientTemperatureSchedule = modelObject.ambientTemperatureSchedule()) { + if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureSchedule.get())) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, _owo->nameString()); + ambientTempOk = true; + } + } + } else if (openstudio::istringEqual("Zone", ambientTemperatureIndicator)) { + // Ambient Temperature Zone Name: Optional Object + if (boost::optional _ambientTemperatureZone = modelObject.ambientTemperatureZone()) { + if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureZone.get())) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, _owo->nameString()); + ambientTempOk = true; + } + } + } else if (openstudio::istringEqual("Outdoors", ambientTemperatureIndicator)) { + ambientTempOk = true; + } + if (!ambientTempOk) { + LOG(Warn, "For " << modelObject.briefDescription() << " the Ambient Temperature Indicator is " << ambientTemperatureIndicator + << " but the required objects don't match. Falling back to 'Outdoors'"); + ambientTemperatureIndicator = "Outdoors"; + } + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, ambientTemperatureIndicator); - // Ambient Temperature Schedule Name: Optional Object - if (boost::optional _ambientTemperatureSchedule = modelObject.ambientTemperatureSchedule()) { - if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureSchedule.get())) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, _owo->nameString()); + if (openstudio::istringEqual("Outdoors", ambientTemperatureIndicator)) { + std::string oaNodeName = modelObject.nameString() + " OA Node"; + if (boost::optional s_ = modelObject.ambientTemperatureOutdoorAirNodeName()) { + oaNodeName = s_.get(); } + + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, oaNodeName); + + IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList); + _oaNodeList.setString(0, oaNodeName); + m_idfObjects.push_back(_oaNodeList); } - // Ambient Temperature Zone Name: Optional Object - if (boost::optional _ambientTemperatureZone = modelObject.ambientTemperatureZone()) { - if (boost::optional _owo = translateAndMapModelObject(_ambientTemperatureZone.get())) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, _owo->nameString()); - } + // Chilled Water Node Names: Required Nodes + if (auto node_ = modelObject.chilledWaterInletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, node_->nameString()); } - // Ambient Temperature Outdoor Air Node Name: Optional Node - Node ambientTemperatureOutdoorAirNodeName = modelObject.ambientTemperatureOutdoorAirNodeName(); - if (boost::optional _owo = translateAndMapModelObject(ambientTemperatureOutdoorAirNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, _owo->nameString()); + if (auto node_ = modelObject.chilledWaterOutletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, node_->nameString()); } - // Chilled Water Inlet Node Name: Required Node - Node chilledWaterInletNodeName = modelObject.chilledWaterInletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(chilledWaterInletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, _owo->nameString()); + // Optional Nodes + + // Condenser + if (auto node_ = modelObject.condenserInletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, node_->nameString()); } - // Chilled Water Outlet Node Name: Required Node - Node chilledWaterOutletNodeName = modelObject.chilledWaterOutletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(chilledWaterOutletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, _owo->nameString()); + if (auto node_ = modelObject.condenserOutletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, node_->nameString()); } - if (modelObject.isChilledWaterMaximumRequestedFlowRateAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "Autosize"); - } else { - // Chilled Water Maximum Requested Flow Rate: boost::optional - if (boost::optional _chilledWaterMaximumRequestedFlowRate = modelObject.chilledWaterMaximumRequestedFlowRate()) { - idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, _chilledWaterMaximumRequestedFlowRate.get()); - } + // Heat Recovery + if (auto node_ = modelObject.heatRecoveryInletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, node_->nameString()); } - // Condenser Inlet Node Name: Optional Node - Node condenserInletNodeName = modelObject.condenserInletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(condenserInletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, _owo->nameString()); + if (auto node_ = modelObject.heatRecoveryOutletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, node_->nameString()); } - // Condenser Outlet Node Name: Optional Node - Node condenserOutletNodeName = modelObject.condenserOutletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(condenserOutletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, _owo->nameString()); + // Oil Cooler + if (auto node_ = modelObject.oilCoolerInletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, node_->nameString()); + } + + if (auto node_ = modelObject.oilCoolerOutletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, node_->nameString()); + } + + // Auxiliary + if (auto node_ = modelObject.auxiliaryInletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, node_->nameString()); + } + + if (auto node_ = modelObject.auxiliaryOutletNode()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, node_->nameString()); } if (modelObject.isCondenserMaximumRequestedFlowRateAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "Autosize"); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "AutoSize"); } else { // Condenser Maximum Requested Flow Rate: boost::optional if (boost::optional _condenserMaximumRequestedFlowRate = modelObject.condenserMaximumRequestedFlowRate()) { @@ -162,61 +185,25 @@ namespace energyplus { } // Chiller Flow Mode: Optional String - std::string chillerFlowMode = modelObject.chillerFlowMode(); - idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, chillerFlowMode); - - // Oil Cooler Inlet Node Name: Optional Node - Node oilCoolerInletNodeName = modelObject.oilCoolerInletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(oilCoolerInletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, _owo->nameString()); - } - - // Oil Cooler Outlet Node Name: Optional Node - Node oilCoolerOutletNodeName = modelObject.oilCoolerOutletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(oilCoolerOutletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, _owo->nameString()); - } + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, modelObject.chillerFlowMode()); // Oil Cooler Design Flow Rate: boost::optional if (boost::optional _oilCoolerDesignFlowRate = modelObject.oilCoolerDesignFlowRate()) { idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, _oilCoolerDesignFlowRate.get()); } - // Auxiliary Inlet Node Name: Optional Node - Node auxiliaryInletNodeName = modelObject.auxiliaryInletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(auxiliaryInletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, _owo->nameString()); - } - - // Auxiliary Outlet Node Name: Optional Node - Node auxiliaryOutletNodeName = modelObject.auxiliaryOutletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(auxiliaryOutletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, _owo->nameString()); - } - // Auxiliary Cooling Design Flow Rate: boost::optional if (boost::optional _auxiliaryCoolingDesignFlowRate = modelObject.auxiliaryCoolingDesignFlowRate()) { idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, _auxiliaryCoolingDesignFlowRate.get()); } - // Heat Recovery Inlet Node Name: Optional Node - Node heatRecoveryInletNodeName = modelObject.heatRecoveryInletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(heatRecoveryInletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, _owo->nameString()); - } - - // Heat Recovery Outlet Node Name: Optional Node - Node heatRecoveryOutletNodeName = modelObject.heatRecoveryOutletNodeName(); - if (boost::optional _owo = translateAndMapModelObject(heatRecoveryOutletNodeName)) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, _owo->nameString()); - } - // End-Use Subcategory: Optional String - std::string endUseSubcategory = modelObject.endUseSubcategory(); - idfObject.setString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, endUseSubcategory); + if (!modelObject.isEndUseSubcategoryDefaulted()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, modelObject.endUseSubcategory()); + } return idfObject; } // End of translate function } // end namespace energyplus -} // end namespace openstudio \ No newline at end of file +} // end namespace openstudio diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp index 92fbac6415..7852a789cd 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp @@ -43,6 +43,8 @@ #include "../../model/CentralHeatPumpSystemModule.hpp" #include "../../model/ChillerHeaterPerformanceElectricEIR.hpp" +#include "../../model/ChillerElectricASHRAE205.hpp" +#include "../../model/ChillerElectricASHRAE205_Impl.hpp" #include "../../model/ChillerElectricEIR.hpp" #include "../../model/ChillerElectricEIR_Impl.hpp" #include "../../model/ChillerElectricReformulatedEIR.hpp" @@ -204,8 +206,14 @@ namespace energyplus { // Probably check if all modules have a ChillerHeaterPerformanceComponent // that has a flow rate hardsized, and multiple by the number of performance comp // Better to add a method to centralheatpumpsystem, for eg "totalDesignFlowRate" - // Problem is that you need to know which loop is requesting this since there are three - // "Design XXX Water Flow Rate" (XXX= Chilled Water, Condenser Water, or Hot Water) + // Problem is that you need to know which loop is requesting this since there are two supply loops with + // "Design XXX Water Flow Rate" (XXX= Chilled Water, or Hot Water) + break; + } + + case openstudio::IddObjectType::OS_Chiller_Electric_ASHRAE205: { + auto chiller = component.cast(); + result = chiller.chilledWaterMaximumRequestedFlowRate(); break; } case openstudio::IddObjectType::OS_Chiller_Electric_EIR: { @@ -483,6 +491,9 @@ namespace energyplus { // As a result, this is handled in coolingComponents() and heatingComponents() directly return ComponentType::NONE; } + case openstudio::IddObjectType::OS_Chiller_Electric_ASHRAE205: { + return ComponentType::COOLING; + } case openstudio::IddObjectType::OS_Chiller_Electric_EIR: { return ComponentType::COOLING; } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp index 9712c31f76..c4aa14d46a 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp @@ -54,6 +54,8 @@ #include "../../model/BoilerHotWater_Impl.hpp" #include "../../model/CentralHeatPumpSystem.hpp" #include "../../model/CentralHeatPumpSystem_Impl.hpp" +#include "../../model/ChillerElectricASHRAE205.hpp" +#include "../../model/ChillerElectricASHRAE205_Impl.hpp" #include "../../model/ChillerElectricEIR.hpp" #include "../../model/ChillerElectricEIR_Impl.hpp" #include "../../model/ChillerElectricReformulatedEIR.hpp" @@ -334,21 +336,41 @@ namespace energyplus { auto sourceLoop = central_hp->sourcePlantLoop(); // supply = cooling Loop - if (loop.handle() == coolingLoop->handle()) { + if (coolingLoop && loop.handle() == coolingLoop->handle()) { inletNode = waterToWaterComponent->supplyInletModelObject()->optionalCast(); outletNode = waterToWaterComponent->supplyOutletModelObject()->optionalCast(); // tertiary = heating loop - } else if (loop.handle() == heatingLoop->handle()) { + } else if (heatingLoop && loop.handle() == heatingLoop->handle()) { inletNode = waterToWaterComponent->tertiaryInletModelObject()->optionalCast(); outletNode = waterToWaterComponent->tertiaryOutletModelObject()->optionalCast(); // demand = source loop - } else if (loop.handle() == sourceLoop->handle()) { + } else if (sourceLoop && loop.handle() == sourceLoop->handle()) { inletNode = waterToWaterComponent->demandInletModelObject()->optionalCast(); outletNode = waterToWaterComponent->demandOutletModelObject()->optionalCast(); } + } else if (auto ch = modelObject.optionalCast()) { + // This one has **FIVE** loops + + if (ch->chilledWaterLoop() && loop.handle() == ch->chilledWaterLoop()->handle()) { + inletNode = ch->chilledWaterInletNode(); + outletNode = ch->chilledWaterOutletNode(); + } else if (ch->condenserWaterLoop() && loop.handle() == ch->condenserWaterLoop()->handle()) { + inletNode = ch->condenserInletNode(); + outletNode = ch->condenserOutletNode(); + } else if (ch->heatRecoveryLoop() && loop.handle() == ch->heatRecoveryLoop()->handle()) { + inletNode = ch->heatRecoveryInletNode(); + outletNode = ch->heatRecoveryOutletNode(); + } else if (ch->oilCoolerLoop() && loop.handle() == ch->oilCoolerLoop()->handle()) { + inletNode = ch->oilCoolerInletNode(); + outletNode = ch->oilCoolerOutletNode(); + } else if (ch->auxiliaryLoop() && loop.handle() == ch->auxiliaryLoop()->handle()) { + inletNode = ch->auxiliaryInletNode(); + outletNode = ch->auxiliaryOutletNode(); + } + // Regular case } else if (isSupplyBranch) { inletNode = waterToWaterComponent->supplyInletModelObject()->optionalCast(); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSizingPlant.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSizingPlant.cpp index 88c8399b6b..2700fe9de6 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSizingPlant.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSizingPlant.cpp @@ -68,6 +68,9 @@ namespace energyplus { case openstudio::IddObjectType::OS_DistrictHeating: { return PlantSizingType::HOTWATER; } + case openstudio::IddObjectType::OS_Chiller_Electric_ASHRAE205: { + return PlantSizingType::CHILLEDWATER; + } case openstudio::IddObjectType::OS_Chiller_Electric_EIR: { return PlantSizingType::CHILLEDWATER; } diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp new file mode 100644 index 0000000000..349cf45ba1 --- /dev/null +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -0,0 +1,269 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ErrorFile.hpp" +#include "../ForwardTranslator.hpp" +#include "../ReverseTranslator.hpp" + +#include "../../model/ChillerElectricASHRAE205.hpp" +#include "../../model/ChillerElectricASHRAE205_Impl.hpp" + +#include "../../model/ExternalFile.hpp" +#include "../../model/ExternalFile_Impl.hpp" + +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/PlantLoop_Impl.hpp" +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/ScheduleConstant.hpp" +#include "../../model/Mixer.hpp" +#include "../../model/Splitter.hpp" + +#include "../../utilities/geometry/Point3d.hpp" + +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include "../../utilities/idf/WorkspaceExtensibleGroup.hpp" + +// E+ FieldEnums +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "../../utilities/core/PathHelpers.hpp" +#include +#include + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +/* Ensures that the nodes that translated correctly + * that means correct node names in the ChillerElectricASHRAE205 but also + * on the Branches + */ +TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { + + ForwardTranslator ft; + + Model m; + + auto createLoop = [&m](const std::string& prefix) { + PlantLoop p(m); + static constexpr std::array compNames = { + "Supply Inlet", "Supply Splitter", "Supply Connection Node", "Supply Mixer", "Supply Outlet", + "Demand Inlet", "Demand Splitter", "Demand Connection Node", "Demand Mixer", "Demand Outlet", + }; + p.setName(prefix); + for (size_t i = 0; auto& comp : p.components()) { + comp.setName(prefix + " " + std::string{compNames[i++]}); + } + return p; + }; + + openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); + EXPECT_TRUE(exists(p)); + + boost::optional representationFile = ExternalFile::getExternalFile(m, openstudio::toString(p)); + ASSERT_TRUE(representationFile); + + ChillerElectricASHRAE205 ch(representationFile.get()); + + EXPECT_TRUE(ch.setPerformanceInterpolationMethod("Cubic")); + ch.autosizeRatedCapacity(); + EXPECT_TRUE(ch.setSizingFactor(1.1)); + + ThermalZone z(m); + z.setName("Basement"); + { + std::vector sPoints{{0, 0, 0}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0}}; + auto space_ = Space::fromFloorPrint(sPoints, 3.0, m); + ASSERT_TRUE(space_); + EXPECT_TRUE(space_->setThermalZone(z)); + } + + EXPECT_TRUE(ch.setAmbientTemperatureZone(z)); + + EXPECT_TRUE(ch.setChilledWaterMaximumRequestedFlowRate(0.0428)); + + auto chwLoop = createLoop("chwLoop"); + EXPECT_TRUE(chwLoop.addSupplyBranchForComponent(ch)); + + auto cndLoop = createLoop("cndLoop"); + EXPECT_TRUE(cndLoop.addDemandBranchForComponent(ch)); + EXPECT_TRUE(ch.setCondenserMaximumRequestedFlowRate(0.0552)); + + EXPECT_TRUE(ch.setChillerFlowMode("ConstantFlow")); + + auto ocLoop = createLoop("ocLoop"); + EXPECT_TRUE(ch.addDemandBranchOnOilCoolerLoop(ocLoop)); + EXPECT_TRUE(ch.setOilCoolerDesignFlowRate(0.001)); + + auto auxLoop = createLoop("auxLoop"); + EXPECT_TRUE(ch.addDemandBranchOnAuxiliaryLoop(ocLoop)); + EXPECT_TRUE(ch.setAuxiliaryCoolingDesignFlowRate(0.002)); + + auto hrLoop = createLoop("hrLoop"); + EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch, true)); + + EXPECT_TRUE(ch.setEndUseSubcategory("Chiller")); + + ch.chilledWaterInletNode()->setName("ChilledWater Inlet Node"); + ch.chilledWaterOutletNode()->setName("ChilledWater Outlet Node"); + ch.condenserInletNode()->setName("Condenser Inlet Node"); + ch.condenserOutletNode()->setName("Condenser Outlet Node"); + ch.heatRecoveryInletNode()->setName("HeatRecovery Inlet Node"); + ch.heatRecoveryOutletNode()->setName("HeatRecovery Outlet Node"); + ch.oilCoolerInletNode()->setName("OilCooler Inlet Node"); + ch.oilCoolerOutletNode()->setName("OilCooler Outlet Node"); + ch.auxiliaryInletNode()->setName("Auxiliary Inlet Node"); + ch.auxiliaryOutletNode()->setName("Auxiliary Outlet Node"); + + { + Workspace w = ft.translateModel(m); + + std::vector woChs = w.getObjectsByType(IddObjectType::Chiller_Electric_ASHRAE205); + ASSERT_EQ(1, woChs.size()); + auto& woCh = woChs.front(); + + EXPECT_EQ(ch.nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::Name).get()); + EXPECT_EQ(representationFile->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); + EXPECT_EQ("Cubic", woCh.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod).get()); + EXPECT_EQ("AutoSize", woCh.getString(Chiller_Electric_ASHRAE205Fields::RatedCapacity).get()); + EXPECT_EQ(1.1, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor).get()); + + EXPECT_EQ("Zone", woCh.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator).get()); + EXPECT_TRUE(woCh.isEmpty(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName)); + EXPECT_EQ("Basement", woCh.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName).get()); + EXPECT_TRUE(woCh.isEmpty(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName)); + + EXPECT_EQ(0.0428, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate).get()); + + EXPECT_EQ(0.0552, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate).get()); + + EXPECT_EQ("ConstantFlow", woCh.getString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode).get()); + + EXPECT_EQ(0.001, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate).get()); + + EXPECT_EQ(0.002, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate).get()); + + EXPECT_EQ("Chiller", woCh.getString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory).get()); + + EXPECT_EQ("ChilledWater Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName).get()); + EXPECT_EQ("ChilledWater Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName).get()); + EXPECT_EQ("Condenser Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName).get()); + EXPECT_EQ("Condenser Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName).get()); + EXPECT_EQ("HeatRecovery Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); + EXPECT_EQ("HeatRecovery Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); + EXPECT_EQ("OilCooler Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName).get()); + EXPECT_EQ("OilCooler Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName).get()); + EXPECT_EQ("Auxiliary Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName).get()); + EXPECT_EQ("Auxiliary Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName).get()); + + EXPECT_EQ(ch.chilledWaterInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName).get()); + EXPECT_EQ(ch.chilledWaterOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName).get()); + EXPECT_EQ(ch.condenserInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName).get()); + EXPECT_EQ(ch.condenserOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName).get()); + EXPECT_EQ(ch.heatRecoveryInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); + EXPECT_EQ(ch.heatRecoveryOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); + EXPECT_EQ(ch.oilCoolerInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName).get()); + EXPECT_EQ(ch.oilCoolerOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName).get()); + EXPECT_EQ(ch.auxiliaryInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName).get()); + EXPECT_EQ(ch.auxiliaryOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName).get()); + + // Check node names on supply/demand branches + // Checks that the special case implemented in ForwardTranslatePlantLoop::populateBranch does the right job + + struct Expected + { + bool isSupply = true; + std::string plantName; + std::string inletNodeName; + std::string outletNodeName; + }; + + std::vector expecteds = { + {true, ch.chilledWaterLoop()->nameString(), ch.chilledWaterInletNode()->nameString(), ch.chilledWaterOutletNode()->nameString()}, + {false, ch.condenserWaterLoop()->nameString(), ch.condenserInletNode()->nameString(), ch.condenserOutletNode()->nameString()}, + {false, ch.heatRecoveryLoop()->nameString(), ch.heatRecoveryInletNode()->nameString(), ch.heatRecoveryOutletNode()->nameString()}, + {false, ch.oilCoolerLoop()->nameString(), ch.oilCoolerInletNode()->nameString(), ch.oilCoolerOutletNode()->nameString()}, + {false, ch.auxiliaryLoop()->nameString(), ch.auxiliaryInletNode()->nameString(), ch.auxiliaryOutletNode()->nameString()}, + }; + for (const auto& e : expecteds) { + auto p_ = w.getObjectByTypeAndName(IddObjectType::PlantLoop, e.plantName); + ASSERT_TRUE(p_.is_initialized()) << "Cannot find PlantLoop named " << e.plantName; + WorkspaceObject idf_plant = p_.get(); + unsigned index = e.isSupply ? PlantLoopFields::PlantSideBranchListName : PlantLoopFields::DemandSideBranchListName; + WorkspaceObject idf_brlist = idf_plant.getTarget(index).get(); + + // Should have three branches: supply inlet, the one with the centralHP, supply outlet + ASSERT_EQ(3u, idf_brlist.extensibleGroups().size()); + // Get the Chiller one + auto w_eg = idf_brlist.extensibleGroups()[1].cast(); + WorkspaceObject idf_branch = w_eg.getTarget(BranchListExtensibleFields::BranchName).get(); + + // There should be only one equipment on the branch + ASSERT_EQ(1u, idf_branch.extensibleGroups().size()); + auto w_eg2 = idf_branch.extensibleGroups()[0].cast(); + + ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(), ch.nameString()); + ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentInletNodeName).get(), e.inletNodeName); + ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentOutletNodeName).get(), e.outletNodeName); + } + } + + // Not assigned to a Chilled Water Loop? not translated, it's required + ch.removeFromPlantLoop(); + { + // Assigned to a Surface + Workspace w = ft.translateModel(m); + + EXPECT_EQ(0, w.getObjectsByType(IddObjectType::Chiller_Electric_ASHRAE205).size()); + } +} From f53424a7f0f95ba615359dfb89b6511bbb6c8c20 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 17:21:43 +0200 Subject: [PATCH 14/24] Write a RT --- src/energyplus/CMakeLists.txt | 1 + src/energyplus/ReverseTranslator.cpp | 4 + src/energyplus/ReverseTranslator.hpp | 2 + ...verseTranslateChillerElectricASHRAE205.cpp | 242 +++++------------- 4 files changed, 69 insertions(+), 180 deletions(-) diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index 49b5c032f0..76eb248ddc 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -458,6 +458,7 @@ set(${target_name}_src ReverseTranslator/ReverseTranslateBuilding.cpp ReverseTranslator/ReverseTranslateBuildingSurfaceDetailed.cpp ReverseTranslator/ReverseTranslateControllerOutdoorAir.cpp + ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp ReverseTranslator/ReverseTranslateCoilCoolingDX.cpp ReverseTranslator/ReverseTranslateCoilCoolingDXCurveFitPerformance.cpp ReverseTranslator/ReverseTranslateCoilCoolingDXCurveFitOperatingMode.cpp diff --git a/src/energyplus/ReverseTranslator.cpp b/src/energyplus/ReverseTranslator.cpp index 9d3ef0e899..45028fa46d 100644 --- a/src/energyplus/ReverseTranslator.cpp +++ b/src/energyplus/ReverseTranslator.cpp @@ -338,6 +338,10 @@ namespace energyplus { modelObject = translateBuilding(workspaceObject); break; } + case openstudio::IddObjectType::Chiller_Electric_ASHRAE205: { + modelObject = translateChillerElectricASHRAE205(workspaceObject); + break; + } case openstudio::IddObjectType::Coil_Heating_Fuel: { //modelObject = translateCoilHeatingGas(workspaceObject ); break; diff --git a/src/energyplus/ReverseTranslator.hpp b/src/energyplus/ReverseTranslator.hpp index 73bbda6606..24cdf0f6b6 100644 --- a/src/energyplus/ReverseTranslator.hpp +++ b/src/energyplus/ReverseTranslator.hpp @@ -95,6 +95,8 @@ namespace energyplus { boost::optional translateBuildingSurfaceDetailed(const WorkspaceObject& workspaceObject); + boost::optional translateChillerElectricASHRAE205(const WorkspaceObject& workspaceObject); + boost::optional translateControllerOutdoorAir(const WorkspaceObject& workspaceObject); boost::optional translateCoilHeatingGas(const WorkspaceObject& workspaceObject); diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp index 6d17b3af63..cedf25ab07 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp @@ -31,15 +31,13 @@ #include "../../model/ChillerElectricASHRAE205.hpp" -// TODO: Check the following class names against object getters and setters. #include "../../model/Schedule.hpp" #include "../../model/Schedule_Impl.hpp" -#include "../../model/Zone.hpp" -#include "../../model/Zone_Impl.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" -#include "../../model/Node.hpp" -#include "../../model/Node_Impl.hpp" +#include "../../model/ExternalFile.hpp" #include #include @@ -51,14 +49,23 @@ namespace openstudio { namespace energyplus { boost::optional ReverseTranslator::translateChillerElectricASHRAE205(const WorkspaceObject& workspaceObject) { - boost::optional result; - boost::optional _wo; - boost::optional _mo; - // Instantiate an object of the class to store the values, - // but we don't return it until we know it's ok - // TODO: check constructor, it might need other objects - openstudio::model::ChillerElectricASHRAE205 modelObject(m_model); + std::string fileName = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get(); + boost::optional extfile = ExternalFile::getExternalFile(m_model, fileName); + + if (!extfile) { + LOG(Error, "Could not translate " << workspaceObject.briefDescription() << ", cannot find Representation File \"" << fileName << "\""); + return boost::none; + } + + boost::optional ambientTemperatureIndicator_ = + workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator); + if (!ambientTemperatureIndicator_) { + LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required property 'Ambient Temperature Indicator'"); + return boost::none; + } + + openstudio::model::ChillerElectricASHRAE205 modelObject(extfile.get()); // TODO: Note JM 2018-10-17 // You are responsible for implementing any additional logic based on choice fields, etc. @@ -69,14 +76,6 @@ namespace energyplus { modelObject.setName(_name.get()); } - // Representation File Name: Required String - if (boost::optional _representationFileName = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName)) { - modelObject.setRepresentationFileName(_representationFileName.get()); - } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required property 'Representation File Name'"); - return result; - } - // Performance Interpolation Method: Optional String if (boost::optional _performanceInterpolationMethod = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod)) { @@ -94,109 +93,47 @@ namespace energyplus { } // Ambient Temperature Indicator: Required String - if (boost::optional _ambientTemperatureIndicator = - workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator)) { - modelObject.setAmbientTemperatureIndicator(_ambientTemperatureIndicator.get()); - } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required property 'Ambient Temperature Indicator'"); - return result; - } - - // Ambient Temperature Schedule Name: Optional Object - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _ambientTemperatureSchedule = _mo->optionalCast()) { - modelObject.setAmbientTemperatureSchedule(_ambientTemperatureSchedule.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Schedule Name'"); - } - } - } - // Ambient Temperature Zone Name: Optional Object - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _ambientTemperatureZone = _mo->optionalCast()) { - modelObject.setAmbientTemperatureZone(_ambientTemperatureZone.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Zone Name'"); - } - } - } - // Ambient Temperature Outdoor Air Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _ambientTemperatureOutdoorAirNodeName = _mo->optionalCast()) { - modelObject.setAmbientTemperatureOutdoorAirNodeName(_ambientTemperatureOutdoorAirNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Outdoor Air Node Name'"); - } - } - } - // Chilled Water Inlet Node Name: Required Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _chilledWaterInletNodeName = _mo->optionalCast()) { - modelObject.setChilledWaterInletNodeName(_chilledWaterInletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Chilled Water Inlet Node Name'"); + if (openstudio::istringEqual("Schedule", ambientTemperatureIndicator_.get())) { + + // Ambient Temperature Schedule Name: Optional Object + if (auto wo_sch_ = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName)) { + if (auto mo_sch_ = translateAndMapWorkspaceObject(wo_sch_.get())) { + if (boost::optional sch_ = mo_sch_->optionalCast()) { + modelObject.setAmbientTemperatureSchedule(sch_.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Schedule Name'"); + } } } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot reverse translate required object 'Chilled Water Inlet Node Name'"); - return result; + LOG(Warn, workspaceObject.briefDescription() + << " has an Ambient Temperature Indicator of type Schedule, but no Schedule. Falling back to 'Outdoors'"); } - } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required object 'Chilled Water Inlet Node Name'"); - return result; - } - // Chilled Water Outlet Node Name: Required Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _chilledWaterOutletNodeName = _mo->optionalCast()) { - modelObject.setChilledWaterOutletNodeName(_chilledWaterOutletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Chilled Water Outlet Node Name'"); + } else if (openstudio::istringEqual("Zone", ambientTemperatureIndicator_.get())) { + + // Ambient Temperature Zone Name: Optional Object + if (auto wo_z_ = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName)) { + if (auto mo_z_ = translateAndMapWorkspaceObject(wo_z_.get())) { + // TODO: check return types + if (boost::optional z_ = mo_z_->optionalCast()) { + modelObject.setAmbientTemperatureZone(z_.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Zone Name'"); + } } - } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot reverse translate required object 'Chilled Water Outlet Node Name'"); - return result; } } else { - LOG(Error, "For " << workspaceObject.briefDescription() << ", cannot find required object 'Chilled Water Outlet Node Name'"); - return result; + // Ambient Temperature Outdoor Air Node Name: Optional Node + if (boost::optional s_ = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName)) { + modelObject.setAmbientTemperatureOutdoorAirNodeName(s_.get()); + } } + // Chilled Water Maximum Requested Flow Rate: Optional Double if (boost::optional _chilledWaterMaximumRequestedFlowRate = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate)) { modelObject.setChilledWaterMaximumRequestedFlowRate(_chilledWaterMaximumRequestedFlowRate.get()); } - // Condenser Inlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _condenserInletNodeName = _mo->optionalCast()) { - modelObject.setCondenserInletNodeName(_condenserInletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Condenser Inlet Node Name'"); - } - } - } - // Condenser Outlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _condenserOutletNodeName = _mo->optionalCast()) { - modelObject.setCondenserOutletNodeName(_condenserOutletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Condenser Outlet Node Name'"); - } - } - } // Condenser Maximum Requested Flow Rate: Optional Double if (boost::optional _condenserMaximumRequestedFlowRate = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate)) { @@ -208,91 +145,36 @@ namespace energyplus { modelObject.setChillerFlowMode(_chillerFlowMode.get()); } - // Oil Cooler Inlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _oilCoolerInletNodeName = _mo->optionalCast()) { - modelObject.setOilCoolerInletNodeName(_oilCoolerInletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Oil Cooler Inlet Node Name'"); - } - } - } - // Oil Cooler Outlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _oilCoolerOutletNodeName = _mo->optionalCast()) { - modelObject.setOilCoolerOutletNodeName(_oilCoolerOutletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Oil Cooler Outlet Node Name'"); - } - } - } - // Oil Cooler Design Flow Rate: Optional Double if (boost::optional _oilCoolerDesignFlowRate = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate)) { modelObject.setOilCoolerDesignFlowRate(_oilCoolerDesignFlowRate.get()); } - // Auxiliary Inlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _auxiliaryInletNodeName = _mo->optionalCast()) { - modelObject.setAuxiliaryInletNodeName(_auxiliaryInletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Auxiliary Inlet Node Name'"); - } - } - } - // Auxiliary Outlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _auxiliaryOutletNodeName = _mo->optionalCast()) { - modelObject.setAuxiliaryOutletNodeName(_auxiliaryOutletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Auxiliary Outlet Node Name'"); - } - } - } // Auxiliary Cooling Design Flow Rate: Optional Double if (boost::optional _auxiliaryCoolingDesignFlowRate = workspaceObject.getDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate)) { modelObject.setAuxiliaryCoolingDesignFlowRate(_auxiliaryCoolingDesignFlowRate.get()); } - // Heat Recovery Inlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _heatRecoveryInletNodeName = _mo->optionalCast()) { - modelObject.setHeatRecoveryInletNodeName(_heatRecoveryInletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Heat Recovery Inlet Node Name'"); - } - } - } - // Heat Recovery Outlet Node Name: Optional Node - if ((_wo = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName))) { - if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - // TODO: check return types - if (boost::optional _heatRecoveryOutletNodeName = _mo->optionalCast()) { - modelObject.setHeatRecoveryOutletNodeName(_heatRecoveryOutletNodeName.get()); - } else { - LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Heat Recovery Outlet Node Name'"); - } - } - } // End-Use Subcategory: Optional String if (boost::optional _endUseSubcategory = workspaceObject.getString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory)) { modelObject.setEndUseSubcategory(_endUseSubcategory.get()); } - result = modelObject; - return result; + if (workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName) + || workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName)) { + LOG(Warn, "For " << workspaceObject.briefDescription() << " Loop Connections are NOT ReverseTranslated."); + } + + return modelObject; } // End of translate function } // end namespace energyplus -} // end namespace openstudio \ No newline at end of file +} // end namespace openstudio From 0a6d3feb5a6b84f93931620f942dd9781f6a94ad Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 17:37:09 +0200 Subject: [PATCH 15/24] Extend FT testign to check the PlantEquipmentOperation --- .../Test/ChillerElectricASHRAE205_GTest.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index 349cf45ba1..c4f4c82f1f 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -255,6 +255,37 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(), ch.nameString()); ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentInletNodeName).get(), e.inletNodeName); ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentOutletNodeName).get(), e.outletNodeName); + + WorkspaceObject idf_plant_op = p_->getTarget(PlantLoopFields::PlantEquipmentOperationSchemeName).get(); + if (e.isSupply) { + // Should have created a Cooling Load one only + ASSERT_EQ(1u, idf_plant_op.extensibleGroups().size()); + auto w_eg = idf_plant_op.extensibleGroups()[0].cast(); + ASSERT_EQ("PlantEquipmentOperation:CoolingLoad", + w_eg.getString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType).get()); + + // Get the Operation Scheme + auto op_scheme_ = w_eg.getTarget(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName); + ASSERT_TRUE(op_scheme_); + + // Get the Plant Equipment List of this CoolingLoad scheme + // There should only be one Load Range + ASSERT_EQ(1u, op_scheme_->extensibleGroups().size()); + + // Load range 1 + w_eg = op_scheme_->extensibleGroups()[0].cast(); + auto peq_list_ = w_eg.getTarget(PlantEquipmentOperation_HeatingLoadExtensibleFields::RangeEquipmentListName); + ASSERT_TRUE(peq_list_); + + // Should have one equipment on it: CentralHeatPumpSystem + auto peqs = peq_list_->extensibleGroups(); + ASSERT_EQ(1u, peqs.size()); + ASSERT_EQ("Chiller:Electric:ASHRAE205", peqs.front().getString(PlantEquipmentListExtensibleFields::EquipmentObjectType).get()); + ASSERT_EQ(ch.nameString(), peqs.front().getString(PlantEquipmentListExtensibleFields::EquipmentName).get()); + + } else { + EXPECT_EQ(1u, idf_plant_op.extensibleGroups().size()); + } } } From c2e79256d703cf63fd2f566b5ad7340a4212af17 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 16 Sep 2022 18:02:16 +0200 Subject: [PATCH 16/24] Missed a field --- .../ForwardTranslateChillerElectricASHRAE205.cpp | 9 +++++++++ src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp index 3a2f320935..a777555ad1 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp @@ -175,6 +175,15 @@ namespace energyplus { idfObject.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, node_->nameString()); } + if (modelObject.isChilledWaterMaximumRequestedFlowRateAutosized()) { + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "AutoSize"); + } else { + // ChilledWater Maximum Requested Flow Rate: boost::optional + if (boost::optional _chilledWaterMaximumRequestedFlowRate = modelObject.chilledWaterMaximumRequestedFlowRate()) { + idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, _chilledWaterMaximumRequestedFlowRate.get()); + } + } + if (modelObject.isCondenserMaximumRequestedFlowRateAutosized()) { idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "AutoSize"); } else { diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index c4f4c82f1f..1eb9ac3328 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -173,7 +173,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { auto& woCh = woChs.front(); EXPECT_EQ(ch.nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::Name).get()); - EXPECT_EQ(representationFile->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); + EXPECT_EQ("A205ExampleChiller.RS0001.a205.cbor", woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); EXPECT_EQ("Cubic", woCh.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod).get()); EXPECT_EQ("AutoSize", woCh.getString(Chiller_Electric_ASHRAE205Fields::RatedCapacity).get()); EXPECT_EQ(1.1, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor).get()); From 7de096e1cca14a84539b729ba0b57dbb7df31348 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 10:02:17 +0200 Subject: [PATCH 17/24] Wrap up FT testing --- .../Test/ChillerElectricASHRAE205_GTest.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index 1eb9ac3328..f3e28f926e 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -146,7 +146,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { EXPECT_TRUE(ch.setOilCoolerDesignFlowRate(0.001)); auto auxLoop = createLoop("auxLoop"); - EXPECT_TRUE(ch.addDemandBranchOnAuxiliaryLoop(ocLoop)); + EXPECT_TRUE(ch.addDemandBranchOnAuxiliaryLoop(auxLoop)); EXPECT_TRUE(ch.setAuxiliaryCoolingDesignFlowRate(0.002)); auto hrLoop = createLoop("hrLoop"); @@ -242,14 +242,15 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { unsigned index = e.isSupply ? PlantLoopFields::PlantSideBranchListName : PlantLoopFields::DemandSideBranchListName; WorkspaceObject idf_brlist = idf_plant.getTarget(index).get(); - // Should have three branches: supply inlet, the one with the centralHP, supply outlet - ASSERT_EQ(3u, idf_brlist.extensibleGroups().size()); + // Should have at least three branches: supply inlet, the one with the Chiller, supply outlet. + // On the demand side, there's also a bypass branch that is added by the FT by default + ASSERT_EQ(e.isSupply ? 3 : 4, idf_brlist.extensibleGroups().size()) << "Failed for " << e.plantName; // Get the Chiller one auto w_eg = idf_brlist.extensibleGroups()[1].cast(); WorkspaceObject idf_branch = w_eg.getTarget(BranchListExtensibleFields::BranchName).get(); // There should be only one equipment on the branch - ASSERT_EQ(1u, idf_branch.extensibleGroups().size()); + ASSERT_EQ(1, idf_branch.extensibleGroups().size()); auto w_eg2 = idf_branch.extensibleGroups()[0].cast(); ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(), ch.nameString()); @@ -259,7 +260,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { WorkspaceObject idf_plant_op = p_->getTarget(PlantLoopFields::PlantEquipmentOperationSchemeName).get(); if (e.isSupply) { // Should have created a Cooling Load one only - ASSERT_EQ(1u, idf_plant_op.extensibleGroups().size()); + ASSERT_EQ(1, idf_plant_op.extensibleGroups().size()); auto w_eg = idf_plant_op.extensibleGroups()[0].cast(); ASSERT_EQ("PlantEquipmentOperation:CoolingLoad", w_eg.getString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType).get()); @@ -279,12 +280,12 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { // Should have one equipment on it: CentralHeatPumpSystem auto peqs = peq_list_->extensibleGroups(); - ASSERT_EQ(1u, peqs.size()); + ASSERT_EQ(1, peqs.size()); ASSERT_EQ("Chiller:Electric:ASHRAE205", peqs.front().getString(PlantEquipmentListExtensibleFields::EquipmentObjectType).get()); ASSERT_EQ(ch.nameString(), peqs.front().getString(PlantEquipmentListExtensibleFields::EquipmentName).get()); } else { - EXPECT_EQ(1u, idf_plant_op.extensibleGroups().size()); + EXPECT_EQ(0, idf_plant_op.extensibleGroups().size()); } } } From bc3e48e03069a40b93246eedbabab4c54b3302c5 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 11:16:13 +0200 Subject: [PATCH 18/24] Write a RT test and fix RT: when a Zone is RT'ed, a Space is returned not a ThermalZone --- ...verseTranslateChillerElectricASHRAE205.cpp | 21 +++-- .../Test/ChillerElectricASHRAE205_GTest.cpp | 94 +++++++++++++++++++ 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp index cedf25ab07..cc17074003 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateChillerElectricASHRAE205.cpp @@ -36,6 +36,8 @@ #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../model/ExternalFile.hpp" @@ -67,10 +69,6 @@ namespace energyplus { openstudio::model::ChillerElectricASHRAE205 modelObject(extfile.get()); - // TODO: Note JM 2018-10-17 - // You are responsible for implementing any additional logic based on choice fields, etc. - // The ReverseTranslator generator script is meant to facilitate your work, not get you 100% of the way - // Name if (boost::optional _name = workspaceObject.name()) { modelObject.setName(_name.get()); @@ -106,20 +104,25 @@ namespace energyplus { } } else { LOG(Warn, workspaceObject.briefDescription() - << " has an Ambient Temperature Indicator of type Schedule, but no Schedule. Falling back to 'Outdoors'"); + << " has an Ambient Temperature Indicator of type 'Schedule', but no Schedule assigned. Falling back to 'Outdoors'"); } } else if (openstudio::istringEqual("Zone", ambientTemperatureIndicator_.get())) { // Ambient Temperature Zone Name: Optional Object if (auto wo_z_ = workspaceObject.getTarget(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName)) { - if (auto mo_z_ = translateAndMapWorkspaceObject(wo_z_.get())) { - // TODO: check return types - if (boost::optional z_ = mo_z_->optionalCast()) { - modelObject.setAmbientTemperatureZone(z_.get()); + if (auto mo_ = translateAndMapWorkspaceObject(wo_z_.get())) { + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo_->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + modelObject.setAmbientTemperatureZone(z_.get()); + } } else { LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Ambient Temperature Zone Name'"); } } + } else { + LOG(Warn, workspaceObject.briefDescription() + << " has an Ambient Temperature Indicator of type 'Zone', but no Zone assigned. Falling back to 'Outdoors'"); } } else { // Ambient Temperature Outdoor Air Node Name: Optional Node diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index f3e28f926e..bc6556b784 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -299,3 +299,97 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { EXPECT_EQ(0, w.getObjectsByType(IddObjectType::Chiller_Electric_ASHRAE205).size()); } } + +TEST_F(EnergyPlusFixture, ReverseTranslator_ChillerElectricASHRAE205) { + + ReverseTranslator rt; + + Workspace w(StrictnessLevel::Minimal, IddFileType::EnergyPlus); + + auto wo_zone = w.addObject(IdfObject(IddObjectType::Zone)).get(); + wo_zone.setName("Basement"); + + auto woCh = w.addObject(IdfObject(IddObjectType::Chiller_Electric_ASHRAE205)).get(); + woCh.setName("Chiller ASHRAE205"); + + openstudio::path p = resourcesPath() / toPath("model/A205ExampleChiller.RS0001.a205.cbor"); + EXPECT_TRUE(exists(p)); + + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, openstudio::toString(p))); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, "Cubic")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "")); // Defaults to AutoSize + EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor, 1.1)); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, "Zone")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, "")); + EXPECT_TRUE(woCh.setPointer(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureZoneName, wo_zone.handle())); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureOutdoorAirNodeName, "")); + EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, 0.0428)); + EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, 0.0552)); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::ChillerFlowMode, "ConstantFlow")); + EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::OilCoolerDesignFlowRate, 0.001)); + EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::AuxiliaryCoolingDesignFlowRate, 0.002)); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::EndUseSubcategory, "Chiller")); + + // Nodes not RT'ed + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName, "ChilledWater Inlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName, "ChilledWater Outlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName, "Condenser Inlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName, "Condenser Outlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName, "OilCooler Inlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName, "OilCooler Outlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName, "Auxiliary Inlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName, "Auxiliary Outlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName, "HeatRecovery Inlet Node")); + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName, "HeatRecovery Outlet Node")); + + Model m = rt.translateWorkspace(w); + + auto chs = m.getConcreteModelObjects(); + ASSERT_EQ(1, chs.size()); + auto& ch = chs.front(); + + ASSERT_TRUE(ch.name()); + EXPECT_EQ("Chiller ASHRAE205", ch.nameString()); + EXPECT_EQ("A205ExampleChiller.RS0001.a205.cbor", ch.representationFile().fileName()); + EXPECT_EQ("Cubic", ch.performanceInterpolationMethod()); + EXPECT_TRUE(ch.isRatedCapacityAutosized()); + EXPECT_EQ(1.1, ch.sizingFactor()); + EXPECT_EQ("Zone", ch.ambientTemperatureIndicator()); + EXPECT_FALSE(ch.ambientTemperatureSchedule()); + ASSERT_TRUE(ch.ambientTemperatureZone()); + EXPECT_EQ("Basement", ch.ambientTemperatureZone()->nameString()); + EXPECT_FALSE(ch.ambientTemperatureOutdoorAirNodeName()); + + EXPECT_FALSE(ch.isChilledWaterMaximumRequestedFlowRateAutosized()); + ASSERT_TRUE(ch.chilledWaterMaximumRequestedFlowRate()); + EXPECT_EQ(0.0428, ch.chilledWaterMaximumRequestedFlowRate().get()); + + EXPECT_FALSE(ch.isCondenserMaximumRequestedFlowRateAutosized()); + ASSERT_TRUE(ch.condenserMaximumRequestedFlowRate()); + EXPECT_EQ(0.0552, ch.condenserMaximumRequestedFlowRate().get()); + + EXPECT_EQ("ConstantFlow", ch.chillerFlowMode()); + + ASSERT_TRUE(ch.oilCoolerDesignFlowRate()); + EXPECT_EQ(0.001, ch.oilCoolerDesignFlowRate().get()); + ASSERT_TRUE(ch.auxiliaryCoolingDesignFlowRate()); + EXPECT_EQ(0.002, ch.auxiliaryCoolingDesignFlowRate().get()); + + EXPECT_EQ("Chiller", ch.endUseSubcategory()); + + EXPECT_FALSE(ch.chilledWaterLoop()); + EXPECT_FALSE(ch.condenserWaterLoop()); + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.oilCoolerLoop()); + EXPECT_FALSE(ch.auxiliaryLoop()); + EXPECT_FALSE(ch.chilledWaterInletNode()); + EXPECT_FALSE(ch.chilledWaterOutletNode()); + EXPECT_FALSE(ch.condenserInletNode()); + EXPECT_FALSE(ch.condenserOutletNode()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + EXPECT_FALSE(ch.oilCoolerInletNode()); + EXPECT_FALSE(ch.oilCoolerOutletNode()); + EXPECT_FALSE(ch.auxiliaryInletNode()); + EXPECT_FALSE(ch.auxiliaryOutletNode()); +} From 6d1b68ef74b0e7d44b2f77b846dcb094de97319b Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 11:02:54 +0200 Subject: [PATCH 19/24] Caught a few of the same issue in existing RTs: when a Zone is trnaslated, a Space is returned not a ThermalZone! --- .../ReverseTranslateCoilCoolingDX.cpp | 14 ++++-- ...lateElectricLoadCenterStorageConverter.cpp | 16 ++++--- ...ectricLoadCenterStorageLiIonNMCBattery.cpp | 12 ++++-- ...anslateElectricLoadCenterStorageSimple.cpp | 17 +++++--- .../ReverseTranslateFanSystemModel.cpp | 10 ++++- .../ReverseTranslateRefrigerationCase.cpp | 15 +++++-- .../ReverseTranslateZoneCrossMixing.cpp | 23 +++++++--- .../ReverseTranslateZoneMixing.cpp | 43 +++++++++++++------ 8 files changed, 107 insertions(+), 43 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateCoilCoolingDX.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateCoilCoolingDX.cpp index 1c37e6a1ed..76a4b06920 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateCoilCoolingDX.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateCoilCoolingDX.cpp @@ -38,6 +38,8 @@ #include "../../model/Schedule_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../model/CoilCoolingDXCurveFitPerformance.hpp" #include "../../model/CoilCoolingDXCurveFitPerformance_Impl.hpp" @@ -90,10 +92,14 @@ namespace energyplus { } if ((target = workspaceObject.getTarget(openstudio::Coil_Cooling_DXFields::CondenserZoneName))) { - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject) { - if (auto optZ = modelObject->optionalCast()) { - dx.setCondenserZone(optZ.get()); + if (auto mo_ = translateAndMapWorkspaceObject(*target)) { + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo_->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + dx.setCondenserZone(z_.get()); + } + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Condenser Zone Name'"); } } } diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageConverter.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageConverter.cpp index 190d87fb17..6aa2e3c63f 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageConverter.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageConverter.cpp @@ -36,6 +36,8 @@ #include "../../model/Schedule_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../model/Curve.hpp" #include "../../model/Curve_Impl.hpp" @@ -53,7 +55,7 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateElectricLoadCenterStorageConverter(const WorkspaceObject& workspaceObject) { - OptionalModelObject result, omo; + OptionalModelObject omo; OptionalDouble optD; boost::optional owo; OptionalString optS; @@ -116,9 +118,12 @@ namespace energyplus { // ZoneName if ((owo = workspaceObject.getTarget(ElectricLoadCenter_Storage_ConverterFields::ZoneName))) { - if ((omo = translateAndMapWorkspaceObject(owo.get()))) { - if (boost::optional thermalZone = omo->optionalCast()) { - elcConv.setThermalZone(thermalZone.get()); + if (boost::optional mo = translateAndMapWorkspaceObject(owo.get())) { + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + elcConv.setThermalZone(z_.get()); + } } } } @@ -129,8 +134,7 @@ namespace energyplus { elcConv.setRadiativeFraction(*optD); } - result = elcConv; - return result; + return elcConv; } } // namespace energyplus diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageLiIonNMCBattery.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageLiIonNMCBattery.cpp index cc449caa71..33a399ee4b 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageLiIonNMCBattery.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageLiIonNMCBattery.cpp @@ -36,6 +36,8 @@ #include "../../model/Schedule_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include @@ -50,7 +52,6 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateElectricLoadCenterStorageLiIonNMCBattery(const WorkspaceObject& workspaceObject) { - OptionalModelObject result, temp; OptionalDouble d; boost::optional owo; OptionalString optS; @@ -105,8 +106,11 @@ namespace energyplus { // ZoneName if ((owo = workspaceObject.getTarget(ElectricLoadCenter_Storage_LiIonNMCBatteryFields::ZoneName))) { if (boost::optional mo = translateAndMapWorkspaceObject(owo.get())) { - if (boost::optional thermalZone = mo->optionalCast()) { - elcStorLiIonNMCBattery.setThermalZone(thermalZone.get()); + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + elcStorLiIonNMCBattery.setThermalZone(z_.get()); + } } } } @@ -201,7 +205,7 @@ namespace energyplus { elcStorLiIonNMCBattery.setBatteryCellInternalElectricalResistance(*d); } - return result; + return elcStorLiIonNMCBattery; } } // namespace energyplus diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp index eedf6bd632..81ae5ca5b4 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp @@ -36,6 +36,8 @@ #include "../../model/Schedule_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include @@ -50,7 +52,6 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateElectricLoadCenterStorageSimple(const WorkspaceObject& workspaceObject) { - OptionalModelObject result, temp; OptionalDouble d; boost::optional owo; OptionalString optS; @@ -74,9 +75,14 @@ namespace energyplus { // ZoneName if ((owo = workspaceObject.getTarget(ElectricLoadCenter_Storage_SimpleFields::ZoneName))) { - if (boost::optional mo = translateAndMapWorkspaceObject(owo.get())) { - if (boost::optional thermalZone = mo->optionalCast()) { - elcStorSimple.setThermalZone(thermalZone.get()); + if (boost::optional mo_ = translateAndMapWorkspaceObject(owo.get())) { + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo_->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + elcStorSimple.setThermalZone(z_.get()); + } + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Zone Name'"); } } } @@ -129,8 +135,7 @@ namespace energyplus { elcStorSimple.setInitialStateofCharge(*d); } - result = elcStorSimple; - return result; + return elcStorSimple; } } // namespace energyplus diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateFanSystemModel.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateFanSystemModel.cpp index 9116a155ba..011fc6937b 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateFanSystemModel.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateFanSystemModel.cpp @@ -39,6 +39,8 @@ #include "../../model/Curve_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../utilities/idf/IdfExtensibleGroup.hpp" @@ -170,13 +172,17 @@ namespace energyplus { // Motor Loss Zone Name: Optional Object if ((_wo = workspaceObject.getTarget(Fan_SystemModelFields::MotorLossZoneName))) { if ((_mo = translateAndMapWorkspaceObject(_wo.get()))) { - if (boost::optional _motorLossZone = _mo->optionalCast()) { - modelObject.setMotorLossZone(_motorLossZone.get()); + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = _mo->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + modelObject.setMotorLossZone(z_.get()); + } } else { LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Motor Loss Zone Name'"); } } } + // Motor Loss Radiative Fraction: Optional Double if (boost::optional _motorLossRadiativeFraction = workspaceObject.getDouble(Fan_SystemModelFields::MotorLossRadiativeFraction)) { modelObject.setMotorLossRadiativeFraction(_motorLossRadiativeFraction.get()); diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateRefrigerationCase.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateRefrigerationCase.cpp index 30856e8a33..bb94d8ffea 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateRefrigerationCase.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateRefrigerationCase.cpp @@ -36,6 +36,9 @@ #include "../../model/ThermalZone_Impl.hpp" #include "../../model/CurveCubic.hpp" #include "../../model/CurveCubic_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" + #include #include "../../utilities/idd/IddEnums.hpp" #include @@ -88,12 +91,18 @@ namespace energyplus { } // ZoneName if ((wo = workspaceObject.getTarget(Refrigeration_CaseFields::ZoneName))) { - if (boost::optional mo = translateAndMapWorkspaceObject(wo.get())) { - if (boost::optional thermalZone = mo->optionalCast()) { - refrigerationCase->setThermalZone(thermalZone.get()); + if (boost::optional mo_ = translateAndMapWorkspaceObject(wo.get())) { + // Zone is translated, and a Space is returned instead + if (boost::optional space_ = mo_->optionalCast()) { + if (auto z_ = space_->thermalZone()) { + refrigerationCase->setThermalZone(z_.get()); + } + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Zone Name'"); } } } + // RatedAmbientTemperature value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedAmbientTemperature); if (value) { diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateZoneCrossMixing.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateZoneCrossMixing.cpp index a1ffe2e8ea..49e88815ab 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateZoneCrossMixing.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateZoneCrossMixing.cpp @@ -33,6 +33,8 @@ #include "../../model/ZoneMixing_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../model/Schedule.hpp" #include "../../model/Schedule_Impl.hpp" @@ -57,9 +59,15 @@ namespace energyplus { OptionalWorkspaceObject target = workspaceObject.getTarget(openstudio::ZoneCrossMixingFields::ZoneorSpaceName); OptionalThermalZone zone; if (target) { - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject) { - zone = modelObject->optionalCast(); + if (OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target)) { + if (target->iddObject().type() == IddObjectType::Zone) { + // Zone maps to Space in RT + if (auto s_ = modelObject->optionalCast()) { + zone = s_->thermalZone(); + } + } else { + // It's a space, but we don't allow mapping to a space in model SDK for now, and we don't have a Space RT... so we'll never get here + } } } @@ -71,8 +79,13 @@ namespace energyplus { OptionalThermalZone sourceZone; if (target) { OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject) { - sourceZone = modelObject->optionalCast(); + if (target->iddObject().type() == IddObjectType::Zone) { + // Zone maps to Space in RT + if (auto s_ = modelObject->optionalCast()) { + sourceZone = s_->thermalZone(); + } + } else { + // It's a space, but we don't allow mapping to a space in model SDK for now, and we don't have a Space RT... so we'll never get here } } diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateZoneMixing.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateZoneMixing.cpp index d2c47866e9..94467e6a71 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateZoneMixing.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateZoneMixing.cpp @@ -33,6 +33,8 @@ #include "../../model/ZoneMixing_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" #include "../../model/Schedule.hpp" #include "../../model/Schedule_Impl.hpp" @@ -57,9 +59,15 @@ namespace energyplus { OptionalWorkspaceObject target = workspaceObject.getTarget(openstudio::ZoneMixingFields::ZoneorSpaceName); OptionalThermalZone zone; if (target) { - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject) { - zone = modelObject->optionalCast(); + if (OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target)) { + if (target->iddObject().type() == IddObjectType::Zone) { + // Zone maps to Space in RT + if (auto s_ = modelObject->optionalCast()) { + zone = s_->thermalZone(); + } + } else { + // It's a space, but we don't allow mapping to a space in model SDK for now, and we don't have a Space RT... so we'll never get here + } } } @@ -67,7 +75,26 @@ namespace energyplus { return boost::none; } + target = workspaceObject.getTarget(openstudio::ZoneMixingFields::SourceZoneorSpaceName); + OptionalThermalZone sourceZone; + if (target) { + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (target->iddObject().type() == IddObjectType::Zone) { + // Zone maps to Space in RT + if (auto s_ = modelObject->optionalCast()) { + sourceZone = s_->thermalZone(); + } + } else { + // It's a space, but we don't allow mapping to a space in model SDK for now, and we don't have a Space RT... so we'll never get here + } + } + + if (!sourceZone) { + return boost::none; + } + openstudio::model::ZoneMixing mixing(*zone); + mixing.setSourceZone(sourceZone.get()); OptionalString s = workspaceObject.name(); if (s) { @@ -120,16 +147,6 @@ namespace energyplus { LOG(Error, "Unknown DesignFlowRateCalculationMethod value for workspace object" << workspaceObject); } - target = workspaceObject.getTarget(openstudio::ZoneMixingFields::SourceZoneorSpaceName); - if (target) { - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject) { - if (modelObject->optionalCast()) { - mixing.setSourceZone(modelObject->cast()); - } - } - } - d = workspaceObject.getDouble(openstudio::ZoneMixingFields::DeltaTemperature); if (d) { mixing.setDeltaTemperature(*d); From 2de0acbbf6cb38dd72dcf47326defdfea24e2112 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 11:33:35 +0200 Subject: [PATCH 20/24] Clarify why I'm not allowing ChillerElectricASRHAE205 to be present TWICE on the same branch --- src/model/ChillerElectricASHRAE205.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 3632dc8d94..cdfd79d85c 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -678,7 +678,11 @@ namespace model { bool ChillerElectricASHRAE205_Impl::addToOilCoolerLoopNode(Node& node) { + // One of the example files actually has the Oil Coiler and Auxiliary nodes in series on the same branch... + // But this would require a bunch of changes to allow a component to be twice on the same branch, so I'm not allowing it if (node.getImpl()->isConnected(getObject())) { + // if ((oilCoolerInletNode() && (node.handle() == oilCoolerInletNode()->handle())) + // || (oilCoolerOutletNode() && (node.handle() == oilCoolerOutletNode()->handle()))) { return false; } @@ -790,7 +794,11 @@ namespace model { bool ChillerElectricASHRAE205_Impl::addToAuxiliaryLoopNode(Node& node) { + // One of the example files actually has the Oil Coiler and Auxiliary nodes in series on the same branch... + // But this would require a bunch of changes to allow a component to be twice on the same branch, so I'm not allowing it if (node.getImpl()->isConnected(getObject())) { + // if ((auxiliaryInletNode() && (node.handle() == auxiliaryInletNode()->handle())) + // || (auxiliaryOutletNode() && (node.handle() == auxiliaryOutletNode()->handle()))) { return false; } From 0cb44c78a7b98d98e0c26f167b0b23f523cc86cf Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 11:47:29 +0200 Subject: [PATCH 21/24] Openstudio-resources reg tests showed that I must write a full path to the representation filename --- .../ForwardTranslateChillerElectricASHRAE205.cpp | 2 +- src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp index a777555ad1..77ebd9487a 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp @@ -69,7 +69,7 @@ namespace energyplus { IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Chiller_Electric_ASHRAE205, modelObject); // Representation File Name: Required String - idfObject.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, openstudio::toString(filePath.filename())); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, openstudio::toString(filePath)); // Performance Interpolation Method std::string performanceInterpolationMethod = modelObject.performanceInterpolationMethod(); diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index bc6556b784..5ab8a09793 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -173,7 +173,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { auto& woCh = woChs.front(); EXPECT_EQ(ch.nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::Name).get()); - EXPECT_EQ("A205ExampleChiller.RS0001.a205.cbor", woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); + EXPECT_EQ(representationFile->filePath(), woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); EXPECT_EQ("Cubic", woCh.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod).get()); EXPECT_EQ("AutoSize", woCh.getString(Chiller_Electric_ASHRAE205Fields::RatedCapacity).get()); EXPECT_EQ(1.1, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor).get()); From 1679b2f15529c6750fd6ea84aaea35a481607e58 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 12:22:29 +0200 Subject: [PATCH 22/24] Cosmetic AutoSize > Autosize --- .../ForwardTranslateChillerElectricASHRAE205.cpp | 6 +++--- .../Test/ChillerElectricASHRAE205_GTest.cpp | 4 ++-- src/model/ChillerElectricASHRAE205.cpp | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp index 77ebd9487a..aedd456216 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateChillerElectricASHRAE205.cpp @@ -76,7 +76,7 @@ namespace energyplus { idfObject.setString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, performanceInterpolationMethod); if (modelObject.isRatedCapacityAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "AutoSize"); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "Autosize"); } else { idfObject.setDouble(Chiller_Electric_ASHRAE205Fields::RatedCapacity, modelObject.ratedCapacity().get()); } @@ -176,7 +176,7 @@ namespace energyplus { } if (modelObject.isChilledWaterMaximumRequestedFlowRateAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "AutoSize"); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "Autosize"); } else { // ChilledWater Maximum Requested Flow Rate: boost::optional if (boost::optional _chilledWaterMaximumRequestedFlowRate = modelObject.chilledWaterMaximumRequestedFlowRate()) { @@ -185,7 +185,7 @@ namespace energyplus { } if (modelObject.isCondenserMaximumRequestedFlowRateAutosized()) { - idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "AutoSize"); + idfObject.setString(Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "Autosize"); } else { // Condenser Maximum Requested Flow Rate: boost::optional if (boost::optional _condenserMaximumRequestedFlowRate = modelObject.condenserMaximumRequestedFlowRate()) { diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index 5ab8a09793..a9ebe55a61 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -175,7 +175,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { EXPECT_EQ(ch.nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::Name).get()); EXPECT_EQ(representationFile->filePath(), woCh.getString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName).get()); EXPECT_EQ("Cubic", woCh.getString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod).get()); - EXPECT_EQ("AutoSize", woCh.getString(Chiller_Electric_ASHRAE205Fields::RatedCapacity).get()); + EXPECT_EQ("Autosize", woCh.getString(Chiller_Electric_ASHRAE205Fields::RatedCapacity).get()); EXPECT_EQ(1.1, woCh.getDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor).get()); EXPECT_EQ("Zone", woCh.getString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator).get()); @@ -317,7 +317,7 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ChillerElectricASHRAE205) { EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::RepresentationFileName, openstudio::toString(p))); EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::PerformanceInterpolationMethod, "Cubic")); - EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "")); // Defaults to AutoSize + EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::RatedCapacity, "")); // Defaults to Autosize EXPECT_TRUE(woCh.setDouble(Chiller_Electric_ASHRAE205Fields::SizingFactor, 1.1)); EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureIndicator, "Zone")); EXPECT_TRUE(woCh.setString(Chiller_Electric_ASHRAE205Fields::AmbientTemperatureScheduleName, "")); diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index cdfd79d85c..1c503ef820 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -151,7 +151,7 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, true); if (value) { - result = openstudio::istringEqual(value.get(), "AutoSize"); + result = openstudio::istringEqual(value.get(), "Autosize"); } return result; } @@ -162,7 +162,7 @@ namespace model { } void ChillerElectricASHRAE205_Impl::autosizeRatedCapacity() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, "AutoSize"); + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::RatedCapacity, "Autosize"); OS_ASSERT(result); } @@ -259,7 +259,7 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, true); if (value) { - result = openstudio::istringEqual(value.get(), "AutoSize"); + result = openstudio::istringEqual(value.get(), "Autosize"); } return result; } @@ -270,7 +270,7 @@ namespace model { } void ChillerElectricASHRAE205_Impl::autosizeChilledWaterMaximumRequestedFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "AutoSize"); + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::ChilledWaterMaximumRequestedFlowRate, "Autosize"); OS_ASSERT(result); } @@ -282,7 +282,7 @@ namespace model { bool result = false; boost::optional value = getString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, true); if (value) { - result = openstudio::istringEqual(value.get(), "AutoSize"); + result = openstudio::istringEqual(value.get(), "Autosize"); } return result; } @@ -293,7 +293,7 @@ namespace model { } void ChillerElectricASHRAE205_Impl::autosizeCondenserMaximumRequestedFlowRate() { - bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "AutoSize"); + bool result = setString(OS_Chiller_Electric_ASHRAE205Fields::CondenserMaximumRequestedFlowRate, "Autosize"); OS_ASSERT(result); } From 352b01f50f187a67ae77f2db9b73eb0c5f1eace1 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 13:59:12 +0200 Subject: [PATCH 23/24] OpenStudio-resources test showed that checking the loop isn't enough, we need to check by inlet node! --- .../ForwardTranslatePlantLoop.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp index c4aa14d46a..e2cd3bb2ee 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp @@ -154,6 +154,8 @@ namespace energyplus { if (modelObjects.size() > 0) { int i = 0; + boost::optional prevNode_; + for (auto& modelObject : modelObjects) { boost::optional inletNode; boost::optional outletNode; @@ -169,6 +171,7 @@ namespace energyplus { if (modelObject.optionalCast()) { // Skip nodes we don't want them showing up on branches + prevNode_ = modelObject.cast(); continue; } @@ -352,21 +355,25 @@ namespace energyplus { } } else if (auto ch = modelObject.optionalCast()) { - // This one has **FIVE** loops + // This one has **FIVE** loops and can be potentially several time on the same loop (demand side, eg: Condenser + Oil Cooler + Auxiliary) + + // Doing this: `if (ch->chilledWaterLoop() && loop.handle() == ch->chilledWaterLoop()->handle())` isn't enough because we could be on the + // same loop, so we rely on prevNode_ instead + OS_ASSERT(prevNode_); - if (ch->chilledWaterLoop() && loop.handle() == ch->chilledWaterLoop()->handle()) { + if (ch->chilledWaterInletNode() && ch->chilledWaterInletNode()->handle() == prevNode_->handle()) { inletNode = ch->chilledWaterInletNode(); outletNode = ch->chilledWaterOutletNode(); - } else if (ch->condenserWaterLoop() && loop.handle() == ch->condenserWaterLoop()->handle()) { + } else if (ch->condenserInletNode() && ch->condenserInletNode()->handle() == prevNode_->handle()) { inletNode = ch->condenserInletNode(); outletNode = ch->condenserOutletNode(); - } else if (ch->heatRecoveryLoop() && loop.handle() == ch->heatRecoveryLoop()->handle()) { + } else if (ch->heatRecoveryInletNode() && ch->heatRecoveryInletNode()->handle() == prevNode_->handle()) { inletNode = ch->heatRecoveryInletNode(); outletNode = ch->heatRecoveryOutletNode(); - } else if (ch->oilCoolerLoop() && loop.handle() == ch->oilCoolerLoop()->handle()) { + } else if (ch->oilCoolerInletNode() && ch->oilCoolerInletNode()->handle() == prevNode_->handle()) { inletNode = ch->oilCoolerInletNode(); outletNode = ch->oilCoolerOutletNode(); - } else if (ch->auxiliaryLoop() && loop.handle() == ch->auxiliaryLoop()->handle()) { + } else if (ch->auxiliaryInletNode() && ch->auxiliaryInletNode()->handle() == prevNode_->handle()) { inletNode = ch->auxiliaryInletNode(); outletNode = ch->auxiliaryOutletNode(); } From 121142875ddbd33252210c2b17fa7d294af16b80 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 19 Sep 2022 15:18:33 +0200 Subject: [PATCH 24/24] Disable Heat Recovery as it's 1) Not implemented in E+, 2) Make E+ Fatal cf https://github.com/NREL/EnergyPlus/issues/9662 --- .../Test/ChillerElectricASHRAE205_GTest.cpp | 47 +++++++----- src/model/ChillerElectricASHRAE205.cpp | 7 +- src/model/ChillerElectricASHRAE205.hpp | 3 + .../test/ChillerElectricASHRAE205_GTest.cpp | 71 ++++++++----------- 4 files changed, 67 insertions(+), 61 deletions(-) diff --git a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp index a9ebe55a61..a5d8772f98 100644 --- a/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/energyplus/Test/ChillerElectricASHRAE205_GTest.cpp @@ -149,22 +149,25 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { EXPECT_TRUE(ch.addDemandBranchOnAuxiliaryLoop(auxLoop)); EXPECT_TRUE(ch.setAuxiliaryCoolingDesignFlowRate(0.002)); - auto hrLoop = createLoop("hrLoop"); - EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch, true)); - EXPECT_TRUE(ch.setEndUseSubcategory("Chiller")); ch.chilledWaterInletNode()->setName("ChilledWater Inlet Node"); ch.chilledWaterOutletNode()->setName("ChilledWater Outlet Node"); ch.condenserInletNode()->setName("Condenser Inlet Node"); ch.condenserOutletNode()->setName("Condenser Outlet Node"); - ch.heatRecoveryInletNode()->setName("HeatRecovery Inlet Node"); - ch.heatRecoveryOutletNode()->setName("HeatRecovery Outlet Node"); + ch.oilCoolerInletNode()->setName("OilCooler Inlet Node"); ch.oilCoolerOutletNode()->setName("OilCooler Outlet Node"); ch.auxiliaryInletNode()->setName("Auxiliary Inlet Node"); ch.auxiliaryOutletNode()->setName("Auxiliary Outlet Node"); + if constexpr (ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + auto hrLoop = createLoop("hrLoop"); + EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch, true)); + ch.heatRecoveryInletNode()->setName("HeatRecovery Inlet Node"); + ch.heatRecoveryOutletNode()->setName("HeatRecovery Outlet Node"); + } + { Workspace w = ft.translateModel(m); @@ -197,26 +200,31 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { EXPECT_EQ("ChilledWater Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName).get()); EXPECT_EQ("ChilledWater Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName).get()); - EXPECT_EQ("Condenser Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName).get()); - EXPECT_EQ("Condenser Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName).get()); - EXPECT_EQ("HeatRecovery Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); - EXPECT_EQ("HeatRecovery Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); - EXPECT_EQ("OilCooler Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName).get()); - EXPECT_EQ("OilCooler Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName).get()); - EXPECT_EQ("Auxiliary Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName).get()); - EXPECT_EQ("Auxiliary Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName).get()); - EXPECT_EQ(ch.chilledWaterInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterInletNodeName).get()); EXPECT_EQ(ch.chilledWaterOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::ChilledWaterOutletNodeName).get()); + + EXPECT_EQ("Condenser Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName).get()); + EXPECT_EQ("Condenser Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName).get()); EXPECT_EQ(ch.condenserInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserInletNodeName).get()); EXPECT_EQ(ch.condenserOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::CondenserOutletNodeName).get()); - EXPECT_EQ(ch.heatRecoveryInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); - EXPECT_EQ(ch.heatRecoveryOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); + + EXPECT_EQ("OilCooler Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName).get()); + EXPECT_EQ("OilCooler Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName).get()); EXPECT_EQ(ch.oilCoolerInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerInletNodeName).get()); EXPECT_EQ(ch.oilCoolerOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::OilCoolerOutletNodeName).get()); + + EXPECT_EQ("Auxiliary Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName).get()); + EXPECT_EQ("Auxiliary Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName).get()); EXPECT_EQ(ch.auxiliaryInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryInletNodeName).get()); EXPECT_EQ(ch.auxiliaryOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::AuxiliaryOutletNodeName).get()); + if constexpr (ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + EXPECT_EQ("HeatRecovery Inlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); + EXPECT_EQ("HeatRecovery Outlet Node", woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); + EXPECT_EQ(ch.heatRecoveryInletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryInletNodeName).get()); + EXPECT_EQ(ch.heatRecoveryOutletNode()->nameString(), woCh.getString(Chiller_Electric_ASHRAE205Fields::HeatRecoveryOutletNodeName).get()); + } + // Check node names on supply/demand branches // Checks that the special case implemented in ForwardTranslatePlantLoop::populateBranch does the right job @@ -231,10 +239,15 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ChillerElectricASHRAE205) { std::vector expecteds = { {true, ch.chilledWaterLoop()->nameString(), ch.chilledWaterInletNode()->nameString(), ch.chilledWaterOutletNode()->nameString()}, {false, ch.condenserWaterLoop()->nameString(), ch.condenserInletNode()->nameString(), ch.condenserOutletNode()->nameString()}, - {false, ch.heatRecoveryLoop()->nameString(), ch.heatRecoveryInletNode()->nameString(), ch.heatRecoveryOutletNode()->nameString()}, {false, ch.oilCoolerLoop()->nameString(), ch.oilCoolerInletNode()->nameString(), ch.oilCoolerOutletNode()->nameString()}, {false, ch.auxiliaryLoop()->nameString(), ch.auxiliaryInletNode()->nameString(), ch.auxiliaryOutletNode()->nameString()}, }; + + if constexpr (ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + expecteds.emplace_back(false, ch.heatRecoveryLoop()->nameString(), ch.heatRecoveryInletNode()->nameString(), + ch.heatRecoveryOutletNode()->nameString()); + } + for (const auto& e : expecteds) { auto p_ = w.getObjectByTypeAndName(IddObjectType::PlantLoop, e.plantName); ASSERT_TRUE(p_.is_initialized()) << "Cannot find PlantLoop named " << e.plantName; diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp index 1c503ef820..18a33a96c4 100644 --- a/src/model/ChillerElectricASHRAE205.cpp +++ b/src/model/ChillerElectricASHRAE205.cpp @@ -476,7 +476,6 @@ namespace model { if (t_plantLoop.get() != cndLoop_.get()) { // And if there is no Heat Recovery (tertiary) if (!this->heatRecoveryLoop().is_initialized()) { - ; // Then try to add it to the tertiary one LOG(Warn, "Calling addToTertiaryNode to connect it to the tertiary (=Heat Recovery) loop for " << briefDescription()); return this->addToTertiaryNode(node); @@ -491,6 +490,12 @@ namespace model { } bool ChillerElectricASHRAE205_Impl::addToTertiaryNode(Node& node) { + + if constexpr (!ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + LOG(Warn, "For " << briefDescription() << ", Heat Recovery isn't implemented by EnergyPlus yet, so tertiary connection is disabled."); + return false; + } + auto t_plantLoop = node.plantLoop(); // Only accept adding to a node that is on a demand side of a plant loop diff --git a/src/model/ChillerElectricASHRAE205.hpp b/src/model/ChillerElectricASHRAE205.hpp index de7a069403..396f376c9d 100644 --- a/src/model/ChillerElectricASHRAE205.hpp +++ b/src/model/ChillerElectricASHRAE205.hpp @@ -59,6 +59,9 @@ namespace model { virtual ~ChillerElectricASHRAE205() = default; + // TODO: once supported by E+, re-enable + static constexpr bool isHeatRecoverySupportedByEnergyplus = false; + //@} static IddObjectType iddObjectType(); diff --git a/src/model/test/ChillerElectricASHRAE205_GTest.cpp b/src/model/test/ChillerElectricASHRAE205_GTest.cpp index 9817714b29..81b0fb768a 100644 --- a/src/model/test/ChillerElectricASHRAE205_GTest.cpp +++ b/src/model/test/ChillerElectricASHRAE205_GTest.cpp @@ -381,9 +381,29 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { EXPECT_FALSE(ch.auxiliaryOutletNode()); } + auto checkHeatRecoveryLoop = [&ch, &hrLoop]() { + if constexpr (ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + + ASSERT_TRUE(ch.heatRecoveryLoop()); + EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); + ASSERT_TRUE(ch.heatRecoveryInletNode()); + EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); + ASSERT_TRUE(ch.heatRecoveryOutletNode()); + EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + } else { + EXPECT_FALSE(ch.heatRecoveryLoop()); + EXPECT_FALSE(ch.heatRecoveryInletNode()); + EXPECT_FALSE(ch.heatRecoveryOutletNode()); + } + }; + // Heat Recovery { - EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch)); + if constexpr (ChillerElectricASHRAE205::isHeatRecoverySupportedByEnergyplus) { + EXPECT_TRUE(hrLoop.addDemandBranchForComponent(ch)); + } else { + EXPECT_FALSE(hrLoop.addDemandBranchForComponent(ch)); + } ASSERT_TRUE(ch.chilledWaterLoop()); ASSERT_EQ(chwLoop, ch.chilledWaterLoop().get()); @@ -399,12 +419,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); EXPECT_FALSE(ch.oilCoolerLoop()); EXPECT_FALSE(ch.oilCoolerInletNode()); @@ -441,12 +456,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); ASSERT_TRUE(ch.oilCoolerLoop()); EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); @@ -477,12 +487,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); EXPECT_FALSE(ch.oilCoolerLoop()); EXPECT_FALSE(ch.oilCoolerInletNode()); @@ -514,12 +519,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); ASSERT_TRUE(ch.oilCoolerLoop()); EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); @@ -563,12 +563,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); ASSERT_TRUE(ch.oilCoolerLoop()); EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); @@ -596,12 +591,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); ASSERT_TRUE(ch.oilCoolerLoop()); EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get()); @@ -639,12 +629,7 @@ TEST_F(ModelFixture, ChillerElectricASHRAE205_Loops) { ASSERT_TRUE(ch.condenserOutletNode()); EXPECT_EQ(ch.demandOutletModelObject()->handle(), ch.condenserOutletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryLoop()); - EXPECT_EQ(hrLoop, ch.heatRecoveryLoop().get()); - ASSERT_TRUE(ch.heatRecoveryInletNode()); - EXPECT_EQ(ch.tertiaryInletModelObject()->handle(), ch.heatRecoveryInletNode()->handle()); - ASSERT_TRUE(ch.heatRecoveryOutletNode()); - EXPECT_EQ(ch.tertiaryOutletModelObject()->handle(), ch.heatRecoveryOutletNode()->handle()); + checkHeatRecoveryLoop(); ASSERT_TRUE(ch.oilCoolerLoop()); EXPECT_EQ(ocLoop, ch.oilCoolerLoop().get());