diff --git a/resources/energyplus/ProposedEnergy+.idd b/resources/energyplus/ProposedEnergy+.idd index 168d825023..874f9a53d2 100644 --- a/resources/energyplus/ProposedEnergy+.idd +++ b/resources/energyplus/ProposedEnergy+.idd @@ -26360,7 +26360,7 @@ ZoneHVAC:Baseboard:RadiantConvective:Water:Design, A1, \field Name \required-field \type alpha - \reference RadiantDesignObject + \reference RadiantWaterDesignObject A2, \field Heating Design Capacity Method \type choice \key HeatingDesignCapacity @@ -26412,7 +26412,7 @@ ZoneHVAC:Baseboard:RadiantConvective:Water, A2, \field Design Object \required-field \type object-list - \object-list RadiantDesignObject + \object-list RadiantWaterDesignObject A3, \field Availability Schedule Name \note Availability schedule name for this system. Schedule value > 0 means the system is available. \note If this field is blank, the system is always available. @@ -26472,12 +26472,11 @@ ZoneHVAC:Baseboard:RadiantConvective:Water, ZoneHVAC:Baseboard:RadiantConvective:Steam:Design, \min-fields 7 - A1, \field Name + A1, \field Name \required-field - \reference-class-name validBranchEquipmentTypes - \reference validBranchEquipmentNames - \reference ZoneEquipmentNames - A2, \field Heating Design Capacity Method + \type alpha + \reference RadiantSteamDesignObject + A2, \field Heating Design Capacity Method \type choice \key HeatingDesignCapacity \key CapacityPerFloorArea @@ -26528,7 +26527,7 @@ ZoneHVAC:Baseboard:RadiantConvective:Steam, A2, \field Design Object \required-field \type object-list - \object-list RadiantDesignObject + \object-list RadiantSteamDesignObject A3, \field Availability Schedule Name \note Availability schedule name for this system. Schedule value > 0 means the system is available. \note If this field is blank, the system is always available. @@ -32576,6 +32575,7 @@ Coil:Heating:Steam, \required-field \type alpha \reference HeatingCoilName + \reference HeatingCoilsSteam \reference-class-name validBranchEquipmentTypes \reference validBranchEquipmentNames \reference-class-name validOASysEquipmentTypes @@ -39331,6 +39331,8 @@ AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed, \object-list HeatingCoilsDXMultiSpeed \object-list HeatingCoilsElectricMultiStage \object-list HeatingCoilsGasMultiStage + \object-list HeatingCoilsWater + \object-list HeatingCoilsSteam N1 , \field DX Heating Coil Sizing Ratio \type real \default 1.0 diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index ed654f503e..209ca5d20c 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -11323,6 +11323,8 @@ OS:AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed, \object-list HeatingCoilsElectricMultiStage \object-list HeatingCoilsGasMultiStage \object-list HeatingCoilsDXMultiSpeed + \object-list HeatingCoilsWater + \object-list HeatingCoilsSteam N1, \field DX Heating Coil Sizing Ratio \type real \required-field @@ -21391,6 +21393,66 @@ OS:Coil:Heating:Water, \minimum> 0 \default 0.5 +OS:Coil:Heating:Steam, + \memo Steam heating coil. Condenses and sub-cools steam at loop pressure and discharges + \memo condensate through steam traps to low pressure condensate line. + A1, \field Handle + \type handle + \required-field + A2, \field Name + \type alpha + \required-field + \reference HeatingCoilName + \reference HeatingCoilsSteam + \reference ConnectionObject + A3, \field Availability Schedule Name + \type object-list + \object-list ScheduleNames + \required-field + N1, \field Maximum Steam Flow Rate + \type real + \autosizable + \units m3/s + \ip-units gal/min + \required-field + N2, \field Degree of SubCooling + \units C + \minimum 1.0 + \maximum 5.0 + \required-field + N3, \field Degree of Loop SubCooling + \units C + \minimum 10.0 + \required-field + A4, \field Water Inlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + A5, \field Water Outlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + A6, \field Air Inlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + A7, \field Air Outlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + A8, \field Coil Control Type + \note Use ZoneLoadControl if the coil is contained within another component such as an air + \note terminal unit, zone HVAC equipment, or unitary system. Use TemperatureSetpointControl + \note if the coil is located directly in an air loop branch or outdoor air equipment list. + \type choice + \key TemperatureSetpointControl + \key ZoneLoadControl + \required-field + A9; \field Temperature Setpoint Node Name + \type object-list + \note Required if Coil Control Type is TemperatureSetpointControl + \object-list Node + OS:Coil:Heating:Water:Baseboard, A1, \field Handle \type handle @@ -21464,7 +21526,7 @@ OS:Coil:Heating:Water:Baseboard:Radiant, A2, \field Name \type alpha \required-field - \reference RadiantBaseboardHeatingCoil + \reference RadiantBaseboardHeatingCoilWater \reference ConnectionObject A3, \field Inlet Node Name \required-field @@ -21519,6 +21581,61 @@ OS:Coil:Heating:Water:Baseboard:Radiant, \type real \minimum> 0.0 +OS:Coil:Heating:Steam:Baseboard:Radiant, + A1, \field Handle + \type handle + \required-field + A2, \field Name + \type alpha + \required-field + \reference RadiantBaseboardHeatingCoilSteam + \reference ConnectionObject + A3, \field Inlet Node Name + \required-field + \type object-list + \object-list ConnectionNames + A4, \field Outlet Node Name + \required-field + \type object-list + \object-list ConnectionNames + A5, \field Heating Design Capacity Method + \required-field + \type choice + \key HeatingDesignCapacity + \key CapacityPerFloorArea + \key FractionOfAutosizedHeatingCapacity + N1, \field Heating Design Capacity + \required-field + \type real + \units W + \minimum 0.0 + \autosizable + \ip-units W + N2, \field Heating Design Capacity Per Floor Area + \required-field + \type real + \units W/m2 + \minimum 0.0 + N3, \field Fraction of Autosized Heating Design Capacity + \required-field + \type real + \minimum 0.0 + N4, \field Degree of SubCooling + \type real + \minimum 1.0 + \required-field + \units deltaC + N5, \field Maximum Steam Flow Rate + \required-field + \autosizable + \type real + \units m3/s + \ip-units gal/min + N6; \field Convergence Tolerance + \required-field + \type real + \minimum> 0.0 + OS:Coil:Heating:WaterToAirHeatPump:EquationFit, \memo Direct expansion (DX) heating coil for water-to-air heat pump (includes electric \memo compressor), single-speed, equation-fit model. Equation-fit model uses normalized @@ -27332,6 +27449,112 @@ OS:Pump:VariableSpeed, \retaincase \default General +OS:Pump:VariableSpeed:Condensate, + \memo This pump model is described in the ASHRAE secondary HVAC toolkit. + \memo Variable Speed Condensate pump for Steam Systems + A1, \field Handle + \type handle + \required-field + A2, \field Name + \type alpha + \required-field + \reference ConnectionObject + A3, \field Inlet Node Name + \required-field + \type object-list + \object-list ConnectionNames + A4, \field Outlet Node Name + \required-field + \type object-list + \object-list ConnectionNames + N1, \field Rated Steam Volume Flow Rate + \note this is the volume of steam before condensation, the volume of condensate is much lower and calculated from steam density + \units m3/s + \autosizable + \ip-units gal/min + \minimum> 0 + \required-field + N2, \field Rated Pump Head + \units Pa + \required-field + \note default head is 60 feet + \ip-units ftH2O + N3, \field Rated Power Consumption + \note When autosized the type of scaling factor is chosen in the input field Design Power Sizing Method + \units W + \autosizable + \ip-units W + \required-field + N4 , \field Motor Efficiency + \note This is the motor efficiency only. When the Design Power Consumption is autosized using PowerPerFlowPerPressure, + \note the Design Shaft Power per Unit Flow Rate per Unit Head is used in addition to the motor efficiency. + \type real + \minimum> 0.0 + \maximum 1.0 + \required-field + N5, \field Fraction of Motor Inefficiencies to Fluid Stream + \minimum 0.0 + \maximum 1.0 + \required-field + N6, \field Coefficient 1 of the Part Load Performance Curve + \type real + \required-field + N7, \field Coefficient 2 of the Part Load Performance Curve + \type real + \required-field + N8, \field Coefficient 3 of the Part Load Performance Curve + \type real + \required-field + N9, \field Coefficient 4 of the Part Load Performance Curve + \type real + \required-field + A5, \field Pump Flow Rate Schedule Name + \note Modifies the rated flow rate of the pump on a time basis. Default is + \note that the pump is on and runs according to its other operational requirements + \note specified above. The schedule is for special pump operations. + \type object-list + \object-list ScheduleNames + A6, \field Zone Name + \note optional, if used pump losses transferred to zone as internal gains + \type object-list + \object-list ThermalZoneNames + N10, \field Skin Loss Radiative Fraction + \required-field + \note optional. If zone identified in previous field then this determines + \note the split between convection and radiation for the skin losses + \type real + \minimum 0.0 + \maximum 1.0 + A7, \field Design Power Sizing Method + \note Used to indicate which sizing factor is used to calculate Design Power Consumption. + \type choice + \key PowerPerFlow + \note PowerPerFlow indicates that Design Electric Power per Unit Flow Rate is used as scaling factor. + \note Design Power Consumption = Design Maximum Flow Rate * scaling factor + \key PowerPerFlowPerPressure + \note PowerPerFlowPerPressure indicates that Design Shaft Power per Unit Flow Rate per Unit Head is used as scaling factor. + \note Design Power Consumption = Design Maximum Flow Rate * Design Pump Head * scaling factor / Motor Efficiency + \required-field + N11, \field Design Electric Power per Unit Flow Rate + \type real + \note Used to size Design Power Consumption from design flow rate + \required-field + \units W/(m3/s) + \ip-units W/(gal/min) + \minimum> 0 + N12, \field Design Shaft Power per Unit Flow Rate per Unit Head + \type real + \note Used to size Design Power Consumption from design flow rate for head and motor efficiency + \required-field + \units W-s/m3-Pa + \ip-units W-min/gal-ftH2O + \minimum> 0 + A8; \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 + \required-field + OS:HeaderedPumps:ConstantSpeed, \memo This Headered pump object describes a pump bank with more than 1 pump in parallel A1, \field Handle @@ -31409,7 +31632,36 @@ OS:ZoneHVAC:Baseboard:RadiantConvective:Water, A4, \field Heating Coil Name \type object-list \required-field - \object-list RadiantBaseboardHeatingCoil + \object-list RadiantBaseboardHeatingCoilWater + N1, \field Fraction Radiant + \required-field + \type real + \minimum 0 + \maximum 1 + N2; \field Fraction of Radiant Energy Incident on People + \required-field + \type real + \minimum 0 + \maximum 1 + +OS:ZoneHVAC:Baseboard:RadiantConvective:Steam, + A1, \field Handle + \type handle + \required-field + A2, \field Name + \required-field + \type alpha + \reference ConnectionObject + A3, \field Availability Schedule Name + \note Availability schedule name for this system. Schedule value > 0 means the system is available. + \note If this field is blank, the system is always available. + \type object-list + \object-list ScheduleNames + \required-field + A4, \field Heating Coil Name + \type object-list + \required-field + \object-list RadiantBaseboardHeatingCoilSteam N1, \field Fraction Radiant \required-field \type real diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index 37e9662cb5..606359d972 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -94,6 +94,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateCoilHeatingGas.cpp ForwardTranslator/ForwardTranslateCoilHeatingGasMultiStage.cpp ForwardTranslator/ForwardTranslateCoilHeatingWater.cpp + ForwardTranslator/ForwardTranslateCoilHeatingSteam.cpp ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpEquationFit.cpp ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.cpp ForwardTranslator/ForwardTranslateCoilPerformanceDXCooling.cpp @@ -302,6 +303,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslatePortList.cpp ForwardTranslator/ForwardTranslatePumpConstantSpeed.cpp ForwardTranslator/ForwardTranslatePumpVariableSpeed.cpp + ForwardTranslator/ForwardTranslatePumpVariableSpeedCondensate.cpp ForwardTranslator/ForwardTranslatePythonPluginInstance.cpp ForwardTranslator/ForwardTranslatePythonPluginVariable.cpp ForwardTranslator/ForwardTranslatePythonPluginTrendVariable.cpp @@ -444,6 +446,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateZoneHVACBaseboardConvectiveWater.cpp ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveElectric.cpp ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveWater.cpp + ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveSteam.cpp ForwardTranslator/ForwardTranslateZoneHVACCoolingPanelRadiantConvectiveWater.cpp ForwardTranslator/ForwardTranslateZoneHVACDehumidifierDX.cpp ForwardTranslator/ForwardTranslateZoneHVACEnergyRecoveryVentilator.cpp @@ -698,6 +701,7 @@ set(${target_name}_test_src Test/AvailabilityManagerNightCycle_GTest.cpp Test/AvailabilityManagerHybridVentilation_GTest.cpp Test/BoilerHotWater_GTest.cpp + Test/BoilerSteam_GTest.cpp Test/Building_GTest.cpp Test/ChillerElectricASHRAE205_GTest.cpp Test/ChillerElectricEIR_GTest.cpp @@ -724,6 +728,7 @@ set(${target_name}_test_src Test/CoilHeatingGasMultiStage_GTest.cpp Test/CoilHeatingWaterToAirHeatPumpEquationFit_GTest.cpp Test/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_GTest.cpp + Test/CoilHeatingSteam_GTest.cpp Test/CoilSystemCoolingWater_GTest.cpp Test/CoilSystemCoolingWaterHeatExchangerAssisted_GTest.cpp Test/CoilSystemIntegratedHeatPumpAirSource_GTest.cpp @@ -744,6 +749,9 @@ set(${target_name}_test_src Test/DaylightingDeviceLightWell_GTest.cpp Test/DesignDay_GTest.cpp Test/DesignSpecificationOutdoorAir_GTest.cpp + Test/DistrictCooling_GTest.cpp + Test/DistrictHeatingWater_GTest.cpp + Test/DistrictHeatingSteam_GTest.cpp Test/ElectricEquipment_GTest.cpp Test/ElectricEquipmentITEAirCooled_GTest.cpp Test/ElectricLoadCenterDistribution_GTest.cpp @@ -859,6 +867,7 @@ set(${target_name}_test_src Test/WaterUseConnections_GTest.cpp Test/ZoneAirHeatBalanceAlgorithm_GTest.cpp Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp + Test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp Test/ZoneHVACEvaporativeCoolerUnit_GTest.cpp Test/ZoneHVACIdealLoadsAirSystem_GTest.cpp Test/ZoneHVACLowTemperatureRadiantElectric_GTest.cpp diff --git a/src/energyplus/ForwardTranslator.cpp b/src/energyplus/ForwardTranslator.cpp index 98575da2a6..1897f8f755 100644 --- a/src/energyplus/ForwardTranslator.cpp +++ b/src/energyplus/ForwardTranslator.cpp @@ -1180,6 +1180,11 @@ namespace energyplus { retVal = translateCoilHeatingWater(coil); break; } + case openstudio::IddObjectType::OS_Coil_Heating_Steam: { + auto coil = modelObject.cast(); + retVal = translateCoilHeatingSteam(coil); + break; + } case openstudio::IddObjectType::OS_Coil_Heating_WaterToAirHeatPump_EquationFit: { auto coil = modelObject.cast(); retVal = translateCoilHeatingWaterToAirHeatPumpEquationFit(coil); @@ -2294,6 +2299,11 @@ namespace energyplus { retVal = translatePumpVariableSpeed(pump); break; } + case openstudio::IddObjectType::OS_Pump_VariableSpeed_Condensate: { + auto pump = modelObject.cast(); + retVal = translatePumpVariableSpeedCondensate(pump); + break; + } case openstudio::IddObjectType::OS_OutputControl_Files: { auto outputControlFiles = modelObject.cast(); retVal = translateOutputControlFiles(outputControlFiles); @@ -3199,6 +3209,11 @@ namespace energyplus { retVal = translateZoneHVACBaseboardRadiantConvectiveWater(mo); break; } + case openstudio::IddObjectType::OS_ZoneHVAC_Baseboard_RadiantConvective_Steam: { + auto mo = modelObject.cast(); + retVal = translateZoneHVACBaseboardRadiantConvectiveSteam(mo); + break; + } case openstudio::IddObjectType::OS_ZoneHVAC_CoolingPanel_RadiantConvective_Water: { auto mo = modelObject.cast(); retVal = translateZoneHVACCoolingPanelRadiantConvectiveWater(mo); diff --git a/src/energyplus/ForwardTranslator.hpp b/src/energyplus/ForwardTranslator.hpp index 24a8e5f209..8b8eed94cf 100644 --- a/src/energyplus/ForwardTranslator.hpp +++ b/src/energyplus/ForwardTranslator.hpp @@ -130,6 +130,7 @@ namespace model { class CoilHeatingGas; class CoilHeatingGasMultiStage; class CoilHeatingWater; + class CoilHeatingSteam; class CoilHeatingWaterToAirHeatPumpEquationFit; class CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit; class CoilPerformanceDXCooling; @@ -337,6 +338,7 @@ namespace model { class PortList; class PumpConstantSpeed; class PumpVariableSpeed; + class PumpVariableSpeedCondensate; class PythonPluginInstance; class PythonPluginVariable; class PythonPluginTrendVariable; @@ -481,6 +483,7 @@ namespace model { class ZoneHVACBaseboardConvectiveWater; class ZoneHVACBaseboardRadiantConvectiveElectric; class ZoneHVACBaseboardRadiantConvectiveWater; + class ZoneHVACBaseboardRadiantConvectiveSteam; class ZoneHVACCoolingPanelRadiantConvectiveWater; class ZoneHVACDehumidifierDX; class ZoneHVACEnergyRecoveryVentilator; @@ -841,6 +844,8 @@ namespace energyplus { boost::optional translateCoilHeatingWater(model::CoilHeatingWater& modelObject); + boost::optional translateCoilHeatingSteam(model::CoilHeatingSteam& modelObject); + boost::optional translateCoilHeatingWaterToAirHeatPumpEquationFit(model::CoilHeatingWaterToAirHeatPumpEquationFit& modelObject); boost::optional @@ -1274,6 +1279,8 @@ namespace energyplus { boost::optional translatePumpVariableSpeed(model::PumpVariableSpeed& modelObject); + boost::optional translatePumpVariableSpeedCondensate(model::PumpVariableSpeedCondensate& modelObject); + boost::optional translatePythonPluginInstance(model::PythonPluginInstance& modelObject); boost::optional translatePythonPluginVariable(model::PythonPluginVariable& modelObject); @@ -1571,6 +1578,8 @@ namespace energyplus { boost::optional translateZoneHVACBaseboardRadiantConvectiveWater(model::ZoneHVACBaseboardRadiantConvectiveWater& modelObject); + boost::optional translateZoneHVACBaseboardRadiantConvectiveSteam(model::ZoneHVACBaseboardRadiantConvectiveSteam& modelObject); + boost::optional translateZoneHVACCoolingPanelRadiantConvectiveWater(model::ZoneHVACCoolingPanelRadiantConvectiveWater& modelObject); boost::optional translateZoneHVACDehumidifierDX(model::ZoneHVACDehumidifierDX& modelObject); @@ -1627,6 +1636,12 @@ namespace energyplus { // helper method used by ForwardTranslatePlantLoop IdfObject populateBranch(IdfObject& branchIdfObject, std::vector& modelObjects, model::Loop& loop, bool isSupplyBranch); + // helper method used by ForwardTranslatePlantLoop + std::pair hasWaterAndSteam(model::Loop& loop); + + // helper method used by ForwardTranslatePipeAdiabatic + boost::optional createPipeAdiabatic(bool hasSteam); + // translate all constructions void translateConstructions(const model::Model& model); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp index a386009bf7..f820c4386d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp @@ -25,6 +25,8 @@ #include "../../model/CoilHeatingElectric_Impl.hpp" #include "../../model/CoilHeatingWater.hpp" #include "../../model/CoilHeatingWater_Impl.hpp" +#include "../../model/CoilHeatingSteam.hpp" +#include "../../model/CoilHeatingSteam_Impl.hpp" #include "../../model/AirToAirComponent.hpp" #include "../../model/AirToAirComponent_Impl.hpp" #include "../../model/Node.hpp" @@ -43,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -202,7 +205,7 @@ namespace energyplus { _heatingCoil = translateCoilHeatingDXVariableSpeedWithoutUnitary(dxCoil.get()); m_map.insert(std::make_pair(heatingCoil->handle(), _heatingCoil.get())); } else if ((heatingCoil->optionalCast()) || (heatingCoil->optionalCast()) - || (heatingCoil->optionalCast())) { + || (heatingCoil->optionalCast()) || (heatingCoil->optionalCast())) { // translateAndMapModelObject already inserts into m_map _heatingCoil = translateAndMapModelObject(heatingCoil.get()); } else { @@ -356,6 +359,9 @@ namespace energyplus { } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatInletNodeName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, heatOutletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatInletNodeName); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, heatOutletNodeName); } IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp index 5d0635e507..3472d7d4c7 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "../../utilities/idd/IddEnums.hpp" @@ -325,12 +326,15 @@ namespace energyplus { } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric_MultiStage) { _heatingCoil->setString(Coil_Heating_Electric_MultiStageFields::AirInletNodeName, heatingCoilInletNodeName); _heatingCoil->setString(Coil_Heating_Electric_MultiStageFields::AirOutletNodeName, heatingCoilOutletNodeName); - } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { - _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilInletNodeName); - _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, heatingCoilOutletNodeName); } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_DX_MultiSpeed) { _heatingCoil->setString(Coil_Heating_DX_MultiSpeedFields::AirInletNodeName, heatingCoilInletNodeName); _heatingCoil->setString(Coil_Heating_DX_MultiSpeedFields::AirOutletNodeName, heatingCoilOutletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { + _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilInletNodeName); + _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, heatingCoilOutletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatingCoilInletNodeName); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, heatingCoilOutletNodeName); } } @@ -338,6 +342,9 @@ namespace energyplus { if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, suppCoilInletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, suppCoilOutletNodeName); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, suppCoilInletNodeName); + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, suppCoilOutletNodeName); } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Fuel) { _supplementalHeatingCoil->setString(Coil_Heating_FuelFields::AirInletNodeName, suppCoilInletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_FuelFields::AirOutletNodeName, suppCoilOutletNodeName); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitarySystem.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitarySystem.cpp index 538292847c..2ac7bda6ee 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitarySystem.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirLoopHVACUnitarySystem.cpp @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -780,6 +781,9 @@ namespace energyplus { } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, inletNodeName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, inletNodeName); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName); } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_DX_MultiSpeed) { _heatingCoil->setString(Coil_Heating_DX_MultiSpeedFields::AirInletNodeName, inletNodeName); _heatingCoil->setString(Coil_Heating_DX_MultiSpeedFields::AirOutletNodeName, outletNodeName); @@ -830,6 +834,9 @@ namespace energyplus { } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, inletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName.get()); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, inletNodeName); + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName.get()); } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Desuperheater) { _supplementalHeatingCoil->setString(Coil_Heating_DesuperheaterFields::AirInletNodeName, inletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_DesuperheaterFields::AirOutletNodeName, airOutletNodeName.get()); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp index 4640924892..7dceca0b73 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "../../utilities/idd/IddEnums.hpp" #include @@ -175,6 +176,9 @@ namespace energyplus { if (_heatingCoil && (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water)) { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilInlet); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, heatingCoilOutlet); + } else if (_heatingCoil && (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam)) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatingCoilInlet); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, heatingCoilOutlet); } if (_coolingCoil && (_coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_Water)) { diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeReheat.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeReheat.cpp index d58064e396..32e7cbb153 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeReheat.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctConstantVolumeReheat.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "../../utilities/idd/IddEnums.hpp" #include #include @@ -82,6 +83,9 @@ namespace energyplus { } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, inletNodeName.get()); _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName.get()); + } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _reheatCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, inletNodeName.get()); + _reheatCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName.get()); } idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::AirOutletNodeName, outletNodeName.get()); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctParallelPIUReheat.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctParallelPIUReheat.cpp index fd2f4ed3aa..58406570d6 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctParallelPIUReheat.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctParallelPIUReheat.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "../../utilities/idd/IddEnums.hpp" @@ -157,6 +158,9 @@ namespace energyplus { } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, mixerOutletNodeName); _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName.get()); + } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _reheatCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, mixerOutletNodeName); + _reheatCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName.get()); } } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctSeriesPIUReheat.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctSeriesPIUReheat.cpp index 73446fb05d..b497f0d3ad 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctSeriesPIUReheat.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctSeriesPIUReheat.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "../../utilities/idd/IddEnums.hpp" @@ -154,6 +155,9 @@ namespace energyplus { } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, fanOutletNodeName); _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName.get()); + } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _reheatCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, fanOutletNodeName); + _reheatCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName.get()); } } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVHeatAndCoolReheat.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVHeatAndCoolReheat.cpp index 01884d0692..cc9d786dcc 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVHeatAndCoolReheat.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVHeatAndCoolReheat.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "../../utilities/idd/IddEnums.hpp" #include #include @@ -78,6 +79,9 @@ namespace energyplus { } else if (_coil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _coil->setString(Coil_Heating_WaterFields::AirInletNodeName, damperOutletNodeName); _coil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName.get()); + } else if (_coil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _coil->setString(Coil_Heating_SteamFields::AirInletNodeName, damperOutletNodeName); + _coil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName.get()); } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVReheat.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVReheat.cpp index 83fcafd2b2..09d573f56d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVReheat.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateAirTerminalSingleDuctVAVReheat.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "../../utilities/idd/IddEnums.hpp" #include #include @@ -91,6 +92,9 @@ namespace energyplus { } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, damperOutletNodeName); _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, outletNodeName.get()); + } else if (_reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _reheatCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, damperOutletNodeName); + _reheatCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, outletNodeName.get()); } idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::AirOutletNodeName, outletNodeName.get()); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingSteam.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingSteam.cpp new file mode 100644 index 0000000000..c8af843054 --- /dev/null +++ b/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingSteam.cpp @@ -0,0 +1,120 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "../ForwardTranslator.hpp" +#include "../../model/Model.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" +#include "../../model/CoilHeatingSteam.hpp" +#include "../../model/CoilHeatingSteam_Impl.hpp" +#include "../../utilities/core/Logger.hpp" +#include "../../utilities/core/Assert.hpp" +#include +#include "../../utilities/idd/IddEnums.hpp" +#include +#include + +using namespace openstudio::model; + +using namespace std; + +namespace openstudio { + +namespace energyplus { + + boost::optional ForwardTranslator::translateCoilHeatingSteam(CoilHeatingSteam& modelObject) { + boost::optional s; + boost::optional value; + + IdfObject idfObject(IddObjectType::Coil_Heating_Steam); + + m_idfObjects.push_back(idfObject); + + s = modelObject.name(); + if (s) { + idfObject.setName(*s); + } + + Schedule sched = modelObject.availabilitySchedule(); + boost::optional _sched = translateAndMapModelObject(sched); + if (_sched) { + idfObject.setString(Coil_Heating_SteamFields::AvailabilityScheduleName, _sched->name().get()); + } + + // MaximumSteamFlowRate + + if (modelObject.isMaximumSteamFlowRateAutosized()) { + idfObject.setString(Coil_Heating_SteamFields::MaximumSteamFlowRate, "Autosize"); + } else if ((value = modelObject.maximumSteamFlowRate())) { + idfObject.setDouble(Coil_Heating_SteamFields::MaximumSteamFlowRate, value.get()); + } + + // DegreeofSubCooling + + if (value = modelObject.degreeofSubCooling()) { + idfObject.setDouble(Coil_Heating_SteamFields::DegreeofSubCooling, value.get()); + } + + // DegreeofLoopSubCooling + + if (value = modelObject.degreeofLoopSubCooling()) { + idfObject.setDouble(Coil_Heating_SteamFields::DegreeofLoopSubCooling, value.get()); + } + + // WaterInletNodeName + + if (boost::optional mo = modelObject.waterInletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Coil_Heating_SteamFields::WaterInletNodeName, node->name().get()); + } + } + + // WaterOutletNodeName + + if (boost::optional mo = modelObject.waterOutletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Coil_Heating_SteamFields::WaterOutletNodeName, node->name().get()); + } + } + + // AirInletNodeName + + if (boost::optional mo = modelObject.airInletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Coil_Heating_SteamFields::AirInletNodeName, node->name().get()); + } + } + + // AirOutletNodeName + + if (boost::optional mo = modelObject.airOutletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Coil_Heating_SteamFields::AirOutletNodeName, node->name().get()); + } + } + + // CoilControlType + + if (s = modelObject.coilControlType()) { + idfObject.setString(Coil_Heating_SteamFields::CoilControlType, s.get()); + } + + // TemperatureSetpointNodeName + // If it was hardset we actually use that, otherwise keep above default (coil outlet) + if (boost::optional node = modelObject.temperatureSetpointNode()) { + idfObject.setString(Coil_Heating_SteamFields::TemperatureSetpointNodeName, node->name().get()); + } + + return boost::optional(idfObject); + } + + //((Name)(Name)) + //((AvailabilityScheduleName)(Availability Schedule Name)) + +} // namespace energyplus + +} // namespace openstudio diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePipeAdiabatic.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePipeAdiabatic.cpp index 668234dd96..113780de4d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePipeAdiabatic.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePipeAdiabatic.cpp @@ -14,26 +14,61 @@ #include #include +#include "../../model/BoilerSteam.hpp" +#include "../../model/BoilerSteam_Impl.hpp" +#include "../../model/DistrictHeatingSteam.hpp" +#include "../../model/DistrictHeatingSteam_Impl.hpp" +#include "../../model/PumpVariableSpeedCondensate.hpp" +#include "../../model/PumpVariableSpeedCondensate_Impl.hpp" +#include "../../model/CoilHeatingSteam.hpp" +#include "../../model/CoilHeatingSteam_Impl.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant_Impl.hpp" +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" +#include "../../model/Splitter.hpp" +#include "../../model/Splitter_Impl.hpp" +#include "../../model/Mixer.hpp" +#include "../../model/Mixer_Impl.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/PlantLoop_Impl.hpp" + using namespace openstudio::model; namespace openstudio { namespace energyplus { + boost::optional ForwardTranslator::createPipeAdiabatic(bool hasSteam) { + // PipeAdiabatic or PipeAdiabaticSteam + + boost::optional idfObject; + idfObject = IdfObject(IddObjectType::Pipe_Adiabatic); + if (hasSteam) { + idfObject = IdfObject(IddObjectType::Pipe_Adiabatic_Steam); + } else { + idfObject = IdfObject(IddObjectType::Pipe_Adiabatic); + } + + return idfObject; + } + boost::optional ForwardTranslator::translatePipeAdiabatic(PipeAdiabatic& modelObject) { OptionalString s; OptionalDouble d; OptionalModelObject temp; - IdfObject idfObject(IddObjectType::Pipe_Adiabatic); + boost::optional plantLoop = modelObject.plantLoop(); + auto [hasWater, hasSteam] = hasWaterAndSteam(*plantLoop); + boost::optional idfObject = createPipeAdiabatic(hasSteam); - m_idfObjects.push_back(idfObject); + m_idfObjects.push_back(*idfObject); /////////////////////////////////////////////////////////////////////////// // Field: Name //////////////////////////////////////////////////////////// s = modelObject.name(); if (s) { - idfObject.setName(*s); + idfObject->setName(*s); } /////////////////////////////////////////////////////////////////////////// @@ -43,7 +78,7 @@ namespace energyplus { if (temp) { s = temp->name(); if (s) { - idfObject.setString(openstudio::Pipe_AdiabaticFields::InletNodeName, *s); + idfObject->setString(openstudio::Pipe_AdiabaticFields::InletNodeName, *s); } } /////////////////////////////////////////////////////////////////////////// @@ -54,13 +89,13 @@ namespace energyplus { if (temp) { s = temp->name(); if (s) { - idfObject.setString(openstudio::Pipe_AdiabaticFields::OutletNodeName, *s); + idfObject->setString(openstudio::Pipe_AdiabaticFields::OutletNodeName, *s); } } /// //////////////////////////////////////////////////////////////////////// - return boost::optional(idfObject); + return idfObject; } } // namespace energyplus diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp index a3dc363a53..718d25be76 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp @@ -26,8 +26,16 @@ #include "../../model/PumpVariableSpeed.hpp" #include "../../model/Schedule.hpp" #include "../../model/Schedule_Impl.hpp" -#include "../../model/BoilerHotWater.hpp" -#include "../../model/BoilerHotWater_Impl.hpp" +#include "../../model/PipeAdiabatic.hpp" +#include "../../model/PipeAdiabatic_Impl.hpp" +#include "../../model/BoilerSteam.hpp" +#include "../../model/BoilerSteam_Impl.hpp" +#include "../../model/DistrictHeatingSteam.hpp" +#include "../../model/DistrictHeatingSteam_Impl.hpp" +#include "../../model/PumpVariableSpeedCondensate.hpp" +#include "../../model/PumpVariableSpeedCondensate_Impl.hpp" +#include "../../model/CoilHeatingSteam.hpp" +#include "../../model/CoilHeatingSteam_Impl.hpp" #include "../../model/CentralHeatPumpSystem.hpp" #include "../../model/CentralHeatPumpSystem_Impl.hpp" #include "../../model/ChillerElectricASHRAE205.hpp" @@ -70,6 +78,8 @@ #include "../../model/CoilHeatingWaterBaseboard_Impl.hpp" #include "../../model/CoilHeatingWaterBaseboardRadiant.hpp" #include "../../model/CoilHeatingWaterBaseboardRadiant_Impl.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant_Impl.hpp" #include "../../model/CoilCoolingWaterPanelRadiant.hpp" #include "../../model/CoilCoolingWaterPanelRadiant_Impl.hpp" #include "../../model/CoilCoolingCooledBeam.hpp" @@ -184,6 +194,21 @@ namespace energyplus { } } } + //special case for ZoneHVAC:Baseboard:RadiantConvective:Steam. In E+, this object appears on both the + //zonehvac:equipmentlist and the branch. In OpenStudio, this object was broken into 2 objects: + //ZoneHVACBaseboardRadiantConvectiveSteam and CoilHeatingSteamBaseboardRadiant. The ZoneHVAC goes onto the zone and + //has a child coil that goes onto the plantloop. In order to get the correct translation to E+, we need + //to put the name of the containing ZoneHVACBaseboardRadiantConvectiveSteam onto the branch. + if (auto coilBBRad = modelObject.optionalCast()) { + if (auto contZnBBRad = coilBBRad->containingZoneHVACComponent()) { + //translate and map containingZoneHVACBBRadConvWater + if (auto idfContZnBBRad = this->translateAndMapModelObject(*contZnBBRad)) { + //Get the name and the idd object from the idf object version of this + objectName = idfContZnBBRad->name().get(); + iddType = idfContZnBBRad->iddObject().name(); + } + } + } //special case for ZoneHVAC:CoolingPanel:RadiantConvective:Water. In E+, this object appears on both the //zonehvac:equipmentlist and the branch. In OpenStudio, this object was broken into 2 objects: //ZoneHVACCoolingPanelRadiantConvectiveWater and CoilCoolingWaterPanelRadiant. The ZoneHVAC goes onto the zone and @@ -443,7 +468,36 @@ namespace energyplus { return branchIdfObject; } + std::pair ForwardTranslator::hasWaterAndSteam(Loop& loop) { + bool hasWater = false; + bool hasSteam = false; + + std::vector components = loop.components(); + + for (auto& component : components) { + if (component.optionalCast() || component.optionalCast() || component.optionalCast() + || component.optionalCast()) { // these are components associated with either Water or Steam + // no-op + } else if (component.optionalCast() || component.optionalCast() + || component.optionalCast() || component.optionalCast() + || component.optionalCast()) { + hasSteam = true; + } else { + hasWater = true; + } + } + + return std::pair{hasWater, hasSteam}; + } + boost::optional ForwardTranslator::translatePlantLoop(PlantLoop& plantLoop) { + // First check that the plant loop does not have both Water AND Steam components + auto [hasWater, hasSteam] = hasWaterAndSteam(plantLoop); + if (hasWater && hasSteam) { + LOG(Error, "Did not translate " << plantLoop.briefDescription() << " because there is a mix of Water and Steam components."); + return boost::none; + } + // Create a new IddObjectType::PlantLoop IdfObject idfObject(IddObjectType::PlantLoop); m_idfObjects.push_back(idfObject); @@ -564,8 +618,6 @@ namespace energyplus { idfObject.setString(PlantLoopFields::DemandSideInletNodeName, plantLoop.demandInletNode().name().get()); idfObject.setString(PlantLoopFields::DemandSideOutletNodeName, plantLoop.demandOutletNode().name().get()); - auto supplyComponents = plantLoop.supplyComponents(); - SizingPlant sizingPlant = plantLoop.sizingPlant(); translateAndMapModelObject(sizingPlant); @@ -633,19 +685,19 @@ namespace energyplus { if (supplyInletModelObjects.size() > 2u) { populateBranch(_supplyInletBranch, supplyInletModelObjects, plantLoop, true); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Supply Inlet Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Supply Inlet Pipe"); + m_idfObjects.push_back(*pipe); std::string inletNodeName = plantLoop.supplyInletNode().name().get(); std::string outletNodeName = plantLoop.name().get() + " Supply Inlet Pipe Node"; - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _supplyInletBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -686,19 +738,19 @@ namespace energyplus { if (allComponents.size() > 2u) { populateBranch(_equipmentBranch, allComponents, plantLoop, true); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Supply Branch " + istring + " Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Supply Branch " + istring + " Pipe"); + m_idfObjects.push_back(*pipe); - std::string inletNodeName = pipe.name().get() + " Inlet Node"; - std::string outletNodeName = pipe.name().get() + " Outlet Node"; + std::string inletNodeName = pipe->name().get() + " Inlet Node"; + std::string outletNodeName = pipe->name().get() + " Outlet Node"; - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _equipmentBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -726,19 +778,19 @@ namespace energyplus { if (supplyOutletModelObjects.size() > 2u) { populateBranch(_supplyOutletBranch, supplyOutletModelObjects, plantLoop, true); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Supply Outlet Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Supply Outlet Pipe"); + m_idfObjects.push_back(*pipe); std::string inletNodeName = plantLoop.name().get() + " Supply Outlet Pipe Node"; std::string outletNodeName = plantLoop.supplyOutletNode().name().get(); - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _supplyOutletBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -803,19 +855,19 @@ namespace energyplus { if (demandInletModelObjects.size() > 2u) { populateBranch(_demandInletBranch, demandInletModelObjects, plantLoop, false); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Demand Inlet Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Demand Inlet Pipe"); + m_idfObjects.push_back(*pipe); std::string inletNodeName = plantLoop.demandInletNode().name().get(); std::string outletNodeName = plantLoop.name().get() + " Demand Inlet Pipe Node"; - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _demandInletBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -856,19 +908,19 @@ namespace energyplus { if (allComponents.size() > 2u) { populateBranch(_equipmentBranch, allComponents, plantLoop, false); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Demand Branch " + istring + " Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Demand Branch " + istring + " Pipe"); + m_idfObjects.push_back(*pipe); - std::string inletNodeName = pipe.name().get() + " Inlet Node"; - std::string outletNodeName = pipe.name().get() + " Outlet Node"; + std::string inletNodeName = pipe->name().get() + " Inlet Node"; + std::string outletNodeName = pipe->name().get() + " Outlet Node"; - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _equipmentBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -893,19 +945,19 @@ namespace energyplus { eg = _demandBranchList.pushExtensibleGroup(); eg.setString(BranchListExtensibleFields::BranchName, _equipmentBranch.name().get()); - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Demand Bypass Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Demand Bypass Pipe"); + m_idfObjects.push_back(*pipe); - std::string inletNodeName = pipe.name().get() + " Inlet Node"; - std::string outletNodeName = pipe.name().get() + " Outlet Node"; + std::string inletNodeName = pipe->name().get() + " Inlet Node"; + std::string outletNodeName = pipe->name().get() + " Outlet Node"; - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _equipmentBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } @@ -930,19 +982,19 @@ namespace energyplus { if (demandOutletModelObjects.size() > 2u) { populateBranch(_demandOutletBranch, demandOutletModelObjects, plantLoop, false); } else { - IdfObject pipe(IddObjectType::Pipe_Adiabatic); - pipe.setName(plantLoop.name().get() + " Demand Outlet Pipe"); - m_idfObjects.push_back(pipe); + boost::optional pipe = createPipeAdiabatic(hasSteam); + pipe->setName(plantLoop.name().get() + " Demand Outlet Pipe"); + m_idfObjects.push_back(*pipe); std::string inletNodeName = plantLoop.name().get() + " Demand Outlet Pipe Node"; std::string outletNodeName = plantLoop.demandOutletNode().name().get(); - pipe.setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); - pipe.setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); + pipe->setString(Pipe_AdiabaticFields::InletNodeName, inletNodeName); + pipe->setString(Pipe_AdiabaticFields::OutletNodeName, outletNodeName); IdfExtensibleGroup eg = _demandOutletBranch.pushExtensibleGroup(); - eg.setString(BranchExtensibleFields::ComponentObjectType, pipe.iddObject().name()); - eg.setString(BranchExtensibleFields::ComponentName, pipe.name().get()); + eg.setString(BranchExtensibleFields::ComponentObjectType, pipe->iddObject().name()); + eg.setString(BranchExtensibleFields::ComponentName, pipe->name().get()); eg.setString(BranchExtensibleFields::ComponentInletNodeName, inletNodeName); eg.setString(BranchExtensibleFields::ComponentOutletNodeName, outletNodeName); } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeed.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeed.cpp index ea81545ed2..0df5166bca 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeed.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeed.cpp @@ -184,25 +184,35 @@ namespace energyplus { idfObject.setString(Pump_VariableSpeedFields::MaximumRPMSchedule, schedule->name().get()); } + // SkinLossRadiativeFraction + if ((value = modelObject.skinLossRadiativeFraction())) { idfObject.setDouble(Pump_VariableSpeedFields::SkinLossRadiativeFraction, value.get()); } + // DesignPowerSizingMethod + { s = modelObject.designPowerSizingMethod(); idfObject.setString(Pump_VariableSpeedFields::DesignPowerSizingMethod, s.get()); } + // DesignElectricPowerperUnitFlowRate + { value = modelObject.designElectricPowerPerUnitFlowRate(); idfObject.setDouble(Pump_VariableSpeedFields::DesignElectricPowerperUnitFlowRate, value.get()); } + // DesignShaftPowerperUnitFlowRateperUnitHead + { value = modelObject.designShaftPowerPerUnitFlowRatePerUnitHead(); idfObject.setDouble(Pump_VariableSpeedFields::DesignShaftPowerperUnitFlowRateperUnitHead, value.get()); } + // DesignMinimumFlowRateFraction + { value = modelObject.designMinimumFlowRateFraction(); idfObject.setDouble(Pump_VariableSpeedFields::DesignMinimumFlowRateFraction, value.get()); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeedCondensate.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeedCondensate.cpp new file mode 100644 index 0000000000..89e412582e --- /dev/null +++ b/src/energyplus/ForwardTranslator/ForwardTranslatePumpVariableSpeedCondensate.cpp @@ -0,0 +1,162 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "../ForwardTranslator.hpp" + +#include "../../model/PumpVariableSpeedCondensate.hpp" +#include "../../model/PumpVariableSpeedCondensate_Impl.hpp" +#include "../../model/Model.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" +#include "../../model/Curve.hpp" +#include "../../model/Curve_Impl.hpp" + +#include "../../utilities/core/Assert.hpp" + +#include +#include + +using namespace openstudio::model; + +using namespace std; + +namespace openstudio { + +namespace energyplus { + + boost::optional ForwardTranslator::translatePumpVariableSpeedCondensate(PumpVariableSpeedCondensate& modelObject) { + boost::optional s; + boost::optional value; + OptionalSchedule schedule; + + IdfObject idfObject(IddObjectType::Pump_VariableSpeed_Condensate); + + m_idfObjects.push_back(idfObject); + + // Name + + s = modelObject.name(); + if (s) { + idfObject.setName(*s); + } + + // InletNodeName + + if (boost::optional mo = modelObject.inletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Pump_VariableSpeed_CondensateFields::InletNodeName, node->name().get()); + } + } + + // OutletNodeName + + if (boost::optional mo = modelObject.outletModelObject()) { + if (boost::optional node = mo->optionalCast()) { + idfObject.setString(Pump_VariableSpeed_CondensateFields::OutletNodeName, node->name().get()); + } + } + + // RatedSteamVolumeFlowRate + + if (modelObject.isRatedSteamVolumeFlowRateAutosized()) { + idfObject.setString(Pump_VariableSpeed_CondensateFields::DesignSteamVolumeFlowRate, "Autosize"); + } else if ((value = modelObject.ratedSteamVolumeFlowRate())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::DesignSteamVolumeFlowRate, value.get()); + } + + // RatedPumpHead + + if ((value = modelObject.ratedPumpHead())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::DesignPumpHead, value.get()); + } + + // RatedPowerConsumption + + if (modelObject.isRatedPowerConsumptionAutosized()) { + idfObject.setString(Pump_VariableSpeed_CondensateFields::DesignPowerConsumption, "Autosize"); + } else if ((value = modelObject.ratedPowerConsumption())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::DesignPowerConsumption, value.get()); + } + + // MotorEfficiency + + if ((value = modelObject.motorEfficiency())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::MotorEfficiency, value.get()); + } + + // FractionofMotorInefficienciestoFluidStream + + if ((value = modelObject.fractionofMotorInefficienciestoFluidStream())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::FractionofMotorInefficienciestoFluidStream, value.get()); + } + + // Coefficient1ofthePartLoadPerformanceCurve + + if ((value = modelObject.coefficient1ofthePartLoadPerformanceCurve())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::Coefficient1ofthePartLoadPerformanceCurve, value.get()); + } + + // Coefficient2ofthePartLoadPerformanceCurve + + if ((value = modelObject.coefficient2ofthePartLoadPerformanceCurve())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::Coefficient2ofthePartLoadPerformanceCurve, value.get()); + } + + // Coefficient3ofthePartLoadPerformanceCurve + + if ((value = modelObject.coefficient3ofthePartLoadPerformanceCurve())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::Coefficient3ofthePartLoadPerformanceCurve, value.get()); + } + + // Coefficient4ofthePartLoadPerformanceCurve + + if ((value = modelObject.coefficient4ofthePartLoadPerformanceCurve())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::Coefficient4ofthePartLoadPerformanceCurve, value.get()); + } + + // PumpFlowRateSchedule + + if ((schedule = modelObject.pumpFlowRateSchedule())) { + idfObject.setString(Pump_VariableSpeed_CondensateFields::PumpFlowRateScheduleName, schedule->name().get()); + } + + // SkinLossRadiativeFraction + + if ((value = modelObject.skinLossRadiativeFraction())) { + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::SkinLossRadiativeFraction, value.get()); + } + + // DesignPowerSizingMethod + + { + s = modelObject.designPowerSizingMethod(); + idfObject.setString(Pump_VariableSpeed_CondensateFields::DesignPowerSizingMethod, s.get()); + } + + // DesignElectricPowerperUnitFlowRate + + { + value = modelObject.designElectricPowerPerUnitFlowRate(); + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::DesignElectricPowerperUnitFlowRate, value.get()); + } + + // DesignShaftPowerperUnitFlowRateperUnitHead + + { + value = modelObject.designShaftPowerPerUnitFlowRatePerUnitHead(); + idfObject.setDouble(Pump_VariableSpeed_CondensateFields::DesignShaftPowerperUnitFlowRateperUnitHead, value.get()); + } + + // EndUseSubcategory + + idfObject.setString(Pump_VariableSpeed_CondensateFields::EndUseSubcategory, modelObject.endUseSubcategory()); + + return idfObject; + } + +} // namespace energyplus +} // namespace openstudio diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveSteam.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveSteam.cpp new file mode 100644 index 0000000000..7cfa7c4602 --- /dev/null +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveSteam.cpp @@ -0,0 +1,177 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "../ForwardTranslator.hpp" +#include "../../model/Model.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/ModelObject.hpp" +#include "../../model/ModelObject_Impl.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Surface.hpp" +#include "../../model/Surface_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" +#include "../../model/ZoneHVACBaseboardRadiantConvectiveSteam.hpp" +#include "../../model/ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" +#include "../../model/ZoneHVACEquipmentList.hpp" +#include "../../model/ZoneHVACEquipmentList_Impl.hpp" +#include "../../model/ZoneHVACComponent.hpp" +#include "../../model/ZoneHVACComponent_Impl.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant_Impl.hpp" +#include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include +#include + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + + boost::optional + ForwardTranslator::translateZoneHVACBaseboardRadiantConvectiveSteam(ZoneHVACBaseboardRadiantConvectiveSteam& modelObject) { + boost::optional s; + boost::optional value; + boost::optional temp; + + // Name + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Steam, modelObject); + + IdfObject designObject(openstudio::IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Steam_Design); + m_idfObjects.push_back(designObject); + designObject.setName(idfObject.nameString() + " Design"); + + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::DesignObject, designObject.nameString()); + + // AvailabilityScheduleName + { + auto schedule = modelObject.availabilitySchedule(); + if (auto _schedule = translateAndMapModelObject(schedule)) { + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::AvailabilityScheduleName, _schedule->name().get()); + } + } + + if (auto heatingCoil = modelObject.heatingCoil().optionalCast()) { + + // InletNodeName + if (auto node = heatingCoil->inletModelObject()) { + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::InletNodeName, node->name().get()); + } + + // OutletNodeName + if (auto node = heatingCoil->outletModelObject()) { + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::OutletNodeName, node->name().get()); + } + + // HeatingDesignCapacity + if (heatingCoil->isHeatingDesignCapacityAutosized()) { + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::HeatingDesignCapacity, "AutoSize"); + } else if ((value = heatingCoil->heatingDesignCapacity())) { + idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::HeatingDesignCapacity, value.get()); + } + + // DegreeofSubCooling + if ((value = heatingCoil->degreeofSubCooling())) { + idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::DegreeofSubCooling, value.get()); + } + + // MaximumSteamFlowRate + if (heatingCoil->isMaximumSteamFlowRateAutosized()) { + idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::MaximumSteamFlowRate, "AutoSize"); + } else if ((value = heatingCoil->maximumSteamFlowRate())) { + idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::MaximumSteamFlowRate, value.get()); + } + + // Starting Here: all these fields are now on the Design object + + // HeatingDesignCapacityMethod + if ((s = heatingCoil->heatingDesignCapacityMethod())) { + designObject.setString(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::HeatingDesignCapacityMethod, s.get()); + } + + // HeatingDesignCapacityPerFloorArea + if ((value = heatingCoil->heatingDesignCapacityPerFloorArea())) { + designObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::HeatingDesignCapacityPerFloorArea, value.get()); + } + + // FractionofAutosizedHeatingDesignCapacity + if ((value = heatingCoil->fractionofAutosizedHeatingDesignCapacity())) { + designObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionofAutosizedHeatingDesignCapacity, value.get()); + } + + // ConvergenceTolerance + if ((value = heatingCoil->convergenceTolerance())) { + designObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::ConvergenceTolerance, value.get()); + } + } + + // FractionRadiant: On Design object + if ((value = modelObject.fractionRadiant())) { + designObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionRadiant, value.get()); + } + + // FractionofRadiantEnergyIncidentonPeople: On Design object + double fractionofRadiantEnergyIncidentonPeople = modelObject.fractionofRadiantEnergyIncidentonPeople(); + { + designObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionofRadiantEnergyIncidentonPeople, + fractionofRadiantEnergyIncidentonPeople); + } + + //get rid of any existing surface (just to be safe) + idfObject.clearExtensibleGroups(); + + //aggregator for total area; will be used to create weighted area + double totalAreaOfWallSurfaces = 0; + double totalAreaOfCeilingSurfaces = 0; + double totalAreaOfFloorSurfaces = 0; + + //loop through all surfaces, adding up their area + auto const& surfaces = modelObject.getImpl()->surfaces(); + + for (auto const& surface : surfaces) { + if (istringEqual(surface.surfaceType(), "Floor")) { + totalAreaOfFloorSurfaces += surface.grossArea(); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + totalAreaOfCeilingSurfaces += surface.grossArea(); + } else { + totalAreaOfWallSurfaces += surface.grossArea(); + } + } + + // Assume that 5% of what is not on people is on the floor + double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.05; + // Assume that 55% of what is not on people is on the walls + double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.55; + // Assume that 40% of what is not on people is on the ceiling + double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.40; + //loop through all the surfaces, adding them and their flow fractions (weighted per-area) + for (auto const& surface : surfaces) { + IdfExtensibleGroup group = idfObject.pushExtensibleGroup(); + group.setString(ZoneHVAC_Baseboard_RadiantConvective_SteamExtensibleFields::SurfaceName, surface.name().get()); + if (istringEqual(surface.surfaceType(), "Floor")) { + group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamExtensibleFields::FractionofRadiantEnergytoSurface, + (surface.grossArea() / totalAreaOfFloorSurfaces * fractionOnFloor)); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamExtensibleFields::FractionofRadiantEnergytoSurface, + (surface.grossArea() / totalAreaOfCeilingSurfaces * fractionOnCeiling)); + } else { + group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamExtensibleFields::FractionofRadiantEnergytoSurface, + (surface.grossArea() / totalAreaOfWallSurfaces * fractionOnWall)); + } + } + + return idfObject; + } + +} // namespace energyplus + +} // namespace openstudio diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalAirConditioner.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalAirConditioner.cpp index f85265a848..61063d130e 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalAirConditioner.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalAirConditioner.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -270,6 +271,10 @@ namespace energyplus { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, coolingCoilOutletNodeName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, coolingCoilOutletNodeName); + + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName); } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Fuel) { _heatingCoil->setString(Coil_Heating_FuelFields::AirInletNodeName, coolingCoilOutletNodeName); @@ -284,6 +289,10 @@ namespace energyplus { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, coolingCoilOutletNodeName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, heatingCoilOutletNodeName); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, coolingCoilOutletNodeName); + + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, heatingCoilOutletNodeName); } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Fuel) { _heatingCoil->setString(Coil_Heating_FuelFields::AirInletNodeName, coolingCoilOutletNodeName); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalHeatPump.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalHeatPump.cpp index f5284b5bbc..a4ce3f8176 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalHeatPump.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACPackagedTerminalHeatPump.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -381,6 +382,10 @@ namespace energyplus { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilOutletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatingCoilOutletNodeName); + + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName); } } else { if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Fuel) { @@ -395,6 +400,10 @@ namespace energyplus { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, fanOutletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, fanOutletNodeName); + + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName); } } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACTerminalUnitVariableRefrigerantFlow.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACTerminalUnitVariableRefrigerantFlow.cpp index f06b536c8b..e9fe94feab 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACTerminalUnitVariableRefrigerantFlow.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACTerminalUnitVariableRefrigerantFlow.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include "../../utilities/idd/IddEnums.hpp" #include @@ -351,8 +352,7 @@ namespace energyplus { } else if (idf_coil.iddObject().type() == IddObjectType::Coil_Heating_Water) { return std::pair{Coil_Heating_WaterFields::AirInletNodeName, Coil_Heating_WaterFields::AirOutletNodeName}; } else if (idf_coil.iddObject().type() == IddObjectType::Coil_Heating_Steam) { - // Not yet supported in OS - OS_ASSERT(false); + return std::pair{Coil_Heating_SteamFields::AirInletNodeName, Coil_Heating_SteamFields::AirOutletNodeName}; } else { LOG(Error, "Unsupported supplemental heating Coil type for " << modelObject.briefDescription()); OS_ASSERT(false); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitHeater.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitHeater.cpp index 9a542b53d2..966510cce1 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitHeater.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitHeater.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "../../utilities/idd/IddEnums.hpp" @@ -183,6 +184,9 @@ namespace energyplus { } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, fanOutletNodeName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, *s); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, fanOutletNodeName); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, *s); } else { OS_ASSERT(false); // We're missing a coil type! } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitVentilator.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitVentilator.cpp index 2c739b08ad..cf8eb48730 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitVentilator.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACUnitVentilator.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -193,6 +194,9 @@ namespace energyplus { } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) { _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilOutletName); _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNode->name().get()); + } else if (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _heatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatingCoilOutletName); + _heatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNode->name().get()); } } } diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACWaterToAirHeatPump.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACWaterToAirHeatPump.cpp index c9a236369e..9af5775ad7 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACWaterToAirHeatPump.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACWaterToAirHeatPump.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "../../utilities/idd/IddEnums.hpp" #include "../../utilities/math/FloatCompare.hpp" #include @@ -312,6 +313,10 @@ namespace energyplus { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, heatingCoilOutletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, heatingCoilOutletNodeName); + + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName); } } else { if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Fuel) { @@ -326,6 +331,10 @@ namespace energyplus { _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName, fanOutletNodeName); _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName, airOutletNodeName); + } else if (_supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Steam) { + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirInletNodeName, fanOutletNodeName); + + _supplementalHeatingCoil->setString(Coil_Heating_SteamFields::AirOutletNodeName, airOutletNodeName); } } } diff --git a/src/energyplus/Test/BoilerSteam_GTest.cpp b/src/energyplus/Test/BoilerSteam_GTest.cpp new file mode 100644 index 0000000000..676750780b --- /dev/null +++ b/src/energyplus/Test/BoilerSteam_GTest.cpp @@ -0,0 +1,75 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/BoilerSteam.hpp" +#include "../../model/PlantLoop.hpp" + +#include + +#include +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/IdfObject_Impl.hpp" + +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/idf/WorkspaceObject_Impl.hpp" + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ForwardTranslator_BoilerSteam) { + Model m; + + PlantLoop plant_loop(m); + + BoilerSteam bs(m); + + EXPECT_TRUE(bs.setFuelType("Electricity")); + EXPECT_TRUE(bs.setMaximumOperatingPressure(10.03)); + EXPECT_TRUE(bs.setTheoreticalEfficiency(0.5)); + EXPECT_TRUE(bs.setDesignOutletSteamTemperature(10.03)); + EXPECT_TRUE(bs.setNominalCapacity(10.03)); + EXPECT_TRUE(bs.setMinimumPartLoadRatio(1.0)); + EXPECT_TRUE(bs.setMaximumPartLoadRatio(1.0)); + EXPECT_TRUE(bs.setOptimumPartLoadRatio(1.0)); + EXPECT_TRUE(bs.setCoefficient1ofFuelUseFunctionofPartLoadRatioCurve(10.03)); + EXPECT_TRUE(bs.setCoefficient2ofFuelUseFunctionofPartLoadRatioCurve(10.03)); + EXPECT_TRUE(bs.setCoefficient3ofFuelUseFunctionofPartLoadRatioCurve(10.03)); + EXPECT_TRUE(bs.setSizingFactor(0.5)); + EXPECT_TRUE(bs.setEndUseSubcategory("SteamBoiler")); + + EXPECT_TRUE(plant_loop.addSupplyBranchForComponent(bs)); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Boiler_Steam).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(6u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); + IdfObject idf_bs = w.getObjectsByType(IddObjectType::Boiler_Steam)[0]; + + EXPECT_EQ(bs.nameString(), idf_bs.getString(Boiler_SteamFields::Name, false).get()); + EXPECT_EQ("Electricity", idf_bs.getString(Boiler_SteamFields::FuelType, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::MaximumOperatingPressure, false).get()); + EXPECT_EQ(0.5, idf_bs.getDouble(Boiler_SteamFields::TheoreticalEfficiency, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::DesignOutletSteamTemperature, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::NominalCapacity, false).get()); + EXPECT_EQ(1.0, idf_bs.getDouble(Boiler_SteamFields::MinimumPartLoadRatio, false).get()); + EXPECT_EQ(1.0, idf_bs.getDouble(Boiler_SteamFields::MaximumPartLoadRatio, false).get()); + EXPECT_EQ(1.0, idf_bs.getDouble(Boiler_SteamFields::OptimumPartLoadRatio, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::Coefficient1ofFuelUseFunctionofPartLoadRatioCurve, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::Coefficient2ofFuelUseFunctionofPartLoadRatioCurve, false).get()); + EXPECT_EQ(10.03, idf_bs.getDouble(Boiler_SteamFields::Coefficient3ofFuelUseFunctionofPartLoadRatioCurve, false).get()); + EXPECT_EQ(bs.inletModelObject().get().nameString(), idf_bs.getString(Boiler_SteamFields::WaterInletNodeName, false).get()); + EXPECT_EQ(bs.outletModelObject().get().nameString(), idf_bs.getString(Boiler_SteamFields::SteamOutletNodeName, false).get()); + EXPECT_EQ(0.5, idf_bs.getDouble(Boiler_SteamFields::SizingFactor, false).get()); + EXPECT_EQ("SteamBoiler", idf_bs.getString(Boiler_SteamFields::EndUseSubcategory, false).get()); +} diff --git a/src/energyplus/Test/CoilHeatingSteam_GTest.cpp b/src/energyplus/Test/CoilHeatingSteam_GTest.cpp new file mode 100644 index 0000000000..ca6309090d --- /dev/null +++ b/src/energyplus/Test/CoilHeatingSteam_GTest.cpp @@ -0,0 +1,620 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/CoilHeatingSteam.hpp" +#include "../../model/CoilHeatingDXSingleSpeed.hpp" +#include "../../model/CoilCoolingDXSingleSpeed.hpp" +#include "../../model/CoilCoolingDXMultiSpeed.hpp" +#include "../../model/CoilHeatingGasMultiStage.hpp" +#include "../../model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp" +#include "../../model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp" +#include "../../model/CoilCoolingDXVariableRefrigerantFlow.hpp" +#include "../../model/CoilHeatingDXVariableRefrigerantFlow.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/AirLoopHVAC.hpp" +#include "../../model/Node.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/FanConstantVolume.hpp" +#include "../../model/FanSystemModel.hpp" +#include "../../model/FanOnOff.hpp" +#include "../../model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.hpp" +#include "../../model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.hpp" +#include "../../model/AirLoopHVACUnitarySystem.hpp" +#include "../../model/AirTerminalSingleDuctVAVReheat.hpp" +#include "../../model/AirTerminalSingleDuctVAVHeatAndCoolReheat.hpp" +#include "../../model/AirTerminalSingleDuctConstantVolumeReheat.hpp" +#include "../../model/AirTerminalSingleDuctSeriesPIUReheat.hpp" +#include "../../model/AirTerminalSingleDuctParallelPIUReheat.hpp" +#include "../../model/AirTerminalSingleDuctConstantVolumeFourPipeInduction.hpp" +#include "../../model/ZoneHVACPackagedTerminalAirConditioner.hpp" +#include "../../model/ZoneHVACPackagedTerminalHeatPump.hpp" +#include "../../model/ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp" +#include "../../model/ZoneHVACWaterToAirHeatPump.hpp" +#include "../../model/ZoneHVACUnitHeater.hpp" +#include "../../model/ZoneHVACUnitVentilator.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/IdfObject_Impl.hpp" + +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/idf/WorkspaceObject_Impl.hpp" + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ForwardTranslator_CoilHeatingSteam) { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + AirLoopHVAC a(m); + PlantLoop p(m); + + CoilHeatingSteam coil = CoilHeatingSteam(m); + + Schedule availabilitySchedule = m.alwaysOnDiscreteSchedule(); + EXPECT_TRUE(coil.setAvailabilitySchedule(availabilitySchedule)); + EXPECT_TRUE(coil.setMaximumSteamFlowRate(1.1)); + EXPECT_TRUE(coil.setDegreeofSubCooling(2.5)); + EXPECT_TRUE(coil.setDegreeofLoopSubCooling(15.0)); + EXPECT_TRUE(coil.setCoilControlType("TemperatureSetpointControl")); + Node outletNode = a.supplyOutletNode(); + EXPECT_TRUE(coil.setTemperatureSetpointNode(outletNode)); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + AirTerminalSingleDuctVAVReheat atu(m, sch, coil); + + p.addDemandBranchForComponent(coil); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + ASSERT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + IdfObject idf_coil = w.getObjectsByType(IddObjectType::Coil_Heating_Steam)[0]; + + EXPECT_EQ(coil.nameString(), idf_coil.getString(Coil_Heating_SteamFields::Name, false).get()); + EXPECT_EQ(sch.nameString(), idf_coil.getString(Coil_Heating_SteamFields::AvailabilityScheduleName, false).get()); + EXPECT_EQ(1.1, idf_coil.getDouble(Coil_Heating_SteamFields::MaximumSteamFlowRate, false).get()); + EXPECT_EQ(2.5, idf_coil.getDouble(Coil_Heating_SteamFields::DegreeofSubCooling, false).get()); + EXPECT_EQ(15.0, idf_coil.getDouble(Coil_Heating_SteamFields::DegreeofLoopSubCooling, false).get()); + EXPECT_EQ(coil.waterInletModelObject()->nameString(), idf_coil.getString(Coil_Heating_SteamFields::WaterInletNodeName, false).get()); + EXPECT_EQ(coil.waterOutletModelObject()->nameString(), idf_coil.getString(Coil_Heating_SteamFields::WaterOutletNodeName, false).get()); + EXPECT_EQ(atu.nameString() + " Damper Outlet", idf_coil.getString(Coil_Heating_SteamFields::AirInletNodeName, false).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), idf_coil.getString(Coil_Heating_SteamFields::AirOutletNodeName, false).get()); + EXPECT_EQ("TemperatureSetpointControl", idf_coil.getString(Coil_Heating_SteamFields::CoilControlType, false).get()); + EXPECT_EQ(outletNode.nameString(), idf_coil.getString(Coil_Heating_SteamFields::TemperatureSetpointNodeName, false).get()); +} + +TEST_F(EnergyPlusFixture, ForwardTranslator_CoilHeatingSteam_Equipment) { + // AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed + { + Model m; + + FanConstantVolume f(m); + CoilHeatingGasMultiStage h(m); + CoilHeatingSteam s = CoilHeatingSteam(m); + CoilCoolingDXMultiSpeed c(m); + + AirLoopHVAC a(m); + AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed u(m, f, h, c, s); + + Node supplyOutletNode = a.supplyOutletNode(); + u.addToNode(supplyOutletNode); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_us(w.getObjectsByType(IddObjectType::AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeed)); + ASSERT_EQ(1u, idf_us.size()); + WorkspaceObject idf_u(idf_us[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_u.getString(AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeedFields::SupplementalHeatingCoilObjectType).get()); + boost::optional woSuppHeatCoil( + idf_u.getTarget(AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeedFields::SupplementalHeatingCoilName)); + EXPECT_TRUE(woSuppHeatCoil); + EXPECT_EQ(woSuppHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woSuppHeatCoil->nameString()); + EXPECT_EQ(u.nameString() + " Fan Outlet", woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(u.outletModelObject()->nameString(), woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass + { + Model m; + + FanConstantVolume f(m); + CoilHeatingSteam h = CoilHeatingSteam(m); + CoilCoolingDXSingleSpeed c(m); + + AirLoopHVAC a(m); + AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass u(m, f, c, h); + + Node supplyOutletNode = a.supplyOutletNode(); + u.addToNode(supplyOutletNode); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_us(w.getObjectsByType(IddObjectType::AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypass)); + ASSERT_EQ(1u, idf_us.size()); + WorkspaceObject idf_u(idf_us[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_u.getString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_u.getTarget(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(u.nameString() + " Cooling Coil Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(u.nameString() + " Heating Coil Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirLoopHVAC:UnitarySystem + { + Model m; + + CoilHeatingSteam h = CoilHeatingSteam(m); + CoilHeatingSteam s = CoilHeatingSteam(m); + + AirLoopHVAC a(m); + AirLoopHVACUnitarySystem u(m); + + u.setHeatingCoil(h); + u.setSupplementalHeatingCoil(s); + + Node supplyOutletNode = a.supplyOutletNode(); + u.addToNode(supplyOutletNode); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(2u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_us(w.getObjectsByType(IddObjectType::AirLoopHVAC_UnitarySystem)); + ASSERT_EQ(1u, idf_us.size()); + WorkspaceObject idf_u(idf_us[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_u.getString(AirLoopHVAC_UnitarySystemFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_u.getTarget(AirLoopHVAC_UnitarySystemFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(u.inletNode()->nameString(), woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(u.nameString() + " Heating Coil - Supplemental Coil Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + + EXPECT_EQ("Coil:Heating:Steam", idf_u.getString(AirLoopHVAC_UnitarySystemFields::SupplementalHeatingCoilObjectType).get()); + boost::optional woSuppHeatCoil(idf_u.getTarget(AirLoopHVAC_UnitarySystemFields::SupplementalHeatingCoilName)); + EXPECT_TRUE(woSuppHeatCoil); + EXPECT_EQ(woSuppHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 2", woSuppHeatCoil->nameString()); + EXPECT_EQ(u.nameString() + " Heating Coil - Supplemental Coil Node", woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(u.outletNode()->nameString(), woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminalSingleDuctVAVReheat + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctVAVReheat atu(m, sch, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_VAV_Reheat)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_VAV_ReheatFields::ReheatCoilObjectType).get()); + boost::optional woReheatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_VAV_ReheatFields::ReheatCoilName)); + EXPECT_TRUE(woReheatCoil); + EXPECT_EQ(woReheatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woReheatCoil->nameString()); + EXPECT_EQ(atu.nameString() + " Damper Outlet", woReheatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctVAVHeatAndCoolReheat atu(m, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_VAV_HeatAndCool_Reheat)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_VAV_HeatAndCool_ReheatFields::ReheatCoilObjectType).get()); + boost::optional woReheatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_VAV_HeatAndCool_ReheatFields::ReheatCoilName)); + EXPECT_TRUE(woReheatCoil); + EXPECT_EQ(woReheatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woReheatCoil->nameString()); + EXPECT_EQ(atu.nameString() + " Damper Outlet Node", woReheatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminal:SingleDuct:ConstantVolume:Reheat + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctConstantVolumeReheat atu(m, sch, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_ConstantVolume_Reheat)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ReheatCoilObjectType).get()); + boost::optional woReheatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ReheatCoilName)); + EXPECT_TRUE(woReheatCoil); + EXPECT_EQ(woReheatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woReheatCoil->nameString()); + EXPECT_EQ(atu.inletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminal:SingleDuct:SeriesPIU:Reheat + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanSystemModel fan(m); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctSeriesPIUReheat atu(m, fan, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_SeriesPIU_Reheat)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_SeriesPIU_ReheatFields::ReheatCoilObjectType).get()); + boost::optional woReheatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_SeriesPIU_ReheatFields::ReheatCoilName)); + EXPECT_TRUE(woReheatCoil); + EXPECT_EQ(woReheatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woReheatCoil->nameString()); + EXPECT_EQ(atu.nameString() + " Fan Outlet", woReheatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminal:SingleDuct:ParallelPIU:Reheat + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanSystemModel fan(m); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctParallelPIUReheat atu(m, sch, fan, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_ParallelPIU_Reheat)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_ParallelPIU_ReheatFields::ReheatCoilObjectType).get()); + boost::optional woReheatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_ParallelPIU_ReheatFields::ReheatCoilName)); + EXPECT_TRUE(woReheatCoil); + EXPECT_EQ(woReheatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woReheatCoil->nameString()); + EXPECT_EQ(atu.nameString() + " Mixer Outlet", woReheatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.outletModelObject()->nameString(), woReheatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + CoilHeatingSteam coil = CoilHeatingSteam(m, sch); + AirTerminalSingleDuctConstantVolumeFourPipeInduction atu(m, coil); + + AirLoopHVAC a(m); + a.addBranchForZone(z, atu); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_atus(w.getObjectsByType(IddObjectType::AirTerminal_SingleDuct_ConstantVolume_FourPipeInduction)); + ASSERT_EQ(1u, idf_atus.size()); + WorkspaceObject idf_atu(idf_atus[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_atu.getString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_atu.getTarget(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(atu.inducedAirInletNode()->nameString(), woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(atu.nameString() + " Heating Coil Outlet", woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:PackagedTerminalHeatPump + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanConstantVolume fan(m); + CoilHeatingSteam sh = CoilHeatingSteam(m, sch); + CoilHeatingDXSingleSpeed h(m); + CoilCoolingDXSingleSpeed c(m); + ZoneHVACPackagedTerminalHeatPump zh(m, sch, fan, h, c, sh); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_PackagedTerminalHeatPump)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_PackagedTerminalHeatPumpFields::SupplementalHeatingCoilObjectType).get()); + boost::optional woSuppHeatCoil(idf_zh.getTarget(ZoneHVAC_PackagedTerminalHeatPumpFields::SupplementalHeatingCoilName)); + EXPECT_TRUE(woSuppHeatCoil); + EXPECT_EQ(woSuppHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woSuppHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Fan Outlet Node", woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.outletNode()->nameString(), woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:PackagedTerminalAirConditioner + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanConstantVolume fan(m); + CoilHeatingSteam h = CoilHeatingSteam(m, sch); + CoilCoolingDXSingleSpeed c(m); + ZoneHVACPackagedTerminalAirConditioner zh(m, sch, fan, h, c); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_PackagedTerminalAirConditioner)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_zh.getTarget(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Cooling Coil Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.nameString() + " Heating Coil Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:TerminalUnit:VariableRefrigerantFlow + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanOnOff fan(m); + CoilCoolingDXVariableRefrigerantFlow c(m); + CoilHeatingDXVariableRefrigerantFlow h(m); + CoilHeatingSteam sh = CoilHeatingSteam(m, sch); + ZoneHVACTerminalUnitVariableRefrigerantFlow zh(m, c, h, fan); + EXPECT_TRUE(zh.setSupplementalHeatingCoil(sh)); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_TerminalUnit_VariableRefrigerantFlow)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplementalHeatingCoilObjectType).get()); + boost::optional woSuppHeatCoil( + idf_zh.getTarget(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplementalHeatingCoilName)); + EXPECT_TRUE(woSuppHeatCoil); + EXPECT_EQ(woSuppHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woSuppHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Fan Outlet Node", woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.outletNode()->nameString(), woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:WaterToAirHeatPump + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanOnOff fan(m); + CoilHeatingWaterToAirHeatPumpEquationFit h(m); + CoilCoolingWaterToAirHeatPumpEquationFit c(m); + CoilHeatingSteam sh = CoilHeatingSteam(m, sch); + ZoneHVACWaterToAirHeatPump zh(m, sch, fan, h, c, sh); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_WaterToAirHeatPump)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_WaterToAirHeatPumpFields::SupplementalHeatingCoilObjectType).get()); + boost::optional woSuppHeatCoil(idf_zh.getTarget(ZoneHVAC_WaterToAirHeatPumpFields::SupplementalHeatingCoilName)); + EXPECT_TRUE(woSuppHeatCoil); + EXPECT_EQ(woSuppHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woSuppHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Heating Coil Outlet Node", woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.outletNode()->nameString(), woSuppHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:UnitHeater + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanConstantVolume fan(m); + CoilHeatingSteam h = CoilHeatingSteam(m, sch); + ZoneHVACUnitHeater zh(m, sch, fan, h); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_UnitHeater)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_UnitHeaterFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_zh.getTarget(ZoneHVAC_UnitHeaterFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Fan Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.outletNode()->nameString(), woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } + + // ZoneHVAC:UnitVentilator + { + Model m; + + ThermalZone z(m); + Space s(m); + s.setThermalZone(z); + + Schedule sch = m.alwaysOnDiscreteSchedule(); + FanConstantVolume fan(m); + CoilHeatingSteam h = CoilHeatingSteam(m, sch); + ZoneHVACUnitVentilator zh(m, fan); + EXPECT_TRUE(zh.setHeatingCoil(h)); + + zh.addToThermalZone(z); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::Coil_Heating_Steam).size()); + WorkspaceObjectVector idf_zhs(w.getObjectsByType(IddObjectType::ZoneHVAC_UnitVentilator)); + ASSERT_EQ(1u, idf_zhs.size()); + WorkspaceObject idf_zh(idf_zhs[0]); + + EXPECT_EQ("Coil:Heating:Steam", idf_zh.getString(ZoneHVAC_UnitVentilatorFields::HeatingCoilObjectType).get()); + boost::optional woHeatCoil(idf_zh.getTarget(ZoneHVAC_UnitVentilatorFields::HeatingCoilName)); + EXPECT_TRUE(woHeatCoil); + EXPECT_EQ(woHeatCoil->iddObject().type(), IddObjectType::Coil_Heating_Steam); + EXPECT_EQ("Coil Heating Steam 1", woHeatCoil->nameString()); + EXPECT_EQ(zh.nameString() + " Fan Outlet Node", woHeatCoil->getString(Coil_Heating_SteamFields::AirInletNodeName).get()); + EXPECT_EQ(zh.outletNode()->nameString(), woHeatCoil->getString(Coil_Heating_SteamFields::AirOutletNodeName).get()); + } +} diff --git a/src/energyplus/Test/DistrictCooling_GTest.cpp b/src/energyplus/Test/DistrictCooling_GTest.cpp index a340686c88..696f5fd993 100644 --- a/src/energyplus/Test/DistrictCooling_GTest.cpp +++ b/src/energyplus/Test/DistrictCooling_GTest.cpp @@ -10,6 +10,8 @@ #include "../../model/Model.hpp" #include "../../model/DistrictCooling.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/ScheduleConstant.hpp" #include diff --git a/src/energyplus/Test/DistrictHeatingSteam_GTest.cpp b/src/energyplus/Test/DistrictHeatingSteam_GTest.cpp index 50ec46480a..b8d4ab0c92 100644 --- a/src/energyplus/Test/DistrictHeatingSteam_GTest.cpp +++ b/src/energyplus/Test/DistrictHeatingSteam_GTest.cpp @@ -10,8 +10,12 @@ #include "../../model/Model.hpp" #include "../../model/DistrictHeatingSteam.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/ScheduleConstant.hpp" #include +#include +#include #include #include "../../utilities/idf/IdfObject.hpp" @@ -41,7 +45,8 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_DistrictHeatingSteam) { Workspace w = ft.translateModel(m); EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::DistrictHeating_Steam).size()); - + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(6u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); IdfObject idf_dhs = w.getObjectsByType(IddObjectType::DistrictHeating_Steam)[0]; EXPECT_EQ(districtHeatingSteam.nameString(), idf_dhs.getString(DistrictHeating_SteamFields::Name, false).get()); diff --git a/src/energyplus/Test/DistrictHeatingWater_GTest.cpp b/src/energyplus/Test/DistrictHeatingWater_GTest.cpp index c1c870fbcf..749bd5564d 100644 --- a/src/energyplus/Test/DistrictHeatingWater_GTest.cpp +++ b/src/energyplus/Test/DistrictHeatingWater_GTest.cpp @@ -10,9 +10,12 @@ #include "../../model/Model.hpp" #include "../../model/DistrictHeatingWater.hpp" +#include "../../model/PlantLoop.hpp" #include "../../model/ScheduleConstant.hpp" #include +#include +#include #include #include "../../utilities/idf/IdfObject.hpp" @@ -42,7 +45,8 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_DistrictHeatingWater) { Workspace w = ft.translateModel(m); EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::DistrictHeating_Water).size()); - + ASSERT_EQ(6u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); IdfObject idf_dhw = w.getObjectsByType(IddObjectType::DistrictHeating_Water)[0]; EXPECT_EQ(districtHeatingWater.nameString(), idf_dhw.getString(DistrictHeating_WaterFields::Name, false).get()); diff --git a/src/energyplus/Test/PlantLoop_GTest.cpp b/src/energyplus/Test/PlantLoop_GTest.cpp index b20a3cb217..f9ac148f20 100644 --- a/src/energyplus/Test/PlantLoop_GTest.cpp +++ b/src/energyplus/Test/PlantLoop_GTest.cpp @@ -20,6 +20,8 @@ #include "../../model/AvailabilityManagerScheduledOff.hpp" #include "../../model/Node.hpp" #include "../../model/ScheduleCompact.hpp" +#include "../../model/BoilerSteam.hpp" +#include "../../model/CoilHeatingWater.hpp" #include "../../model/PumpVariableSpeed.hpp" #include "../../model/PumpVariableSpeed_Impl.hpp" @@ -163,3 +165,26 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_PlantLoop_createFluidProperties) { ASSERT_NO_THROW(ft.translateModel(m)) << "Failed for " << n << " PlantLoops"; } } + +TEST_F(EnergyPlusFixture, ForwardTranslator_PlantLoop_WaterAndSteam) { + Model m; + + PlantLoop plant_loop(m); + + BoilerSteam bs(m); + CoilHeatingWater chw(m); + + EXPECT_TRUE(plant_loop.addSupplyBranchForComponent(bs)); + EXPECT_TRUE(plant_loop.addDemandBranchForComponent(chw)); + + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + EXPECT_EQ(2u, ft.errors().size()); + EXPECT_EQ("Did not translate Object of type 'OS:PlantLoop' and named 'Plant Loop 1' because there is a mix of Water and Steam components.", + ft.errors().front().logMessage()); + + EXPECT_EQ(0u, w.getObjectsByType(IddObjectType::PlantLoop).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); +} diff --git a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp new file mode 100644 index 0000000000..e714ee9855 --- /dev/null +++ b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp @@ -0,0 +1,130 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" +#include "../ReverseTranslator.hpp" + +#include "../../model/ZoneHVACBaseboardRadiantConvectiveSteam.hpp" +#include "../../model/ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant.hpp" +#include "../../model/CoilHeatingSteamBaseboardRadiant_Impl.hpp" + +#include "../../model/Model.hpp" +#include "../../model/HVACComponent.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/Surface.hpp" +#include "../../model/Schedule.hpp" +#include "../../utilities/geometry/Point3d.hpp" + +#include "../../utilities/idf/IdfFile.hpp" +#include "../../utilities/idf/Workspace.hpp" +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/geometry/Point3d.hpp" + +#include +#include +#include +#include +#include + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveSteam) { + //make the example model + Model m = model::exampleModel(); + + ZoneHVACBaseboardRadiantConvectiveSteam baseboard(m); + auto coil = baseboard.heatingCoil().cast(); + + PlantLoop p(m); + EXPECT_TRUE(p.addDemandBranchForComponent(coil)); + + Point3dVector floorPrint{ + {0, 10, 0}, + {10, 10, 0}, + {10, 0, 0}, + {0, 0, 0}, + }; + boost::optional space1 = Space::fromFloorPrint(floorPrint, 3, m); + ASSERT_TRUE(space1); + auto surfaces = space1->surfaces(); + EXPECT_EQ(6u, surfaces.size()); + + // Space needs to be in a ThermalZone or it's not translated + ThermalZone z(m); + EXPECT_TRUE(space1->setThermalZone(z)); + + EXPECT_TRUE(baseboard.addToThermalZone(z)); + + // Some tweaks to disambiguate the ft tests later + baseboard.setName("My Baseboard"); + EXPECT_TRUE(baseboard.setFractionRadiant(0.4)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergyIncidentonPeople(0.3)); + EXPECT_TRUE(coil.setMaximumSteamFlowRate(1.0)); + + // Translate + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + ASSERT_EQ(1u, w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Steam_Design).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(6u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); + ASSERT_EQ(1u, w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Steam_Design).size()); + WorkspaceObjectVector idfBaseboards = w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Steam); + ASSERT_EQ(1u, idfBaseboards.size()); + WorkspaceObject idfBaseboard(idfBaseboards[0]); + + // Name + EXPECT_EQ(baseboard.nameString(), idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::Name).get()); + // Design Object: see below + // Availability Schedule Name + EXPECT_EQ(baseboard.availabilitySchedule().nameString(), + idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::AvailabilityScheduleName).get()); + // Inlet Node Name + EXPECT_FALSE(idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::InletNodeName).get().empty()); + // Outlet Node Name + EXPECT_FALSE(idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::OutletNodeName).get().empty()); + // Heating Design Capacity + EXPECT_TRUE( + openstudio::istringEqual("autosize", idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::HeatingDesignCapacity).get())); + // Degree of SubCooling + EXPECT_EQ(coil.degreeofSubCooling(), idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::DegreeofSubCooling).get()); + // Maximum Steam Flow Rate + EXPECT_EQ(coil.maximumSteamFlowRate().get(), idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::MaximumSteamFlowRate).get()); + + // Surface 1 Name + // Fraction of Radiant Energy to Surface 1 + EXPECT_EQ(surfaces.size(), idfBaseboard.numExtensibleGroups()); + + // We check that it does have a design object assigned + ASSERT_TRUE(idfBaseboard.getTarget(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::DesignObject)); + WorkspaceObject idfDesign = idfBaseboard.getTarget(ZoneHVAC_Baseboard_RadiantConvective_SteamFields::DesignObject).get(); + // Name + EXPECT_EQ("My Baseboard Design", idfDesign.nameString()); + // Heating Design Capacity Method + EXPECT_EQ(coil.heatingDesignCapacityMethod(), + idfDesign.getString(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::HeatingDesignCapacityMethod).get()); + // Heating Design Capacity Per Floor Area + EXPECT_EQ(coil.heatingDesignCapacityPerFloorArea(), + idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::HeatingDesignCapacityPerFloorArea).get()); + // Fraction of Autosized Heating Design Capacity + EXPECT_EQ(coil.fractionofAutosizedHeatingDesignCapacity(), + idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionofAutosizedHeatingDesignCapacity).get()); + // Convergence Tolerance + EXPECT_EQ(coil.convergenceTolerance(), idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::ConvergenceTolerance).get()); + // Fraction Radiant + EXPECT_EQ(baseboard.fractionRadiant(), idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionRadiant).get()); + // Fraction of Radiant Energy Incident on People + EXPECT_EQ(baseboard.fractionofRadiantEnergyIncidentonPeople(), + idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Steam_DesignFields::FractionofRadiantEnergyIncidentonPeople).get()); +} diff --git a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp index 1186e1991d..c9873baf51 100644 --- a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp +++ b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include #include using namespace openstudio::energyplus; @@ -75,6 +77,8 @@ TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveWater) { Workspace w = ft.translateModel(m); ASSERT_EQ(1u, w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Water_Design).size()); + ASSERT_EQ(6u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic).size()); + ASSERT_EQ(0u, w.getObjectsByType(IddObjectType::Pipe_Adiabatic_Steam).size()); WorkspaceObjectVector idfBaseboards = w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Water); ASSERT_EQ(1u, idfBaseboards.size()); WorkspaceObject idfBaseboard(idfBaseboards[0]); diff --git a/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp b/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp index b2601ad362..6aaa5d5413 100644 --- a/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp +++ b/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp @@ -335,6 +335,10 @@ namespace model { result = true; break; } + case openstudio::IddObjectType::OS_Coil_Heating_Steam: { + result = true; + break; + } default: { LOG(Warn, "Unsupported or invalid IddObjectType: '" << coil.iddObject().name() << "'"); result = false; diff --git a/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp b/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp index 70caf70e96..24e60f2d3d 100644 --- a/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp +++ b/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp @@ -394,6 +394,8 @@ namespace model { isTypeCorrect = true; } else if (hvacComponent.iddObjectType() == IddObjectType::OS_Coil_Heating_Water) { isTypeCorrect = true; + } else if (hvacComponent.iddObjectType() == IddObjectType::OS_Coil_Heating_Steam) { + isTypeCorrect = true; } if (isTypeCorrect) { diff --git a/src/model/AirTerminalSingleDuctVAVReheat.cpp b/src/model/AirTerminalSingleDuctVAVReheat.cpp index c9ff38f484..c2356fa50c 100644 --- a/src/model/AirTerminalSingleDuctVAVReheat.cpp +++ b/src/model/AirTerminalSingleDuctVAVReheat.cpp @@ -492,6 +492,11 @@ namespace model { break; } + case openstudio::IddObjectType::OS_Coil_Heating_Steam: { + result = true; + + break; + } default: { LOG(Warn, "Unsupported or invalid IddObjectType: '" << coil.iddObject().name() << "'"); diff --git a/src/model/CMakeLists.txt b/src/model/CMakeLists.txt index aa91ad5add..3ffdce8043 100644 --- a/src/model/CMakeLists.txt +++ b/src/model/CMakeLists.txt @@ -425,6 +425,9 @@ set(${target_name}_src CoilHeatingWater.hpp CoilHeatingWater_Impl.hpp CoilHeatingWater.cpp + CoilHeatingSteam.hpp + CoilHeatingSteam_Impl.hpp + CoilHeatingSteam.cpp CoilHeatingWaterToAirHeatPumpEquationFit.hpp CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp CoilHeatingWaterToAirHeatPumpEquationFit.cpp @@ -440,6 +443,9 @@ set(${target_name}_src CoilHeatingWaterBaseboardRadiant.hpp CoilHeatingWaterBaseboardRadiant_Impl.hpp CoilHeatingWaterBaseboardRadiant.cpp + CoilHeatingSteamBaseboardRadiant.hpp + CoilHeatingSteamBaseboardRadiant_Impl.hpp + CoilHeatingSteamBaseboardRadiant.cpp CoilPerformanceDXCooling.hpp CoilPerformanceDXCooling_Impl.hpp CoilPerformanceDXCooling.cpp @@ -1228,6 +1234,9 @@ set(${target_name}_src PumpVariableSpeed.hpp PumpVariableSpeed_Impl.hpp PumpVariableSpeed.cpp + PumpVariableSpeedCondensate.hpp + PumpVariableSpeedCondensate_Impl.hpp + PumpVariableSpeedCondensate.cpp PythonPluginInstance.hpp PythonPluginInstance_Impl.hpp PythonPluginInstance.cpp @@ -1771,6 +1780,9 @@ set(${target_name}_src ZoneHVACBaseboardRadiantConvectiveWater.hpp ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp ZoneHVACBaseboardRadiantConvectiveWater.cpp + ZoneHVACBaseboardRadiantConvectiveSteam.hpp + ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp + ZoneHVACBaseboardRadiantConvectiveSteam.cpp ZoneHVACCoolingPanelRadiantConvectiveWater.hpp ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp ZoneHVACCoolingPanelRadiantConvectiveWater.cpp @@ -2010,11 +2022,13 @@ set(${target_name}_test_src test/CoilHeatingLowTempRadiantConstFlow_GTest.cpp test/CoilHeatingLowTempRadiantVarFlow_GTest.cpp test/CoilHeatingWater_GTest.cpp + test/CoilHeatingSteam_GTest.cpp test/CoilHeatingWaterToAirHeatPumpEquationFit_GTest.cpp test/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_GTest.cpp test/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData_GTest.cpp test/CoilHeatingWaterBaseboard_GTest.cpp test/CoilHeatingWaterBaseboardRadiant_GTest.cpp + test/CoilHeatingSteamBaseboardRadiant_GTest.cpp test/CoilPerformanceDXCooling_GTest.cpp test/CoilSystemCoolingDXHeatExchangerAssisted_GTest.cpp test/CoilSystemCoolingWater_GTest.cpp @@ -2239,6 +2253,7 @@ set(${target_name}_test_src test/Plenums_GTest.cpp test/PumpConstantSpeed_GTest.cpp test/PumpVariableSpeed_GTest.cpp + test/PumpVariableSpeedCondensate_GTest.cpp test/PythonPluginInstance_GTest.cpp test/PythonPluginVariable_GTest.cpp test/PythonPluginTrendVariable_GTest.cpp @@ -2380,6 +2395,7 @@ set(${target_name}_test_src test/ZoneHVACBaseboardConvectiveWater_GTest.cpp test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp + test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp test/ZoneHVACDehumidifierDX_GTest.cpp test/ZoneHVACEnergyRecoveryVentilator_GTest.cpp diff --git a/src/model/CoilHeatingElectric.cpp b/src/model/CoilHeatingElectric.cpp index e8233acf73..3c0ff44689 100644 --- a/src/model/CoilHeatingElectric.cpp +++ b/src/model/CoilHeatingElectric.cpp @@ -148,7 +148,6 @@ namespace model { bool CoilHeatingElectric_Impl::setTemperatureSetpointNode(Node& temperatureSetpointNode) { return setPointer(OS_Coil_Heating_ElectricFields::TemperatureSetpointNodeName, temperatureSetpointNode.handle()); - ; } void CoilHeatingElectric_Impl::resetTemperatureSetpointNode() { diff --git a/src/model/CoilHeatingGas.cpp b/src/model/CoilHeatingGas.cpp index c7eccde8e7..348d260c16 100644 --- a/src/model/CoilHeatingGas.cpp +++ b/src/model/CoilHeatingGas.cpp @@ -360,7 +360,7 @@ namespace model { } } - // ZoneHVACUnitHeater + // ZoneHVACUnitVentilator std::vector zoneHVACUnitVentilators; diff --git a/src/model/CoilHeatingSteam.cpp b/src/model/CoilHeatingSteam.cpp new file mode 100644 index 0000000000..6bb9a74c69 --- /dev/null +++ b/src/model/CoilHeatingSteam.cpp @@ -0,0 +1,634 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "CoilHeatingSteam.hpp" +#include "CoilHeatingSteam_Impl.hpp" +#include "ControllerWaterCoil.hpp" +#include "ControllerWaterCoil_Impl.hpp" +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "ZoneHVACComponent.hpp" +#include "ZoneHVACComponent_Impl.hpp" +#include "ZoneHVACFourPipeFanCoil.hpp" +#include "ZoneHVACFourPipeFanCoil_Impl.hpp" +#include "ZoneHVACPackagedTerminalAirConditioner.hpp" +#include "ZoneHVACPackagedTerminalAirConditioner_Impl.hpp" +#include "ZoneHVACPackagedTerminalHeatPump.hpp" +#include "ZoneHVACPackagedTerminalHeatPump_Impl.hpp" +#include "ZoneHVACWaterToAirHeatPump.hpp" +#include "ZoneHVACWaterToAirHeatPump_Impl.hpp" +#include "ZoneHVACUnitHeater.hpp" +#include "ZoneHVACUnitHeater_Impl.hpp" +#include "ZoneHVACUnitVentilator.hpp" +#include "ZoneHVACUnitVentilator_Impl.hpp" +#include "ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp" +#include "ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp" +#include "AirLoopHVACUnitarySystem.hpp" +#include "AirLoopHVACUnitarySystem_Impl.hpp" +#include "AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.hpp" +#include "AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl.hpp" +#include "AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.hpp" +#include "AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl.hpp" +#include "Node.hpp" +#include "Node_Impl.hpp" +#include "ScheduleCompact.hpp" +#include "ScheduleCompact_Impl.hpp" +#include "AirTerminalSingleDuctConstantVolumeReheat.hpp" +#include "AirTerminalSingleDuctConstantVolumeReheat_Impl.hpp" +#include "AirTerminalSingleDuctVAVReheat.hpp" +#include "AirTerminalSingleDuctVAVReheat_Impl.hpp" +#include "AirTerminalSingleDuctVAVHeatAndCoolReheat.hpp" +#include "AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl.hpp" +#include "AirTerminalSingleDuctParallelPIUReheat.hpp" +#include "AirTerminalSingleDuctParallelPIUReheat_Impl.hpp" +#include "AirTerminalSingleDuctSeriesPIUReheat.hpp" +#include "AirTerminalSingleDuctSeriesPIUReheat_Impl.hpp" +#include "AirTerminalSingleDuctConstantVolumeFourPipeInduction.hpp" +#include "AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl.hpp" +#include "Model.hpp" +#include +#include +#include "../utilities/core/Compare.hpp" +#include "../utilities/core/Assert.hpp" +#include "../utilities/data/DataEnums.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + CoilHeatingSteam_Impl::CoilHeatingSteam_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : WaterToAirComponent_Impl(idfObject, model, keepHandle) { + OS_ASSERT(idfObject.iddObject().type() == CoilHeatingSteam::iddObjectType()); + } + + CoilHeatingSteam_Impl::CoilHeatingSteam_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle) + : WaterToAirComponent_Impl(other, model, keepHandle) { + OS_ASSERT(other.iddObject().type() == CoilHeatingSteam::iddObjectType()); + } + + CoilHeatingSteam_Impl::CoilHeatingSteam_Impl(const CoilHeatingSteam_Impl& other, Model_Impl* model, bool keepHandle) + : WaterToAirComponent_Impl(other, model, keepHandle) {} + + const std::vector& CoilHeatingSteam_Impl::outputVariableNames() const { + static const std::vector result{"Heating Coil Heating Energy", "Total Steam Coil Heating Rate", + "Heating Coil Steam Trap Loss Rate", "Heating Coil Steam Inlet Temperature", + "Heating Coil Steam Outlet Temperature", "Heating Coil Steam Mass Flow Rate"}; + return result; + } + + bool CoilHeatingSteam_Impl::addToNode(Node& node) { + bool success = WaterToAirComponent_Impl::addToNode(node); + + if (success && (!containingHVACComponent()) && (!containingZoneHVACComponent())) { + if (boost::optional _waterInletModelObject = waterInletModelObject()) { + if (auto oldController = controllerWaterCoil()) { + if (!openstudio::istringEqual(oldController->action().get(), "Normal")) { + LOG(Warn, briefDescription() + << " has an existing ControllerWaterCoil with action set to something else than 'Normal'. Make sure this is what you want"); + } + } else { + Model t_model = model(); + ControllerWaterCoil controller(t_model); + controller.getImpl()->setWaterCoil(getObject()); + controller.setAction("Normal"); + } + } + } + + return success; + } + + bool CoilHeatingSteam_Impl::removeFromPlantLoop() { + if (boost::optional controller = this->controllerWaterCoil()) { + controller->remove(); + } + + return WaterToAirComponent_Impl::removeFromPlantLoop(); + } + + std::vector CoilHeatingSteam_Impl::remove() { + if (isRemovable()) { + return WaterToAirComponent_Impl::remove(); + } + + return {}; + } + + ModelObject CoilHeatingSteam_Impl::clone(Model model) const { + return WaterToAirComponent_Impl::clone(model); + } + + IddObjectType CoilHeatingSteam_Impl::iddObjectType() const { + return CoilHeatingSteam::iddObjectType(); + } + + std::vector CoilHeatingSteam_Impl::children() const { + std::vector result; + return result; + } + + std::vector CoilHeatingSteam_Impl::getScheduleTypeKeys(const Schedule& schedule) const { + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()); + UnsignedVector::const_iterator e(fieldIndices.end()); + if (std::find(b, e, OS_Coil_Heating_SteamFields::AvailabilityScheduleName) != e) { + result.emplace_back("CoilHeatingSteam", "Availability"); + } + return result; + } + + Schedule CoilHeatingSteam_Impl::availabilitySchedule() const { + OptionalSchedule value = getObject().getModelObjectTarget(OS_Coil_Heating_SteamFields::AvailabilityScheduleName); + if (!value) { + // it is an error if we get here, however we don't want to crash + // so we hook up to global always on schedule + LOG(Error, "Required availability schedule not set, using 'Always On' schedule"); + value = this->model().alwaysOnDiscreteSchedule(); + OS_ASSERT(value); + const_cast(this)->setAvailabilitySchedule(*value); + value = getObject().getModelObjectTarget(OS_Coil_Heating_SteamFields::AvailabilityScheduleName); + } + OS_ASSERT(value); + return value.get(); + } + + bool CoilHeatingSteam_Impl::setAvailabilitySchedule(Schedule& schedule) { + bool result = setSchedule(OS_Coil_Heating_SteamFields::AvailabilityScheduleName, "CoilHeatingSteam", "Availability", schedule); + return result; + } + + boost::optional CoilHeatingSteam_Impl::maximumSteamFlowRate() { + return getDouble(openstudio::OS_Coil_Heating_SteamFields::MaximumSteamFlowRate); + } + + bool CoilHeatingSteam_Impl::setMaximumSteamFlowRate(double value) { + return setDouble(openstudio::OS_Coil_Heating_SteamFields::MaximumSteamFlowRate, value); + } + + bool CoilHeatingSteam_Impl::isMaximumSteamFlowRateAutosized() { + bool result = false; + boost::optional value = getString(OS_Coil_Heating_SteamFields::MaximumSteamFlowRate, true); + if (value) { + result = openstudio::istringEqual(value.get(), "Autosize"); + } + return result; + } + + void CoilHeatingSteam_Impl::autosizeMaximumSteamFlowRate() { + setString(OS_Coil_Heating_SteamFields::MaximumSteamFlowRate, "Autosize"); + } + + double CoilHeatingSteam_Impl::degreeofSubCooling() const { + boost::optional value = getDouble(OS_Coil_Heating_SteamFields::DegreeofSubCooling, true); + OS_ASSERT(value); + return value.get(); + } + + bool CoilHeatingSteam_Impl::setDegreeofSubCooling(double degreeofSubCooling) { + bool result = setDouble(OS_Coil_Heating_SteamFields::DegreeofSubCooling, degreeofSubCooling); + OS_ASSERT(result); + return result; + } + + double CoilHeatingSteam_Impl::degreeofLoopSubCooling() const { + boost::optional value = getDouble(OS_Coil_Heating_SteamFields::DegreeofLoopSubCooling, true); + OS_ASSERT(value); + return value.get(); + } + + bool CoilHeatingSteam_Impl::setDegreeofLoopSubCooling(double degreeofLoopSubCooling) { + bool result = setDouble(OS_Coil_Heating_SteamFields::DegreeofLoopSubCooling, degreeofLoopSubCooling); + OS_ASSERT(result); + return result; + } + + std::string CoilHeatingSteam_Impl::coilControlType() const { + boost::optional value = getString(OS_Coil_Heating_SteamFields::CoilControlType, true); + OS_ASSERT(value); + return value.get(); + } + + bool CoilHeatingSteam_Impl::setCoilControlType(const std::string& coilControlType) { + const bool result = setString(OS_Coil_Heating_SteamFields::CoilControlType, coilControlType); + return result; + } + + boost::optional CoilHeatingSteam_Impl::temperatureSetpointNode() const { + return getObject().getModelObjectTarget(OS_Coil_Heating_SteamFields::TemperatureSetpointNodeName); + } + + bool CoilHeatingSteam_Impl::setTemperatureSetpointNode(Node& temperatureSetpointNode) { + return setPointer(OS_Coil_Heating_SteamFields::TemperatureSetpointNodeName, temperatureSetpointNode.handle()); + } + + void CoilHeatingSteam_Impl::resetTemperatureSetpointNode() { + bool result = setString(OS_Coil_Heating_SteamFields::TemperatureSetpointNodeName, ""); + OS_ASSERT(result); + } + + unsigned CoilHeatingSteam_Impl::airInletPort() const { + return OS_Coil_Heating_SteamFields::AirInletNodeName; + } + + unsigned CoilHeatingSteam_Impl::airOutletPort() const { + return OS_Coil_Heating_SteamFields::AirOutletNodeName; + } + + unsigned CoilHeatingSteam_Impl::waterInletPort() const { + return OS_Coil_Heating_SteamFields::WaterInletNodeName; + } + + unsigned CoilHeatingSteam_Impl::waterOutletPort() const { + return OS_Coil_Heating_SteamFields::WaterOutletNodeName; + } + + boost::optional CoilHeatingSteam_Impl::containingHVACComponent() const { + // Process all types that might contain a CoilHeatingSteam object. + + // Here is the list of AirTerminals and AirLoopHVACUnitary that are in OpenStudio as of 2.3.0 + + // Can have a heating coil (and are implemented below) + // * AirTerminalSingleDuctConstantVolumeFourPipeInduction + // * AirTerminalSingleDuctConstantVolumeReheat + // * AirTerminalSingleDuctParallelPIUReheat + // * AirTerminalSingleDuctSeriesPIUReheat + // * AirTerminalSingleDuctVAVHeatAndCoolReheat + // * AirTerminalSingleDuctVAVReheat + // * AirLoopHVACUnitarySystem + // * AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass + // * AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed + + // Cannot have a heating coil: + // * AirTerminalDualDuctVAV + // * AirTerminalSingleDuctConstantVolumeCooledBeam + // * AirTerminalSingleDuctInletSideMixer + // * AirTerminalSingleDuctConstantVolumeNoReheat (previously named AirTerminalSingleDuctUncontrolled) + // * AirTerminalSingleDuctVAVHeatAndCoolNoReheat + // * AirTerminalSingleDuctVAVNoReheat + + // AirLoopHVACUnitarySystem + std::vector airLoopHVACUnitarySystems = this->model().getConcreteModelObjects(); + + for (const auto& airLoopHVACUnitarySystem : airLoopHVACUnitarySystems) { + if (boost::optional heatingCoil = airLoopHVACUnitarySystem.heatingCoil()) { + if (heatingCoil->handle() == this->handle()) { + return airLoopHVACUnitarySystem; + } + } + if (boost::optional suppHeatingCoil = airLoopHVACUnitarySystem.supplementalHeatingCoil()) { + if (suppHeatingCoil->handle() == this->handle()) { + return airLoopHVACUnitarySystem; + } + } + } + + // AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass + std::vector bypassSystems = + this->model().getConcreteModelObjects(); + + for (const auto& bypassSystem : bypassSystems) { + if (boost::optional heatingCoil = bypassSystem.heatingCoil()) { + if (heatingCoil->handle() == this->handle()) { + return bypassSystem; + } + } + } + + // AirTerminalSingleDuctVAVReheat + + std::vector airTerminalSingleDuctVAVReheatObjects = + this->model().getConcreteModelObjects(); + + for (const auto& airTerminalSingleDuctVAVReheatObject : airTerminalSingleDuctVAVReheatObjects) { + if (boost::optional coil = airTerminalSingleDuctVAVReheatObject.reheatCoil()) { + if (coil->handle() == this->handle()) { + return airTerminalSingleDuctVAVReheatObject; + } + } + } + + // AirTerminalSingleDuctVAVHeatAndCoolReheat + std::vector airTerminalSingleDuctVAVHeatAndCoolReheatObjects = + this->model().getConcreteModelObjects(); + + for (const auto& airTerminalSingleDuctVAVHeatAndCoolReheatObject : airTerminalSingleDuctVAVHeatAndCoolReheatObjects) { + // Not an optional + if (airTerminalSingleDuctVAVHeatAndCoolReheatObject.reheatCoil().handle() == this->handle()) { + return airTerminalSingleDuctVAVHeatAndCoolReheatObject; + } + } + + // AirTerminalSingleDuctConstantVolumeReheat + + std::vector airTerminalSingleDuctConstantVolumeReheatObjects = + this->model().getConcreteModelObjects(); + + for (const auto& airTerminalSingleDuctConstantVolumeReheatObject : airTerminalSingleDuctConstantVolumeReheatObjects) { + if (boost::optional coil = airTerminalSingleDuctConstantVolumeReheatObject.reheatCoil()) { + // Not an optional actually... + if (coil->handle() == this->handle()) { + return airTerminalSingleDuctConstantVolumeReheatObject; + } + } + } + + // AirTerminalSingleDuctSeriesPIUReheat + + std::vector airTerminalSingleDuctSeriesPIUReheatObjects = + this->model().getConcreteModelObjects(); + + for (const auto& airTerminalSingleDuctSeriesPIUReheatObject : airTerminalSingleDuctSeriesPIUReheatObjects) { + // Not an optional + if (airTerminalSingleDuctSeriesPIUReheatObject.reheatCoil().handle() == this->handle()) { + return airTerminalSingleDuctSeriesPIUReheatObject; + } + } + + // AirTerminalSingleDuctParallelPIUReheat + + std::vector airTerminalSingleDuctParallelPIUReheatObjects = + this->model().getConcreteModelObjects(); + + for (const auto& airTerminalSingleDuctParallelPIUReheatObject : airTerminalSingleDuctParallelPIUReheatObjects) { + // Not an optional + if (airTerminalSingleDuctParallelPIUReheatObject.reheatCoil().handle() == this->handle()) { + return airTerminalSingleDuctParallelPIUReheatObject; + } + } + + // AirTerminalSingleDuctConstantVolumeFourPipeInduction + std::vector fourPipeSystems = + this->model().getConcreteModelObjects(); + + for (const auto& fourPipeSystem : fourPipeSystems) { + // Not an optional + if (fourPipeSystem.heatingCoil().handle() == this->handle()) { + return fourPipeSystem; + } + } + + // AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed + { + auto systems = this->model().getConcreteModelObjects(); + + for (const auto& system : systems) { + auto heatingCoil = system.heatingCoil(); + if (heatingCoil.handle() == this->handle()) { + return system; + } + auto supHeatingCoil = system.supplementalHeatingCoil(); + if (supHeatingCoil.handle() == this->handle()) { + return system; + } + } + } + + return boost::none; + } + + boost::optional CoilHeatingSteam_Impl::containingZoneHVACComponent() const { + // ZoneHVACPackagedTerminalAirConditioner + + std::vector zoneHVACPackagedTerminalAirConditioners; + + zoneHVACPackagedTerminalAirConditioners = this->model().getConcreteModelObjects(); + + for (const auto& zoneHVACPackagedTerminalAirConditioner : zoneHVACPackagedTerminalAirConditioners) { + if (boost::optional coil = zoneHVACPackagedTerminalAirConditioner.heatingCoil()) { + if (coil->handle() == this->handle()) { + return zoneHVACPackagedTerminalAirConditioner; + } + } + } + + // ZoneHVACPackagedTerminalHeatPump + + std::vector zoneHVACPackagedTerminalHeatPumps; + + zoneHVACPackagedTerminalHeatPumps = this->model().getConcreteModelObjects(); + + for (const auto& zoneHVACPackagedTerminalHeatPump : zoneHVACPackagedTerminalHeatPumps) { + if (boost::optional coil = zoneHVACPackagedTerminalHeatPump.supplementalHeatingCoil()) { + if (coil->handle() == this->handle()) { + return zoneHVACPackagedTerminalHeatPump; + } + } + } + + // ZoneHVACWaterToAirHeatPump + + std::vector zoneHVACWaterToAirHeatPumps; + + zoneHVACWaterToAirHeatPumps = this->model().getConcreteModelObjects(); + + for (const auto& zoneHVACWaterToAirHeatPump : zoneHVACWaterToAirHeatPumps) { + if (boost::optional coil = zoneHVACWaterToAirHeatPump.supplementalHeatingCoil()) { + if (coil->handle() == this->handle()) { + return zoneHVACWaterToAirHeatPump; + } + } + } + + // ZoneHVACUnitHeater + + std::vector zoneHVACUnitHeater; + + zoneHVACUnitHeater = this->model().getConcreteModelObjects(); + + for (const auto& elem : zoneHVACUnitHeater) { + if (boost::optional coil = elem.heatingCoil()) { + if (coil->handle() == this->handle()) { + return elem; + } + } + } + + // ZoneHVACUnitVentilator + + std::vector zoneHVACUnitVentilator; + + zoneHVACUnitVentilator = this->model().getConcreteModelObjects(); + + for (const auto& elem : zoneHVACUnitVentilator) { + if (boost::optional coil = elem.heatingCoil()) { + if (coil->handle() == this->handle()) { + return elem; + } + } + } + + // ZoneHVACTerminalUnitVariableRefrigerantFlow + + std::vector zoneHVACTerminalUnitVariableRefrigerantFlow; + + zoneHVACTerminalUnitVariableRefrigerantFlow = this->model().getConcreteModelObjects(); + + for (const auto& elem : zoneHVACTerminalUnitVariableRefrigerantFlow) { + if (boost::optional coil = elem.supplementalHeatingCoil()) { + if (coil->handle() == this->handle()) { + return elem; + } + } + } + + return boost::none; + } + + boost::optional CoilHeatingSteam_Impl::availabilityScheduleAsModelObject() const { + OptionalModelObject result = availabilitySchedule(); + return result; + } + + bool CoilHeatingSteam_Impl::setAvailabilityScheduleAsModelObject(const boost::optional& modelObject) { + if (modelObject) { + OptionalSchedule intermediate = modelObject->optionalCast(); + if (intermediate) { + Schedule schedule(*intermediate); + return setAvailabilitySchedule(schedule); + } + } + return false; + } + + boost::optional CoilHeatingSteam_Impl::autosizedMaximumSteamFlowRate() const { + return getAutosizedValue("Design Size Maximum Steam Flow Rate", "m3/s"); + } + + void CoilHeatingSteam_Impl::autosize() { + autosizeMaximumSteamFlowRate(); + } + + void CoilHeatingSteam_Impl::applySizingValues() { + boost::optional val; + val = autosizedMaximumSteamFlowRate(); + if (val) { + setMaximumSteamFlowRate(val.get()); + } + } + + ComponentType CoilHeatingSteam_Impl::componentType() const { + return ComponentType::Heating; + } + + std::vector CoilHeatingSteam_Impl::coolingFuelTypes() const { + return {}; + } + + std::vector CoilHeatingSteam_Impl::heatingFuelTypes() const { + if (auto p_ = plantLoop()) { + return p_->heatingFuelTypes(); + } + return {}; + } + + std::vector CoilHeatingSteam_Impl::appGHeatingFuelTypes() const { + if (auto p_ = plantLoop()) { + return p_->appGHeatingFuelTypes(); + } + return {}; + } + + } // namespace detail + + CoilHeatingSteam::CoilHeatingSteam(const Model& model, Schedule& schedule) : WaterToAirComponent(CoilHeatingSteam::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + setAvailabilitySchedule(schedule); + autosizeMaximumSteamFlowRate(); + setDegreeofSubCooling(5.0); + setDegreeofLoopSubCooling(20.0); + setCoilControlType("ZoneLoadControl"); + } + + CoilHeatingSteam::CoilHeatingSteam(const Model& model) : WaterToAirComponent(CoilHeatingSteam::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + auto schedule = model.alwaysOnDiscreteSchedule(); + setAvailabilitySchedule(schedule); + autosizeMaximumSteamFlowRate(); + setDegreeofSubCooling(5.0); + setDegreeofLoopSubCooling(20.0); + setCoilControlType("ZoneLoadControl"); + } + + CoilHeatingSteam::CoilHeatingSteam(std::shared_ptr p) : WaterToAirComponent(std::move(p)) {} + + Schedule CoilHeatingSteam::availabilitySchedule() const { + return getImpl()->availabilitySchedule(); + } + + bool CoilHeatingSteam::setAvailabilitySchedule(Schedule& schedule) { + return getImpl()->setAvailabilitySchedule(schedule); + } + + boost::optional CoilHeatingSteam::maximumSteamFlowRate() { + return getImpl()->maximumSteamFlowRate(); + } + + bool CoilHeatingSteam::setMaximumSteamFlowRate(double value) { + return getImpl()->setMaximumSteamFlowRate(value); + } + + bool CoilHeatingSteam::isMaximumSteamFlowRateAutosized() { + return getImpl()->isMaximumSteamFlowRateAutosized(); + } + + void CoilHeatingSteam::autosizeMaximumSteamFlowRate() { + getImpl()->autosizeMaximumSteamFlowRate(); + } + + double CoilHeatingSteam::degreeofSubCooling() const { + return getImpl()->degreeofSubCooling(); + } + + bool CoilHeatingSteam::setDegreeofSubCooling(double degreeofSubCooling) { + return getImpl()->setDegreeofSubCooling(degreeofSubCooling); + } + + double CoilHeatingSteam::degreeofLoopSubCooling() const { + return getImpl()->degreeofLoopSubCooling(); + } + + bool CoilHeatingSteam::setDegreeofLoopSubCooling(double degreeofLoopSubCooling) { + return getImpl()->setDegreeofLoopSubCooling(degreeofLoopSubCooling); + } + + std::string CoilHeatingSteam::coilControlType() const { + return getImpl()->coilControlType(); + } + + bool CoilHeatingSteam::setCoilControlType(const std::string& coilControlType) { + return getImpl()->setCoilControlType(coilControlType); + } + + boost::optional CoilHeatingSteam::temperatureSetpointNode() const { + return getImpl()->temperatureSetpointNode(); + } + + bool CoilHeatingSteam::setTemperatureSetpointNode(Node& temperatureSetpointNode) { + return getImpl()->setTemperatureSetpointNode(temperatureSetpointNode); + } + + void CoilHeatingSteam::resetTemperatureSetpointNode() { + getImpl()->resetTemperatureSetpointNode(); + } + + IddObjectType CoilHeatingSteam::iddObjectType() { + IddObjectType result(IddObjectType::OS_Coil_Heating_Steam); + return result; + } + + boost::optional CoilHeatingSteam::controllerWaterCoil() { + return getImpl()->controllerWaterCoil(); + } + + boost::optional CoilHeatingSteam::autosizedMaximumSteamFlowRate() const { + return getImpl()->autosizedMaximumSteamFlowRate(); + } + +} // namespace model +} // namespace openstudio diff --git a/src/model/CoilHeatingSteam.hpp b/src/model/CoilHeatingSteam.hpp new file mode 100644 index 0000000000..ae125e642e --- /dev/null +++ b/src/model/CoilHeatingSteam.hpp @@ -0,0 +1,116 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_COILHEATINGSTEAM_HPP +#define MODEL_COILHEATINGSTEAM_HPP + +#include "ModelAPI.hpp" +#include "WaterToAirComponent.hpp" + +namespace openstudio { +namespace model { + + class Schedule; + class ControllerWaterCoil; + + namespace detail { + + class CoilHeatingSteam_Impl; + + } // namespace detail + + /** CoilHeatingSteam is a WaterToAirComponent that wraps the IDD object named "OS:Coil:Heating:Steam". */ + class MODEL_API CoilHeatingSteam : public WaterToAirComponent + { + public: + /** @name Constructors and Destructors */ + //@{ + + CoilHeatingSteam(const Model& model, Schedule& schedule); + + CoilHeatingSteam(const Model& model); + + virtual ~CoilHeatingSteam() override = default; + // Default the copy and move operators because the virtual dtor is explicit + CoilHeatingSteam(const CoilHeatingSteam& other) = default; + CoilHeatingSteam(CoilHeatingSteam&& other) = default; + CoilHeatingSteam& operator=(const CoilHeatingSteam&) = default; + CoilHeatingSteam& operator=(CoilHeatingSteam&&) = default; + + //@} + + static IddObjectType iddObjectType(); + + /** @name Getters */ + //@{ + + Schedule availabilitySchedule() const; + + boost::optional maximumSteamFlowRate(); + + bool isMaximumSteamFlowRateAutosized(); + + double degreeofSubCooling() const; + + double degreeofLoopSubCooling() const; + + std::string coilControlType() const; + + boost::optional temperatureSetpointNode() const; + + boost::optional controllerWaterCoil(); + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + + bool setMaximumSteamFlowRate(double value); + + void autosizeMaximumSteamFlowRate(); + + bool setDegreeofSubCooling(double degreeofSubCooling); + + bool setDegreeofLoopSubCooling(double degreeofLoopSubCooling); + + bool setCoilControlType(const std::string& coilControlType); + + bool setTemperatureSetpointNode(Node& temperatureSetpointNode); + + void resetTemperatureSetpointNode(); + + //@} + /** @name Other */ + //@{ + + boost::optional autosizedMaximumSteamFlowRate() const; + + //@} + protected: + friend class Model; + + friend class openstudio::IdfObject; + friend class openstudio::detail::IdfObject_Impl; + + /// @cond + using ImplType = detail::CoilHeatingSteam_Impl; + + explicit CoilHeatingSteam(std::shared_ptr impl); + + private: + REGISTER_LOGGER("openstudio.model.CoilHeatingSteam"); + + CoilHeatingSteam(const Handle& handle, const Model& model); + + /// @endcond + }; // detail + + using OptionalCoilHeatingSteam = boost::optional; + +} // namespace model +} // namespace openstudio + +#endif // MODEL_COILHEATINGSTEAM_HPP diff --git a/src/model/CoilHeatingSteamBaseboardRadiant.cpp b/src/model/CoilHeatingSteamBaseboardRadiant.cpp new file mode 100644 index 0000000000..2dabda4013 --- /dev/null +++ b/src/model/CoilHeatingSteamBaseboardRadiant.cpp @@ -0,0 +1,376 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "CoilHeatingSteamBaseboardRadiant.hpp" +#include "CoilHeatingSteamBaseboardRadiant_Impl.hpp" +#include "Node.hpp" +#include "Node_Impl.hpp" +#include "Model.hpp" +#include "Model_Impl.hpp" +#include "PlantLoop.hpp" +#include "PlantLoop_Impl.hpp" +#include "ZoneHVACBaseboardRadiantConvectiveSteam.hpp" +#include "ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" + +#include +#include +#include + +#include "../utilities/core/Assert.hpp" +#include "../utilities/data/DataEnums.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + CoilHeatingSteamBaseboardRadiant_Impl::CoilHeatingSteamBaseboardRadiant_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : StraightComponent_Impl(idfObject, model, keepHandle) { + OS_ASSERT(idfObject.iddObject().type() == CoilHeatingSteamBaseboardRadiant::iddObjectType()); + } + + CoilHeatingSteamBaseboardRadiant_Impl::CoilHeatingSteamBaseboardRadiant_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) { + OS_ASSERT(other.iddObject().type() == CoilHeatingSteamBaseboardRadiant::iddObjectType()); + } + + CoilHeatingSteamBaseboardRadiant_Impl::CoilHeatingSteamBaseboardRadiant_Impl(const CoilHeatingSteamBaseboardRadiant_Impl& other, + Model_Impl* model, bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) {} + + const std::vector& CoilHeatingSteamBaseboardRadiant_Impl::outputVariableNames() const { + static const std::vector result; + return result; + } + + IddObjectType CoilHeatingSteamBaseboardRadiant_Impl::iddObjectType() const { + return CoilHeatingSteamBaseboardRadiant::iddObjectType(); + } + + unsigned CoilHeatingSteamBaseboardRadiant_Impl::inletPort() const { + return OS_Coil_Heating_Steam_Baseboard_RadiantFields::InletNodeName; + } + + unsigned CoilHeatingSteamBaseboardRadiant_Impl::outletPort() const { + return OS_Coil_Heating_Steam_Baseboard_RadiantFields::OutletNodeName; + } + + boost::optional CoilHeatingSteamBaseboardRadiant_Impl::containingZoneHVACComponent() const { + // this coil can only be found in a ZoneHVACBaseboardRadiantConvectiveSteam + // check all ZoneHVACBaseboardRadiantConvectiveSteams in the model, seeing if this coil + // is inside of one of them. Return the one it is inside of + + auto const zoneHVACBaseboardRadiantConvectiveSteams = this->model().getConcreteModelObjects(); + // loop through each one, seeing if the coil is contained by the zonehvacbaseboard + for (const auto& zoneHVACBaseboardRadiantConvectiveSteam : zoneHVACBaseboardRadiantConvectiveSteams) { + if (boost::optional coil = zoneHVACBaseboardRadiantConvectiveSteam.heatingCoil()) { + if (coil->handle() == this->handle()) { //if the handles match, this coil is inside of a zonehvacbaseboard + return zoneHVACBaseboardRadiantConvectiveSteam; + } + } + } + + // if the coil isn't inside any zonehvacbaseboards (which currently should never happen), return nothing + return boost::none; + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::addToNode(Node& node) { + if (boost::optional plant = node.plantLoop()) { + if (plant->demandComponent(node.handle())) { + return StraightComponent_Impl::addToNode(node); + } + } + + return false; + } + + std::string CoilHeatingSteamBaseboardRadiant_Impl::heatingDesignCapacityMethod() const { + boost::optional value = getString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacityMethod, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional CoilHeatingSteamBaseboardRadiant_Impl::heatingDesignCapacity() const { + return getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacity, true); + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::isHeatingDesignCapacityAutosized() const { + bool result = false; + boost::optional value = getString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacity, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + double CoilHeatingSteamBaseboardRadiant_Impl::heatingDesignCapacityPerFloorArea() const { + boost::optional value = getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacityPerFloorArea, true); + OS_ASSERT(value); + return value.get(); + } + + double CoilHeatingSteamBaseboardRadiant_Impl::fractionofAutosizedHeatingDesignCapacity() const { + boost::optional value = getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::FractionofAutosizedHeatingDesignCapacity, true); + OS_ASSERT(value); + return value.get(); + } + + double CoilHeatingSteamBaseboardRadiant_Impl::degreeofSubCooling() const { + boost::optional value = getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::DegreeofSubCooling, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional CoilHeatingSteamBaseboardRadiant_Impl::maximumSteamFlowRate() const { + return getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::MaximumSteamFlowRate, true); + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::isMaximumSteamFlowRateAutosized() const { + bool result = false; + boost::optional value = getString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::MaximumSteamFlowRate, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + double CoilHeatingSteamBaseboardRadiant_Impl::convergenceTolerance() const { + boost::optional value = getDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::ConvergenceTolerance, true); + OS_ASSERT(value); + return value.get(); + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setHeatingDesignCapacityMethod(const std::string& heatingDesignCapacityMethod) { + bool result = setString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacityMethod, heatingDesignCapacityMethod); + return result; + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setHeatingDesignCapacity(boost::optional heatingDesignCapacity) { + bool result(false); + if (heatingDesignCapacity) { + result = setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacity, heatingDesignCapacity.get()); + } + return result; + } + + void CoilHeatingSteamBaseboardRadiant_Impl::autosizeHeatingDesignCapacity() { + bool result = setString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacity, "autosize"); + OS_ASSERT(result); + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setHeatingDesignCapacityPerFloorArea(double heatingDesignCapacityPerFloorArea) { + bool result = setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacityPerFloorArea, heatingDesignCapacityPerFloorArea); + return result; + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setFractionofAutosizedHeatingDesignCapacity(double fractionofAutosizedHeatingDesignCapacity) { + bool result = + setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::FractionofAutosizedHeatingDesignCapacity, fractionofAutosizedHeatingDesignCapacity); + return result; + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setDegreeofSubCooling(double degreeofSubCooling) { + bool result = setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::DegreeofSubCooling, degreeofSubCooling); + OS_ASSERT(result); + return result; + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setMaximumSteamFlowRate(boost::optional maximumSteamFlowRate) { + bool result(false); + if (maximumSteamFlowRate) { + result = setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::MaximumSteamFlowRate, maximumSteamFlowRate.get()); + } + OS_ASSERT(result); + return result; + } + + void CoilHeatingSteamBaseboardRadiant_Impl::autosizeMaximumSteamFlowRate() { + bool result = setString(OS_Coil_Heating_Steam_Baseboard_RadiantFields::MaximumSteamFlowRate, "autosize"); + OS_ASSERT(result); + } + + bool CoilHeatingSteamBaseboardRadiant_Impl::setConvergenceTolerance(double convergenceTolerance) { + bool result = setDouble(OS_Coil_Heating_Steam_Baseboard_RadiantFields::ConvergenceTolerance, convergenceTolerance); + return result; + } + + boost::optional CoilHeatingSteamBaseboardRadiant_Impl::autosizedHeatingDesignCapacity() const { + boost::optional result; + // Get the containing ZoneHVAC equipment and get its autosized value + auto parentHVAC = containingZoneHVACComponent(); + if (!parentHVAC) { + return result; + } + return parentHVAC->getAutosizedValue("Design Size Heating Design Capacity", "W"); + } + + boost::optional CoilHeatingSteamBaseboardRadiant_Impl::autosizedMaximumSteamFlowRate() const { + boost::optional result; + // Get the containing ZoneHVAC equipment and get its autosized value + auto parentHVAC = containingZoneHVACComponent(); + if (!parentHVAC) { + return result; + } + return parentHVAC->getAutosizedValue("Design Size Maximum Steam Flow Rate", "m3/s"); + } + + void CoilHeatingSteamBaseboardRadiant_Impl::autosize() { + autosizeHeatingDesignCapacity(); + autosizeMaximumSteamFlowRate(); + } + + void CoilHeatingSteamBaseboardRadiant_Impl::applySizingValues() { + boost::optional val; + val = autosizedHeatingDesignCapacity(); + if (val) { + setHeatingDesignCapacity(val.get()); + } + + val = autosizedMaximumSteamFlowRate(); + if (val) { + setMaximumSteamFlowRate(val.get()); + } + } + + ComponentType CoilHeatingSteamBaseboardRadiant_Impl::componentType() const { + return ComponentType::Heating; + } + + std::vector CoilHeatingSteamBaseboardRadiant_Impl::coolingFuelTypes() const { + return {}; + } + + std::vector CoilHeatingSteamBaseboardRadiant_Impl::heatingFuelTypes() const { + if (auto p_ = plantLoop()) { + return p_->heatingFuelTypes(); + } + return {}; + } + + std::vector CoilHeatingSteamBaseboardRadiant_Impl::appGHeatingFuelTypes() const { + if (auto p_ = plantLoop()) { + return p_->appGHeatingFuelTypes(); + } + return {}; + } + + } // namespace detail + + CoilHeatingSteamBaseboardRadiant::CoilHeatingSteamBaseboardRadiant(const Model& model) + : StraightComponent(CoilHeatingSteamBaseboardRadiant::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + bool ok = true; + ok = setHeatingDesignCapacityMethod("HeatingDesignCapacity"); + OS_ASSERT(ok); + autosizeHeatingDesignCapacity(); + ok = setHeatingDesignCapacityPerFloorArea(0); + OS_ASSERT(ok); + ok = setFractionofAutosizedHeatingDesignCapacity(1.0); + OS_ASSERT(ok); + ok = setDegreeofSubCooling(5.0); + autosizeMaximumSteamFlowRate(); + ok = setConvergenceTolerance(0.001); + OS_ASSERT(ok); + } + + IddObjectType CoilHeatingSteamBaseboardRadiant::iddObjectType() { + return {IddObjectType::OS_Coil_Heating_Steam_Baseboard_Radiant}; + } + + std::vector CoilHeatingSteamBaseboardRadiant::heatingDesignCapacityMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Coil_Heating_Steam_Baseboard_RadiantFields::HeatingDesignCapacityMethod); + } + + std::string CoilHeatingSteamBaseboardRadiant::heatingDesignCapacityMethod() const { + return getImpl()->heatingDesignCapacityMethod(); + } + + boost::optional CoilHeatingSteamBaseboardRadiant::heatingDesignCapacity() const { + return getImpl()->heatingDesignCapacity(); + } + + bool CoilHeatingSteamBaseboardRadiant::isHeatingDesignCapacityAutosized() const { + return getImpl()->isHeatingDesignCapacityAutosized(); + } + + double CoilHeatingSteamBaseboardRadiant::heatingDesignCapacityPerFloorArea() const { + return getImpl()->heatingDesignCapacityPerFloorArea(); + } + + double CoilHeatingSteamBaseboardRadiant::fractionofAutosizedHeatingDesignCapacity() const { + return getImpl()->fractionofAutosizedHeatingDesignCapacity(); + } + + double CoilHeatingSteamBaseboardRadiant::degreeofSubCooling() const { + return getImpl()->degreeofSubCooling(); + } + + boost::optional CoilHeatingSteamBaseboardRadiant::maximumSteamFlowRate() const { + return getImpl()->maximumSteamFlowRate(); + } + + bool CoilHeatingSteamBaseboardRadiant::isMaximumSteamFlowRateAutosized() const { + return getImpl()->isMaximumSteamFlowRateAutosized(); + } + + double CoilHeatingSteamBaseboardRadiant::convergenceTolerance() const { + return getImpl()->convergenceTolerance(); + } + + bool CoilHeatingSteamBaseboardRadiant::setHeatingDesignCapacityMethod(const std::string& heatingDesignCapacityMethod) { + return getImpl()->setHeatingDesignCapacityMethod(heatingDesignCapacityMethod); + } + + bool CoilHeatingSteamBaseboardRadiant::setHeatingDesignCapacity(double heatingDesignCapacity) { + return getImpl()->setHeatingDesignCapacity(heatingDesignCapacity); + } + + void CoilHeatingSteamBaseboardRadiant::autosizeHeatingDesignCapacity() { + getImpl()->autosizeHeatingDesignCapacity(); + } + + bool CoilHeatingSteamBaseboardRadiant::setHeatingDesignCapacityPerFloorArea(double heatingDesignCapacityPerFloorArea) { + return getImpl()->setHeatingDesignCapacityPerFloorArea(heatingDesignCapacityPerFloorArea); + } + + bool CoilHeatingSteamBaseboardRadiant::setFractionofAutosizedHeatingDesignCapacity(double fractionofAutosizedHeatingDesignCapacity) { + return getImpl()->setFractionofAutosizedHeatingDesignCapacity( + fractionofAutosizedHeatingDesignCapacity); + } + + bool CoilHeatingSteamBaseboardRadiant::setDegreeofSubCooling(double degreeofSubCooling) { + return getImpl()->setDegreeofSubCooling(degreeofSubCooling); + } + + bool CoilHeatingSteamBaseboardRadiant::setMaximumSteamFlowRate(double maximumSteamFlowRate) { + return getImpl()->setMaximumSteamFlowRate(maximumSteamFlowRate); + } + + void CoilHeatingSteamBaseboardRadiant::autosizeMaximumSteamFlowRate() { + getImpl()->autosizeMaximumSteamFlowRate(); + } + + bool CoilHeatingSteamBaseboardRadiant::setConvergenceTolerance(double convergenceTolerance) { + return getImpl()->setConvergenceTolerance(convergenceTolerance); + } + + /// @cond + CoilHeatingSteamBaseboardRadiant::CoilHeatingSteamBaseboardRadiant(std::shared_ptr impl) + : StraightComponent(std::move(impl)) {} + /// @endcond + + boost::optional CoilHeatingSteamBaseboardRadiant::autosizedHeatingDesignCapacity() const { + return getImpl()->autosizedHeatingDesignCapacity(); + } + + boost::optional CoilHeatingSteamBaseboardRadiant::autosizedMaximumSteamFlowRate() const { + return getImpl()->autosizedMaximumSteamFlowRate(); + } + +} // namespace model +} // namespace openstudio diff --git a/src/model/CoilHeatingSteamBaseboardRadiant.hpp b/src/model/CoilHeatingSteamBaseboardRadiant.hpp new file mode 100644 index 0000000000..a30cba03a5 --- /dev/null +++ b/src/model/CoilHeatingSteamBaseboardRadiant.hpp @@ -0,0 +1,120 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_HPP +#define MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_HPP + +#include "ModelAPI.hpp" +#include "StraightComponent.hpp" + +namespace openstudio { + +namespace model { + + namespace detail { + + class CoilHeatingSteamBaseboardRadiant_Impl; + + } // namespace detail + + /** CoilHeatingSteamBaseboardRadiant is a StraightComponent that wraps the OpenStudio IDD object 'OS:Coil:Heating:Steam:Baseboard:Radiant'. */ + class MODEL_API CoilHeatingSteamBaseboardRadiant : public StraightComponent + { + public: + /** @name Constructors and Destructors */ + //@{ + + explicit CoilHeatingSteamBaseboardRadiant(const Model& model); + + virtual ~CoilHeatingSteamBaseboardRadiant() override = default; + // Default the copy and move operators because the virtual dtor is explicit + CoilHeatingSteamBaseboardRadiant(const CoilHeatingSteamBaseboardRadiant& other) = default; + CoilHeatingSteamBaseboardRadiant(CoilHeatingSteamBaseboardRadiant&& other) = default; + CoilHeatingSteamBaseboardRadiant& operator=(const CoilHeatingSteamBaseboardRadiant&) = default; + CoilHeatingSteamBaseboardRadiant& operator=(CoilHeatingSteamBaseboardRadiant&&) = default; + + //@} + + static IddObjectType iddObjectType(); + + static std::vector heatingDesignCapacityMethodValues(); + + /** @name Getters */ + //@{ + + std::string heatingDesignCapacityMethod() const; + + boost::optional heatingDesignCapacity() const; + + bool isHeatingDesignCapacityAutosized() const; + + double heatingDesignCapacityPerFloorArea() const; + + double fractionofAutosizedHeatingDesignCapacity() const; + + boost::optional maximumSteamFlowRate() const; + + bool isMaximumSteamFlowRateAutosized() const; + + double degreeofSubCooling() const; + + double convergenceTolerance() const; + + //@} + /** @name Setters */ + //@{ + + bool setHeatingDesignCapacityMethod(const std::string& heatingDesignCapacityMethod); + + bool setHeatingDesignCapacity(double heatingDesignCapacity); + + void autosizeHeatingDesignCapacity(); + + bool setHeatingDesignCapacityPerFloorArea(double heatingDesignCapacityPerFloorArea); + + bool setFractionofAutosizedHeatingDesignCapacity(double fractionofAutosizedHeatingDesignCapacity); + + bool setMaximumSteamFlowRate(double maximumSteamFlowRate); + + void autosizeMaximumSteamFlowRate(); + + bool setDegreeofSubCooling(double degreeofSubCooling); + + bool setConvergenceTolerance(double convergenceTolerance); + + //@} + /** @name Other */ + //@{ + + boost::optional autosizedHeatingDesignCapacity() const; + + boost::optional autosizedMaximumSteamFlowRate() const; + + //@} + protected: + /// @cond + using ImplType = detail::CoilHeatingSteamBaseboardRadiant_Impl; + + explicit CoilHeatingSteamBaseboardRadiant(std::shared_ptr impl); + + friend class detail::CoilHeatingSteamBaseboardRadiant_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.CoilHeatingSteamBaseboardRadiant"); + }; + + /** \relates CoilHeatingSteamBaseboardRadiant*/ + using OptionalCoilHeatingSteamBaseboardRadiant = boost::optional; + + /** \relates CoilHeatingSteamBaseboardRadiant*/ + using CoilHeatingSteamBaseboardRadiantVector = std::vector; + +} // namespace model +} // namespace openstudio + +#endif // MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_HPP diff --git a/src/model/CoilHeatingSteamBaseboardRadiant_Impl.hpp b/src/model/CoilHeatingSteamBaseboardRadiant_Impl.hpp new file mode 100644 index 0000000000..110d6ed432 --- /dev/null +++ b/src/model/CoilHeatingSteamBaseboardRadiant_Impl.hpp @@ -0,0 +1,122 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_IMPL_HPP +#define MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_IMPL_HPP + +#include "ModelAPI.hpp" +#include "StraightComponent_Impl.hpp" +#include "ZoneHVACComponent.hpp" +#include "ZoneHVACComponent_Impl.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + /** CoilHeatingSteamBaseboardRadiant_Impl is a StraightComponent_Impl that is the implementation class for CoilHeatingSteamBaseboardRadiant.*/ + class MODEL_API CoilHeatingSteamBaseboardRadiant_Impl : public StraightComponent_Impl + { + public: + /** @name Constructors and Destructors */ + //@{ + + CoilHeatingSteamBaseboardRadiant_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + CoilHeatingSteamBaseboardRadiant_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle); + + CoilHeatingSteamBaseboardRadiant_Impl(const CoilHeatingSteamBaseboardRadiant_Impl& other, Model_Impl* model, bool keepHandle); + + virtual ~CoilHeatingSteamBaseboardRadiant_Impl() override = default; + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const override; + + virtual IddObjectType iddObjectType() const override; + + virtual unsigned inletPort() const override; + + virtual unsigned outletPort() const override; + + virtual boost::optional containingZoneHVACComponent() const override; + + virtual bool addToNode(Node& node) override; + + virtual ComponentType componentType() const override; + virtual std::vector coolingFuelTypes() const override; + virtual std::vector heatingFuelTypes() const override; + virtual std::vector appGHeatingFuelTypes() const override; + + //@} + /** @name Getters */ + //@{ + + std::string heatingDesignCapacityMethod() const; + + boost::optional heatingDesignCapacity() const; + + bool isHeatingDesignCapacityAutosized() const; + + double heatingDesignCapacityPerFloorArea() const; + + double fractionofAutosizedHeatingDesignCapacity() const; + + boost::optional maximumSteamFlowRate() const; + + bool isMaximumSteamFlowRateAutosized() const; + + double degreeofSubCooling() const; + + double convergenceTolerance() const; + + boost::optional autosizedHeatingDesignCapacity() const; + + boost::optional autosizedMaximumSteamFlowRate() const; + + virtual void autosize() override; + + virtual void applySizingValues() override; + + //@} + /** @name Setters */ + //@{ + + bool setHeatingDesignCapacityMethod(const std::string& heatingDesignCapacityMethod); + + bool setHeatingDesignCapacity(boost::optional heatingDesignCapacity); + + void autosizeHeatingDesignCapacity(); + + bool setHeatingDesignCapacityPerFloorArea(double heatingDesignCapacityPerFloorArea); + + bool setFractionofAutosizedHeatingDesignCapacity(double fractionofAutosizedHeatingDesignCapacity); + + bool setMaximumSteamFlowRate(boost::optional maximumSteamFlowRate); + + void autosizeMaximumSteamFlowRate(); + + bool setDegreeofSubCooling(double degreeofSubCooling); + + bool setConvergenceTolerance(double convergenceTolerance); + + //@} + /** @name Other */ + //@{ + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.CoilHeatingSteamBaseboardRadiant"); + }; + + } // namespace detail + +} // namespace model +} // namespace openstudio + +#endif // MODEL_COILHEATINGSTEAMBASEBOARDRADIANT_IMPL_HPP diff --git a/src/model/CoilHeatingSteam_Impl.hpp b/src/model/CoilHeatingSteam_Impl.hpp new file mode 100644 index 0000000000..bc75b97c5d --- /dev/null +++ b/src/model/CoilHeatingSteam_Impl.hpp @@ -0,0 +1,133 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_COILHEATINGSTEAM_IMPL_HPP +#define MODEL_COILHEATINGSTEAM_IMPL_HPP + +#include "WaterToAirComponent_Impl.hpp" + +namespace openstudio { +namespace model { + + class Schedule; + class Node; + + namespace detail { + + class MODEL_API CoilHeatingSteam_Impl : public WaterToAirComponent_Impl + { + public: + /** @name Constructors and Destructors */ + //@{ + + CoilHeatingSteam_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + CoilHeatingSteam_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle); + + CoilHeatingSteam_Impl(const CoilHeatingSteam_Impl& other, Model_Impl* model, bool keepHandle); + + virtual ~CoilHeatingSteam_Impl() override = default; + + //@} + /** @name Virtual Methods */ + //@{ + + virtual std::vector remove() override; + + virtual bool removeFromPlantLoop() override; + + virtual ModelObject clone(Model model) const override; + + virtual IddObjectType iddObjectType() const override; + + virtual std::vector children() const override; + + virtual const std::vector& outputVariableNames() const override; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + virtual bool addToNode(Node& node) override; + + virtual unsigned airInletPort() const override; + + virtual unsigned airOutletPort() const override; + + virtual unsigned waterInletPort() const override; + + virtual unsigned waterOutletPort() const override; + + virtual boost::optional containingHVACComponent() const override; + + virtual boost::optional containingZoneHVACComponent() const override; + + virtual void autosize() override; + + virtual void applySizingValues() override; + + virtual ComponentType componentType() const override; + virtual std::vector coolingFuelTypes() const override; + virtual std::vector heatingFuelTypes() const override; + virtual std::vector appGHeatingFuelTypes() const override; + + //@} + /** @name Getters */ + //@{ + + Schedule availabilitySchedule() const; + + boost::optional maximumSteamFlowRate(); + + bool isMaximumSteamFlowRateAutosized(); + + double degreeofSubCooling() const; + + double degreeofLoopSubCooling() const; + + std::string coilControlType() const; + + boost::optional temperatureSetpointNode() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + + bool setMaximumSteamFlowRate(double value); + + void autosizeMaximumSteamFlowRate(); + + bool setDegreeofSubCooling(double degreeofSubCooling); + + bool setDegreeofLoopSubCooling(double degreeofLoopSubCooling); + + bool setCoilControlType(const std::string& coilControlType); + + bool setTemperatureSetpointNode(Node& temperatureSetpointNode); + + void resetTemperatureSetpointNode(); + + //@} + /** @name Other */ + //@{ + + boost::optional autosizedMaximumSteamFlowRate() const; + + //@} + + private: + REGISTER_LOGGER("openstudio.model.CoilHeatingSteam"); + + boost::optional availabilityScheduleAsModelObject() const; + + bool setAvailabilityScheduleAsModelObject(const boost::optional& modelObject); + }; + + } // namespace detail + +} // namespace model +} // namespace openstudio + +#endif // MODEL_COILHEATINGSTEAM_IMPL_HPP diff --git a/src/model/CoilHeatingWater.cpp b/src/model/CoilHeatingWater.cpp index a5d12efee8..3a527aee3c 100644 --- a/src/model/CoilHeatingWater.cpp +++ b/src/model/CoilHeatingWater.cpp @@ -23,6 +23,8 @@ #include "ZoneHVACUnitHeater_Impl.hpp" #include "ZoneHVACUnitVentilator.hpp" #include "ZoneHVACUnitVentilator_Impl.hpp" +#include "ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp" +#include "ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp" #include "AirLoopHVACUnitarySystem.hpp" #include "AirLoopHVACUnitarySystem_Impl.hpp" #include "AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.hpp" @@ -522,6 +524,20 @@ namespace model { } } + // ZoneHVACTerminalUnitVariableRefrigerantFlow + + std::vector zoneHVACTerminalUnitVariableRefrigerantFlow; + + zoneHVACTerminalUnitVariableRefrigerantFlow = this->model().getConcreteModelObjects(); + + for (const auto& elem : zoneHVACTerminalUnitVariableRefrigerantFlow) { + if (boost::optional coil = elem.supplementalHeatingCoil()) { + if (coil->handle() == this->handle()) { + return elem; + } + } + } + return boost::none; } diff --git a/src/model/ConcreteModelObjects.hpp b/src/model/ConcreteModelObjects.hpp index 57e043e49b..e63c96ccd0 100644 --- a/src/model/ConcreteModelObjects.hpp +++ b/src/model/ConcreteModelObjects.hpp @@ -129,11 +129,13 @@ #include "CoilHeatingDXVariableSpeed.hpp" #include "CoilHeatingDXVariableSpeedSpeedData.hpp" #include "CoilHeatingWater.hpp" +#include "CoilHeatingSteam.hpp" #include "CoilHeatingWaterToAirHeatPumpEquationFit.hpp" #include "CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.hpp" #include "CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.hpp" #include "CoilHeatingWaterBaseboard.hpp" #include "CoilHeatingWaterBaseboardRadiant.hpp" +#include "CoilHeatingSteamBaseboardRadiant.hpp" #include "CoilPerformanceDXCooling.hpp" #include "CoilSystemCoolingWater.hpp" #include "CoilSystemCoolingWaterHeatExchangerAssisted.hpp" @@ -374,6 +376,7 @@ #include "ProgramControl.hpp" #include "PumpConstantSpeed.hpp" #include "PumpVariableSpeed.hpp" +#include "PumpVariableSpeedCondensate.hpp" #include "PythonPluginInstance.hpp" #include "PythonPluginVariable.hpp" #include "PythonPluginTrendVariable.hpp" @@ -541,6 +544,7 @@ #include "ZoneHVACBaseboardConvectiveWater.hpp" #include "ZoneHVACBaseboardRadiantConvectiveElectric.hpp" #include "ZoneHVACBaseboardRadiantConvectiveWater.hpp" +#include "ZoneHVACBaseboardRadiantConvectiveSteam.hpp" #include "ZoneHVACCoolingPanelRadiantConvectiveWater.hpp" #include "ZoneHVACDehumidifierDX.hpp" #include "ZoneHVACEnergyRecoveryVentilator.hpp" @@ -688,11 +692,13 @@ #include "CoilHeatingDXVariableSpeed_Impl.hpp" #include "CoilHeatingDXVariableSpeedSpeedData_Impl.hpp" #include "CoilHeatingWater_Impl.hpp" +#include "CoilHeatingSteam_Impl.hpp" #include "CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp" #include "CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp" #include "CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData_Impl.hpp" #include "CoilHeatingWaterBaseboard_Impl.hpp" #include "CoilHeatingWaterBaseboardRadiant_Impl.hpp" +#include "CoilHeatingSteamBaseboardRadiant_Impl.hpp" #include "CoilPerformanceDXCooling_Impl.hpp" #include "CoilSystemCoolingWater_Impl.hpp" #include "CoilSystemCoolingWaterHeatExchangerAssisted_Impl.hpp" @@ -933,6 +939,7 @@ #include "ProgramControl_Impl.hpp" #include "PumpConstantSpeed_Impl.hpp" #include "PumpVariableSpeed_Impl.hpp" +#include "PumpVariableSpeedCondensate_Impl.hpp" #include "PythonPluginInstance_Impl.hpp" #include "PythonPluginVariable_Impl.hpp" #include "PythonPluginTrendVariable_Impl.hpp" @@ -1100,6 +1107,7 @@ #include "ZoneHVACBaseboardConvectiveWater_Impl.hpp" #include "ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp" #include "ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp" +#include "ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" #include "ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp" #include "ZoneHVACDehumidifierDX_Impl.hpp" #include "ZoneHVACEnergyRecoveryVentilator_Impl.hpp" diff --git a/src/model/ControllerWaterCoil.hpp b/src/model/ControllerWaterCoil.hpp index bab927a439..be28f24d54 100644 --- a/src/model/ControllerWaterCoil.hpp +++ b/src/model/ControllerWaterCoil.hpp @@ -20,6 +20,7 @@ namespace model { class ControllerWaterCoil_Impl; class CoilCoolingWater_Impl; class CoilHeatingWater_Impl; + class CoilHeatingSteam_Impl; class CoilSystemCoolingWater_Impl; class CoilSystemCoolingWaterHeatExchangerAssisted_Impl; @@ -142,6 +143,7 @@ namespace model { // Classes that need to instantiate it friend class openstudio::model::detail::CoilCoolingWater_Impl; friend class openstudio::model::detail::CoilHeatingWater_Impl; + friend class openstudio::model::detail::CoilHeatingSteam_Impl; friend class openstudio::model::detail::CoilSystemCoolingWater_Impl; friend class openstudio::model::detail::CoilSystemCoolingWaterHeatExchangerAssisted_Impl; diff --git a/src/model/Model.cpp b/src/model/Model.cpp index 657761bf56..4ba818183d 100644 --- a/src/model/Model.cpp +++ b/src/model/Model.cpp @@ -4028,11 +4028,13 @@ namespace model { REGISTER_CONSTRUCTOR(CoilHeatingDXVariableSpeed); REGISTER_CONSTRUCTOR(CoilHeatingDXVariableSpeedSpeedData); REGISTER_CONSTRUCTOR(CoilHeatingWater); + REGISTER_CONSTRUCTOR(CoilHeatingSteam); REGISTER_CONSTRUCTOR(CoilHeatingWaterToAirHeatPumpEquationFit); REGISTER_CONSTRUCTOR(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit); REGISTER_CONSTRUCTOR(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData); REGISTER_CONSTRUCTOR(CoilHeatingWaterBaseboard); REGISTER_CONSTRUCTOR(CoilHeatingWaterBaseboardRadiant); + REGISTER_CONSTRUCTOR(CoilHeatingSteamBaseboardRadiant); REGISTER_CONSTRUCTOR(CoilPerformanceDXCooling); REGISTER_CONSTRUCTOR(CoilSystemCoolingWater); REGISTER_CONSTRUCTOR(CoilSystemCoolingWaterHeatExchangerAssisted); @@ -4272,6 +4274,7 @@ namespace model { REGISTER_CONSTRUCTOR(ProgramControl); REGISTER_CONSTRUCTOR(PumpConstantSpeed); REGISTER_CONSTRUCTOR(PumpVariableSpeed); + REGISTER_CONSTRUCTOR(PumpVariableSpeedCondensate); REGISTER_CONSTRUCTOR(PythonPluginInstance); REGISTER_CONSTRUCTOR(PythonPluginVariable); REGISTER_CONSTRUCTOR(PythonPluginTrendVariable); @@ -4453,6 +4456,7 @@ namespace model { REGISTER_CONSTRUCTOR(ZoneHVACBaseboardConvectiveWater); REGISTER_CONSTRUCTOR(ZoneHVACBaseboardRadiantConvectiveElectric); REGISTER_CONSTRUCTOR(ZoneHVACBaseboardRadiantConvectiveWater); + REGISTER_CONSTRUCTOR(ZoneHVACBaseboardRadiantConvectiveSteam); REGISTER_CONSTRUCTOR(ZoneHVACCoolingPanelRadiantConvectiveWater); REGISTER_CONSTRUCTOR(ZoneHVACIdealLoadsAirSystem); REGISTER_CONSTRUCTOR(ZoneHVACFourPipeFanCoil); @@ -4607,11 +4611,13 @@ namespace model { REGISTER_COPYCONSTRUCTORS(CoilHeatingDXVariableSpeed); REGISTER_COPYCONSTRUCTORS(CoilHeatingDXVariableSpeedSpeedData); REGISTER_COPYCONSTRUCTORS(CoilHeatingWater); + REGISTER_COPYCONSTRUCTORS(CoilHeatingSteam); REGISTER_COPYCONSTRUCTORS(CoilHeatingWaterToAirHeatPumpEquationFit); REGISTER_COPYCONSTRUCTORS(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit); REGISTER_COPYCONSTRUCTORS(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData); REGISTER_COPYCONSTRUCTORS(CoilHeatingWaterBaseboard); REGISTER_COPYCONSTRUCTORS(CoilHeatingWaterBaseboardRadiant); + REGISTER_COPYCONSTRUCTORS(CoilHeatingSteamBaseboardRadiant); REGISTER_COPYCONSTRUCTORS(CoilPerformanceDXCooling); REGISTER_COPYCONSTRUCTORS(CoilSystemCoolingWater); REGISTER_COPYCONSTRUCTORS(CoilSystemCoolingWaterHeatExchangerAssisted); @@ -4851,6 +4857,7 @@ namespace model { REGISTER_COPYCONSTRUCTORS(ProgramControl); REGISTER_COPYCONSTRUCTORS(PumpConstantSpeed); REGISTER_COPYCONSTRUCTORS(PumpVariableSpeed); + REGISTER_COPYCONSTRUCTORS(PumpVariableSpeedCondensate); REGISTER_COPYCONSTRUCTORS(PythonPluginInstance); REGISTER_COPYCONSTRUCTORS(PythonPluginVariable); REGISTER_COPYCONSTRUCTORS(PythonPluginTrendVariable); @@ -5032,6 +5039,7 @@ namespace model { REGISTER_COPYCONSTRUCTORS(ZoneHVACBaseboardConvectiveWater); REGISTER_COPYCONSTRUCTORS(ZoneHVACBaseboardRadiantConvectiveElectric); REGISTER_COPYCONSTRUCTORS(ZoneHVACBaseboardRadiantConvectiveWater); + REGISTER_COPYCONSTRUCTORS(ZoneHVACBaseboardRadiantConvectiveSteam); REGISTER_COPYCONSTRUCTORS(ZoneHVACCoolingPanelRadiantConvectiveWater); REGISTER_COPYCONSTRUCTORS(ZoneHVACIdealLoadsAirSystem); REGISTER_COPYCONSTRUCTORS(ZoneHVACFourPipeFanCoil); diff --git a/src/model/ModelHVAC.i b/src/model/ModelHVAC.i index 356ce9c494..306da18fa5 100644 --- a/src/model/ModelHVAC.i +++ b/src/model/ModelHVAC.i @@ -197,6 +197,7 @@ MODELOBJECT_TEMPLATES(CoilHeatingGasMultiStageStageData); MODELOBJECT_TEMPLATES(CoilHeatingElectricMultiStageStageData); MODELOBJECT_TEMPLATES(CoilHeatingDXVariableSpeedSpeedData); MODELOBJECT_TEMPLATES(CoilHeatingWater); +MODELOBJECT_TEMPLATES(CoilHeatingSteam); MODELOBJECT_TEMPLATES(CoilHeatingWaterToAirHeatPumpEquationFit); MODELOBJECT_TEMPLATES(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit); MODELOBJECT_TEMPLATES(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData); @@ -327,6 +328,7 @@ SWIG_MODELOBJECT(CoilHeatingGasMultiStageStageData, 1); SWIG_MODELOBJECT(CoilHeatingElectricMultiStageStageData, 1); SWIG_MODELOBJECT(CoilHeatingDXVariableSpeedSpeedData, 1); SWIG_MODELOBJECT(CoilHeatingWater, 1); +SWIG_MODELOBJECT(CoilHeatingSteam, 1); SWIG_MODELOBJECT(CoilHeatingWaterToAirHeatPumpEquationFit, 1); SWIG_MODELOBJECT(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit, 1); SWIG_MODELOBJECT(CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData, 1); diff --git a/src/model/ModelStraightComponent.i b/src/model/ModelStraightComponent.i index 8a8c5cc7e7..831816fbbe 100644 --- a/src/model/ModelStraightComponent.i +++ b/src/model/ModelStraightComponent.i @@ -158,6 +158,7 @@ MODELOBJECT_TEMPLATES(CoilHeatingLowTempRadiantConstFlow); MODELOBJECT_TEMPLATES(CoilHeatingLowTempRadiantVarFlow); MODELOBJECT_TEMPLATES(CoilHeatingWaterBaseboard); MODELOBJECT_TEMPLATES(CoilHeatingWaterBaseboardRadiant); +MODELOBJECT_TEMPLATES(CoilHeatingSteamBaseboardRadiant); MODELOBJECT_TEMPLATES(CoilSystemCoolingDXHeatExchangerAssisted); MODELOBJECT_TEMPLATES(CoilSystemCoolingWater); MODELOBJECT_TEMPLATES(CoilSystemCoolingWaterHeatExchangerAssisted); @@ -197,6 +198,7 @@ MODELOBJECT_TEMPLATES(PipeOutdoor); MODELOBJECT_TEMPLATES(PlantComponentTemperatureSource); MODELOBJECT_TEMPLATES(PumpConstantSpeed); MODELOBJECT_TEMPLATES(PumpVariableSpeed); +MODELOBJECT_TEMPLATES(PumpVariableSpeedCondensate); MODELOBJECT_TEMPLATES(SolarCollectorFlatPlatePhotovoltaicThermal); MODELOBJECT_TEMPLATES(SolarCollectorFlatPlateWater); MODELOBJECT_TEMPLATES(SolarCollectorIntegralCollectorStorage); @@ -247,6 +249,7 @@ SWIG_MODELOBJECT(CoilHeatingLowTempRadiantConstFlow,1); SWIG_MODELOBJECT(CoilHeatingLowTempRadiantVarFlow,1); SWIG_MODELOBJECT(CoilHeatingWaterBaseboard,1); SWIG_MODELOBJECT(CoilHeatingWaterBaseboardRadiant,1); +SWIG_MODELOBJECT(CoilHeatingSteamBaseboardRadiant,1); SWIG_MODELOBJECT(CoilSystemCoolingDXHeatExchangerAssisted,1); SWIG_MODELOBJECT(CoilSystemCoolingWater,1); SWIG_MODELOBJECT(CoilSystemCoolingWaterHeatExchangerAssisted,1); @@ -285,6 +288,7 @@ SWIG_MODELOBJECT(PipeOutdoor,1); SWIG_MODELOBJECT(PlantComponentTemperatureSource,1); SWIG_MODELOBJECT(PumpConstantSpeed,1); SWIG_MODELOBJECT(PumpVariableSpeed,1); +SWIG_MODELOBJECT(PumpVariableSpeedCondensate,1); SWIG_MODELOBJECT(SolarCollectorFlatPlatePhotovoltaicThermal,1); SWIG_MODELOBJECT(SolarCollectorFlatPlateWater,1); SWIG_MODELOBJECT(SolarCollectorIntegralCollectorStorage,1); diff --git a/src/model/ModelZoneHVAC.i b/src/model/ModelZoneHVAC.i index 2d0ee760dc..ccecb77f62 100644 --- a/src/model/ModelZoneHVAC.i +++ b/src/model/ModelZoneHVAC.i @@ -50,6 +50,7 @@ MODELOBJECT_TEMPLATES(ZoneHVACBaseboardConvectiveElectric); MODELOBJECT_TEMPLATES(ZoneHVACBaseboardConvectiveWater); MODELOBJECT_TEMPLATES(ZoneHVACBaseboardRadiantConvectiveElectric); MODELOBJECT_TEMPLATES(ZoneHVACBaseboardRadiantConvectiveWater); +MODELOBJECT_TEMPLATES(ZoneHVACBaseboardRadiantConvectiveSteam); MODELOBJECT_TEMPLATES(ZoneHVACCoolingPanelRadiantConvectiveWater); MODELOBJECT_TEMPLATES(ZoneHVACDehumidifierDX); MODELOBJECT_TEMPLATES(ZoneHVACEnergyRecoveryVentilator); @@ -76,6 +77,7 @@ SWIG_MODELOBJECT(ZoneHVACBaseboardConvectiveElectric,1); SWIG_MODELOBJECT(ZoneHVACBaseboardConvectiveWater,1); SWIG_MODELOBJECT(ZoneHVACBaseboardRadiantConvectiveElectric,1); SWIG_MODELOBJECT(ZoneHVACBaseboardRadiantConvectiveWater,1); +SWIG_MODELOBJECT(ZoneHVACBaseboardRadiantConvectiveSteam,1); SWIG_MODELOBJECT(ZoneHVACCoolingPanelRadiantConvectiveWater,1); SWIG_MODELOBJECT(ZoneHVACDehumidifierDX,1); SWIG_MODELOBJECT(ZoneHVACEnergyRecoveryVentilator,1); diff --git a/src/model/PumpVariableSpeedCondensate.cpp b/src/model/PumpVariableSpeedCondensate.cpp new file mode 100644 index 0000000000..f5b83256c7 --- /dev/null +++ b/src/model/PumpVariableSpeedCondensate.cpp @@ -0,0 +1,618 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "PumpVariableSpeedCondensate.hpp" +#include "PumpVariableSpeedCondensate_Impl.hpp" + +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "Node.hpp" +#include "Node_Impl.hpp" +#include "ThermalZone.hpp" +#include "ThermalZone_Impl.hpp" + +#include + +#include +#include +#include "../utilities/core/Assert.hpp" +#include "../utilities/data/DataEnums.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + PumpVariableSpeedCondensate_Impl::PumpVariableSpeedCondensate_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : StraightComponent_Impl(idfObject, model, keepHandle) { + OS_ASSERT(idfObject.iddObject().type() == PumpVariableSpeedCondensate::iddObjectType()); + } + + PumpVariableSpeedCondensate_Impl::PumpVariableSpeedCondensate_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, + bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) { + OS_ASSERT(other.iddObject().type() == PumpVariableSpeedCondensate::iddObjectType()); + } + + PumpVariableSpeedCondensate_Impl::PumpVariableSpeedCondensate_Impl(const PumpVariableSpeedCondensate_Impl& other, Model_Impl* model, + bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) {} + + const std::vector& PumpVariableSpeedCondensate_Impl::outputVariableNames() const { + static const std::vector result{ + "Pump Electricity Rate", "Pump Electricity Energy", "Pump Shaft Power", "Pump Fluid Heat Gain Rate", "Pump Fluid Heat Gain Energy", + "Pump Outlet Temperature", "Pump Mass Flow Rate", "Pump Operating Pumps Count", + + // The Key is the Pump, not the zone, so it's right to report here + // EnergyPlus/Pumps.cc::GetPumpInput() + // TODO: Implement this check and make not static above once ModelObject return type has changed + //if (! p.zone().empty() ) { + "Pump Zone Total Heating Rate", "Pump Zone Total Heating Energy", "Pump Zone Convective Heating Rate", "Pump Zone Radiative Heating Rate" + // } + }; + return result; + } + + std::vector PumpVariableSpeedCondensate_Impl::getScheduleTypeKeys(const Schedule& schedule) const { + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()); + UnsignedVector::const_iterator e(fieldIndices.end()); + if (std::find(b, e, OS_Pump_VariableSpeed_CondensateFields::PumpFlowRateScheduleName) != e) { + result.push_back(ScheduleTypeKey("PumpVariableSpeedCondensate", "Pump Flow Rate")); + } + return result; + } + + IddObjectType PumpVariableSpeedCondensate_Impl::iddObjectType() const { + return PumpVariableSpeedCondensate::iddObjectType(); + } + + std::vector PumpVariableSpeedCondensate_Impl::children() const { + ModelObjectVector result; + + return result; + } + + unsigned PumpVariableSpeedCondensate_Impl::inletPort() const { + return OS_Pump_VariableSpeed_CondensateFields::InletNodeName; + } + + unsigned PumpVariableSpeedCondensate_Impl::outletPort() const { + return OS_Pump_VariableSpeed_CondensateFields::OutletNodeName; + } + + boost::optional PumpVariableSpeedCondensate_Impl::ratedSteamVolumeFlowRate() const { + return getDouble(OS_Pump_VariableSpeed_CondensateFields::RatedSteamVolumeFlowRate, true); + } + + bool PumpVariableSpeedCondensate_Impl::isRatedSteamVolumeFlowRateAutosized() const { + bool result = false; + boost::optional value = getString(OS_Pump_VariableSpeed_CondensateFields::RatedSteamVolumeFlowRate, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + double PumpVariableSpeedCondensate_Impl::ratedPumpHead() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::RatedPumpHead, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional PumpVariableSpeedCondensate_Impl::ratedPowerConsumption() const { + return getDouble(OS_Pump_VariableSpeed_CondensateFields::RatedPowerConsumption, true); + } + + bool PumpVariableSpeedCondensate_Impl::isRatedPowerConsumptionAutosized() const { + bool result = false; + boost::optional value = getString(OS_Pump_VariableSpeed_CondensateFields::RatedPowerConsumption, true); + if (value) { + result = openstudio::istringEqual(value.get(), "autosize"); + } + return result; + } + + double PumpVariableSpeedCondensate_Impl::motorEfficiency() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::MotorEfficiency, true); + OS_ASSERT(value); + return value.get(); + } + + double PumpVariableSpeedCondensate_Impl::fractionofMotorInefficienciestoFluidStream() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::FractionofMotorInefficienciestoFluidStream, true); + OS_ASSERT(value); + return value.get(); + } + + double PumpVariableSpeedCondensate_Impl::coefficient1ofthePartLoadPerformanceCurve() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient1ofthePartLoadPerformanceCurve, true); + OS_ASSERT(value); + return value.get(); + } + + double PumpVariableSpeedCondensate_Impl::coefficient2ofthePartLoadPerformanceCurve() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient2ofthePartLoadPerformanceCurve, true); + OS_ASSERT(value); + return value.get(); + } + + double PumpVariableSpeedCondensate_Impl::coefficient3ofthePartLoadPerformanceCurve() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient3ofthePartLoadPerformanceCurve, true); + OS_ASSERT(value); + return value.get(); + } + + double PumpVariableSpeedCondensate_Impl::coefficient4ofthePartLoadPerformanceCurve() const { + boost::optional value = getDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient4ofthePartLoadPerformanceCurve, true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional PumpVariableSpeedCondensate_Impl::pumpFlowRateSchedule() const { + return getObject().getModelObjectTarget(OS_Pump_VariableSpeed_CondensateFields::PumpFlowRateScheduleName); + } + + bool PumpVariableSpeedCondensate_Impl::setRatedSteamVolumeFlowRate(boost::optional ratedSteamVolumeFlowRate) { + bool result(false); + if (ratedSteamVolumeFlowRate) { + result = setDouble(OS_Pump_VariableSpeed_CondensateFields::RatedSteamVolumeFlowRate, ratedSteamVolumeFlowRate.get()); + } else { + resetRatedSteamVolumeFlowRate(); + result = true; + } + OS_ASSERT(result); + return result; + } + + void PumpVariableSpeedCondensate_Impl::resetRatedSteamVolumeFlowRate() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::RatedSteamVolumeFlowRate, ""); + OS_ASSERT(result); + } + + void PumpVariableSpeedCondensate_Impl::autosizeRatedSteamVolumeFlowRate() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::RatedSteamVolumeFlowRate, "autosize"); + OS_ASSERT(result); + } + + bool PumpVariableSpeedCondensate_Impl::setRatedPumpHead(double ratedPumpHead) { + bool result = setDouble(OS_Pump_VariableSpeed_CondensateFields::RatedPumpHead, ratedPumpHead); + OS_ASSERT(result); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setRatedPowerConsumption(boost::optional ratedPowerConsumption) { + bool result(false); + if (ratedPowerConsumption) { + result = setDouble(OS_Pump_VariableSpeed_CondensateFields::RatedPowerConsumption, ratedPowerConsumption.get()); + } else { + resetRatedPowerConsumption(); + result = true; + } + OS_ASSERT(result); + return result; + } + + void PumpVariableSpeedCondensate_Impl::resetRatedPowerConsumption() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::RatedPowerConsumption, ""); + OS_ASSERT(result); + } + + void PumpVariableSpeedCondensate_Impl::autosizeRatedPowerConsumption() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::RatedPowerConsumption, "autosize"); + OS_ASSERT(result); + } + + bool PumpVariableSpeedCondensate_Impl::setMotorEfficiency(double motorEfficiency) { + bool result = setDouble(OS_Pump_VariableSpeed_CondensateFields::MotorEfficiency, motorEfficiency); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setFractionofMotorInefficienciestoFluidStream(double fractionofMotorInefficienciestoFluidStream) { + bool result = + setDouble(OS_Pump_VariableSpeed_CondensateFields::FractionofMotorInefficienciestoFluidStream, fractionofMotorInefficienciestoFluidStream); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setCoefficient1ofthePartLoadPerformanceCurve(double coefficient1ofthePartLoadPerformanceCurve) { + bool result = + setDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient1ofthePartLoadPerformanceCurve, coefficient1ofthePartLoadPerformanceCurve); + OS_ASSERT(result); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setCoefficient2ofthePartLoadPerformanceCurve(double coefficient2ofthePartLoadPerformanceCurve) { + bool result = + setDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient2ofthePartLoadPerformanceCurve, coefficient2ofthePartLoadPerformanceCurve); + OS_ASSERT(result); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setCoefficient3ofthePartLoadPerformanceCurve(double coefficient3ofthePartLoadPerformanceCurve) { + bool result = + setDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient3ofthePartLoadPerformanceCurve, coefficient3ofthePartLoadPerformanceCurve); + OS_ASSERT(result); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setCoefficient4ofthePartLoadPerformanceCurve(double coefficient4ofthePartLoadPerformanceCurve) { + bool result = + setDouble(OS_Pump_VariableSpeed_CondensateFields::Coefficient4ofthePartLoadPerformanceCurve, coefficient4ofthePartLoadPerformanceCurve); + OS_ASSERT(result); + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setPumpFlowRateSchedule(Schedule& schedule) { + bool result = + setSchedule(OS_Pump_VariableSpeed_CondensateFields::PumpFlowRateScheduleName, "PumpVariableSpeedCondensate", "Pump Flow Rate", schedule); + return result; + } + + void PumpVariableSpeedCondensate_Impl::resetPumpFlowRateSchedule() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::PumpFlowRateScheduleName, ""); + OS_ASSERT(result); + } + + bool PumpVariableSpeedCondensate_Impl::addToNode(Node& node) { + if (node.plantLoop()) { + return StraightComponent_Impl::addToNode(node); + } + + return false; + } + + boost::optional PumpVariableSpeedCondensate_Impl::pumpFlowRateScheduleAsModelObject() const { + OptionalModelObject result; + OptionalSchedule intermediate = pumpFlowRateSchedule(); + if (intermediate) { + result = *intermediate; + } + return result; + } + + bool PumpVariableSpeedCondensate_Impl::setPumpFlowRateScheduleAsModelObject(const boost::optional& modelObject) { + if (modelObject) { + OptionalSchedule intermediate = modelObject->optionalCast(); + if (intermediate) { + Schedule schedule(*intermediate); + return setPumpFlowRateSchedule(schedule); + } else { + return false; + } + } else { + resetPumpFlowRateSchedule(); + } + return true; + } + + boost::optional PumpVariableSpeedCondensate_Impl::autosizedRatedSteamVolumeFlowRate() const { + return getAutosizedValue("Design Steam Volume Flow Rate", "m3/s"); + } + + boost::optional PumpVariableSpeedCondensate_Impl::autosizedRatedPowerConsumption() const { + return getAutosizedValue("Design Power Consumption", "W"); + } + + void PumpVariableSpeedCondensate_Impl::autosize() { + autosizeRatedSteamVolumeFlowRate(); + autosizeRatedPowerConsumption(); + } + + void PumpVariableSpeedCondensate_Impl::applySizingValues() { + boost::optional val; + val = autosizedRatedSteamVolumeFlowRate(); + if (val) { + setRatedSteamVolumeFlowRate(val.get()); + } + + val = autosizedRatedPowerConsumption(); + if (val) { + setRatedPowerConsumption(val.get()); + } + } + + std::string PumpVariableSpeedCondensate_Impl::designPowerSizingMethod() const { + auto value = getString(OS_Pump_VariableSpeed_CondensateFields::DesignPowerSizingMethod, true); + OS_ASSERT(value); + return value.get(); + } + + bool PumpVariableSpeedCondensate_Impl::setDesignPowerSizingMethod(const std::string& designPowerSizingMethod) { + return setString(OS_Pump_VariableSpeed_CondensateFields::DesignPowerSizingMethod, designPowerSizingMethod); + } + + double PumpVariableSpeedCondensate_Impl::designElectricPowerPerUnitFlowRate() const { + auto value = getDouble(OS_Pump_VariableSpeed_CondensateFields::DesignElectricPowerperUnitFlowRate, true); + OS_ASSERT(value); + return value.get(); + } + + bool PumpVariableSpeedCondensate_Impl::setDesignElectricPowerPerUnitFlowRate(double designElectricPowerPerUnitFlowRate) { + return setDouble(OS_Pump_VariableSpeed_CondensateFields::DesignElectricPowerperUnitFlowRate, designElectricPowerPerUnitFlowRate); + } + + double PumpVariableSpeedCondensate_Impl::designShaftPowerPerUnitFlowRatePerUnitHead() const { + auto value = getDouble(OS_Pump_VariableSpeed_CondensateFields::DesignShaftPowerperUnitFlowRateperUnitHead, true); + OS_ASSERT(value); + return value.get(); + } + + bool PumpVariableSpeedCondensate_Impl::setDesignShaftPowerPerUnitFlowRatePerUnitHead(double designShaftPowerPerUnitFlowRatePerUnitHead) { + return setDouble(OS_Pump_VariableSpeed_CondensateFields::DesignShaftPowerperUnitFlowRateperUnitHead, + designShaftPowerPerUnitFlowRatePerUnitHead); + } + + double PumpVariableSpeedCondensate_Impl::skinLossRadiativeFraction() const { + auto value = getDouble(OS_Pump_VariableSpeed_CondensateFields::SkinLossRadiativeFraction, true); + OS_ASSERT(value); + return value.get(); + } + + bool PumpVariableSpeedCondensate_Impl::setSkinLossRadiativeFraction(double skinLossRadiativeFraction) { + return setDouble(OS_Pump_VariableSpeed_CondensateFields::SkinLossRadiativeFraction, skinLossRadiativeFraction); + } + + boost::optional PumpVariableSpeedCondensate_Impl::zone() const { + return getObject().getModelObjectTarget(OS_Pump_VariableSpeed_CondensateFields::ZoneName); + } + + bool PumpVariableSpeedCondensate_Impl::setZone(const ThermalZone& thermalZone) { + return setPointer(OS_Pump_VariableSpeed_CondensateFields::ZoneName, thermalZone.handle()); + } + + void PumpVariableSpeedCondensate_Impl::resetZone() { + bool result = setString(OS_Pump_VariableSpeed_CondensateFields::ZoneName, ""); + OS_ASSERT(result); + } + + std::vector PumpVariableSpeedCondensate_Impl::emsActuatorNames() const { + std::vector actuators{{"Pump", "Pump Mass Flow Rate"}, {"Pump", "Pump Pressure Rise"}}; + return actuators; + } + + std::vector PumpVariableSpeedCondensate_Impl::emsInternalVariableNames() const { + std::vector types{"Pump Maximum Mass Flow Rate"}; + return types; + } + + std::string PumpVariableSpeedCondensate_Impl::endUseSubcategory() const { + auto value = getString(OS_Pump_VariableSpeed_CondensateFields::EndUseSubcategory, true); + OS_ASSERT(value); + return value.get(); + } + + bool PumpVariableSpeedCondensate_Impl::setEndUseSubcategory(const std::string& endUseSubcategory) { + return setString(OS_Pump_VariableSpeed_CondensateFields::EndUseSubcategory, endUseSubcategory); + } + + ComponentType PumpVariableSpeedCondensate_Impl::componentType() const { + return ComponentType::None; + } + + std::vector PumpVariableSpeedCondensate_Impl::coolingFuelTypes() const { + return {}; + } + + std::vector PumpVariableSpeedCondensate_Impl::heatingFuelTypes() const { + return {}; + } + + std::vector PumpVariableSpeedCondensate_Impl::appGHeatingFuelTypes() const { + return {}; + } + + } // namespace detail + + PumpVariableSpeedCondensate::PumpVariableSpeedCondensate(const Model& model) + : StraightComponent(PumpVariableSpeedCondensate::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + autosizeRatedSteamVolumeFlowRate(); + setRatedPumpHead(179352); + autosizeRatedPowerConsumption(); + setMotorEfficiency(0.9); + setFractionofMotorInefficienciestoFluidStream(0.0); + setCoefficient1ofthePartLoadPerformanceCurve(0.0); + setCoefficient2ofthePartLoadPerformanceCurve(1.0); + setCoefficient3ofthePartLoadPerformanceCurve(0.0); + setCoefficient4ofthePartLoadPerformanceCurve(0.0); + setSkinLossRadiativeFraction(0.5); + setDesignPowerSizingMethod("PowerPerFlowPerPressure"); + setDesignElectricPowerPerUnitFlowRate(348701.1); + setDesignShaftPowerPerUnitFlowRatePerUnitHead(1.282051282); + setEndUseSubcategory("General"); + } + + IddObjectType PumpVariableSpeedCondensate::iddObjectType() { + IddObjectType result(IddObjectType::OS_Pump_VariableSpeed_Condensate); + return result; + } + + std::vector PumpVariableSpeedCondensate::designPowerSizingMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_Pump_VariableSpeed_CondensateFields::DesignPowerSizingMethod); + } + + boost::optional PumpVariableSpeedCondensate::ratedSteamVolumeFlowRate() const { + return getImpl()->ratedSteamVolumeFlowRate(); + } + + bool PumpVariableSpeedCondensate::isRatedSteamVolumeFlowRateAutosized() const { + return getImpl()->isRatedSteamVolumeFlowRateAutosized(); + } + + double PumpVariableSpeedCondensate::ratedPumpHead() const { + return getImpl()->ratedPumpHead(); + } + + boost::optional PumpVariableSpeedCondensate::ratedPowerConsumption() const { + return getImpl()->ratedPowerConsumption(); + } + + bool PumpVariableSpeedCondensate::isRatedPowerConsumptionAutosized() const { + return getImpl()->isRatedPowerConsumptionAutosized(); + } + + double PumpVariableSpeedCondensate::motorEfficiency() const { + return getImpl()->motorEfficiency(); + } + + double PumpVariableSpeedCondensate::fractionofMotorInefficienciestoFluidStream() const { + return getImpl()->fractionofMotorInefficienciestoFluidStream(); + } + + double PumpVariableSpeedCondensate::coefficient1ofthePartLoadPerformanceCurve() const { + return getImpl()->coefficient1ofthePartLoadPerformanceCurve(); + } + + double PumpVariableSpeedCondensate::coefficient2ofthePartLoadPerformanceCurve() const { + return getImpl()->coefficient2ofthePartLoadPerformanceCurve(); + } + + double PumpVariableSpeedCondensate::coefficient3ofthePartLoadPerformanceCurve() const { + return getImpl()->coefficient3ofthePartLoadPerformanceCurve(); + } + + double PumpVariableSpeedCondensate::coefficient4ofthePartLoadPerformanceCurve() const { + return getImpl()->coefficient4ofthePartLoadPerformanceCurve(); + } + + boost::optional PumpVariableSpeedCondensate::pumpFlowRateSchedule() const { + return getImpl()->pumpFlowRateSchedule(); + } + + bool PumpVariableSpeedCondensate::setRatedSteamVolumeFlowRate(double ratedSteamVolumeFlowRate) { + return getImpl()->setRatedSteamVolumeFlowRate(ratedSteamVolumeFlowRate); + } + + void PumpVariableSpeedCondensate::resetRatedSteamVolumeFlowRate() { + getImpl()->resetRatedSteamVolumeFlowRate(); + } + + void PumpVariableSpeedCondensate::autosizeRatedSteamVolumeFlowRate() { + getImpl()->autosizeRatedSteamVolumeFlowRate(); + } + + bool PumpVariableSpeedCondensate::setRatedPumpHead(double ratedPumpHead) { + return getImpl()->setRatedPumpHead(ratedPumpHead); + } + + bool PumpVariableSpeedCondensate::setRatedPowerConsumption(double ratedPowerConsumption) { + return getImpl()->setRatedPowerConsumption(ratedPowerConsumption); + } + + void PumpVariableSpeedCondensate::resetRatedPowerConsumption() { + getImpl()->resetRatedPowerConsumption(); + } + + void PumpVariableSpeedCondensate::autosizeRatedPowerConsumption() { + getImpl()->autosizeRatedPowerConsumption(); + } + + bool PumpVariableSpeedCondensate::setMotorEfficiency(double motorEfficiency) { + return getImpl()->setMotorEfficiency(motorEfficiency); + } + + bool PumpVariableSpeedCondensate::setFractionofMotorInefficienciestoFluidStream(double fractionofMotorInefficienciestoFluidStream) { + return getImpl()->setFractionofMotorInefficienciestoFluidStream( + fractionofMotorInefficienciestoFluidStream); + } + + bool PumpVariableSpeedCondensate::setCoefficient1ofthePartLoadPerformanceCurve(double coefficient1ofthePartLoadPerformanceCurve) { + return getImpl()->setCoefficient1ofthePartLoadPerformanceCurve( + coefficient1ofthePartLoadPerformanceCurve); + } + + bool PumpVariableSpeedCondensate::setCoefficient2ofthePartLoadPerformanceCurve(double coefficient2ofthePartLoadPerformanceCurve) { + return getImpl()->setCoefficient2ofthePartLoadPerformanceCurve( + coefficient2ofthePartLoadPerformanceCurve); + } + + bool PumpVariableSpeedCondensate::setCoefficient3ofthePartLoadPerformanceCurve(double coefficient3ofthePartLoadPerformanceCurve) { + return getImpl()->setCoefficient3ofthePartLoadPerformanceCurve( + coefficient3ofthePartLoadPerformanceCurve); + } + + bool PumpVariableSpeedCondensate::setCoefficient4ofthePartLoadPerformanceCurve(double coefficient4ofthePartLoadPerformanceCurve) { + return getImpl()->setCoefficient4ofthePartLoadPerformanceCurve( + coefficient4ofthePartLoadPerformanceCurve); + } + + bool PumpVariableSpeedCondensate::setPumpFlowRateSchedule(Schedule& schedule) { + return getImpl()->setPumpFlowRateSchedule(schedule); + } + + void PumpVariableSpeedCondensate::resetPumpFlowRateSchedule() { + getImpl()->resetPumpFlowRateSchedule(); + } + + std::string PumpVariableSpeedCondensate::designPowerSizingMethod() const { + return getImpl()->designPowerSizingMethod(); + } + + bool PumpVariableSpeedCondensate::setDesignPowerSizingMethod(const std::string& designPowerSizingMethod) { + return getImpl()->setDesignPowerSizingMethod(designPowerSizingMethod); + } + + double PumpVariableSpeedCondensate::designElectricPowerPerUnitFlowRate() const { + return getImpl()->designElectricPowerPerUnitFlowRate(); + } + + bool PumpVariableSpeedCondensate::setDesignElectricPowerPerUnitFlowRate(double designElectricPowerPerUnitFlowRate) { + return getImpl()->setDesignElectricPowerPerUnitFlowRate(designElectricPowerPerUnitFlowRate); + } + + double PumpVariableSpeedCondensate::designShaftPowerPerUnitFlowRatePerUnitHead() const { + return getImpl()->designShaftPowerPerUnitFlowRatePerUnitHead(); + } + + bool PumpVariableSpeedCondensate::setDesignShaftPowerPerUnitFlowRatePerUnitHead(double designShaftPowerPerUnitFlowRatePerUnitHead) { + return getImpl()->setDesignShaftPowerPerUnitFlowRatePerUnitHead( + designShaftPowerPerUnitFlowRatePerUnitHead); + } + + boost::optional PumpVariableSpeedCondensate::zone() const { + return getImpl()->zone(); + } + + bool PumpVariableSpeedCondensate::setZone(const ThermalZone& thermalZone) { + return getImpl()->setZone(thermalZone); + } + + void PumpVariableSpeedCondensate::resetZone() { + getImpl()->resetZone(); + } + + double PumpVariableSpeedCondensate::skinLossRadiativeFraction() const { + return getImpl()->skinLossRadiativeFraction(); + } + + bool PumpVariableSpeedCondensate::setSkinLossRadiativeFraction(double skinLossRadiativeFraction) { + return getImpl()->setSkinLossRadiativeFraction(skinLossRadiativeFraction); + } + + std::string PumpVariableSpeedCondensate::endUseSubcategory() const { + return getImpl()->endUseSubcategory(); + } + + bool PumpVariableSpeedCondensate::setEndUseSubcategory(const std::string& endUseSubcategory) { + return getImpl()->setEndUseSubcategory(endUseSubcategory); + } + + /// @cond + PumpVariableSpeedCondensate::PumpVariableSpeedCondensate(std::shared_ptr impl) + : StraightComponent(std::move(impl)) {} + /// @endcond + + boost::optional PumpVariableSpeedCondensate::autosizedRatedSteamVolumeFlowRate() const { + return getImpl()->autosizedRatedSteamVolumeFlowRate(); + } + + boost::optional PumpVariableSpeedCondensate::autosizedRatedPowerConsumption() const { + return getImpl()->autosizedRatedPowerConsumption(); + } + +} // namespace model +} // namespace openstudio diff --git a/src/model/PumpVariableSpeedCondensate.hpp b/src/model/PumpVariableSpeedCondensate.hpp new file mode 100644 index 0000000000..5d68008060 --- /dev/null +++ b/src/model/PumpVariableSpeedCondensate.hpp @@ -0,0 +1,168 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_PUMPVARIABLESPEEDCONDENSATE_HPP +#define MODEL_PUMPVARIABLESPEEDCONDENSATE_HPP + +#include "ModelAPI.hpp" +#include "StraightComponent.hpp" + +namespace openstudio { +namespace model { + + class Schedule; + class ThermalZone; + + namespace detail { + + class PumpVariableSpeedCondensate_Impl; + + } // namespace detail + + /** PumpVariableSpeedCondensate is a StraightComponent that wraps the OpenStudio IDD object + * 'OS:Pump:VariableSpeed:Condensate'. */ + class MODEL_API PumpVariableSpeedCondensate : public StraightComponent + { + public: + /** @name Constructors and Destructors */ + //@{ + + explicit PumpVariableSpeedCondensate(const Model& model); + + virtual ~PumpVariableSpeedCondensate() override = default; + // Default the copy and move operators because the virtual dtor is explicit + PumpVariableSpeedCondensate(const PumpVariableSpeedCondensate& other) = default; + PumpVariableSpeedCondensate(PumpVariableSpeedCondensate&& other) = default; + PumpVariableSpeedCondensate& operator=(const PumpVariableSpeedCondensate&) = default; + PumpVariableSpeedCondensate& operator=(PumpVariableSpeedCondensate&&) = default; + + //@} + + static IddObjectType iddObjectType(); + + static std::vector designPowerSizingMethodValues(); + + /** @name Getters */ + //@{ + + boost::optional ratedSteamVolumeFlowRate() const; + + bool isRatedSteamVolumeFlowRateAutosized() const; + + double ratedPumpHead() const; + + boost::optional ratedPowerConsumption() const; + + bool isRatedPowerConsumptionAutosized() const; + + double motorEfficiency() const; + + double fractionofMotorInefficienciestoFluidStream() const; + + double coefficient1ofthePartLoadPerformanceCurve() const; + + double coefficient2ofthePartLoadPerformanceCurve() const; + + double coefficient3ofthePartLoadPerformanceCurve() const; + + double coefficient4ofthePartLoadPerformanceCurve() const; + + boost::optional pumpFlowRateSchedule() const; + + boost::optional zone() const; + + double skinLossRadiativeFraction() const; + + std::string designPowerSizingMethod() const; + + double designElectricPowerPerUnitFlowRate() const; + + double designShaftPowerPerUnitFlowRatePerUnitHead() const; + + std::string endUseSubcategory() const; + + //@} + /** @name Setters */ + //@{ + + bool setRatedSteamVolumeFlowRate(double ratedSteamVolumeFlowRate); + + void resetRatedSteamVolumeFlowRate(); + + void autosizeRatedSteamVolumeFlowRate(); + + bool setRatedPumpHead(double ratedPumpHead); + + bool setRatedPowerConsumption(double ratedPowerConsumption); + + void resetRatedPowerConsumption(); + + void autosizeRatedPowerConsumption(); + + bool setMotorEfficiency(double motorEfficiency); + + bool setFractionofMotorInefficienciestoFluidStream(double fractionofMotorInefficienciestoFluidStream); + + bool setCoefficient1ofthePartLoadPerformanceCurve(double coefficient1ofthePartLoadPerformanceCurve); + + bool setCoefficient2ofthePartLoadPerformanceCurve(double coefficient2ofthePartLoadPerformanceCurve); + + bool setCoefficient3ofthePartLoadPerformanceCurve(double coefficient3ofthePartLoadPerformanceCurve); + + bool setCoefficient4ofthePartLoadPerformanceCurve(double coefficient4ofthePartLoadPerformanceCurve); + + bool setPumpFlowRateSchedule(Schedule& schedule); + + void resetPumpFlowRateSchedule(); + + bool setDesignPowerSizingMethod(const std::string& designPowerSizingMethod); + + bool setDesignElectricPowerPerUnitFlowRate(double designElectricPowerPerUnitFlowRate); + + bool setDesignShaftPowerPerUnitFlowRatePerUnitHead(double designShaftPowerPerUnitFlowRatePerUnitHead); + + bool setZone(const ThermalZone& thermalZone); + + void resetZone(); + + bool setSkinLossRadiativeFraction(double skinLossRadiativeFraction); + + bool setEndUseSubcategory(const std::string& endUseSubcategory); + + //@} + /** @name Other */ + //@{ + + boost::optional autosizedRatedSteamVolumeFlowRate() const; + + boost::optional autosizedRatedPowerConsumption() const; + + //@} + protected: + /// @cond + using ImplType = detail::PumpVariableSpeedCondensate_Impl; + + friend class detail::PumpVariableSpeedCondensate_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + + explicit PumpVariableSpeedCondensate(std::shared_ptr impl); + + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.PumpVariableSpeedCondensate"); + }; + + /** \relates PumpVariableSpeedCondensate*/ + using OptionalPumpVariableSpeedCondensate = boost::optional; + + /** \relates PumpVariableSpeedCondensate*/ + using PumpVariableSpeedCondensateVector = std::vector; + +} // namespace model +} // namespace openstudio + +#endif // MODEL_PUMPVARIABLESPEEDCONDENSATE_HPP diff --git a/src/model/PumpVariableSpeedCondensate_Impl.hpp b/src/model/PumpVariableSpeedCondensate_Impl.hpp new file mode 100644 index 0000000000..d2a0ad4813 --- /dev/null +++ b/src/model/PumpVariableSpeedCondensate_Impl.hpp @@ -0,0 +1,180 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_PUMPVARIABLESPEEDCONDENSATE_IMPL_HPP +#define MODEL_PUMPVARIABLESPEEDCONDENSATE_IMPL_HPP + +#include "ModelAPI.hpp" +#include "StraightComponent_Impl.hpp" + +namespace openstudio { +namespace model { + + class Schedule; + class Curve; + + namespace detail { + + /** PumpVariableSpeedCondensate_Impl is a StraightComponent_Impl that is the implementation class for + * PumpVariableSpeedCondensate.*/ + class MODEL_API PumpVariableSpeedCondensate_Impl : public StraightComponent_Impl + { + public: + /** @name Constructors and Destructors */ + //@{ + + PumpVariableSpeedCondensate_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + PumpVariableSpeedCondensate_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle); + + PumpVariableSpeedCondensate_Impl(const PumpVariableSpeedCondensate_Impl& other, Model_Impl* model, bool keepHandle); + + virtual ~PumpVariableSpeedCondensate_Impl() override = default; + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const override; + + virtual IddObjectType iddObjectType() const override; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + virtual std::vector children() const override; + + virtual unsigned inletPort() const override; + + virtual unsigned outletPort() const override; + + virtual bool addToNode(Node& node) override; + + virtual void autosize() override; + + virtual void applySizingValues() override; + + virtual std::vector emsActuatorNames() const override; + + virtual std::vector emsInternalVariableNames() const override; + + virtual ComponentType componentType() const override; + virtual std::vector coolingFuelTypes() const override; + virtual std::vector heatingFuelTypes() const override; + virtual std::vector appGHeatingFuelTypes() const override; + + //@} + /** @name Getters */ + //@{ + + boost::optional ratedSteamVolumeFlowRate() const; + + bool isRatedSteamVolumeFlowRateAutosized() const; + + double ratedPumpHead() const; + + boost::optional ratedPowerConsumption() const; + + bool isRatedPowerConsumptionAutosized() const; + + double motorEfficiency() const; + + double fractionofMotorInefficienciestoFluidStream() const; + + double coefficient1ofthePartLoadPerformanceCurve() const; + + double coefficient2ofthePartLoadPerformanceCurve() const; + + double coefficient3ofthePartLoadPerformanceCurve() const; + + double coefficient4ofthePartLoadPerformanceCurve() const; + + boost::optional pumpFlowRateSchedule() const; + + boost::optional zone() const; + + double skinLossRadiativeFraction() const; + + std::string designPowerSizingMethod() const; + + double designElectricPowerPerUnitFlowRate() const; + + double designShaftPowerPerUnitFlowRatePerUnitHead() const; + + std::string endUseSubcategory() const; + + //@} + /** @name Setters */ + //@{ + + bool setRatedSteamVolumeFlowRate(boost::optional ratedSteamVolumeFlowRate); + + void resetRatedSteamVolumeFlowRate(); + + void autosizeRatedSteamVolumeFlowRate(); + + bool setRatedPumpHead(double ratedPumpHead); + + bool setRatedPowerConsumption(boost::optional ratedPowerConsumption); + + void resetRatedPowerConsumption(); + + void autosizeRatedPowerConsumption(); + + bool setMotorEfficiency(double motorEfficiency); + + bool setFractionofMotorInefficienciestoFluidStream(double fractionofMotorInefficienciestoFluidStream); + + bool setCoefficient1ofthePartLoadPerformanceCurve(double coefficient1ofthePartLoadPerformanceCurve); + + bool setCoefficient2ofthePartLoadPerformanceCurve(double coefficient2ofthePartLoadPerformanceCurve); + + bool setCoefficient3ofthePartLoadPerformanceCurve(double coefficient3ofthePartLoadPerformanceCurve); + + bool setCoefficient4ofthePartLoadPerformanceCurve(double coefficient4ofthePartLoadPerformanceCurve); + + bool setPumpFlowRateSchedule(Schedule& schedule); + + void resetPumpFlowRateSchedule(); + + bool setDesignPowerSizingMethod(const std::string& designPowerSizingMethod); + + bool setDesignElectricPowerPerUnitFlowRate(double designElectricPowerPerUnitFlowRate); + + bool setDesignShaftPowerPerUnitFlowRatePerUnitHead(double designShaftPowerPerUnitFlowRatePerUnitHead); + + bool setZone(const ThermalZone& thermalZone); + + void resetZone(); + + bool setSkinLossRadiativeFraction(double skinLossRadiativeFraction); + + bool setEndUseSubcategory(const std::string& endUseSubcategory); + + //@} + /** @name Other */ + //@{ + + boost::optional autosizedRatedSteamVolumeFlowRate() const; + + boost::optional autosizedRatedPowerConsumption() const; + + //@} + private: + REGISTER_LOGGER("openstudio.model.PumpVariableSpeedCondensate"); + + std::vector pumpControlTypeValues() const; + std::vector vfdControlTypeValues() const; + + boost::optional pumpFlowRateScheduleAsModelObject() const; + + bool setPumpFlowRateScheduleAsModelObject(const boost::optional& modelObject); + }; + + } // namespace detail + +} // namespace model +} // namespace openstudio + +#endif // MODEL_PUMPVARIABLESPEEDCONDENSATE_IMPL_HPP diff --git a/src/model/ScheduleTypeRegistry.cpp b/src/model/ScheduleTypeRegistry.cpp index c3fad35a17..25ba4f6cb8 100644 --- a/src/model/ScheduleTypeRegistry.cpp +++ b/src/model/ScheduleTypeRegistry.cpp @@ -232,6 +232,7 @@ namespace model { {"CoilHeatingLowTempRadiantVarFlow", "Heating Control Temperature", "heatingControlTemperature", true, "Temperature", OptionalDouble(), OptionalDouble()}, {"CoilHeatingWater", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, + {"CoilHeatingSteam", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"CoilHeatingWaterBaseboard", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"CoilHeatingWaterToAirHeatPumpEquationFit", "Availability Schedule", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit", "Availability Schedule", "availabilitySchedule", false, "Availability", 0.0, 1.0}, @@ -366,6 +367,7 @@ namespace model { {"PumpVariableSpeed", "Maximum Pressure", "maximumPressureSchedule", true, "Pressure", OptionalDouble(), OptionalDouble()}, {"PumpVariableSpeed", "Minimum RPM", "minimumRPMSchedule", true, "RotationsPerMinute", OptionalDouble(), OptionalDouble()}, {"PumpVariableSpeed", "Maximum RPM", "maximumRPMSchedule", true, "RotationsPerMinute", OptionalDouble(), OptionalDouble()}, + {"PumpVariableSpeedCondensate", "Pump Flow Rate", "pumpFlowRateSchedule", true, "", 0.0, 1.0}, {"HeaderedPumpsConstantSpeed", "Pump Flow Rate Schedule", "pumpFlowRateSchedule", true, "", 0.0, 1.0}, {"HeaderedPumpsVariableSpeed", "Pump Flow Rate Schedule", "pumpFlowRateSchedule", true, "", 0.0, 1.0}, {"RefrigerationCase", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, @@ -565,6 +567,7 @@ namespace model { {"RefrigerationAirChiller", "Defrost Drip-Down", "defrostDripDownSchedule", true, "", 0.0, 1.0}, {"ZoneHVACBaseboardRadiantConvectiveElectric", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"ZoneHVACBaseboardRadiantConvectiveWater", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, + {"ZoneHVACBaseboardRadiantConvectiveSteam", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"ZoneHVACCoolingPanelRadiantConvectiveWater", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"ZoneHVACDehumidifierDX", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, {"ZoneHVACEnergyRecoveryVentilator", "Availability", "availabilitySchedule", false, "Availability", 0.0, 1.0}, diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.cpp b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.cpp new file mode 100644 index 0000000000..1c9c984716 --- /dev/null +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.cpp @@ -0,0 +1,330 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include "ZoneHVACBaseboardRadiantConvectiveSteam.hpp" +#include "ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" + +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "Surface.hpp" +#include "Surface_Impl.hpp" +#include "ThermalZone.hpp" +#include "ThermalZone_Impl.hpp" +#include "HVACComponent.hpp" +#include "HVACComponent_Impl.hpp" +#include "CoilHeatingSteamBaseboardRadiant.hpp" +#include "CoilHeatingSteamBaseboardRadiant_Impl.hpp" +#include "Model.hpp" +#include "Space.hpp" +#include "ScheduleTypeLimits.hpp" +#include "ScheduleTypeRegistry.hpp" + +#include +#include + +#include "../utilities/core/Assert.hpp" +#include "../utilities/data/DataEnums.hpp" + +namespace openstudio { +namespace model { + + namespace detail { + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl::ZoneHVACBaseboardRadiantConvectiveSteam_Impl(const IdfObject& idfObject, Model_Impl* model, + bool keepHandle) + : ZoneHVACComponent_Impl(idfObject, model, keepHandle) { + OS_ASSERT(idfObject.iddObject().type() == ZoneHVACBaseboardRadiantConvectiveSteam::iddObjectType()); + } + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl::ZoneHVACBaseboardRadiantConvectiveSteam_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, bool keepHandle) + : ZoneHVACComponent_Impl(other, model, keepHandle) { + OS_ASSERT(other.iddObject().type() == ZoneHVACBaseboardRadiantConvectiveSteam::iddObjectType()); + } + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl::ZoneHVACBaseboardRadiantConvectiveSteam_Impl( + const ZoneHVACBaseboardRadiantConvectiveSteam_Impl& other, Model_Impl* model, bool keepHandle) + : ZoneHVACComponent_Impl(other, model, keepHandle) {} + + const std::vector& ZoneHVACBaseboardRadiantConvectiveSteam_Impl::outputVariableNames() const { + static const std::vector result{"Baseboard Total Heating Rate", "Baseboard Convective Heating Rate", + "Baseboard Radiant Heating Rate", "Baseboard Total Heating Energy", + "Baseboard Convective Heating Energy", "Baseboard Radiant Heating Energy"}; + return result; + } + + IddObjectType ZoneHVACBaseboardRadiantConvectiveSteam_Impl::iddObjectType() const { + return ZoneHVACBaseboardRadiantConvectiveSteam::iddObjectType(); + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::getScheduleTypeKeys(const Schedule& schedule) const { + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()); + UnsignedVector::const_iterator e(fieldIndices.end()); + if (std::find(b, e, OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::AvailabilityScheduleName) != e) { + result.push_back(ScheduleTypeKey("ZoneHVACBaseboardRadiantConvectiveSteam", "Availability")); + } + return result; + } + + unsigned ZoneHVACBaseboardRadiantConvectiveSteam_Impl::inletPort() const { + return 0; // this object has no inlet or outlet node + } + + unsigned ZoneHVACBaseboardRadiantConvectiveSteam_Impl::outletPort() const { + return 0; // this object has no inlet or outlet node + } + + boost::optional ZoneHVACBaseboardRadiantConvectiveSteam_Impl::thermalZone() const { + auto thisObject = this->getObject(); + auto const thermalZones = this->model().getConcreteModelObjects(); + for (auto const& thermalZone : thermalZones) { + std::vector equipment = thermalZone.equipment(); + + if (std::find(equipment.begin(), equipment.end(), thisObject) != equipment.end()) { + return thermalZone; + } + } + return boost::none; + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam_Impl::addToThermalZone(ThermalZone& thermalZone) { + Model m = this->model(); + + if (thermalZone.model() != m || thermalZone.isPlenum()) { + return false; + } + + removeFromThermalZone(); + + thermalZone.setUseIdealAirLoads(false); + + thermalZone.addEquipment(this->getObject()); + + return true; + } + + void ZoneHVACBaseboardRadiantConvectiveSteam_Impl::removeFromThermalZone() { + if (auto thermalZone = this->thermalZone()) { + thermalZone->removeEquipment(this->getObject()); + } + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::surfaces() const { + + //vector to hold all of the surfaces that this radiant system is attached to + std::vector surfaces; + + //get the thermal zone this equipment belongs to + if (auto const thermalZone = this->thermalZone()) { + + //loop through all the spaces in this zone + for (auto const& space : thermalZone->spaces()) { + + //loop through all the surfaces in this space + for (auto const& surface : space.surfaces()) { + surfaces.push_back(surface); + } + } + } + + return surfaces; + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::children() const { + std::vector result; + if (OptionalHVACComponent intermediate = optionalHeatingCoil()) { + result.push_back(*intermediate); + } + return result; + } + + ModelObject ZoneHVACBaseboardRadiantConvectiveSteam_Impl::clone(Model model) const { + auto baseboardRadConvSteamClone = ZoneHVACComponent_Impl::clone(model).cast(); + + auto t_heatingCoil = heatingCoil(); + auto heatingCoilClone = t_heatingCoil.clone(model).cast(); + + baseboardRadConvSteamClone.setHeatingCoil(heatingCoilClone); + + if (model == this->model()) { + if (auto plant = t_heatingCoil.plantLoop()) { + plant->addDemandBranchForComponent(heatingCoilClone); + } + } + + return std::move(baseboardRadConvSteamClone); + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::remove() { + if (auto waterHeatingCoil = heatingCoil().optionalCast()) { + if (boost::optional plantLoop = waterHeatingCoil->plantLoop()) { + plantLoop->removeDemandBranchWithComponent(waterHeatingCoil.get()); + } + } + return ZoneHVACComponent_Impl::remove(); + } + + Schedule ZoneHVACBaseboardRadiantConvectiveSteam_Impl::availabilitySchedule() const { + boost::optional value = optionalAvailabilitySchedule(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Availability Schedule attached."); + } + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveSteam_Impl::fractionRadiant() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::FractionRadiant, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveSteam_Impl::fractionofRadiantEnergyIncidentonPeople() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::FractionofRadiantEnergyIncidentonPeople, true); + OS_ASSERT(value); + return value.get(); + } + + HVACComponent ZoneHVACBaseboardRadiantConvectiveSteam_Impl::heatingCoil() const { + boost::optional value = optionalHeatingCoil(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Heating Coil attached."); + } + return value.get(); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam_Impl::setAvailabilitySchedule(Schedule& schedule) { + bool result = setSchedule(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::AvailabilityScheduleName, + "ZoneHVACBaseboardRadiantConvectiveSteam", "Availability", schedule); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam_Impl::setFractionRadiant(double fractionRadiant) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::FractionRadiant, fractionRadiant); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam_Impl::setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::FractionofRadiantEnergyIncidentonPeople, + fractionofRadiantEnergyIncidentonPeople); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam_Impl::setHeatingCoil(const HVACComponent& radBaseboardHeatingCoil) { + bool result = setPointer(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::HeatingCoilName, radBaseboardHeatingCoil.handle()); + return result; + } + + boost::optional ZoneHVACBaseboardRadiantConvectiveSteam_Impl::optionalAvailabilitySchedule() const { + return getObject().getModelObjectTarget(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::AvailabilityScheduleName); + } + + boost::optional ZoneHVACBaseboardRadiantConvectiveSteam_Impl::optionalHeatingCoil() const { + return getObject().getModelObjectTarget(OS_ZoneHVAC_Baseboard_RadiantConvective_SteamFields::HeatingCoilName); + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::emsActuatorNames() const { + std::vector actuators{{"ZoneBaseboard:OutdoorTemperatureControlled", "Power Level"}}; + return actuators; + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::emsInternalVariableNames() const { + std::vector types{"Simple Zone Baseboard Capacity At Low Temperature", "Simple Zone Baseboard Capacity At High Temperature"}; + return types; + } + + ComponentType ZoneHVACBaseboardRadiantConvectiveSteam_Impl::componentType() const { + return ComponentType::Heating; + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::coolingFuelTypes() const { + return {}; + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::heatingFuelTypes() const { + return heatingCoil().heatingFuelTypes(); + } + + std::vector ZoneHVACBaseboardRadiantConvectiveSteam_Impl::appGHeatingFuelTypes() const { + return heatingCoil().appGHeatingFuelTypes(); + } + + } // namespace detail + + ZoneHVACBaseboardRadiantConvectiveSteam::ZoneHVACBaseboardRadiantConvectiveSteam(const Model& model) + : ZoneHVACComponent(ZoneHVACBaseboardRadiantConvectiveSteam::iddObjectType(), model) { + OS_ASSERT(getImpl()); + + bool ok = true; + auto alwaysOn = model.alwaysOnDiscreteSchedule(); + ok = setAvailabilitySchedule(alwaysOn); + OS_ASSERT(ok); + ok = setFractionRadiant(0.3); + OS_ASSERT(ok); + ok = setFractionofRadiantEnergyIncidentonPeople(0.3); + OS_ASSERT(ok); + CoilHeatingSteamBaseboardRadiant coil(model); + ok = setHeatingCoil(coil); + OS_ASSERT(ok); + } + + IddObjectType ZoneHVACBaseboardRadiantConvectiveSteam::iddObjectType() { + return {IddObjectType::OS_ZoneHVAC_Baseboard_RadiantConvective_Steam}; + } + + Schedule ZoneHVACBaseboardRadiantConvectiveSteam::availabilitySchedule() const { + return getImpl()->availabilitySchedule(); + } + + double ZoneHVACBaseboardRadiantConvectiveSteam::fractionRadiant() const { + return getImpl()->fractionRadiant(); + } + + double ZoneHVACBaseboardRadiantConvectiveSteam::fractionofRadiantEnergyIncidentonPeople() const { + return getImpl()->fractionofRadiantEnergyIncidentonPeople(); + } + + HVACComponent ZoneHVACBaseboardRadiantConvectiveSteam::heatingCoil() const { + return getImpl()->heatingCoil(); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam::setAvailabilitySchedule(Schedule& schedule) { + return getImpl()->setAvailabilitySchedule(schedule); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam::setFractionRadiant(double fractionRadiant) { + return getImpl()->setFractionRadiant(fractionRadiant); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam::setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople) { + return getImpl()->setFractionofRadiantEnergyIncidentonPeople( + fractionofRadiantEnergyIncidentonPeople); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam::setHeatingCoil(const HVACComponent& radBaseboardHeatingCoil) { + return getImpl()->setHeatingCoil(radBaseboardHeatingCoil); + } + + boost::optional ZoneHVACBaseboardRadiantConvectiveSteam::thermalZone() const { + return getImpl()->thermalZone(); + } + + bool ZoneHVACBaseboardRadiantConvectiveSteam::addToThermalZone(ThermalZone& thermalZone) { + return getImpl()->addToThermalZone(thermalZone); + } + + void ZoneHVACBaseboardRadiantConvectiveSteam::removeFromThermalZone() { + return getImpl()->removeFromThermalZone(); + } + + /// @cond + ZoneHVACBaseboardRadiantConvectiveSteam::ZoneHVACBaseboardRadiantConvectiveSteam( + std::shared_ptr impl) + : ZoneHVACComponent(std::move(impl)) {} + /// @endcond + +} // namespace model +} // namespace openstudio diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.hpp new file mode 100644 index 0000000000..3dee8e9c7c --- /dev/null +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam.hpp @@ -0,0 +1,111 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_HPP +#define MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_HPP + +#include "ModelAPI.hpp" +#include "ZoneHVACComponent.hpp" + +namespace openstudio { + +namespace model { + + class Schedule; + class ThermalZone; + + namespace detail { + + class ZoneHVACBaseboardRadiantConvectiveSteam_Impl; + + } // namespace detail + + /** ZoneHVACBaseboardRadiantConvectiveSteam is a ZoneHVACComponent that wraps the OpenStudio IDD object 'OS:ZoneHVAC:Baseboard:RadiantConvective:Steam'. */ + class MODEL_API ZoneHVACBaseboardRadiantConvectiveSteam : public ZoneHVACComponent + { + public: + /** @name Constructors and Destructors */ + //@{ + + explicit ZoneHVACBaseboardRadiantConvectiveSteam(const Model& model); + + virtual ~ZoneHVACBaseboardRadiantConvectiveSteam() override = default; + // Default the copy and move operators because the virtual dtor is explicit + ZoneHVACBaseboardRadiantConvectiveSteam(const ZoneHVACBaseboardRadiantConvectiveSteam& other) = default; + ZoneHVACBaseboardRadiantConvectiveSteam(ZoneHVACBaseboardRadiantConvectiveSteam&& other) = default; + ZoneHVACBaseboardRadiantConvectiveSteam& operator=(const ZoneHVACBaseboardRadiantConvectiveSteam&) = default; + ZoneHVACBaseboardRadiantConvectiveSteam& operator=(ZoneHVACBaseboardRadiantConvectiveSteam&&) = default; + + //@} + + static IddObjectType iddObjectType(); + + /** @name Getters */ + //@{ + + Schedule availabilitySchedule() const; + + double fractionRadiant() const; + + double fractionofRadiantEnergyIncidentonPeople() const; + + HVACComponent heatingCoil() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + + bool setFractionRadiant(double fractionRadiant); + + bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + + bool setHeatingCoil(const HVACComponent& heatingCoil); + + //@} + /** @name Other */ + //@{ + + /** Returns the optional ThermalZone that this ZoneHVACBaseboardRadiantConvectiveSteam is attached to + **/ + boost::optional thermalZone() const override; + + /** Adds this ZoneHVACBaseboardRadiantConvectiveSteam to the thermal zone. Returns true if the operation was + * successful. + **/ + bool addToThermalZone(ThermalZone& thermalZone); + + /** Detaches this ZoneHVACBaseboardRadiantConvectiveSteam from the associated ThermalZone. + * If there is no attached ThermalZone there is no effect. + **/ + void removeFromThermalZone(); + + //@} + protected: + /// @cond + using ImplType = detail::ZoneHVACBaseboardRadiantConvectiveSteam_Impl; + + explicit ZoneHVACBaseboardRadiantConvectiveSteam(std::shared_ptr impl); + + friend class detail::ZoneHVACBaseboardRadiantConvectiveSteam_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.ZoneHVACBaseboardRadiantConvectiveSteam"); + }; + + /** \relates ZoneHVACBaseboardRadiantConvectiveSteam*/ + using OptionalZoneHVACBaseboardRadiantConvectiveSteam = boost::optional; + + /** \relates ZoneHVACBaseboardRadiantConvectiveSteam*/ + using ZoneHVACBaseboardRadiantConvectiveSteamVector = std::vector; + +} // namespace model +} // namespace openstudio + +#endif // MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_HPP diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp new file mode 100644 index 0000000000..b6aa0acaab --- /dev/null +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp @@ -0,0 +1,119 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#ifndef MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_IMPL_HPP +#define MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_IMPL_HPP + +#include "ModelAPI.hpp" +#include "ZoneHVACComponent_Impl.hpp" + +namespace openstudio { +namespace model { + + class Schedule; + class Surface; + class ThermalZone; + class HVACComponent; + + namespace detail { + + /** ZoneHVACBaseboardRadiantConvectiveSteam_Impl is a ZoneHVACComponent_Impl that is the implementation class for ZoneHVACBaseboardRadiantConvectiveSteam.*/ + class MODEL_API ZoneHVACBaseboardRadiantConvectiveSteam_Impl : public ZoneHVACComponent_Impl + { + public: + /** @name Constructors and Destructors */ + //@{ + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl(const openstudio::detail::WorkspaceObject_Impl& other, Model_Impl* model, bool keepHandle); + + ZoneHVACBaseboardRadiantConvectiveSteam_Impl(const ZoneHVACBaseboardRadiantConvectiveSteam_Impl& other, Model_Impl* model, bool keepHandle); + + virtual ~ZoneHVACBaseboardRadiantConvectiveSteam_Impl() override = default; + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const override; + + virtual IddObjectType iddObjectType() const override; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + boost::optional thermalZone() const override; + + bool addToThermalZone(ThermalZone& thermalZone) override; + + void removeFromThermalZone() override; + + virtual ModelObject clone(Model model) const override; + + virtual unsigned inletPort() const override; + + virtual unsigned outletPort() const override; + + virtual std::vector children() const override; + + virtual std::vector remove() override; + + virtual ComponentType componentType() const override; + virtual std::vector coolingFuelTypes() const override; + virtual std::vector heatingFuelTypes() const override; + virtual std::vector appGHeatingFuelTypes() const override; + + //@} + /** @name Getters */ + //@{ + + Schedule availabilitySchedule() const; + + double fractionRadiant() const; + + double fractionofRadiantEnergyIncidentonPeople() const; + + HVACComponent heatingCoil() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + + bool setFractionRadiant(double fractionRadiant); + + bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + + bool setHeatingCoil(const HVACComponent& heatingCoil); + + //@} + /** @name Other */ + //@{ + + virtual std::vector emsActuatorNames() const override; + + virtual std::vector emsInternalVariableNames() const override; + + std::vector surfaces() const; + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.ZoneHVACBaseboardRadiantConvectiveSteam"); + + // 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 optionalAvailabilitySchedule() const; + boost::optional optionalHeatingCoil() const; + }; + + } // namespace detail + +} // namespace model +} // namespace openstudio + +#endif // MODEL_ZONEHVACBASEBOARDRADIANTCONVECTIVESTEAM_IMPL_HPP diff --git a/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp b/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp index f97ca3ac77..c91bf23e69 100644 --- a/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp +++ b/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp @@ -14,6 +14,8 @@ #include "WaterToAirComponent_Impl.hpp" #include "CoilHeatingWater.hpp" #include "CoilHeatingWater_Impl.hpp" +#include "CoilHeatingSteam.hpp" +#include "CoilHeatingSteam_Impl.hpp" #include "Model.hpp" #include "Model_Impl.hpp" #include @@ -85,6 +87,12 @@ namespace model { } } + if (boost::optional waterHeatingCoil = heatingCoil().optionalCast()) { + if (boost::optional plantLoop = waterHeatingCoil->plantLoop()) { + plantLoop->removeDemandBranchWithComponent(waterHeatingCoil.get()); + } + } + return ZoneHVACComponent_Impl::remove(); } @@ -449,14 +457,14 @@ namespace model { auto iddObjectType = heatingCoil.iddObjectType(); if ((iddObjectType == IddObjectType::OS_Coil_Heating_Gas) || (iddObjectType == IddObjectType::OS_Coil_Heating_Electric) - || (iddObjectType == IddObjectType::OS_Coil_Heating_Water)) { + || (iddObjectType == IddObjectType::OS_Coil_Heating_Water) || (iddObjectType == IddObjectType::OS_Coil_Heating_Steam)) { isAllowedType = true; } if (isAllowedType) { return setPointer(OS_ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilName, heatingCoil.handle()); } else { - LOG(Warn, "Invalid Heating Coil Type (expected CoilHeatingGas, CoilHeatingElectric, or CoilHeatingWater, not '" + LOG(Warn, "Invalid Heating Coil Type (expected CoilHeatingGas, CoilHeatingElectric, CoilHeatingWater, or CoilHeatingSteam, not '" << heatingCoil.iddObjectType().valueName() << "') for " << briefDescription()); return false; } diff --git a/src/model/ZoneHVACUnitHeater.cpp b/src/model/ZoneHVACUnitHeater.cpp index 6f8f088113..4a1f107f1d 100644 --- a/src/model/ZoneHVACUnitHeater.cpp +++ b/src/model/ZoneHVACUnitHeater.cpp @@ -12,6 +12,8 @@ #include "HVACComponent_Impl.hpp" #include "CoilHeatingWater.hpp" #include "CoilHeatingWater_Impl.hpp" +#include "CoilHeatingSteam.hpp" +#include "CoilHeatingSteam_Impl.hpp" #include "ScheduleTypeLimits.hpp" #include "ScheduleTypeRegistry.hpp" #include "Model.hpp" @@ -72,6 +74,11 @@ namespace model { plantLoop->removeDemandBranchWithComponent(waterHeatingCoil.get()); } } + if (boost::optional waterHeatingCoil = heatingCoil().optionalCast()) { + if (boost::optional plantLoop = waterHeatingCoil->plantLoop()) { + plantLoop->removeDemandBranchWithComponent(waterHeatingCoil.get()); + } + } return ZoneHVACComponent_Impl::remove(); } diff --git a/src/model/ZoneHVACWaterToAirHeatPump.cpp b/src/model/ZoneHVACWaterToAirHeatPump.cpp index 72798c2b48..1000ce2186 100644 --- a/src/model/ZoneHVACWaterToAirHeatPump.cpp +++ b/src/model/ZoneHVACWaterToAirHeatPump.cpp @@ -25,6 +25,8 @@ #include "CoilHeatingGas_Impl.hpp" #include "CoilHeatingWater.hpp" #include "CoilHeatingWater_Impl.hpp" +#include "CoilHeatingSteam.hpp" +#include "CoilHeatingSteam_Impl.hpp" #include "Model.hpp" #include "Model_Impl.hpp" @@ -126,6 +128,11 @@ namespace model { plantLoop->removeDemandBranchWithComponent(t_supplementalHeatingCoil.get()); } } + if (boost::optional t_supplementalHeatingCoil = supplementalHeatingCoil().optionalCast()) { + if (boost::optional plantLoop = t_supplementalHeatingCoil->plantLoop()) { + plantLoop->removeDemandBranchWithComponent(t_supplementalHeatingCoil.get()); + } + } return ZoneHVACComponent_Impl::remove(); } diff --git a/src/model/test/CoilHeatingSteamBaseboardRadiant_GTest.cpp b/src/model/test/CoilHeatingSteamBaseboardRadiant_GTest.cpp new file mode 100644 index 0000000000..821ace180d --- /dev/null +++ b/src/model/test/CoilHeatingSteamBaseboardRadiant_GTest.cpp @@ -0,0 +1,53 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include + +#include "ModelFixture.hpp" + +#include "../CoilHeatingSteamBaseboardRadiant.hpp" +#include "../CoilHeatingSteamBaseboardRadiant_Impl.hpp" +#include "../PlantLoop.hpp" +#include "../PlantLoop_Impl.hpp" +#include "../Node.hpp" +#include "../Node_Impl.hpp" +#include "../Splitter.hpp" +#include "../Splitter_Impl.hpp" +#include "../AirLoopHVAC.hpp" +#include "../AirLoopHVACZoneSplitter.hpp" + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, CoilHeatingSteamBaseboardRadiant_addToNode) { + Model m; + CoilHeatingSteamBaseboardRadiant testObject(m); + + AirLoopHVAC airLoop(m); + + Node supplyOutletNode = airLoop.supplyOutletNode(); + + EXPECT_FALSE(testObject.addToNode(supplyOutletNode)); + EXPECT_EQ((unsigned)2, airLoop.supplyComponents().size()); + + Node inletNode = airLoop.zoneSplitter().lastOutletModelObject()->cast(); + + EXPECT_FALSE(testObject.addToNode(inletNode)); + EXPECT_EQ((unsigned)5, airLoop.demandComponents().size()); + + PlantLoop plantLoop(m); + supplyOutletNode = plantLoop.supplyOutletNode(); + EXPECT_FALSE(testObject.addToNode(supplyOutletNode)); + EXPECT_EQ((unsigned)5, plantLoop.supplyComponents().size()); + + Node demandOutletNode = plantLoop.demandOutletNode(); + EXPECT_TRUE(testObject.addToNode(demandOutletNode)); + EXPECT_EQ((unsigned)7, plantLoop.demandComponents().size()); + + CoilHeatingSteamBaseboardRadiant testObject2(m); + + EXPECT_TRUE(plantLoop.addDemandBranchForComponent(testObject2)); + EXPECT_EQ(9u, plantLoop.demandComponents().size()); +} diff --git a/src/model/test/CoilHeatingSteam_GTest.cpp b/src/model/test/CoilHeatingSteam_GTest.cpp new file mode 100644 index 0000000000..576ac4e857 --- /dev/null +++ b/src/model/test/CoilHeatingSteam_GTest.cpp @@ -0,0 +1,144 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "ModelFixture.hpp" +#include "../CoilHeatingSteam.hpp" +#include "../CoilHeatingSteam_Impl.hpp" +#include "../ControllerWaterCoil.hpp" +#include "../ControllerWaterCoil_Impl.hpp" +#include "../ScheduleCompact.hpp" +#include "../AirLoopHVAC.hpp" +#include "../PlantLoop.hpp" +#include "../Node.hpp" +#include "../Node_Impl.hpp" + +using namespace openstudio::model; + +TEST_F(ModelFixture, CoilHeatingSteam_CoilHeatingSteam) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + ASSERT_EXIT( + { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); +} + +TEST_F(ModelFixture, CoilHeatingSteam_addToNode) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + AirLoopHVAC airLoop(m); + Node supplyOutletNode = airLoop.supplyOutletNode(); + + coil.addToNode(supplyOutletNode); + ASSERT_EQ((unsigned)3, airLoop.supplyComponents().size()); +} + +// Add CoilHeatingSteam to AirLoopHVAC and PlantLoop +// Test CoilHeatingSteam::remove and make sure that the loops are intact +TEST_F(ModelFixture, CoilHeatingSteam_remove) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + AirLoopHVAC airLoop(m); + Node supplyOutletNode = airLoop.supplyOutletNode(); + + coil.addToNode(supplyOutletNode); + coil.remove(); + ASSERT_EQ((unsigned)2, airLoop.supplyComponents().size()); + + ASSERT_TRUE(m.getConcreteModelObjects().empty()); + + CoilHeatingSteam coil2(m, s); + coil2.addToNode(supplyOutletNode); + + PlantLoop plant(m); + plant.addDemandBranchForComponent(coil2); + + ASSERT_EQ((unsigned)1, m.getConcreteModelObjects().size()); + ASSERT_EQ((unsigned)1, plant.demandComponents(CoilHeatingSteam::iddObjectType()).size()); + + coil2.remove(); + ASSERT_TRUE(m.getConcreteModelObjects().empty()); +} + +// Add ONLY to PlantLoop +// Test CoilHeatingSteam::remove and make sure that the plant is intact +TEST_F(ModelFixture, CoilHeatingSteam_remove2) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + PlantLoop plant(m); + plant.addDemandBranchForComponent(coil); + ASSERT_EQ((unsigned)1, m.getConcreteModelObjects().size()); + ASSERT_EQ((unsigned)1, plant.demandComponents(CoilHeatingSteam::iddObjectType()).size()); + + coil.remove(); + ASSERT_TRUE(m.getConcreteModelObjects().empty()); +} + +// Add ONLY to PlantLoop +// This time use removeDemandBranchWithComponent +TEST_F(ModelFixture, CoilHeatingSteam_remove3) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + PlantLoop plant(m); + plant.addDemandBranchForComponent(coil); + + ASSERT_EQ((unsigned)1, m.getConcreteModelObjects().size()); + ASSERT_EQ((unsigned)1, plant.demandComponents(CoilHeatingSteam::iddObjectType()).size()); + + plant.removeDemandBranchWithComponent(coil); + ASSERT_TRUE(plant.demandComponents(CoilHeatingSteam::iddObjectType()).empty()); + ASSERT_TRUE(m.getConcreteModelObjects().empty()); +} + +// Add CoilHeatingSteam to AirLoopHVAC and PlantLoop +// Test PlantLoop::removeDemandBranchWithComponent and make sure that the loops are intact +// Test that the coil is still in the model and hooked up to AirLoopHVAC +TEST_F(ModelFixture, CoilHeatingSteam_remove4) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + AirLoopHVAC airLoop(m); + Node supplyOutletNode = airLoop.supplyOutletNode(); + + coil.addToNode(supplyOutletNode); + + PlantLoop plant(m); + EXPECT_TRUE(plant.addDemandBranchForComponent(coil)); + + ASSERT_EQ((unsigned)3, airLoop.supplyComponents().size()); + ASSERT_EQ((unsigned)1, m.getConcreteModelObjects().size()); + ASSERT_EQ((unsigned)1, plant.demandComponents(CoilHeatingSteam::iddObjectType()).size()); + + plant.removeDemandBranchWithComponent(coil); + ASSERT_TRUE(plant.demandComponents(CoilHeatingSteam::iddObjectType()).empty()); + ASSERT_EQ((unsigned)3, airLoop.supplyComponents().size()); + ASSERT_EQ((unsigned)1, m.getConcreteModelObjects().size()); +} + +TEST_F(ModelFixture, CoilHeatingSteam_controller) { + Model m; + ScheduleCompact s(m); + CoilHeatingSteam coil(m, s); + + PlantLoop p(m); + + EXPECT_TRUE(p.addDemandBranchForComponent(coil)); + ASSERT_TRUE(coil.controllerWaterCoil()); +} diff --git a/src/model/test/PumpVariableSpeedCondensate_GTest.cpp b/src/model/test/PumpVariableSpeedCondensate_GTest.cpp new file mode 100644 index 0000000000..5f9f17fb35 --- /dev/null +++ b/src/model/test/PumpVariableSpeedCondensate_GTest.cpp @@ -0,0 +1,88 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "ModelFixture.hpp" +#include "../PumpVariableSpeedCondensate.hpp" +#include "../PumpVariableSpeedCondensate_Impl.hpp" +#include "../AirLoopHVAC.hpp" +#include "../PlantLoop.hpp" +#include "../Node.hpp" +#include "../Node_Impl.hpp" +#include "../AirLoopHVACZoneSplitter.hpp" + +using namespace openstudio::model; + +TEST_F(ModelFixture, PumpVariableSpeedCondensate_PumpVariableSpeedCondensate) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + ASSERT_EXIT( + { + Model m; + PumpVariableSpeedCondensate pump(m); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); +} + +TEST_F(ModelFixture, PumpVariableSpeedCondensate_connections) { + Model m; + PumpVariableSpeedCondensate pump(m); + + Node inletNode(m); + Node outletNode(m); + + m.connect(inletNode, inletNode.outletPort(), pump, pump.inletPort()); + m.connect(pump, pump.outletPort(), outletNode, outletNode.inletPort()); + + ASSERT_TRUE(pump.inletModelObject()); + ASSERT_TRUE(pump.outletModelObject()); + + EXPECT_EQ(inletNode.handle(), pump.inletModelObject()->handle()); + EXPECT_EQ(outletNode.handle(), pump.outletModelObject()->handle()); +} + +TEST_F(ModelFixture, PumpVariableSpeedCondensate_addToNode) { + Model m; + PumpVariableSpeedCondensate testObject(m); + + AirLoopHVAC airLoop(m); + + Node supplyOutletNode = airLoop.supplyOutletNode(); + + EXPECT_FALSE(testObject.addToNode(supplyOutletNode)); + EXPECT_EQ((unsigned)2, airLoop.supplyComponents().size()); + + Node inletNode = airLoop.zoneSplitter().lastOutletModelObject()->cast(); + + EXPECT_FALSE(testObject.addToNode(inletNode)); + EXPECT_EQ((unsigned)5, airLoop.demandComponents().size()); + + PlantLoop plantLoop(m); + supplyOutletNode = plantLoop.supplyOutletNode(); + EXPECT_TRUE(testObject.addToNode(supplyOutletNode)); + EXPECT_EQ((unsigned)7, plantLoop.supplyComponents().size()); + + Node demandOutletNode = plantLoop.demandOutletNode(); + EXPECT_TRUE(testObject.addToNode(demandOutletNode)); + EXPECT_EQ((unsigned)7, plantLoop.demandComponents().size()); + + PumpVariableSpeedCondensate testObject2(m); + + EXPECT_TRUE(testObject2.addToNode(demandOutletNode)); + EXPECT_EQ((unsigned)9, plantLoop.demandComponents().size()); + + PlantLoop plantLoop2(m); + demandOutletNode = plantLoop2.demandOutletNode(); + EXPECT_TRUE(testObject.addToNode(demandOutletNode)); + EXPECT_EQ((unsigned)7, plantLoop2.demandComponents().size()); + + auto testObjectClone = testObject.clone(m).cast(); + supplyOutletNode = plantLoop.supplyOutletNode(); + + EXPECT_TRUE(testObjectClone.addToNode(supplyOutletNode)); + EXPECT_EQ((unsigned)7, plantLoop.supplyComponents().size()); +} diff --git a/src/model/test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp b/src/model/test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp new file mode 100644 index 0000000000..46a344787d --- /dev/null +++ b/src/model/test/ZoneHVACBaseboardRadiantConvectiveSteam_GTest.cpp @@ -0,0 +1,45 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "ModelFixture.hpp" + +#include "../ZoneHVACBaseboardRadiantConvectiveSteam.hpp" +#include "../ZoneHVACBaseboardRadiantConvectiveSteam_Impl.hpp" +#include "../ThermalZone.hpp" + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveSteam) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + ASSERT_EXIT( + { + Model m; + ZoneHVACBaseboardRadiantConvectiveSteam zonehvac(m); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); +} + +TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveSteam_AddAndRemove) { + Model m; + ZoneHVACBaseboardRadiantConvectiveSteam zonehvac(m); + + ThermalZone tz(m); + ASSERT_TRUE(zonehvac.addToThermalZone(tz)); + ASSERT_TRUE(zonehvac.thermalZone()); + ASSERT_EQ(tz, zonehvac.thermalZone().get()); + ASSERT_EQ(1u, tz.equipment().size()); + zonehvac.removeFromThermalZone(); + ASSERT_EQ(0u, tz.equipment().size()); + + ZoneHVACBaseboardRadiantConvectiveSteam zonehvac2(m); + zonehvac2.addToThermalZone(tz); + zonehvac2.remove(); + ASSERT_EQ(0u, tz.equipment().size()); +}