From d15c18cc460890ece9be98ab76b34fa732e315de Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Tue, 29 Aug 2023 11:31:57 -0600 Subject: [PATCH 01/16] Remove ValidateFuelType() in ExteriorEnergyUse.cc --- src/EnergyPlus/DataGlobalConstants.hh | 12 ++- src/EnergyPlus/DataHeatBalance.hh | 60 +++++------ src/EnergyPlus/ExteriorEnergyUse.cc | 99 ++----------------- src/EnergyPlus/ExteriorEnergyUse.hh | 34 +------ src/EnergyPlus/InternalHeatGains.cc | 24 ++--- tst/EnergyPlus/unit/InternalHeatGains.unit.cc | 5 +- 6 files changed, 63 insertions(+), 171 deletions(-) diff --git a/src/EnergyPlus/DataGlobalConstants.hh b/src/EnergyPlus/DataGlobalConstants.hh index 63286a97eb6..9054985d420 100644 --- a/src/EnergyPlus/DataGlobalConstants.hh +++ b/src/EnergyPlus/DataGlobalConstants.hh @@ -145,6 +145,7 @@ namespace Constant { DistrictCooling, DistrictHeatingWater, DistrictHeatingSteam, + Water, Num }; @@ -182,7 +183,7 @@ namespace Constant { eFuel::DistrictCooling, eFuel::DistrictHeatingWater, eFuel::DistrictHeatingSteam, - eFuel::Invalid, + eFuel::Water, eFuel::Invalid, eFuel::Invalid, eFuel::Invalid, @@ -229,7 +230,8 @@ namespace Constant { eResource::OtherFuel2, eResource::DistrictCooling, eResource::DistrictHeatingWater, - eResource::DistrictHeatingSteam}; + eResource::DistrictHeatingSteam, + eResource::Water}; constexpr std::array(eResource::Num)> eResource2ePollutant = { ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, @@ -366,7 +368,8 @@ namespace Constant { eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::OtherFuel2)])], eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictCooling)])], eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingWater)])], - eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])]}; + eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])], + eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::Water)])]}; static constexpr std::array(eFuel::Num)> eFuelNames = { eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::Electricity)])], @@ -381,7 +384,8 @@ namespace Constant { eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::OtherFuel2)])], eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictCooling)])], eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingWater)])], - eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])]}; + eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])], + eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::Water)])]}; static constexpr std::array(ePollutant::Num)> ePollutantNamesUC = { eResourceNamesUC[static_cast(ePollutant2eResource[static_cast(ePollutant::SO2)])], diff --git a/src/EnergyPlus/DataHeatBalance.hh b/src/EnergyPlus/DataHeatBalance.hh index 99dc82a45b7..1582b734cd9 100644 --- a/src/EnergyPlus/DataHeatBalance.hh +++ b/src/EnergyPlus/DataHeatBalance.hh @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -477,8 +478,8 @@ namespace DataHeatBalance { Real64 minOccupants = 0.0; // minimum occupancy (sum of NomMinNumberPeople for the space People objects, not multiplied) Real64 maxOccupants = 0.0; // maximum occupancy (sum of NomMaxNumberPeople for the space People objects, not multiplied) bool isRemainderSpace = false; // True if this space is auto-generated "-Remainder" space - std::vector otherEquipFuelTypeNums; // List of fuel types used by other equipment in this space - std::vector otherEquipFuelTypeNames; // List of fuel types used by other equipment in this space + std::vector otherEquipFuelTypeNums; // List of fuel types used by other equipment in this space + std::vector otherEquipFuelTypeNames; // List of fuel types used by other equipment in this space // Pointers to Surface Data Structure // |AllSurfF |AllSurfL @@ -653,17 +654,17 @@ namespace DataHeatBalance { bool HasLtsRetAirGain = false; // TRUE means that zone lights return air heat > 0.0 calculated from plenum temperature bool HasAirFlowWindowReturn = false; // TRUE means that zone has return air flow from windows // from refrigeration cases for this zone - Real64 InternalHeatGains = 0.0; // internal loads (W) - Real64 NominalInfilVent = 0.0; // internal infiltration/ventilation - Real64 NominalMixing = 0.0; // internal mixing/cross mixing - bool TempOutOfBoundsReported = false; // if any temp out of bounds errors, first will show zone details. - bool EnforcedReciprocity = false; // if zone/space required forced reciprocity -- less out of bounds temp errors allowed - int ZoneMinCO2SchedIndex = 0; // Index for the schedule the schedule which determines minimum CO2 concentration - int ZoneMaxCO2SchedIndex = 0; // Index for the schedule the schedule which determines maximum CO2 concentration - int ZoneContamControllerSchedIndex = 0; // Index for this schedule - bool FlagCustomizedZoneCap = false; // True if customized Zone Capacitance Multiplier is used - std::vector otherEquipFuelTypeNums; // List of fuel types used by other equipment in this zone - std::vector otherEquipFuelTypeNames; // List of fuel types used by other equipment in this zone + Real64 InternalHeatGains = 0.0; // internal loads (W) + Real64 NominalInfilVent = 0.0; // internal infiltration/ventilation + Real64 NominalMixing = 0.0; // internal mixing/cross mixing + bool TempOutOfBoundsReported = false; // if any temp out of bounds errors, first will show zone details. + bool EnforcedReciprocity = false; // if zone/space required forced reciprocity -- less out of bounds temp errors allowed + int ZoneMinCO2SchedIndex = 0; // Index for the schedule the schedule which determines minimum CO2 concentration + int ZoneMaxCO2SchedIndex = 0; // Index for the schedule the schedule which determines maximum CO2 concentration + int ZoneContamControllerSchedIndex = 0; // Index for this schedule + bool FlagCustomizedZoneCap = false; // True if customized Zone Capacitance Multiplier is used + std::vector otherEquipFuelTypeNums; // List of fuel types used by other equipment in this zone + std::vector otherEquipFuelTypeNames; // List of fuel types used by other equipment in this zone // Hybrid Modeling Real64 ZoneMeasuredTemperature = 0.0; // Measured zone air temperature input by user @@ -881,23 +882,22 @@ namespace DataHeatBalance { bool ManageDemand = false; // Flag to indicate whether to use demand limiting Real64 DemandLimit = 0.0; // Demand limit set by demand manager [W] // Report variables - Real64 Power = 0.0; // Electric/Gas/Fuel power [W] - Real64 RadGainRate = 0.0; // Radiant heat gain [W] - Real64 ConGainRate = 0.0; // Convective heat gain [W] - Real64 LatGainRate = 0.0; // Latent heat gain [W] - Real64 LostRate = 0.0; // Lost energy (converted to work) [W] - Real64 TotGainRate = 0.0; // Total heat gain [W] - Real64 CO2GainRate = 0.0; // CO2 gain rate [m3/s] - Real64 Consumption = 0.0; // Electric/Gas/Fuel consumption [J] - Real64 RadGainEnergy = 0.0; // Radiant heat gain [J] - Real64 ConGainEnergy = 0.0; // Convective heat gain [J] - Real64 LatGainEnergy = 0.0; // Latent heat gain [J] - Real64 LostEnergy = 0.0; // Lost energy (converted to work) [J] - Real64 TotGainEnergy = 0.0; // Total heat gain [J] - std::string EndUseSubcategory; // user defined name for the end use category - std::string otherEquipFuelTypeString; // Fuel Type string for Other Equipment - ExteriorEnergyUse::ExteriorFuelUsage OtherEquipFuelType = - ExteriorEnergyUse::ExteriorFuelUsage::Invalid; // Fuel Type Number of the Other Equipment (defined in ExteriorEnergyUse.cc) + Real64 Power = 0.0; // Electric/Gas/Fuel power [W] + Real64 RadGainRate = 0.0; // Radiant heat gain [W] + Real64 ConGainRate = 0.0; // Convective heat gain [W] + Real64 LatGainRate = 0.0; // Latent heat gain [W] + Real64 LostRate = 0.0; // Lost energy (converted to work) [W] + Real64 TotGainRate = 0.0; // Total heat gain [W] + Real64 CO2GainRate = 0.0; // CO2 gain rate [m3/s] + Real64 Consumption = 0.0; // Electric/Gas/Fuel consumption [J] + Real64 RadGainEnergy = 0.0; // Radiant heat gain [J] + Real64 ConGainEnergy = 0.0; // Convective heat gain [J] + Real64 LatGainEnergy = 0.0; // Latent heat gain [J] + Real64 LostEnergy = 0.0; // Lost energy (converted to work) [J] + Real64 TotGainEnergy = 0.0; // Total heat gain [J] + std::string EndUseSubcategory; // user defined name for the end use category + std::string otherEquipFuelTypeString; // Fuel Type string for Other Equipment + Constant::eFuel OtherEquipFuelType = Constant::eFuel::Invalid; // Fuel Type Number of the Other Equipment }; struct ExtVentedCavityStruct diff --git a/src/EnergyPlus/ExteriorEnergyUse.cc b/src/EnergyPlus/ExteriorEnergyUse.cc index 51231c29316..40e4ba54548 100644 --- a/src/EnergyPlus/ExteriorEnergyUse.cc +++ b/src/EnergyPlus/ExteriorEnergyUse.cc @@ -48,6 +48,7 @@ // EnergyPlus Headers #include #include +#include #include #include #include @@ -312,15 +313,12 @@ namespace ExteriorEnergyUse { EndUseSubcategoryName = "General"; } - ExteriorEnergyUse::ValidateFuelType(state, - state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType, - state.dataIPShortCut->cAlphaArgs(2), - TypeString, - cCurrentModuleObject, - state.dataIPShortCut->cAlphaFieldNames(2), - state.dataIPShortCut->cAlphaArgs(2)); - if (state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType == - ExteriorEnergyUse::ExteriorFuelUsage::Invalid) { + state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType = + static_cast(getEnumValue(Constant::eFuelNamesUC, state.dataIPShortCut->cAlphaArgs(2))); + TypeString = Constant::eFuelNames[static_cast( + state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType)]; + + if (state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType == Constant::eFuel::Invalid) { if (state.dataIPShortCut->lAlphaFieldBlanks(2)) { ShowSevereError(state, format("{}{}: {} is required, missing for {}={}", @@ -341,8 +339,7 @@ namespace ExteriorEnergyUse { } ErrorsFound = true; } else { - if (state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType != - ExteriorEnergyUse::ExteriorFuelUsage::WaterUse) { + if (state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType != Constant::eFuel::Water) { SetupOutputVariable(state, "Exterior Equipment Fuel Rate", OutputProcessor::Unit::W, @@ -465,8 +462,7 @@ namespace ExteriorEnergyUse { ++state.dataExteriorEnergyUse->NumExteriorEqs; state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).Name = state.dataIPShortCut->cAlphaArgs(1); - state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType = - ExteriorEnergyUse::ExteriorFuelUsage::WaterUse; + state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).FuelType = Constant::eFuel::Water; state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3)); if (state.dataExteriorEnergyUse->ExteriorEquipment(state.dataExteriorEnergyUse->NumExteriorEqs).SchedPtr == 0) { @@ -568,83 +564,6 @@ namespace ExteriorEnergyUse { } } - void ValidateFuelType(EnergyPlusData &state, - ExteriorEnergyUse::ExteriorFuelUsage &FuelTypeNumber, // Fuel Type to be set in structure. - std::string const &FuelTypeAlpha, // Fuel Type String - std::string &FuelTypeString, // Standardized Fuel Type String (for variable naming) - std::string_view CurrentModuleObject, // object being parsed - std::string const &CurrentField, // current field being parsed - std::string const &CurrentName // current object name being parsed - ) - { - - // SUBROUTINE INFORMATION: - // AUTHOR Linda K. Lawrie - // DATE WRITTEN January 2001 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This subroutine compares the input Fuel Type value against the - // valid values and sets the correct in the returned FuelTypeNumber. - - // SUBROUTINE PARAMETER DEFINITIONS: - static constexpr std::string_view RoutineName("ValidateFuelType: "); - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::Invalid; - FuelTypeString = ""; - - // Select the correct Number for the associated ascii name for the fuel type - if (UtilityRoutines::SameString(FuelTypeAlpha, "Electricity")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::ElecUse; - FuelTypeString = "Electricity"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "NaturalGas")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::GasUse; - FuelTypeString = "NaturalGas"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "Coal")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::CoalUse; - FuelTypeString = "Coal"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "FuelOilNo1")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::FuelOil1Use; - FuelTypeString = "FuelOilNo1"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "Propane")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::PropaneUse; - FuelTypeString = "Propane"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "Gasoline")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::GasolineUse; - FuelTypeString = "Gasoline"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "Diesel")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::DieselUse; - FuelTypeString = "Diesel"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "FuelOilNo2")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::FuelOil2Use; - FuelTypeString = "FuelOilNo2"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "OtherFuel1")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::OtherFuel1Use; - FuelTypeString = "OtherFuel1"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "OtherFuel2")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::OtherFuel1Use; - FuelTypeString = "OtherFuel2"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "Water")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::WaterUse; - FuelTypeString = "Water"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "DistrictCooling")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::DistrictCoolUse; - FuelTypeString = "DistrictCooling"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "DistrictHeatingWater")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::DistrictHeatWaterUse; - FuelTypeString = "DistrictHeatingWater"; - } else if (UtilityRoutines::SameString(FuelTypeAlpha, "DistrictHeatingSteam")) { - FuelTypeNumber = ExteriorEnergyUse::ExteriorFuelUsage::DistrictHeatSteamUse; - FuelTypeString = "DistrictHeatingSteam"; - } else { - ShowSevereError(state, format("{}{}=\"{}\".", RoutineName, CurrentModuleObject, CurrentName)); - ShowFatalError(state, format("Heating source/fuel type not recognized. Check input field {}=\"{}", CurrentField, FuelTypeAlpha)); - } - } - void ReportExteriorEnergyUse(EnergyPlusData &state) { diff --git a/src/EnergyPlus/ExteriorEnergyUse.hh b/src/EnergyPlus/ExteriorEnergyUse.hh index 769fb6316e9..9b7ec59d54e 100644 --- a/src/EnergyPlus/ExteriorEnergyUse.hh +++ b/src/EnergyPlus/ExteriorEnergyUse.hh @@ -55,6 +55,7 @@ // EnergyPlus Headers #include +#include #include #include @@ -65,26 +66,6 @@ struct EnergyPlusData; namespace ExteriorEnergyUse { - enum class ExteriorFuelUsage - { - Invalid = -1, - ElecUse, - GasUse, - WaterUse, - CoalUse, - FuelOil1Use, - FuelOil2Use, - PropaneUse, - GasolineUse, - DieselUse, - DistrictCoolUse, - DistrictHeatWaterUse, - DistrictHeatSteamUse, - OtherFuel1Use, - OtherFuel2Use, - Num - }; - enum class LightControlType { Invalid = -1, @@ -121,7 +102,7 @@ namespace ExteriorEnergyUse { { // Members std::string Name; // Descriptive name -- will show on reporting - ExteriorFuelUsage FuelType; + Constant::eFuel FuelType; int SchedPtr; // Can be scheduled Real64 DesignLevel; // Design Consumption (Watts, except for Water Equipment) Real64 Power; // Power = DesignLevel * ScheduleValue @@ -131,7 +112,7 @@ namespace ExteriorEnergyUse { // Default Constructor ExteriorEquipmentUsage() - : FuelType(ExteriorFuelUsage::Invalid), SchedPtr(0), DesignLevel(0.0), Power(0.0), CurrentUse(0.0), ManageDemand(false), DemandLimit(0.0) + : FuelType(Constant::eFuel::Invalid), SchedPtr(0), DesignLevel(0.0), Power(0.0), CurrentUse(0.0), ManageDemand(false), DemandLimit(0.0) { } }; @@ -140,15 +121,6 @@ namespace ExteriorEnergyUse { void GetExteriorEnergyUseInput(EnergyPlusData &state); - void ValidateFuelType(EnergyPlusData &state, - ExteriorEnergyUse::ExteriorFuelUsage &FuelTypeNumber, // Fuel Type to be set in structure. - std::string const &FuelTypeAlpha, // Fuel Type String - std::string &FuelTypeString, // Standardized Fuel Type String (for variable naming) - std::string_view CurrentModuleObject, // object being parsed - std::string const &CurrentField, // current field being parsed - std::string const &CurrentName // current object name being parsed - ); - void ReportExteriorEnergyUse(EnergyPlusData &state); } // namespace ExteriorEnergyUse diff --git a/src/EnergyPlus/InternalHeatGains.cc b/src/EnergyPlus/InternalHeatGains.cc index eb5c5898dfc..a0e7ae5647e 100644 --- a/src/EnergyPlus/InternalHeatGains.cc +++ b/src/EnergyPlus/InternalHeatGains.cc @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -2661,18 +2662,13 @@ namespace InternalHeatGains { std::string FuelTypeString(""); if (IHGAlphas(2) == "NONE") { - thisZoneOthEq.OtherEquipFuelType = ExteriorEnergyUse::ExteriorFuelUsage::Invalid; + thisZoneOthEq.OtherEquipFuelType = Constant::eFuel::Invalid; FuelTypeString = IHGAlphas(2); } else { - ExteriorEnergyUse::ValidateFuelType(state, - thisZoneOthEq.OtherEquipFuelType, - IHGAlphas(2), - FuelTypeString, - othEqModuleObject, - IHGAlphaFieldNames(2), - IHGAlphas(2)); - if (thisZoneOthEq.OtherEquipFuelType == ExteriorEnergyUse::ExteriorFuelUsage::Invalid || - thisZoneOthEq.OtherEquipFuelType == ExteriorEnergyUse::ExteriorFuelUsage::WaterUse) { + thisZoneOthEq.OtherEquipFuelType = static_cast(getEnumValue(Constant::eFuelNamesUC, IHGAlphas(2))); + FuelTypeString = Constant::eFuelNames[static_cast(thisZoneOthEq.OtherEquipFuelType)]; + if (thisZoneOthEq.OtherEquipFuelType == Constant::eFuel::Invalid || + thisZoneOthEq.OtherEquipFuelType == Constant::eFuel::Water) { ShowSevereError(state, format("{}{}: invalid {} entered={} for {}={}", RoutineName, @@ -2686,7 +2682,7 @@ namespace InternalHeatGains { thisZoneOthEq.otherEquipFuelTypeString = FuelTypeString; // Save for output variable setup later // Build list of fuel types used in each zone and space (excluding None and Water) bool found = false; - for (ExteriorEnergyUse::ExteriorFuelUsage fuelType : state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNums) { + for (Constant::eFuel fuelType : state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNums) { if (thisZoneOthEq.OtherEquipFuelType == fuelType) { found = true; break; @@ -2697,7 +2693,7 @@ namespace InternalHeatGains { state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNames.emplace_back(FuelTypeString); } found = false; - for (ExteriorEnergyUse::ExteriorFuelUsage fuelType : state.dataHeatBal->space(spaceNum).otherEquipFuelTypeNums) { + for (Constant::eFuel fuelType : state.dataHeatBal->space(spaceNum).otherEquipFuelTypeNums) { if (thisZoneOthEq.OtherEquipFuelType == fuelType) { found = true; break; @@ -2823,7 +2819,7 @@ namespace InternalHeatGains { } // Throw an error if the design level is negative and we have a fuel type - if (thisZoneOthEq.DesignLevel < 0.0 && thisZoneOthEq.OtherEquipFuelType != ExteriorEnergyUse::ExteriorFuelUsage::Invalid) { + if (thisZoneOthEq.DesignLevel < 0.0 && thisZoneOthEq.OtherEquipFuelType != Constant::eFuel::Invalid) { ShowSevereError(state, format("{}{}=\"{}\", {} is not allowed to be negative", RoutineName, @@ -6134,7 +6130,7 @@ namespace InternalHeatGains { // Set flags for zone and space total report variables addZoneOutputs(state.dataHeatBal->ZoneOtherEq(othEqNum).ZonePtr) = true; addSpaceOutputs(state.dataHeatBal->ZoneOtherEq(othEqNum).spaceIndex) = true; - if (state.dataHeatBal->ZoneOtherEq(othEqNum).OtherEquipFuelType != ExteriorEnergyUse::ExteriorFuelUsage::Invalid) { + if (state.dataHeatBal->ZoneOtherEq(othEqNum).OtherEquipFuelType != Constant::eFuel::Invalid) { std::string fuelTypeString = state.dataHeatBal->ZoneOtherEq(othEqNum).otherEquipFuelTypeString; SetupOutputVariable(state, "Other Equipment " + fuelTypeString + " Rate", diff --git a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc index 2313b840041..3e5400a8762 100644 --- a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc +++ b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -128,9 +129,9 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_OtherEquipment_CheckFuelType) for (unsigned long i = 1; i <= state->dataHeatBal->ZoneOtherEq.size(); ++i) { const DataHeatBalance::ZoneEquipData &equip = state->dataHeatBal->ZoneOtherEq(i); if (equip.Name == "OTHEREQ1") { - ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, ExteriorEnergyUse::ExteriorFuelUsage::Invalid)); + ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, Constant::eFuel::Invalid)); } else if (equip.Name == "OTHEREQ2") { - ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, ExteriorEnergyUse::ExteriorFuelUsage::PropaneUse)); + ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, Constant::eFuel::Propane)); } } } From 98005335785256c4b58dff4901b9c1ab90c5b0d1 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Thu, 31 Aug 2023 22:28:22 -0600 Subject: [PATCH 02/16] address remaining comments --- src/EnergyPlus/OutsideEnergySources.cc | 48 ++++++++++---------------- src/EnergyPlus/PluginManager.cc | 41 +++++----------------- 2 files changed, 26 insertions(+), 63 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index 112984f6778..0180d12ca71 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -325,21 +325,19 @@ void OutsideEnergySourceSpecs::initialize(EnergyPlusData &state, Real64 MyLoad) // The mass flow rate could be an inter-connected-loop side trigger. This is not really the type of // interconnect that that routine was written for, but it is the clearest example of using it. + auto &loop = state.dataPlnt->PlantLoop(this->plantLoc.loopNum); + // begin environment inits if (state.dataGlobal->BeginEnvrnFlag && this->BeginEnvrnInitFlag) { // component model has not design flow rates, using data for overall plant loop - PlantUtilities::InitComponentNodes(state, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinMassFlowRate, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxMassFlowRate, - this->InletNodeNum, - this->OutletNodeNum); + PlantUtilities::InitComponentNodes(state, loop.MinMassFlowRate, loop.MaxMassFlowRate, this->InletNodeNum, this->OutletNodeNum); this->BeginEnvrnInitFlag = false; } if (!state.dataGlobal->BeginEnvrnFlag) this->BeginEnvrnInitFlag = true; Real64 TempPlantMassFlow(0.0); if (std::abs(MyLoad) > 0.0) { - TempPlantMassFlow = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxMassFlowRate; + TempPlantMassFlow = loop.MaxMassFlowRate; } // get actual mass flow to use, hold in MassFlowRate variable @@ -449,6 +447,8 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re // SUBROUTINE PARAMETER DEFINITIONS: static constexpr std::string_view RoutineName("SimDistrictEnergy"); + auto &loop = state.dataPlnt->PlantLoop(this->plantLoc.loopNum); + // set inlet and outlet nodes int const LoopNum = this->plantLoc.loopNum; Real64 const LoopMinTemp = state.dataPlnt->PlantLoop(LoopNum).MinTemp; @@ -487,23 +487,13 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re MyLoad = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp); } } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on MyLoad - Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName, - this->InletTemp, - 1.0, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex, - RoutineName); - Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(state, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName, - this->InletTemp, - 0.0, - state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex, - RoutineName); + Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 1.0, loop.FluidIndex, RoutineName); + Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 0.0, loop.FluidIndex, RoutineName); Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet; this->MassFlowRate = MyLoad / LatentHeatSteam; PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNodeNum, this->OutletNodeNum, this->plantLoc); // Like the assumption in Boiler:Steam, assume that it can meet the steam loop setpoint - this->OutletTemp = state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->plantLoc.loopNum).TempSetPointNodeNum).TempSetPoint; + this->OutletTemp = state.dataLoopNodes->Node(loop.TempSetPointNodeNum).TempSetPoint; this->OutletSteamQuality = 0.0; // apply loop limits on mass flow rate result to keep in check if (this->MassFlowRate < LoopMinMdot) { @@ -531,6 +521,7 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state) { + auto &loop = state.dataPlnt->PlantLoop(this->plantLoc.loopNum); // Locate the unit on the plant loops for later usage bool errFlag = false; @@ -539,14 +530,11 @@ void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state) ShowFatalError(state, "InitSimVars: Program terminated due to previous condition(s)."); } // set limits on outlet node temps to plant loop limits - DataPlant::CompData::getPlantComponent(state, this->plantLoc).MinOutletTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp; - DataPlant::CompData::getPlantComponent(state, this->plantLoc).MaxOutletTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxTemp; + DataPlant::CompData::getPlantComponent(state, this->plantLoc).MinOutletTemp = loop.MinTemp; + DataPlant::CompData::getPlantComponent(state, this->plantLoc).MaxOutletTemp = loop.MaxTemp; // Register design flow rate for inlet node (helps to autosize comp setpoint op scheme flows - PlantUtilities::RegisterPlantCompDesignFlow(state, this->InletNodeNum, state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxVolFlowRate); + PlantUtilities::RegisterPlantCompDesignFlow(state, this->InletNodeNum, loop.MaxVolFlowRate); - // this may need some help, if the objects change location later, due to a push_back, - // then the pointers to these output variables will be bad - // for (int EnergySourceNum = 1; EnergySourceNum <= NumDistrictUnits; ++EnergySourceNum) { std::string reportVarPrefix = "District Heating Water "; std::string heatingOrCooling = "Heating"; std::string_view meterTypeKey = "DistrictHeatingWater"; @@ -560,7 +548,7 @@ void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state) meterTypeKey = "DistrictHeatingSteam"; } SetupOutputVariable(state, - reportVarPrefix + "Energy", + format("{}Energy", reportVarPrefix), OutputProcessor::Unit::J, this->EnergyTransfer, OutputProcessor::SOVTimeStepType::System, @@ -572,28 +560,28 @@ void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state) {}, "Plant"); SetupOutputVariable(state, - reportVarPrefix + "Rate", + format("{}Rate", reportVarPrefix), OutputProcessor::Unit::W, this->EnergyRate, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, this->Name); SetupOutputVariable(state, - reportVarPrefix + "Inlet Temperature", + format("{}Inlet Temperature", reportVarPrefix), OutputProcessor::Unit::C, this->InletTemp, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, this->Name); SetupOutputVariable(state, - reportVarPrefix + "Outlet Temperature", + format("{}Outlet Temperature", reportVarPrefix), OutputProcessor::Unit::C, this->OutletTemp, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, this->Name); SetupOutputVariable(state, - reportVarPrefix + "Mass Flow Rate", + format("{}Mass Flow Rate", reportVarPrefix), OutputProcessor::Unit::kg_s, this->MassFlowRate, OutputProcessor::SOVTimeStepType::System, diff --git a/src/EnergyPlus/PluginManager.cc b/src/EnergyPlus/PluginManager.cc index ab566350406..39b191b339e 100644 --- a/src/EnergyPlus/PluginManager.cc +++ b/src/EnergyPlus/PluginManager.cc @@ -46,6 +46,7 @@ // POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include #include @@ -223,27 +224,7 @@ void PluginManager::setupOutputVariables([[maybe_unused]] EnergyPlusData &state) } std::string const resourceType = EnergyPlus::UtilityRoutines::makeUPPER(fields.at("resource_type").get()); std::string sResourceType; - if (resourceType == "ELECTRICITY") { - sResourceType = "Electricity"; - } else if (resourceType == "NATURALGAS") { - sResourceType = "NaturalGas"; - } else if (resourceType == "GASOLINE") { - sResourceType = "Gasoline"; - } else if (resourceType == "DIESEL") { - sResourceType = "Diesel"; - } else if (resourceType == "COAL") { - sResourceType = "Coal"; - } else if (resourceType == "FUELOILNO1") { - sResourceType = "FuelOilNo1"; - } else if (resourceType == "FUELOILNO2") { - sResourceType = "FuelOilNo2"; - } else if (resourceType == "OTHERFUEL1") { - sResourceType = "OtherFuel1"; - } else if (resourceType == "OTHERFUEL2") { - sResourceType = "OtherFuel2"; - } else if (resourceType == "PROPANE") { - sResourceType = "Propane"; - } else if (resourceType == "WATERUSE") { + if (resourceType == "WATERUSE") { sResourceType = "Water"; } else if (resourceType == "ONSITEWATERPRODUCED") { sResourceType = "OnSiteWater"; @@ -255,16 +236,6 @@ void PluginManager::setupOutputVariables([[maybe_unused]] EnergyPlusData &state) sResourceType = "WellWater"; } else if (resourceType == "CONDENSATEWATERCOLLECTED") { sResourceType = "Condensate"; - } else if (resourceType == "ENERGYTRANSFER") { - sResourceType = "EnergyTransfer"; - } else if (resourceType == "STEAM") { - sResourceType = "Steam"; - } else if (resourceType == "DISTRICTCOOLING") { - sResourceType = "DistrictCooling"; - } else if (resourceType == "DISTRICTHEATINGWATER") { - sResourceType = "DistrictHeatingWater"; - } else if (resourceType == "DISTRICTHEATINGSTEAM") { - sResourceType = "DistrictHeatingSteam"; } else if (resourceType == "ELECTRICITYPRODUCEDONSITE") { sResourceType = "ElectricityProduced"; } else if (resourceType == "SOLARWATERHEATING") { @@ -272,8 +243,12 @@ void PluginManager::setupOutputVariables([[maybe_unused]] EnergyPlusData &state) } else if (resourceType == "SOLARAIRHEATING") { sResourceType = "SolarAir"; } else { - ShowSevereError(state, format("Invalid input for PythonPlugin:OutputVariable, unexpected Resource Type = {}", resourceType)); - ShowFatalError(state, "Python plugin output variable input problem causes program termination"); + if (static_cast(getEnumValue(Constant::eResourceNamesUC, resourceType)) != Constant::eResource::Invalid) { + sResourceType = Constant::eResourceNames[getEnumValue(Constant::eResourceNamesUC, resourceType)]; + } else { + ShowSevereError(state, format("Invalid input for PythonPlugin:OutputVariable, unexpected Resource Type = {}", resourceType)); + ShowFatalError(state, "Python plugin output variable input problem causes program termination"); + } } // Group Type From 27a110b25f7d9db862e7034b6d95f69bf66552c9 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Wed, 13 Sep 2023 14:06:48 -0600 Subject: [PATCH 03/16] add unit tests for LoadProfiles in water loop and steam loop --- src/EnergyPlus/OutsideEnergySources.cc | 4 ++-- tst/EnergyPlus/unit/CMakeLists.txt | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index 0180d12ca71..c4c360cc531 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -521,14 +521,14 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state) { - auto &loop = state.dataPlnt->PlantLoop(this->plantLoc.loopNum); - // Locate the unit on the plant loops for later usage bool errFlag = false; PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->EnergyType, this->plantLoc, errFlag, _, _, _, _, _); if (errFlag) { ShowFatalError(state, "InitSimVars: Program terminated due to previous condition(s)."); } + + auto &loop = state.dataPlnt->PlantLoop(this->plantLoc.loopNum); // set limits on outlet node temps to plant loop limits DataPlant::CompData::getPlantComponent(state, this->plantLoc).MinOutletTemp = loop.MinTemp; DataPlant::CompData::getPlantComponent(state, this->plantLoc).MaxOutletTemp = loop.MaxTemp; diff --git a/tst/EnergyPlus/unit/CMakeLists.txt b/tst/EnergyPlus/unit/CMakeLists.txt index 8ea9d229679..8d605fddd1e 100644 --- a/tst/EnergyPlus/unit/CMakeLists.txt +++ b/tst/EnergyPlus/unit/CMakeLists.txt @@ -172,6 +172,7 @@ set(test_src OutputReportTabular.unit.cc OutputReportTabularAnnual.unit.cc OutputReports.unit.cc + OutsideEnergySources.unit.cc PVWatts.unit.cc PackagedTerminalHeatPump.unit.cc Photovoltaics.unit.cc @@ -185,6 +186,7 @@ set(test_src PlantComponentTemperatureSources.unit.cc PlantCondLoopOperation.unit.cc PlantHeatExchangerFluidToFluid.unit.cc + PlantLoadProfile.unit.cc PlantLoopHeatPumpEIR.unit.cc PlantManager.unit.cc PlantPipingSystemsManager.unit.cc From 796a7540493d93a3e103266e5612efbb37259a5f Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Wed, 13 Sep 2023 14:07:44 -0600 Subject: [PATCH 04/16] add unit tests for LoadProfiles in water loop and steam loop --- .../unit/OutsideEnergySources.unit.cc | 66 +++++ tst/EnergyPlus/unit/PlantLoadProfile.unit.cc | 273 ++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 tst/EnergyPlus/unit/OutsideEnergySources.unit.cc create mode 100644 tst/EnergyPlus/unit/PlantLoadProfile.unit.cc diff --git a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc new file mode 100644 index 00000000000..6e8a4197764 --- /dev/null +++ b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc @@ -0,0 +1,66 @@ +// EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// EnergyPlus::Standalone ERV Unit Tests + +// Google Test Headers +#include + +// EnergyPlus Headers +#include "Fixtures/EnergyPlusFixture.hh" +#include +#include +#include +#include + +using namespace EnergyPlus; +using namespace PlantChillers; + +TEST_F(EnergyPlusFixture, DistrictHeatingSteam) +{ +} + diff --git a/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc new file mode 100644 index 00000000000..faed821f64c --- /dev/null +++ b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc @@ -0,0 +1,273 @@ +// EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// EnergyPlus::Standalone ERV Unit Tests + +// Google Test Headers +#include + +// EnergyPlus Headers +#include "Fixtures/EnergyPlusFixture.hh" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace EnergyPlus; +using namespace PlantLoadProfile; + +TEST_F(EnergyPlusFixture, LoadProfile_GetInput) +{ + std::string const idf_objects = delimited_string({ + + " Schedule:Compact,", + " Load Profile Load Schedule, !- Name ", + " Any Number, !- Schedule Type Limits Name ", + " THROUGH: 12/31, !- Field 1 ", + " FOR: AllDays, !- Field 2 ", + " UNTIL: 24:00,10000; !- Field 3 ", + + " Schedule:Compact,", + " Load Profile Flow Frac Schedule, !- Name ", + " Any Number, !- Schedule Type Limits Name ", + " THROUGH: 12/31, !- Field 1 ", + " FOR: AllDays, !- Field 2 ", + " UNTIL: 24:00,1.0; !- Field 3 ", + + " LoadProfile:Plant,", + " Load Profile Water, !- Name ", + " Demand Load Profile Water Inlet Node, !- Inlet Node Name ", + " Demand Load Profile Water Outlet Node, !- Outlet Node Name ", + " Load Profile Load Schedule, !- Load Schedule Name ", + " 0.002, !- Peak Flow Rate {m3/s} ", + " Load Profile Flow Frac Schedule, !- Flow Rate Fraction Schedule Name ", + " Water; !- Plant Loop Fluid Type ", + + " LoadProfile:Plant,", + " Load Profile Steam, !- Name ", + " Demand Load Profile Steam Inlet Node, !- Inlet Node Name ", + " Demand Load Profile Steam Outlet Node, !- Outlet Node Name ", + " Load Profile Load Schedule, !- Load Schedule Name ", + " 0.008, !- Peak Flow Rate {m3/s} ", + " Load Profile Flow Frac Schedule, !- Flow Rate Fraction Schedule Name ", + " Steam; !- Plant Loop Fluid Type ", + }); + + ASSERT_TRUE(process_idf(idf_objects, false)); + GetPlantProfileInput(*state); + + // Tests for LoadProfile on Water loop + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).Name, "LOAD PROFILE WATER"); + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).FluidType, PlantLoopFluidType::Water); + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).PeakVolFlowRate, 0.002); + + // Tests for LoadProfile on Steam loop + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).Name, "LOAD PROFILE STEAM"); + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).FluidType, PlantLoopFluidType::Steam); + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).PeakVolFlowRate, 0.008); + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).DegOfSubcooling, + 5.0); // check if the default value is assigned in cases where there is no input + EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).LoopSubcoolReturn, + 20.0); // check if the default value is assigned in cases where there is no input +} + +TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Waterloop) +{ + state->dataPlnt->PlantLoop.allocate(1); + state->dataLoopNodes->Node.allocate(2); + state->dataPlantLoadProfile->PlantProfile.allocate(1); + + // Test setup for a load profile in a water loop + state->dataPlnt->PlantLoop(1).FluidName = "WATER"; + state->dataPlnt->PlantLoop(1).FluidIndex = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = + DataPlant::PlantEquipmentType::PlantLoadProfile; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE WATER"; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; + + state->dataLoopNodes->Node(1).Temp = 60.0; + state->dataLoopNodes->Node(1).MassFlowRateMax = 10; + state->dataLoopNodes->Node(1).MassFlowRateMaxAvail = 10; + state->dataLoopNodes->Node(2).MassFlowRateMax = 10; + state->dataLoopNodes->Node(2).MassFlowRateMaxAvail = 10; + + auto &thisLoadProfileWaterLoop = state->dataPlantLoadProfile->PlantProfile(1); + + PlantLocation locWater(1, DataPlant::LoopSideLocation::Demand, 1, 1); + thisLoadProfileWaterLoop.Name = "LOAD PROFILE WATER"; + thisLoadProfileWaterLoop.FluidType = PlantLoopFluidType::Water; + thisLoadProfileWaterLoop.PeakVolFlowRate = 0.002; + thisLoadProfileWaterLoop.LoadSchedule = 1; + thisLoadProfileWaterLoop.FlowRateFracSchedule = 2; + thisLoadProfileWaterLoop.InletNode = 1; + thisLoadProfileWaterLoop.OutletNode = 2; + thisLoadProfileWaterLoop.plantLoc = locWater; + thisLoadProfileWaterLoop.plantLoc.loopNum = 1; + + state->dataScheduleMgr->Schedule.allocate(2); + state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.LoadSchedule).EMSActuatedOn = false; + state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.LoadSchedule).CurrentValue = 10000; + state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.FlowRateFracSchedule).EMSActuatedOn = false; + state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.FlowRateFracSchedule).CurrentValue = 0.8; + + // check InitPlantProfile() + thisLoadProfileWaterLoop.InitPlantProfile(*state); + + EXPECT_EQ(thisLoadProfileWaterLoop.InletTemp, 60.0); // Check the component's inlet temp is set to node data + EXPECT_EQ(thisLoadProfileWaterLoop.Power, 10000); // Check the load schedule's current value is properly applied + EXPECT_EQ(thisLoadProfileWaterLoop.VolFlowRate, 0.0016); // Check the flow rate fraction schedule is properly applied + + // check simulate() + bool firstHVAC = true; + Real64 curLoad = 10000.0; + bool runFlag = true; + thisLoadProfileWaterLoop.simulate(*state, locWater, firstHVAC, curLoad, runFlag); + + Real64 rhoWater = FluidProperties::GetDensityGlycol( + *state, state->dataPlnt->PlantLoop(1).FluidName, 60, state->dataPlnt->PlantLoop(1).FluidIndex, "WaterDensity"); + Real64 Cp = FluidProperties::GetSpecificHeatGlycol( + *state, state->dataPlnt->PlantLoop(1).FluidName, thisLoadProfileWaterLoop.InletTemp, state->dataPlnt->PlantLoop(1).FluidIndex, "GetWaterCp"); + Real64 deltaTemp = curLoad / (rhoWater * thisLoadProfileWaterLoop.VolFlowRate * Cp); + Real64 calOutletTemp = thisLoadProfileWaterLoop.InletTemp - deltaTemp; + + EXPECT_EQ(thisLoadProfileWaterLoop.OutletTemp, calOutletTemp); // Check the water outlet temperature from simulate() is equal to the calculation +} + +TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Steamloop) +{ + state->dataPlnt->PlantLoop.allocate(1); + state->dataLoopNodes->Node.allocate(2); + state->dataPlantLoadProfile->PlantProfile.allocate(1); + + // Test setup for a load profile in a steam loop + state->dataPlnt->PlantLoop(1).FluidName = "STEAM"; + state->dataPlnt->PlantLoop(1).FluidIndex = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = + DataPlant::PlantEquipmentType::PlantLoadProfile; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE STEAM"; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; + state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; + + Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig( + *state, state->dataPlnt->PlantLoop(1).FluidName, DataEnvironment::StdPressureSeaLevel, state->dataPlnt->PlantLoop(1).FluidIndex, "SatTemp"); + + state->dataLoopNodes->Node(1).Temp = SatTempAtmPress; + state->dataLoopNodes->Node(1).MassFlowRateMax = 1; + state->dataLoopNodes->Node(1).MassFlowRateMaxAvail = 1; + state->dataLoopNodes->Node(2).MassFlowRateMax = 1; + state->dataLoopNodes->Node(2).MassFlowRateMaxAvail = 1; + + auto &thisLoadProfileSteamLoop = state->dataPlantLoadProfile->PlantProfile(1); + + PlantLocation locSteam(1, DataPlant::LoopSideLocation::Demand, 1, 1); + thisLoadProfileSteamLoop.Name = "LOAD PROFILE STEAM"; + thisLoadProfileSteamLoop.FluidType = PlantLoopFluidType::Steam; + thisLoadProfileSteamLoop.PeakVolFlowRate = 0.008; + thisLoadProfileSteamLoop.DegOfSubcooling = 3.0; + thisLoadProfileSteamLoop.LoadSchedule = 1; + thisLoadProfileSteamLoop.FlowRateFracSchedule = 2; + thisLoadProfileSteamLoop.InletNode = 1; + thisLoadProfileSteamLoop.OutletNode = 2; + thisLoadProfileSteamLoop.plantLoc = locSteam; + thisLoadProfileSteamLoop.plantLoc.loopNum = 1; + + state->dataScheduleMgr->Schedule.allocate(2); + state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.LoadSchedule).EMSActuatedOn = false; + state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.LoadSchedule).CurrentValue = 10000; + state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.FlowRateFracSchedule).EMSActuatedOn = false; + state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.FlowRateFracSchedule).CurrentValue = 0.8; + + // check InitPlantProfile() + thisLoadProfileSteamLoop.InitPlantProfile(*state); + + EXPECT_EQ(thisLoadProfileSteamLoop.InletTemp, SatTempAtmPress); // Check the component's inlet temp is set to node data + EXPECT_EQ(thisLoadProfileSteamLoop.Power, 10000); // Check the load schedule's current value is properly applied + EXPECT_EQ(thisLoadProfileSteamLoop.VolFlowRate, 0.0064); // Check the flow rate fraction schedule is properly applied + + // check simulate() + bool firstHVAC = true; + Real64 curLoad = 10000.0; + bool runFlag = true; + thisLoadProfileSteamLoop.simulate(*state, locSteam, firstHVAC, curLoad, runFlag); + + Real64 EnthSteamIn = FluidProperties::GetSatEnthalpyRefrig( + *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, 1.0, state->dataPlnt->PlantLoop(1).FluidIndex, "EnthDrySteam"); + Real64 EnthSteamOut = FluidProperties::GetSatEnthalpyRefrig( + *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, 0.0, state->dataPlnt->PlantLoop(1).FluidIndex, "EnthWetSteam"); + Real64 LatentHeatSteam = EnthSteamIn - EnthSteamOut; + + Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol( + *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, state->dataPlnt->PlantLoop(1).FluidIndex, "CpCondensate"); + Real64 calOutletMdot = curLoad / (LatentHeatSteam + thisLoadProfileSteamLoop.DegOfSubcooling * CpCondensate); + + EXPECT_EQ(thisLoadProfileSteamLoop.MassFlowRate, calOutletMdot); + // Check the Steam outlet mass flow rate from simulate() is equal to the calculation +} From c170dfd058cfd84541c484c13c1fc0f82e848fb6 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Thu, 14 Sep 2023 22:58:53 -0600 Subject: [PATCH 05/16] Fix district heatiing steam calculation defect, Unit tests for district cooling, district heating water and steam --- src/EnergyPlus/OutsideEnergySources.cc | 15 +- src/EnergyPlus/OutsideEnergySources.hh | 1 + .../unit/OutsideEnergySources.unit.cc | 163 +++++++++++++++++- tst/EnergyPlus/unit/PlantLoadProfile.unit.cc | 102 +++++------ 4 files changed, 218 insertions(+), 63 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index c4c360cc531..2a5b1e94f08 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -486,11 +486,18 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re this->OutletTemp = min(this->OutletTemp, LoopMaxTemp); MyLoad = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp); } - } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on MyLoad - Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 1.0, loop.FluidIndex, RoutineName); - Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 0.0, loop.FluidIndex, RoutineName); + } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on inlet temp, saturate temp at atmospheric pressure, Cp of inlet condensate, and MyLoad + Real64 SatTempAtmPress = + FluidProperties::GetSatTemperatureRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, loop.FluidIndex, RoutineName); + Real64 CpCondensate = + FluidProperties::GetSatSpecificHeatRefrig(state, loop.FluidName, this->InletTemp, 0.0, loop.FluidIndex, RoutineName); + Real64 deltaTsensible = SatTempAtmPress - this->InletTemp; + Real64 EnthSteamInDry = + FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, loop.FluidIndex, RoutineName); + Real64 EnthSteamOutWet = + FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, 0.0, loop.FluidIndex, RoutineName); Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet; - this->MassFlowRate = MyLoad / LatentHeatSteam; + this->MassFlowRate = MyLoad / (LatentHeatSteam + (CpCondensate * deltaTsensible)); PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNodeNum, this->OutletNodeNum, this->plantLoc); // Like the assumption in Boiler:Steam, assume that it can meet the steam loop setpoint this->OutletTemp = state.dataLoopNodes->Node(loop.TempSetPointNodeNum).TempSetPoint; diff --git a/src/EnergyPlus/OutsideEnergySources.hh b/src/EnergyPlus/OutsideEnergySources.hh index 82088ee6c3a..f31b7dd56d3 100644 --- a/src/EnergyPlus/OutsideEnergySources.hh +++ b/src/EnergyPlus/OutsideEnergySources.hh @@ -56,6 +56,7 @@ #include #include #include +#include namespace EnergyPlus { diff --git a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc index 6e8a4197764..2d37666442f 100644 --- a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc +++ b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc @@ -53,14 +53,169 @@ // EnergyPlus Headers #include "Fixtures/EnergyPlusFixture.hh" #include +#include +#include #include +#include +#include #include -#include using namespace EnergyPlus; -using namespace PlantChillers; +using namespace OutsideEnergySources; -TEST_F(EnergyPlusFixture, DistrictHeatingSteam) +TEST_F(EnergyPlusFixture, DistrictCoolingandHeating) { -} + std::string const idf_objects = delimited_string({ + + " DistrictCooling,", + " Purchased Cooling, !- Name ", + " Purchased Cooling Inlet Node, !- Chilled Water Inlet Node Name ", + " Purchased Cooling Outlet Node, !- Chilled Water Outlet Node Name ", + " 900000; !- Nominal Capacity {W} ", + + " DistrictHeating:Water,", + " Purchased Heating, !- Name ", + " Purchased Heat Inlet Node, !- Hot Water Inlet Node Name ", + " Purchased Heat Outlet Node, !- Hot Water Outlet Node Name ", + " 1000000; !- Nominal Capacity {W} ", + + " DistrictHeating:Steam,", + " DistrictHeating Steam, !- Name ", + " DistrictHeating Steam Inlet Node, !- Steam Inlet Node Name ", + " DistrictHeating Steam Outlet Node, !- Steam Outlet Node Name ", + " 1100000; !- Nominal Capacity {W} ", + }); + + ASSERT_TRUE(process_idf(idf_objects, false)); + GetOutsideEnergySourcesInput(*state); + + // GetOutsideEnergySourcesInput() finds DistrictHeating:Water, DistrictCooling, and DistrictHeating:Steam, respectively + auto &thisDistrictHeatingWater = state->dataOutsideEnergySrcs->EnergySource(1); + auto &thisDistrictCooling = state->dataOutsideEnergySrcs->EnergySource(2); + auto &thisDistrictHeatingSteam = state->dataOutsideEnergySrcs->EnergySource(3); + + // Tests for GetOutsideEnergySourcesInput() + EXPECT_EQ(thisDistrictHeatingWater.EnergyType, DataPlant::PlantEquipmentType::PurchHotWater); + EXPECT_EQ(thisDistrictCooling.EnergyType, DataPlant::PlantEquipmentType::PurchChilledWater); + EXPECT_EQ(thisDistrictHeatingSteam.EnergyType, DataPlant::PlantEquipmentType::PurchSteam); + + EXPECT_EQ(thisDistrictHeatingWater.NomCap, 1000000.0); + EXPECT_EQ(thisDistrictCooling.NomCap, 900000.0); + EXPECT_EQ(thisDistrictHeatingSteam.NomCap, 1100000.0); + + // Test setup for calculate() + bool RunFlag(true); + Real64 MyLoad(1000000.0); + bool firstHVAC = true; + state->dataGlobal->BeginEnvrnFlag = true; + std::string_view RoutineName("OutsideEnergySourcesTests"); + + state->dataPlnt->TotNumLoops = 3; + state->dataPlnt->PlantLoop.allocate(state->dataPlnt->TotNumLoops); + auto &thisHotWaterLoop(state->dataPlnt->PlantLoop(1)); + auto &thisChilledWaterLoop(state->dataPlnt->PlantLoop(2)); + auto &thisSteamLoop(state->dataPlnt->PlantLoop(3)); + + // Setup for DistrictHeating:Water + PlantLocation locHotWater(1, DataPlant::LoopSideLocation::Supply, 1, 1); + thisHotWaterLoop.Name = "HotWaterLoop"; + thisHotWaterLoop.FluidName = "WATER"; + thisHotWaterLoop.FluidIndex = 1; + thisHotWaterLoop.MinTemp = 1.0; + thisHotWaterLoop.MaxTemp = 99.0; + thisHotWaterLoop.MinMassFlowRate = 0.001; + thisHotWaterLoop.MaxMassFlowRate = 20; + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Name = thisDistrictHeatingWater.Name; + thisHotWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Type = DataPlant::PlantEquipmentType::PurchHotWater; + state->dataLoopNodes->Node(thisDistrictHeatingWater.InletNodeNum).Temp = 55.0; + thisDistrictHeatingWater.plantLoc = locHotWater; + thisDistrictHeatingWater.plantLoc.loopNum = 1; + thisDistrictHeatingWater.BeginEnvrnInitFlag = true; + thisDistrictHeatingWater.simulate(*state, locHotWater, firstHVAC, MyLoad, RunFlag); + + Real64 Cp = FluidProperties::GetSpecificHeatGlycol( + *state, thisHotWaterLoop.FluidName, thisDistrictHeatingWater.InletTemp, thisHotWaterLoop.FluidIndex, RoutineName); + Real64 calOutletTemp = + (MyLoad + thisHotWaterLoop.MaxMassFlowRate * Cp * thisDistrictHeatingWater.InletTemp) / (thisHotWaterLoop.MaxMassFlowRate * Cp); + + EXPECT_EQ(thisDistrictHeatingWater.OutletTemp, + calOutletTemp); // check if the water outlet temperature from simulate() is equal to the calculation + + // Setup for DistrictCooling + MyLoad = -900000.0; + PlantLocation locChilledWater(2, DataPlant::LoopSideLocation::Supply, 1, 1); + thisChilledWaterLoop.Name = "ChilledWaterLoop"; + thisChilledWaterLoop.FluidName = "WATER"; + thisChilledWaterLoop.FluidIndex = 1; + thisChilledWaterLoop.MinTemp = 1.0; + thisChilledWaterLoop.MaxTemp = 99.0; + thisChilledWaterLoop.MinMassFlowRate = 0.001; + thisChilledWaterLoop.MaxMassFlowRate = 20; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Name = thisDistrictCooling.Name; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Type = DataPlant::PlantEquipmentType::PurchChilledWater; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).NodeNumIn = thisDistrictCooling.InletNodeNum; + thisChilledWaterLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).NodeNumOut = thisDistrictCooling.OutletNodeNum; + + state->dataLoopNodes->Node(thisDistrictCooling.InletNodeNum).Temp = 65.0; + thisDistrictCooling.plantLoc = locChilledWater; + thisDistrictCooling.plantLoc.loopNum = 2; + thisDistrictCooling.BeginEnvrnInitFlag = true; + thisDistrictCooling.simulate(*state, locChilledWater, firstHVAC, MyLoad, RunFlag); + + Cp = FluidProperties::GetSpecificHeatGlycol( + *state, thisChilledWaterLoop.FluidName, thisDistrictCooling.InletTemp, thisChilledWaterLoop.FluidIndex, RoutineName); + calOutletTemp = + (MyLoad + thisChilledWaterLoop.MaxMassFlowRate * Cp * thisDistrictCooling.InletTemp) / (thisChilledWaterLoop.MaxMassFlowRate * Cp); + + EXPECT_EQ(thisDistrictCooling.OutletTemp, calOutletTemp); // check if the water outlet temperature from simulate() is equal to the calculation + + // Setup for DistrictHeating:Steam + MyLoad = 1100000.0; + PlantLocation locSteam(3, DataPlant::LoopSideLocation::Supply, 1, 1); + thisSteamLoop.Name = "SteamLoop"; + thisSteamLoop.FluidName = "STEAM"; + thisSteamLoop.FluidIndex = 1; + thisSteamLoop.MinMassFlowRate = 0.00001; + thisSteamLoop.MaxMassFlowRate = 20; + thisSteamLoop.TempSetPointNodeNum = thisDistrictHeatingSteam.OutletNodeNum; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Name = thisDistrictHeatingSteam.Name; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Type = DataPlant::PlantEquipmentType::PurchSteam; + + state->dataLoopNodes->Node(thisDistrictHeatingSteam.InletNodeNum).Temp = 95.0; // Temperature of inlet condensate after subcooling + state->dataLoopNodes->Node(thisDistrictHeatingSteam.OutletNodeNum).TempSetPoint = 105.0; + thisDistrictHeatingSteam.plantLoc = locSteam; + thisDistrictHeatingSteam.plantLoc.loopNum = 3; + thisDistrictHeatingSteam.BeginEnvrnInitFlag = true; + thisDistrictHeatingSteam.simulate(*state, locSteam, firstHVAC, MyLoad, RunFlag); + + Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig( + *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, thisSteamLoop.FluidIndex, RoutineName); + Real64 CpCondensate = FluidProperties::GetSatSpecificHeatRefrig( + *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, 0.0, thisSteamLoop.FluidIndex, RoutineName); + Real64 deltaTsensible = SatTempAtmPress - thisDistrictHeatingSteam.InletTemp; + Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig( + *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, thisSteamLoop.FluidIndex, RoutineName); + Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig( + *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 0.0, thisSteamLoop.FluidIndex, RoutineName); + Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet; + Real64 calOutletMdot = MyLoad / (LatentHeatSteam + (CpCondensate * deltaTsensible)); + + EXPECT_EQ(thisDistrictHeatingSteam.MassFlowRate, + calOutletMdot); // check if the steam outlet mass flow rate from simulate() is equal to the calculation +} diff --git a/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc index faed821f64c..abd21c39bcb 100644 --- a/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc +++ b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc @@ -127,22 +127,17 @@ TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Waterloop) state->dataPlantLoadProfile->PlantProfile.allocate(1); // Test setup for a load profile in a water loop - state->dataPlnt->PlantLoop(1).FluidName = "WATER"; - state->dataPlnt->PlantLoop(1).FluidIndex = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = - DataPlant::PlantEquipmentType::PlantLoadProfile; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE WATER"; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; + auto &thisWaterLoop(state->dataPlnt->PlantLoop(1)); + thisWaterLoop.FluidName = "WATER"; + thisWaterLoop.FluidIndex = 1; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = DataPlant::PlantEquipmentType::PlantLoadProfile; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE WATER"; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; + thisWaterLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; state->dataLoopNodes->Node(1).Temp = 60.0; state->dataLoopNodes->Node(1).MassFlowRateMax = 10; @@ -169,27 +164,28 @@ TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Waterloop) state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.FlowRateFracSchedule).EMSActuatedOn = false; state->dataScheduleMgr->Schedule(thisLoadProfileWaterLoop.FlowRateFracSchedule).CurrentValue = 0.8; - // check InitPlantProfile() + // InitPlantProfile() thisLoadProfileWaterLoop.InitPlantProfile(*state); - EXPECT_EQ(thisLoadProfileWaterLoop.InletTemp, 60.0); // Check the component's inlet temp is set to node data - EXPECT_EQ(thisLoadProfileWaterLoop.Power, 10000); // Check the load schedule's current value is properly applied - EXPECT_EQ(thisLoadProfileWaterLoop.VolFlowRate, 0.0016); // Check the flow rate fraction schedule is properly applied + EXPECT_EQ(thisLoadProfileWaterLoop.InletTemp, 60.0); // check if the component's inlet temp is set to node data + EXPECT_EQ(thisLoadProfileWaterLoop.Power, 10000); // check if the load schedule's current value is properly applied + EXPECT_EQ(thisLoadProfileWaterLoop.VolFlowRate, 0.0016); // check if the flow rate fraction schedule is properly applied - // check simulate() + // simulate() bool firstHVAC = true; Real64 curLoad = 10000.0; bool runFlag = true; + std::string_view RoutineName("PlantLoadProfileTests"); thisLoadProfileWaterLoop.simulate(*state, locWater, firstHVAC, curLoad, runFlag); - Real64 rhoWater = FluidProperties::GetDensityGlycol( - *state, state->dataPlnt->PlantLoop(1).FluidName, 60, state->dataPlnt->PlantLoop(1).FluidIndex, "WaterDensity"); + Real64 rhoWater = FluidProperties::GetDensityGlycol(*state, thisWaterLoop.FluidName, 60, thisWaterLoop.FluidIndex, RoutineName); Real64 Cp = FluidProperties::GetSpecificHeatGlycol( - *state, state->dataPlnt->PlantLoop(1).FluidName, thisLoadProfileWaterLoop.InletTemp, state->dataPlnt->PlantLoop(1).FluidIndex, "GetWaterCp"); + *state, thisWaterLoop.FluidName, thisLoadProfileWaterLoop.InletTemp, thisWaterLoop.FluidIndex, RoutineName); Real64 deltaTemp = curLoad / (rhoWater * thisLoadProfileWaterLoop.VolFlowRate * Cp); Real64 calOutletTemp = thisLoadProfileWaterLoop.InletTemp - deltaTemp; - EXPECT_EQ(thisLoadProfileWaterLoop.OutletTemp, calOutletTemp); // Check the water outlet temperature from simulate() is equal to the calculation + EXPECT_EQ(thisLoadProfileWaterLoop.OutletTemp, + calOutletTemp); // check if the water outlet temperature from simulate() is equal to the calculation } TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Steamloop) @@ -199,25 +195,22 @@ TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Steamloop) state->dataPlantLoadProfile->PlantProfile.allocate(1); // Test setup for a load profile in a steam loop - state->dataPlnt->PlantLoop(1).FluidName = "STEAM"; - state->dataPlnt->PlantLoop(1).FluidIndex = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).TotalBranches = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).TotalComponents = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = - DataPlant::PlantEquipmentType::PlantLoadProfile; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE STEAM"; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; - state->dataPlnt->PlantLoop(1).LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; + auto &thisSteamLoop(state->dataPlnt->PlantLoop(1)); + thisSteamLoop.FluidName = "STEAM"; + thisSteamLoop.FluidIndex = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch.allocate(1); + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).TotalBranches = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).TotalComponents = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp.allocate(1); + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type = DataPlant::PlantEquipmentType::PlantLoadProfile; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Name = "LOAD PROFILE STEAM"; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumIn = 1; + thisSteamLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).NodeNumOut = 2; + + std::string_view RoutineName("PlantLoadProfileTests"); Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig( - *state, state->dataPlnt->PlantLoop(1).FluidName, DataEnvironment::StdPressureSeaLevel, state->dataPlnt->PlantLoop(1).FluidIndex, "SatTemp"); + *state, state->dataPlnt->PlantLoop(1).FluidName, DataEnvironment::StdPressureSeaLevel, state->dataPlnt->PlantLoop(1).FluidIndex, RoutineName); state->dataLoopNodes->Node(1).Temp = SatTempAtmPress; state->dataLoopNodes->Node(1).MassFlowRateMax = 1; @@ -245,29 +238,28 @@ TEST_F(EnergyPlusFixture, LoadProfile_initandsimulate_Steamloop) state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.FlowRateFracSchedule).EMSActuatedOn = false; state->dataScheduleMgr->Schedule(thisLoadProfileSteamLoop.FlowRateFracSchedule).CurrentValue = 0.8; - // check InitPlantProfile() + // InitPlantProfile() thisLoadProfileSteamLoop.InitPlantProfile(*state); - EXPECT_EQ(thisLoadProfileSteamLoop.InletTemp, SatTempAtmPress); // Check the component's inlet temp is set to node data - EXPECT_EQ(thisLoadProfileSteamLoop.Power, 10000); // Check the load schedule's current value is properly applied - EXPECT_EQ(thisLoadProfileSteamLoop.VolFlowRate, 0.0064); // Check the flow rate fraction schedule is properly applied + EXPECT_EQ(thisLoadProfileSteamLoop.InletTemp, SatTempAtmPress); // check if the component's inlet temp is set to node data + EXPECT_EQ(thisLoadProfileSteamLoop.Power, 10000); // check if the load schedule's current value is properly applied + EXPECT_EQ(thisLoadProfileSteamLoop.VolFlowRate, 0.0064); // check if the flow rate fraction schedule is properly applied - // check simulate() + // simulate() bool firstHVAC = true; Real64 curLoad = 10000.0; bool runFlag = true; thisLoadProfileSteamLoop.simulate(*state, locSteam, firstHVAC, curLoad, runFlag); - Real64 EnthSteamIn = FluidProperties::GetSatEnthalpyRefrig( - *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, 1.0, state->dataPlnt->PlantLoop(1).FluidIndex, "EnthDrySteam"); - Real64 EnthSteamOut = FluidProperties::GetSatEnthalpyRefrig( - *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, 0.0, state->dataPlnt->PlantLoop(1).FluidIndex, "EnthWetSteam"); + Real64 EnthSteamIn = + FluidProperties::GetSatEnthalpyRefrig(*state, thisSteamLoop.FluidName, SatTempAtmPress, 1.0, thisSteamLoop.FluidIndex, RoutineName); + Real64 EnthSteamOut = + FluidProperties::GetSatEnthalpyRefrig(*state, thisSteamLoop.FluidName, SatTempAtmPress, 0.0, thisSteamLoop.FluidIndex, RoutineName); Real64 LatentHeatSteam = EnthSteamIn - EnthSteamOut; - - Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol( - *state, state->dataPlnt->PlantLoop(1).FluidName, SatTempAtmPress, state->dataPlnt->PlantLoop(1).FluidIndex, "CpCondensate"); + Real64 CpCondensate = + FluidProperties::GetSpecificHeatGlycol(*state, thisSteamLoop.FluidName, SatTempAtmPress, thisSteamLoop.FluidIndex, RoutineName); Real64 calOutletMdot = curLoad / (LatentHeatSteam + thisLoadProfileSteamLoop.DegOfSubcooling * CpCondensate); EXPECT_EQ(thisLoadProfileSteamLoop.MassFlowRate, calOutletMdot); - // Check the Steam outlet mass flow rate from simulate() is equal to the calculation + // check if the Steam outlet mass flow rate from simulate() is equal to the calculation } From e22f0d88bdc333d5a9e4946e0c1bb2e04751d264 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 01:15:36 -0600 Subject: [PATCH 06/16] Update docs --- .../plant-load-profile.tex | 25 +++- .../district-heating.tex | 2 +- .../src/overview/group-non-zone-equipment.tex | 29 ++++- .../src/overview/group-plant-equipment.tex | 123 +++++++++++++----- 4 files changed, 135 insertions(+), 44 deletions(-) diff --git a/doc/engineering-reference/src/building-system-simulation-system-manager/plant-load-profile.tex b/doc/engineering-reference/src/building-system-simulation-system-manager/plant-load-profile.tex index 7a6a938357c..c9420236b50 100644 --- a/doc/engineering-reference/src/building-system-simulation-system-manager/plant-load-profile.tex +++ b/doc/engineering-reference/src/building-system-simulation-system-manager/plant-load-profile.tex @@ -6,7 +6,9 @@ \section{Plant Load Profile}\label{plant-load-profile} \subsection{Calculation Model}\label{calculation-model} -The LoadProfile:Plant object calculates the outlet water temperature based on the inlet water temperature from the plant loop and user inputs for the scheduled plant load and the requested flow rate.~ The calculation can be expressed with the equation: +\subsubsection{Plant Load Profile in the Water Loop}\label{plant-load-profile-in-the-water-loop} + +The LoadProfile:Plant object in the water loop calculates the outlet water temperature based on the inlet water temperature from the plant loop and user inputs for the scheduled plant load and the requested flow rate.~ The calculation can be expressed with the equation: \begin{equation} {T_{out}} = {T_{in}} - \frac{{{Q_{load}}}}{{\dot m{c_p}}} @@ -41,3 +43,24 @@ \subsection{Calculation Model}\label{calculation-model} \({Q_{load}}\) ~ = the scheduled plant load \(\Delta t\) ~ = the time step interval + + +\subsubsection{Plant Load Profile in the Steam Loop}\label{plant-load-profile-in-the-steam-loop} + +The LoadProfile:Plant object in the steam loop calculates the outlet steam flow rate based on the inlet condensate temperature from the plant loop and user inputs for the scheduled plant load.~ This model accounts for the latent heat transfer and sensible cooling of water.~ Steam enters the load profile component at quality equal to 1.0, at saturation temperature and leaves the load profile component with desired degree of sub cooling.~ The user inputs the desired degree of subcooling, which determines the condensate outlet condition from the load profile component.~ The calculation can be expressed with the equation: + +\begin{equation} +{\dot m_{out}}\,\,\,\, = \,\,\,\,\,\frac{{{Q_{load}}}}{{{h_{fg}} + {c_{p,condensate}} \times \Delta {T_{sc}}}} +\end{equation} + +where + +\({\dot m_{out}}\) ~ = the outlet steam mass flow rate + +\({Q_{load}}\) ~ = the scheduled plant load + +\({h_{fg}}\) ~ = the steam latent heat of vaporization + +\({ \Delta {T_{sc}}}\) ~ = the temperature difference between saturation temperature and condensate temperature + +\({c_{p,condensate}}\) ~ = the condensate heat capacity \ No newline at end of file diff --git a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex index 94311f9bae1..947d3bd6731 100644 --- a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex +++ b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex @@ -1,3 +1,3 @@ \section{District Heating }\label{district-heating} -When the user is not interested in a plant simulation or there is some centralized source of hot water, the following model can be used in the input.~ This allows the user to achieve a simulation without specifying operating parameters or curve fits for boiler models.~ This model only needs the connections to the loop and the nominal capacity to simulate.~ See the InputOutput Reference for additional information (Object: DistrictHeating).~ This model calculates the output capacity necessary from the inlet temperature to the setpoint temperature for that loop with the given mass flow rate in Watts. +When the user is not interested in a plant simulation or there is some centralized source of hot water, the following model can be used in the input.~ This allows the user to achieve a simulation without specifying operating parameters or curve fits for boiler models.~ This model only needs the connections to the loop and the nominal capacity to simulate.~ See the InputOutput Reference for additional information (Object: DistrictHeating:Water and DistrictHeating:Steam).~ DistrictHeating:Water calculates the output capacity necessary from the inlet temperature to the setpoint temperature for that loop with the given mass flow rate in Watts.~ DistrictHeating:Steam the output capacity necessary from the inlet condensate to the saturated steam. diff --git a/doc/input-output-reference/src/overview/group-non-zone-equipment.tex b/doc/input-output-reference/src/overview/group-non-zone-equipment.tex index 5d35dff1057..00b6cc83e39 100644 --- a/doc/input-output-reference/src/overview/group-non-zone-equipment.tex +++ b/doc/input-output-reference/src/overview/group-non-zone-equipment.tex @@ -38,17 +38,30 @@ \subsubsection{Inputs}\label{inputs-028} Reference to the schedule object specifying the flow rate fraction relative to the value in the field Peak Flow Rate (above). +\paragraph{Field: Plant Loop Fluid Type}\label{field-plant-loop-fluid-type} + +The fluid type of the plant loop; water or steam. + +\paragraph{Field: Degree of SubCooling}\label{field-degree-of-subcooling-load-profile} + +This field is used only when Plant Loop Fluid Type=Steam. The minimum value is 1$^\circ$ Celsius and default is 5$^\circ$ Celsius. + +\paragraph{Field: Degree of Loop SubCooling}\label{field-degree-of-loop-subcooling-load-profile} + +This field is used only when Plant Loop Fluid Type=Steam. The minimum value is 2$^\circ$ Celsius and default is 5$^\circ$ Celsius. + An example of this object follows. \begin{lstlisting} LoadProfile:Plant, - Load Profile 1, !- Name - Demand Load Profile 1 Inlet Node, !- Inlet Node Name - Demand Load Profile 1 Outlet Node, !- Outlet Node Name - Load Profile 1 Load Schedule, !- Load Schedule Name {W} - 0.003, !- Peak Flow Rate {m3/s} - Load Profile 1 Flow Frac Schedule; !- Flow Rate Fraction Schedule Name + Load Profile 1, !- Name + Demand Load Profile 1 Inlet Node, !- Inlet Node Name + Demand Load Profile 1 Outlet Node, !- Outlet Node Name + Load Profile 1 Load Schedule, !- Load Schedule Name {W} + 0.003, !- Peak Flow Rate {m3/s} + Load Profile 1 Flow Frac Schedule, !- Flow Rate Fraction Schedule Name + Water; !-Plant Loop Fluid Type \end{lstlisting} \subsubsection{Outputs}\label{outputs-020} @@ -66,6 +79,8 @@ \subsubsection{Outputs}\label{outputs-020} HVAC,Sum,Plant Load Profile Heating Energy {[}J{]} \item HVAC,Sum,Plant Load Profile Cooling Energy {[}J{]} +\item + HVAC,Average,Plant Load Profile Steam Outlet Temperature {[}J{]} \end{itemize} \paragraph{Plant Load Profile Mass Flow Rate {[}kg/s{]}}\label{plant-load-profile-mass-flow-rate-kgs} @@ -82,6 +97,8 @@ \subsubsection{Outputs}\label{outputs-020} These report the overall cooling or heating energy that the load profile object places on the plant loop, in Joules. +\paragraph{Plant Load Profile Steam Outlet Temperature {[}C{]}}\label{plant-load-profile-steam-outlet-temperature-c} + The inlet and outlet node temperatures and mass flow rates can be monitored using the system node output variables: \begin{itemize} diff --git a/doc/input-output-reference/src/overview/group-plant-equipment.tex b/doc/input-output-reference/src/overview/group-plant-equipment.tex index d5bd8aad70f..d764010dfe3 100644 --- a/doc/input-output-reference/src/overview/group-plant-equipment.tex +++ b/doc/input-output-reference/src/overview/group-plant-equipment.tex @@ -6129,44 +6129,40 @@ \subsubsection{Outputs}\label{outputs-14-003} \begin{itemize} \item - HVAC,Average, District Cooling Chilled Water Rate {[}W{]} + HVAC,Average, District Cooling Water Rate {[}W{]} \item - HVAC,Sum, District Cooling Chilled Water Energy {[}J{]} + HVAC,Sum, District Cooling Water Energy {[}J{]} \item Zone,Meter, DistrictCooling:Plant {[}J{]} \item Zone,Meter,Cooling: DistrictCooling {[}J{]} \item - HVAC,Average,District Cooling Rate {[}W{]} + HVAC,Average,District Cooling Water Inlet Temperature {[}C{]} \item - HVAC,Average,District Cooling Inlet Temperature {[}C{]} + HVAC,Average,District Cooling Water Outlet Temperature {[}C{]} \item - HVAC,Average,District Cooling Outlet Temperature {[}C{]} - \item - HVAC,Average,District Cooling Mass Flow Rate {[}kg/s{]} + HVAC,Average,District Cooling Water Mass Flow Rate {[}kg/s{]} \end{itemize} -\paragraph{District Cooling Chilled Water Rate {[}W{]}}\label{district-cooling-chilled-water-rate-w} - -\paragraph{District Cooling Chilled Water Energy {[}J{]}}\label{district-cooling-chilled-water-energy-j} +\paragraph{District Cooling Water Rate {[}W{]}}\label{district-cooling-chilled-water-rate-w} -These outputs are the energy taken from purchased chilled water. Consumption is metered on Cooling:DistrictCooling, DistrictCooling:Plant, and DistrictCooling:Facility. +This is the useful rate of cooling energy from purchased chilled water. -\paragraph{District Cooling Rate {[}W{]}}\label{district-cooling-rate-w} +\paragraph{District Cooling Water Energy {[}J{]}}\label{district-cooling-chilled-water-energy-j} -This is the useful rate of cooling energy from purchased chilled water. For the current algorithm, this is the same as District Cooling Chilled Water Rate. +These outputs are the energy taken from purchased chilled water. Consumption is metered on Cooling:DistrictCooling, DistrictCooling:Plant, and DistrictCooling:Facility. -\paragraph{District Cooling Inlet Temperature {[}C{]}}\label{district-cooling-inlet-temperature-c} +\paragraph{District Cooling Water Inlet Temperature {[}C{]}}\label{district-cooling-inlet-temperature-c} -\paragraph{District Cooling Outlet Temperature {[}C{]}}\label{district-cooling-outlet-temperature-c} +\paragraph{District Cooling WaterOutlet Temperature {[}C{]}}\label{district-cooling-outlet-temperature-c} -\paragraph{District Cooling Mass Flow Rate {[}kg/s{]}}\label{district-cooling-mass-flow-rate-kgs} +\paragraph{District Cooling Water Mass Flow Rate {[}kg/s{]}}\label{district-cooling-mass-flow-rate-kgs} These outputs are the supply-side plant loop chilled water inlet and outlet temperatures and mass flow rate. -\subsection{DistrictHeating}\label{districtheating} +\subsection{DistrictHeating:Water}\label{districtheating} -When the user is not interested in a plant simulation or there is some centralized source of hot water (district heating), the following object can be used in the input. +When the user is not interested in a plant simulation or there is some centralized source of hot water (district heating water), the following object can be used in the input. \subsubsection{Inputs}\label{inputs-17-006} @@ -6203,41 +6199,96 @@ \subsubsection{Outputs}\label{outputs-15-002} \begin{itemize} \item - HVAC,Average,District Heating Hot Water Rate {[}W{]} - \item - HVAC,Sum,District Heating Hot Water Energy {[}J{]} + HVAC,Average,District Heating Water Rate {[}W{]} \item - Zone,Meter,DistrictHeating:Plant {[}J{]} + HVAC,Sum,District Heating Water Energy {[}J{]} \item - Zone,Meter,Heating:DistrictHeating {[}J{]} + Zone,Meter,DistrictHeatingWater:Plant {[}J{]} \item - HVAC,Average,District Heating Rate {[}W{]} + Zone,Meter,Heating:DistrictHeatingWater {[}J{]} \item - HVAC,Average,District Heating Inlet Temperature {[}C{]} + HVAC,Average,District Heating Water Inlet Temperature {[}C{]} \item - HVAC,Average,District Heating Outlet Temperature {[}C{]} + HVAC,Average,District Heating Water Outlet Temperature {[}C{]} \item - HVAC,Average,District Heating Mass Flow Rate {[}kg/s{]} + HVAC,Average,District Heating Water Mass Flow Rate {[}kg/s{]} \end{itemize} -\paragraph{District Heating Hot Water Rate {[}W{]}}\label{district-heating-hot-water-rate-w} - -\paragraph{District Heating Hot Water Energy {[}J{]}}\label{district-heating-hot-water-energy-j} +\paragraph{District Heating Water Rate {[}W{]}}\label{district-heating-hot-water-rate-w} -These outputs are the energy taken from purchased hot water. Consumption is metered on Heating:DistrictHeating, DistrictHeating:Plant, and DistrictHeating:Facility. +This is the useful rate of heating energy from purchased hot water. -\paragraph{District Heating Rate {[}W{]}}\label{district-heating-rate-w} +\paragraph{District Heating Water Energy {[}J{]}}\label{district-heating-hot-water-energy-j} -This is the useful rate of heating energy from purchased hot water. For the current algorithm, this is the same as District Heating Hot Water Rate. +These outputs are the energy taken from purchased hot water. Consumption is metered on Heating:DistrictHeatingWater, DistrictHeatingWater:Plant, and DistrictHeatingWater:Facility. -\paragraph{District Heating Inlet Temperature {[}C{]}}\label{district-heating-inlet-temperature-c} +\paragraph{District Heating Water Inlet Temperature {[}C{]}}\label{district-heating-inlet-temperature-c} -\paragraph{District Heating Outlet Temperature {[}C{]}}\label{district-heating-outlet-temperature-c} +\paragraph{District Heating Water Outlet Temperature {[}C{]}}\label{district-heating-outlet-temperature-c} -\paragraph{District Heating Mass Flow Rate {[}kg/s{]}}\label{district-heating-mass-flow-rate-kgs} +\paragraph{District Heating Water Mass Flow Rate {[}kg/s{]}}\label{district-heating-mass-flow-rate-kgs} These outputs are the supply-side plant loop hot water inlet and outlet temperatures and mass flow rate. +\subsection{DistrictHeating:Steam}\label{districtheatingsteam} + +When the user is not interested in a plant simulation or there is some centralized source of steam (district heating steam), the following object can be used in the input. + +\subsubsection{Inputs}\label{inputs-17-006} + +\paragraph{Field: Name}\label{field-name-16-006} + +This alpha field contains the identifying name for the district heating steam (i.e., purchased steam). + +\paragraph{Field:Steam Inlet Node Name}\label{field-steam-inlet-node-name-2} + +This alpha field contains the identifying name for the district heating inlet node. + +\paragraph{Field: Steam Outlet Node Name}\label{field-steam-outlet-node-name-2} + +This alpha field contains the identifying name for the district heating outlet node. + +\paragraph{Field: Nominal Capacity}\label{field-nominal-capacity-12} + +This numeric field contains the nominal demand (W) that the district heating will meet. This field is autosizable. + +\paragraph{Field: Capacity Fraction Schedule Name}\label{field-capacity-fraction-schedule-name-2} + +This alpha field contains the name of a schedule that describes how the nominal capacity varies over time.~ Values must non-negative. The capacity at a given point in time is determined by the product of the previous field and the value in this schedule. If the field is omitted or left blank, then the program assumes a schedule value of 1.0 all the time. + +\subsubsection{Outputs}\label{outputs-15-003} + +\begin{itemize} + \item + HVAC,Average,District Heating Steam Rate {[}W{]} + \item + HVAC,Sum,District Heating Steam Energy {[}J{]} + \item + Zone,Meter,DistrictHeatingSteam:Plant {[}J{]} + \item + Zone,Meter,Heating:DistrictHeatingSteam {[}J{]} + \item + HVAC,Average,District Heating Steam Inlet Temperature {[}C{]} + \item + HVAC,Average,District Heating Steam Outlet Temperature {[}C{]} + \item + HVAC,Average,District Heating Steam Mass Flow Rate {[}kg/s{]} +\end{itemize} + +\paragraph{District Heating Steam Energy {[}J{]}}\label{district-heating-Steam-energy-j} + +These outputs are the energy taken from purchased steam. Consumption is metered on Heating:DistrictHeatingSteam, DistrictHeatingSteam:Plant, and DistrictHeatingSteam:Facility. + +\paragraph{District Heating Steam Rate {[}W{]}}\label{district-heating-steam-rate-w} + +This is the useful rate of heating energy from purchased steam. + +\paragraph{District Heating Steam Inlet Temperature {[}C{]}}\label{district-heating-steam-inlet-temperature-c} + +\paragraph{District Heating Steam Outlet Temperature {[}C{]}}\label{district-heating-steam-outlet-temperature-c} + +\paragraph{District Heating Steam Mass Flow Rate {[}kg/s{]}}\label{district-heating-steam-mass-flow-rate-kgs} + \subsection{PlantComponent:TemperatureSource}\label{plantcomponenttemperaturesource} This object allows the simulation of a water (or other fluid) source at a user-specified temperature.~ This could include a river, well, or seawater source, or any other configuration where the fluid temperature being supplied by the component to the plant is known.~ The temperature may be a constant or scheduled.~ Of course, the scheduled value may also be overwritten via EMS in cases where the specified temperature should be calculated at run-time. From 330ae90c9b5c31185bb2135b76a92c2bd17426b5 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 01:29:52 -0600 Subject: [PATCH 07/16] fix Cp for condensate --- src/EnergyPlus/OutsideEnergySources.cc | 3 +-- tst/EnergyPlus/unit/OutsideEnergySources.unit.cc | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index 2a5b1e94f08..59660e6cd35 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -489,8 +489,7 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on inlet temp, saturate temp at atmospheric pressure, Cp of inlet condensate, and MyLoad Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, loop.FluidIndex, RoutineName); - Real64 CpCondensate = - FluidProperties::GetSatSpecificHeatRefrig(state, loop.FluidName, this->InletTemp, 0.0, loop.FluidIndex, RoutineName); + Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol(state, loop.FluidName, this->InletTemp, loop.FluidIndex, RoutineName); Real64 deltaTsensible = SatTempAtmPress - this->InletTemp; Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, loop.FluidIndex, RoutineName); diff --git a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc index 2d37666442f..3c42c87c7a3 100644 --- a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc +++ b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc @@ -206,8 +206,8 @@ TEST_F(EnergyPlusFixture, DistrictCoolingandHeating) Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig( *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, thisSteamLoop.FluidIndex, RoutineName); - Real64 CpCondensate = FluidProperties::GetSatSpecificHeatRefrig( - *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, 0.0, thisSteamLoop.FluidIndex, RoutineName); + Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol( + *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp,thisSteamLoop.FluidIndex, RoutineName); Real64 deltaTsensible = SatTempAtmPress - thisDistrictHeatingSteam.InletTemp; Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig( *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, thisSteamLoop.FluidIndex, RoutineName); From 05a054c88f64ba9f74b12202eedf7c81d5de0b0e Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 08:51:50 -0600 Subject: [PATCH 08/16] clang format --- src/EnergyPlus/OutsideEnergySources.cc | 3 ++- src/EnergyPlus/PluginManager.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index 59660e6cd35..f5cef2f83d8 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -486,7 +486,8 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re this->OutletTemp = min(this->OutletTemp, LoopMaxTemp); MyLoad = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp); } - } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on inlet temp, saturate temp at atmospheric pressure, Cp of inlet condensate, and MyLoad + } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchSteam) { // determine mass flow rate based on inlet temp, saturate temp at + // atmospheric pressure, Cp of inlet condensate, and MyLoad Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, loop.FluidIndex, RoutineName); Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol(state, loop.FluidName, this->InletTemp, loop.FluidIndex, RoutineName); diff --git a/src/EnergyPlus/PluginManager.cc b/src/EnergyPlus/PluginManager.cc index ab1bdea6212..7389ba6a34a 100644 --- a/src/EnergyPlus/PluginManager.cc +++ b/src/EnergyPlus/PluginManager.cc @@ -245,7 +245,7 @@ void PluginManager::setupOutputVariables([[maybe_unused]] EnergyPlusData &state) } else { if (static_cast(getEnumValue(Constant::eResourceNamesUC, resourceType)) != Constant::eResource::Invalid) { sResourceType = Constant::eResourceNames[getEnumValue(Constant::eResourceNamesUC, resourceType)]; - } else { + } else { ShowSevereError(state, format("Invalid input for PythonPlugin:OutputVariable, unexpected Resource Type = {}", resourceType)); ShowFatalError(state, "Python plugin output variable input problem causes program termination"); } From 5682d7ef3a3b9f5c7999cb255de66072f1ccef89 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 08:52:55 -0600 Subject: [PATCH 09/16] clang format --- tst/EnergyPlus/unit/OutsideEnergySources.unit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc index 3c42c87c7a3..4c56d8cb949 100644 --- a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc +++ b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc @@ -207,7 +207,7 @@ TEST_F(EnergyPlusFixture, DistrictCoolingandHeating) Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig( *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, thisSteamLoop.FluidIndex, RoutineName); Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol( - *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp,thisSteamLoop.FluidIndex, RoutineName); + *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, thisSteamLoop.FluidIndex, RoutineName); Real64 deltaTsensible = SatTempAtmPress - thisDistrictHeatingSteam.InletTemp; Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig( *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, thisSteamLoop.FluidIndex, RoutineName); From ca16188327b5c3fc469c9241036a7ba67057bc84 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 10:03:09 -0600 Subject: [PATCH 10/16] fix errors --- src/EnergyPlus/OutsideEnergySources.cc | 6 ++---- tst/EnergyPlus/unit/OutsideEnergySources.unit.cc | 10 +++++----- tst/EnergyPlus/unit/PlantLoadProfile.unit.cc | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index f5cef2f83d8..798c9e61b02 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -492,10 +492,8 @@ void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Re FluidProperties::GetSatTemperatureRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, loop.FluidIndex, RoutineName); Real64 CpCondensate = FluidProperties::GetSpecificHeatGlycol(state, loop.FluidName, this->InletTemp, loop.FluidIndex, RoutineName); Real64 deltaTsensible = SatTempAtmPress - this->InletTemp; - Real64 EnthSteamInDry = - FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, loop.FluidIndex, RoutineName); - Real64 EnthSteamOutWet = - FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, DataEnvironment::StdPressureSeaLevel, 0.0, loop.FluidIndex, RoutineName); + Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 1.0, loop.FluidIndex, RoutineName); + Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(state, loop.FluidName, this->InletTemp, 0.0, loop.FluidIndex, RoutineName); Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet; this->MassFlowRate = MyLoad / (LatentHeatSteam + (CpCondensate * deltaTsensible)); PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNodeNum, this->OutletNodeNum, this->plantLoc); diff --git a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc index 4c56d8cb949..aad4719a6be 100644 --- a/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc +++ b/tst/EnergyPlus/unit/OutsideEnergySources.unit.cc @@ -95,9 +95,9 @@ TEST_F(EnergyPlusFixture, DistrictCoolingandHeating) auto &thisDistrictHeatingSteam = state->dataOutsideEnergySrcs->EnergySource(3); // Tests for GetOutsideEnergySourcesInput() - EXPECT_EQ(thisDistrictHeatingWater.EnergyType, DataPlant::PlantEquipmentType::PurchHotWater); - EXPECT_EQ(thisDistrictCooling.EnergyType, DataPlant::PlantEquipmentType::PurchChilledWater); - EXPECT_EQ(thisDistrictHeatingSteam.EnergyType, DataPlant::PlantEquipmentType::PurchSteam); + EXPECT_TRUE(compare_enums(thisDistrictHeatingWater.EnergyType, DataPlant::PlantEquipmentType::PurchHotWater)); + EXPECT_TRUE(compare_enums(thisDistrictCooling.EnergyType, DataPlant::PlantEquipmentType::PurchChilledWater)); + EXPECT_TRUE(compare_enums(thisDistrictHeatingSteam.EnergyType, DataPlant::PlantEquipmentType::PurchSteam)); EXPECT_EQ(thisDistrictHeatingWater.NomCap, 1000000.0); EXPECT_EQ(thisDistrictCooling.NomCap, 900000.0); @@ -210,9 +210,9 @@ TEST_F(EnergyPlusFixture, DistrictCoolingandHeating) *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, thisSteamLoop.FluidIndex, RoutineName); Real64 deltaTsensible = SatTempAtmPress - thisDistrictHeatingSteam.InletTemp; Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig( - *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 1.0, thisSteamLoop.FluidIndex, RoutineName); + *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, 1.0, thisSteamLoop.FluidIndex, RoutineName); Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig( - *state, thisSteamLoop.FluidName, DataEnvironment::StdPressureSeaLevel, 0.0, thisSteamLoop.FluidIndex, RoutineName); + *state, thisSteamLoop.FluidName, thisDistrictHeatingSteam.InletTemp, 0.0, thisSteamLoop.FluidIndex, RoutineName); Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet; Real64 calOutletMdot = MyLoad / (LatentHeatSteam + (CpCondensate * deltaTsensible)); diff --git a/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc index abd21c39bcb..8f5e6345d5a 100644 --- a/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc +++ b/tst/EnergyPlus/unit/PlantLoadProfile.unit.cc @@ -107,12 +107,12 @@ TEST_F(EnergyPlusFixture, LoadProfile_GetInput) // Tests for LoadProfile on Water loop EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).Name, "LOAD PROFILE WATER"); - EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).FluidType, PlantLoopFluidType::Water); + EXPECT_TRUE(compare_enums(state->dataPlantLoadProfile->PlantProfile(1).FluidType, PlantLoopFluidType::Water)); EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(1).PeakVolFlowRate, 0.002); // Tests for LoadProfile on Steam loop EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).Name, "LOAD PROFILE STEAM"); - EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).FluidType, PlantLoopFluidType::Steam); + EXPECT_TRUE(compare_enums(state->dataPlantLoadProfile->PlantProfile(2).FluidType, PlantLoopFluidType::Steam)); EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).PeakVolFlowRate, 0.008); EXPECT_EQ(state->dataPlantLoadProfile->PlantProfile(2).DegOfSubcooling, 5.0); // check if the default value is assigned in cases where there is no input From 82a878f7bbce7e13ed252205f1b5fe75184be840 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Fri, 15 Sep 2023 10:39:29 -0600 Subject: [PATCH 11/16] clang format --- src/EnergyPlus/OutsideEnergySources.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/OutsideEnergySources.hh b/src/EnergyPlus/OutsideEnergySources.hh index f31b7dd56d3..9089b5ecfce 100644 --- a/src/EnergyPlus/OutsideEnergySources.hh +++ b/src/EnergyPlus/OutsideEnergySources.hh @@ -55,8 +55,8 @@ #include #include #include -#include #include +#include namespace EnergyPlus { From b4a8cfd1e014d00c3eaec37fd8047be55da17328 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Mon, 18 Sep 2023 10:03:12 -0600 Subject: [PATCH 12/16] resolve conflicts from #10131 --- src/EnergyPlus/DataGlobalConstants.hh | 30 ++++++++++++------- src/EnergyPlus/DataHeatBalance.hh | 1 - src/EnergyPlus/InternalHeatGains.cc | 13 ++++---- tst/EnergyPlus/unit/InternalHeatGains.unit.cc | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/EnergyPlus/DataGlobalConstants.hh b/src/EnergyPlus/DataGlobalConstants.hh index 9054985d420..fb135398b7d 100644 --- a/src/EnergyPlus/DataGlobalConstants.hh +++ b/src/EnergyPlus/DataGlobalConstants.hh @@ -93,6 +93,7 @@ namespace Constant { DistrictHeatingWater, DistrictHeatingSteam, Water, + None, // used for OtherEquipment object EnergyTransfer, ElectricityProduced, ElectricityPurchased, @@ -146,6 +147,7 @@ namespace Constant { DistrictHeatingWater, DistrictHeatingSteam, Water, + None, // used for OtherEquipment object Num }; @@ -184,6 +186,7 @@ namespace Constant { eFuel::DistrictHeatingWater, eFuel::DistrictHeatingSteam, eFuel::Water, + eFuel::None, eFuel::Invalid, eFuel::Invalid, eFuel::Invalid, @@ -231,17 +234,18 @@ namespace Constant { eResource::DistrictCooling, eResource::DistrictHeatingWater, eResource::DistrictHeatingSteam, - eResource::Water}; + eResource::Water, + eResource::None}; constexpr std::array(eResource::Num)> eResource2ePollutant = { - ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, - ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, - ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, - ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, - ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, - ePollutant::Invalid, ePollutant::Invalid, ePollutant::SO2, ePollutant::NOx, ePollutant::N2O, ePollutant::PM, - ePollutant::PM2_5, ePollutant::PM10, ePollutant::CO, ePollutant::CO2, ePollutant::CH4, ePollutant::NH3, - ePollutant::NMVOC, ePollutant::Hg, ePollutant::Pb, ePollutant::NuclearHigh, ePollutant::NuclearLow}; + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, + ePollutant::Invalid, ePollutant::Invalid, ePollutant::Invalid, ePollutant::SO2, ePollutant::NOx, ePollutant::N2O, + ePollutant::PM, ePollutant::PM2_5, ePollutant::PM10, ePollutant::CO, ePollutant::CO2, ePollutant::CH4, + ePollutant::NH3, ePollutant::NMVOC, ePollutant::Hg, ePollutant::Pb, ePollutant::NuclearHigh, ePollutant::NuclearLow}; constexpr std::array(ePollutant::Num)> ePollutant2eResource = {eResource::SO2, eResource::NOx, @@ -273,6 +277,7 @@ namespace Constant { "DISTRICTHEATINGWATER", "DISTRICTHEATINGSTEAM", "WATER", + "NONE", "ENERGYTRANSFER", "ELECTRICITYPRODUCED", "ELECTRICITYPURCHASED", @@ -321,6 +326,7 @@ namespace Constant { "DistrictHeatingWater", "DistrictHeatingSteam", "Water", + "None", "EnergyTransfer", "ElectricityProduced", "ElectricityPurchased", @@ -369,7 +375,8 @@ namespace Constant { eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictCooling)])], eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingWater)])], eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])], - eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::Water)])]}; + eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::Water)])], + eResourceNamesUC[static_cast(eFuel2eResource[static_cast(eFuel::None)])]}; static constexpr std::array(eFuel::Num)> eFuelNames = { eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::Electricity)])], @@ -385,7 +392,8 @@ namespace Constant { eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictCooling)])], eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingWater)])], eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::DistrictHeatingSteam)])], - eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::Water)])]}; + eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::Water)])], + eResourceNames[static_cast(eFuel2eResource[static_cast(eFuel::None)])]}; static constexpr std::array(ePollutant::Num)> ePollutantNamesUC = { eResourceNamesUC[static_cast(ePollutant2eResource[static_cast(ePollutant::SO2)])], diff --git a/src/EnergyPlus/DataHeatBalance.hh b/src/EnergyPlus/DataHeatBalance.hh index cd4e04723b7..65da26de11d 100644 --- a/src/EnergyPlus/DataHeatBalance.hh +++ b/src/EnergyPlus/DataHeatBalance.hh @@ -897,7 +897,6 @@ namespace DataHeatBalance { std::string EndUseSubcategory; // user defined name for the end use category std::string otherEquipFuelTypeString; // Fuel Type string for Other Equipment Constant::eFuel OtherEquipFuelType = Constant::eFuel::Invalid; // Fuel Type Number of the Other Equipment - bool OtherEquipFuelTypeNone = false; // Flag for Fuel Type = "None" }; struct ExtVentedCavityStruct diff --git a/src/EnergyPlus/InternalHeatGains.cc b/src/EnergyPlus/InternalHeatGains.cc index 9a5189c18ff..e0df054086c 100644 --- a/src/EnergyPlus/InternalHeatGains.cc +++ b/src/EnergyPlus/InternalHeatGains.cc @@ -2662,8 +2662,7 @@ namespace InternalHeatGains { std::string FuelTypeString(""); if (IHGAlphas(2) == "NONE") { - thisZoneOthEq.OtherEquipFuelType = Constant::eFuel::Invalid; - thisZoneOthEq.OtherEquipFuelTypeNone = true; + thisZoneOthEq.OtherEquipFuelType = Constant::eFuel::None; FuelTypeString = IHGAlphas(2); } else { thisZoneOthEq.OtherEquipFuelType = static_cast(getEnumValue(Constant::eFuelNamesUC, IHGAlphas(2))); @@ -2681,7 +2680,7 @@ namespace InternalHeatGains { ErrorsFound = true; } thisZoneOthEq.otherEquipFuelTypeString = FuelTypeString; // Save for output variable setup later - // Build list of fuel types used in each zone and space (excluding None and Water) + // Build list of fuel types used in each zone and space (excluding Water) bool found = false; for (Constant::eFuel fuelType : state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNums) { if (thisZoneOthEq.OtherEquipFuelType == fuelType) { @@ -2821,7 +2820,7 @@ namespace InternalHeatGains { // Throw an error if the design level is negative and we have a fuel type if (thisZoneOthEq.DesignLevel < 0.0 && thisZoneOthEq.OtherEquipFuelType != Constant::eFuel::Invalid && - !(thisZoneOthEq.OtherEquipFuelTypeNone)) { + thisZoneOthEq.OtherEquipFuelType != Constant::eFuel::None) { ShowSevereError(state, format("{}{}=\"{}\", {} is not allowed to be negative", RoutineName, @@ -6133,7 +6132,7 @@ namespace InternalHeatGains { addZoneOutputs(state.dataHeatBal->ZoneOtherEq(othEqNum).ZonePtr) = true; addSpaceOutputs(state.dataHeatBal->ZoneOtherEq(othEqNum).spaceIndex) = true; if (state.dataHeatBal->ZoneOtherEq(othEqNum).OtherEquipFuelType != Constant::eFuel::Invalid && - !(state.dataHeatBal->ZoneOtherEq(othEqNum).OtherEquipFuelTypeNone)) { + state.dataHeatBal->ZoneOtherEq(othEqNum).OtherEquipFuelType != Constant::eFuel::None) { std::string fuelTypeString = state.dataHeatBal->ZoneOtherEq(othEqNum).otherEquipFuelTypeString; SetupOutputVariable(state, "Other Equipment " + fuelTypeString + " Rate", @@ -6239,7 +6238,7 @@ namespace InternalHeatGains { if (addZoneOutputs(zoneNum)) { for (size_t i = 0; i < state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNums.size(); ++i) { Constant::eFuel fuelType = state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNums[i]; - if (fuelType == Constant::eFuel::Invalid) continue; + if (fuelType == Constant::eFuel::Invalid || fuelType == Constant::eFuel::None) continue; SetupOutputVariable(state, "Zone Other Equipment " + state.dataHeatBal->Zone(zoneNum).otherEquipFuelTypeNames[i] + " Rate", @@ -6337,7 +6336,7 @@ namespace InternalHeatGains { if (addSpaceOutputs(spaceNum)) { for (size_t i = 0; i < state.dataHeatBal->space(spaceNum).otherEquipFuelTypeNums.size(); ++i) { Constant::eFuel fuelType = state.dataHeatBal->space(spaceNum).otherEquipFuelTypeNums[i]; - if (fuelType == Constant::eFuel::Invalid) continue; + if (fuelType == Constant::eFuel::Invalid || fuelType == Constant::eFuel::None) continue; SetupOutputVariable(state, "Space Other Equipment " + state.dataHeatBal->space(spaceNum).otherEquipFuelTypeNames[i] + " Rate", diff --git a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc index 628ab11ece6..67dd46487fc 100644 --- a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc +++ b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc @@ -129,7 +129,7 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_OtherEquipment_CheckFuelType) for (unsigned long i = 1; i <= state->dataHeatBal->ZoneOtherEq.size(); ++i) { const DataHeatBalance::ZoneEquipData &equip = state->dataHeatBal->ZoneOtherEq(i); if (equip.Name == "OTHEREQ1") { - ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, Constant::eFuel::Invalid)); + ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, Constant::eFuel::None)); } else if (equip.Name == "OTHEREQ2") { ASSERT_TRUE(compare_enums(equip.OtherEquipFuelType, Constant::eFuel::Propane)); } From 1dfc9d1dbb2c4906e5ac16f0400e370884ecf57e Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Tue, 19 Sep 2023 11:44:14 -0600 Subject: [PATCH 13/16] update doc 2 --- .../group-hvac-templates.tex | 2 +- .../src/input-for-output.tex | 6 +-- .../group-energy-management-system-ems.tex | 2 +- .../group-exterior-energy-use-equipment.tex | 2 +- .../group-heating-and-cooling-coils.tex | 2 +- ...oup-internal-gains-people-lights-other.tex | 42 +++++++++---------- .../src/overview/group-plant-equipment.tex | 2 +- .../overview/group-simulation-parameters.tex | 8 ++-- .../src/overview/group-water-heaters.tex | 12 +++--- .../src/overview/group-water-systems.tex | 2 +- .../overview/group-zone-forced-air-units.tex | 12 +++--- .../output-table-summaryreports.tex | 4 +- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/doc/input-output-reference/src/hvac-template-objects/group-hvac-templates.tex b/doc/input-output-reference/src/hvac-template-objects/group-hvac-templates.tex index 40478f5a655..69b8c30ca4a 100644 --- a/doc/input-output-reference/src/hvac-template-objects/group-hvac-templates.tex +++ b/doc/input-output-reference/src/hvac-template-objects/group-hvac-templates.tex @@ -7965,7 +7965,7 @@ \subsubsection{Inputs}\label{inputs-29-000} CondensingHotWaterBoiler -- Hot water boiler (condensing) \end{itemize} -The EnergyPlus equipment object types which are used are \hyperref[districtheating]{DistrictHeating} or \hyperref[boilerhotwater]{Boiler:HotWater}. These equipment type keys must be used if setting up a user-defined boiler plant operation scheme. +The EnergyPlus equipment object types which are used are \hyperref[districtheating]{DistrictHeatingWater} or \hyperref[boilerhotwater]{Boiler:HotWater}. These equipment type keys must be used if setting up a user-defined boiler plant operation scheme. \paragraph{Field: Capacity}\label{field-capacity-1} diff --git a/doc/input-output-reference/src/input-for-output.tex b/doc/input-output-reference/src/input-for-output.tex index 3075c3b30ee..e526ee8c305 100644 --- a/doc/input-output-reference/src/input-for-output.tex +++ b/doc/input-output-reference/src/input-for-output.tex @@ -497,9 +497,9 @@ \subsubsection{Field: Name}\label{field-name-1-036} OtherFuel1 \tabularnewline OtherFuel2 \tabularnewline Water \tabularnewline -Steam \tabularnewline DistrictCooling \tabularnewline -DistrictHeating \tabularnewline +DistrictHeatingWater \tabularnewline +DistrictHeatingSteam \tabularnewline ElectricityPurchased \tabularnewline ElectricitySurplusSold \tabularnewline ElectricityNet \tabularnewline @@ -666,7 +666,7 @@ \subsection{Output:EnvironmentalImpactFactors}\label{outputenvironmentalimpactfa %\endhead % Electricity:Facility & Diesel:Facility \tabularnewline -DistrictCooling:Facility & DistrictHeating:Facility \tabularnewline +DistrictCooling:Facility & DistrictHeatingWater:Facility \tabularnewline NaturalGas:Facility & Gasoline:Facility \tabularnewline Coal:Facility & FuelOilNo1:Facility \tabularnewline FuelOilNo2:Facility & Propane:Facility \tabularnewline diff --git a/doc/input-output-reference/src/overview/group-energy-management-system-ems.tex b/doc/input-output-reference/src/overview/group-energy-management-system-ems.tex index 5032c5146a8..4bb798e247f 100644 --- a/doc/input-output-reference/src/overview/group-energy-management-system-ems.tex +++ b/doc/input-output-reference/src/overview/group-energy-management-system-ems.tex @@ -431,7 +431,7 @@ \subsubsection{Field: Resource Type}\label{field-resource-type} \item \textbf{\hyperref[districtcooling]{DistrictCooling}}, this selects the meter for district chilled water energy consumption, in units of Joules {[}J{]}, \item - \textbf{\hyperref[districtheating]{DistrictHeating}}, this selects the meter for district hot water energy consumption, in units of Joules {[}J{]}, + \textbf{\hyperref[districtheating]{DistrictHeatingWater}}, this selects the meter for district hot water energy consumption, in units of Joules {[}J{]}, \item \textbf{ElectricityProducedOnSite}, this selects the meter for electricity produced on the site, in units of Joules {[}J{]}, \item diff --git a/doc/input-output-reference/src/overview/group-exterior-energy-use-equipment.tex b/doc/input-output-reference/src/overview/group-exterior-energy-use-equipment.tex index 58cc2b45266..e410241c48a 100644 --- a/doc/input-output-reference/src/overview/group-exterior-energy-use-equipment.tex +++ b/doc/input-output-reference/src/overview/group-exterior-energy-use-equipment.tex @@ -65,7 +65,7 @@ \subsubsection{Inputs}\label{inputs-1-015} \paragraph{Field: Fuel Use Type}\label{exteriorfuelequipment-field-fuel-use-type} -This field designates the appropriate meter for the exterior fuel equipment. Valid fuel types are: Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, Steam, \hyperref[districtheating]{DistrictHeating}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. +This field designates the appropriate meter for the exterior fuel equipment. Valid fuel types are: Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, DistrictHeatingSteam, \hyperref[districtheating]{DistrictHeatingWater}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. \paragraph{Field: Schedule Name}\label{field-schedule-name-1-000} diff --git a/doc/input-output-reference/src/overview/group-heating-and-cooling-coils.tex b/doc/input-output-reference/src/overview/group-heating-and-cooling-coils.tex index b831e0c42ae..7d05801d84e 100644 --- a/doc/input-output-reference/src/overview/group-heating-and-cooling-coils.tex +++ b/doc/input-output-reference/src/overview/group-heating-and-cooling-coils.tex @@ -1737,7 +1737,7 @@ \subsubsection{Inputs}\label{inputs-10-006} \paragraph{Field: Fuel Type} -This field designates the appropriate fuel type for the coil. Valid fuel types are: Gas, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, Steam, \hyperref[districtheating]{DistrictHeating}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. NaturalGas is the default. +This field designates the appropriate fuel type for the coil. Valid fuel types are: Gas, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, DistrictHeatingSteam, \hyperref[districtheating]{DistrictHeatingWater}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. NaturalGas is the default. \paragraph{Field: Burner Efficiency}\label{field-gas-burner-efficiency} diff --git a/doc/input-output-reference/src/overview/group-internal-gains-people-lights-other.tex b/doc/input-output-reference/src/overview/group-internal-gains-people-lights-other.tex index 5ea9e8782fc..d721779c79a 100644 --- a/doc/input-output-reference/src/overview/group-internal-gains-people-lights-other.tex +++ b/doc/input-output-reference/src/overview/group-internal-gains-people-lights-other.tex @@ -1706,7 +1706,7 @@ \subsubsection{Inputs}\label{inputs-8-010} \paragraph{Field: Fuel Type}\label{field-fuel-use-type} -This field designates the appropriate meter for the equipment. Valid fuel types are: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, Steam, \hyperref[districtheating]{DistrictHeating}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. If the None fuel type is selected (the default if left blank), no end uses will be associated with the object, only the zone gains. +This field designates the appropriate meter for the equipment. Valid fuel types are: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, DistrictHeatingSteam, \hyperref[districtheating]{DistrictHeatingWater}, \hyperref[districtcooling]{DistrictCooling}, OtherFuel1 and OtherFuel2. The fuel type triggers the application of consumption amounts to the appropriate energy meters. If the None fuel type is selected (the default if left blank), no end uses will be associated with the object, only the zone gains. \paragraph{Field: Zone or ZoneList or Space or SpaceList Name}\label{othereq-field-zone-or-zonelist-name-000} @@ -2243,16 +2243,16 @@ \subsection{Internal Gain Equipment Outputs}\label{outputs-5-004} The hot water equipment district heating consumption in Watts (for power) or Joules (for energy). It is the sum of the radiant, convective, latent and lost components. Hot Water Equipment District Heating Energy is added to the following district heating meters: \begin{lstlisting} -DistrictHeating:Facility -DistrictHeating:Building -DistrictHeating:Zone: -DistrictHeating:SpaceType: -InteriorEquipment:DistrictHeating -InteriorEquipment:DistrictHeating:Zone: -InteriorEquipment:DistrictHeating:SpaceType: -:InteriorEquipment:DistrictHeating -:InteriorEquipment:DistrictHeating:Zone: -:InteriorEquipment:DistrictHeating:SpaceType: +DistrictHeatingWater:Facility +DistrictHeatingWater:Building +DistrictHeatingWater:Zone: +DistrictHeatingWater:SpaceType: +InteriorEquipment:DistrictHeatingWater +InteriorEquipment:DistrictHeatingWater:Zone: +InteriorEquipment:DistrictHeatingWater:SpaceType: +:InteriorEquipment:DistrictHeatingWater +:InteriorEquipment:DistrictHeatingWater:Zone: +:InteriorEquipment:DistrictHeatingWater:SpaceType: \end{lstlisting} \paragraph{Steam Equipment District Heating Rate {[}W{]}}\label{steam-equipment-district-heating-rate-w} @@ -2266,16 +2266,16 @@ \subsection{Internal Gain Equipment Outputs}\label{outputs-5-004} The steam equipment district heating consumption in Watts (for power) or Joules (for energy). It is the sum of the radiant, convective, latent and lost components. Steam Equipment District Heating Energy is added to the following: \begin{lstlisting} -DistrictHeating:Facility -DistrictHeating:Building -DistrictHeating:Zone: -DistrictHeating:SpaceType: -InteriorEquipment:DistrictHeating -InteriorEquipment:DistrictHeating:Zone: -InteriorEquipment:DistrictHeating:SpaceType: -:InteriorEquipment:DistrictHeating -:InteriorEquipment:DistrictHeating:Zone: -:InteriorEquipment:DistrictHeating:SpaceType: +DistrictHeatingWater:Facility +DistrictHeatingWater:Building +DistrictHeatingWater:Zone: +DistrictHeatingWater:SpaceType: +InteriorEquipment:DistrictHeatingWater +InteriorEquipment:DistrictHeatingWater:Zone: +InteriorEquipment:DistrictHeatingWater:SpaceType: +:InteriorEquipment:DistrictHeatingWater +:InteriorEquipment:DistrictHeatingWater:Zone: +:InteriorEquipment:DistrictHeatingWater:SpaceType: \end{lstlisting} \paragraph{Other Equipment Fuel Rate {[}W{]}}\label{otherequip-fuel-rate} diff --git a/doc/input-output-reference/src/overview/group-plant-equipment.tex b/doc/input-output-reference/src/overview/group-plant-equipment.tex index d764010dfe3..caa3d33366b 100644 --- a/doc/input-output-reference/src/overview/group-plant-equipment.tex +++ b/doc/input-output-reference/src/overview/group-plant-equipment.tex @@ -6190,7 +6190,7 @@ \subsubsection{Inputs}\label{inputs-17-006} \begin{lstlisting} -DistrictHeating,Purchased Heating, +DistrictHeatingWater,Purchased Heating, NODE_30,NODE_29, 1000000; \end{lstlisting} diff --git a/doc/input-output-reference/src/overview/group-simulation-parameters.tex b/doc/input-output-reference/src/overview/group-simulation-parameters.tex index 61b9ea68b11..26693f920d6 100644 --- a/doc/input-output-reference/src/overview/group-simulation-parameters.tex +++ b/doc/input-output-reference/src/overview/group-simulation-parameters.tex @@ -1237,9 +1237,9 @@ \subsubsection{Inputs}\label{inputs-17-008} \item OtherFuel2 \item - Steam + DistrictHeatingSteam \item - DistrictHeating + DistrictHeatingWater \item DistrictCooling \item @@ -1302,9 +1302,9 @@ \subsubsection{Inputs}\label{inputs-18-008} \item OtherFuel2 \item - Steam + DistrictHeatingSteam \item - DistrictHeating + DistrictHeatingWater \item DistrictCooling \item diff --git a/doc/input-output-reference/src/overview/group-water-heaters.tex b/doc/input-output-reference/src/overview/group-water-heaters.tex index 73d5696bd74..7d9eb3a6b28 100644 --- a/doc/input-output-reference/src/overview/group-water-heaters.tex +++ b/doc/input-output-reference/src/overview/group-water-heaters.tex @@ -122,7 +122,7 @@ \subsubsection{Inputs}\label{inputs-052} \paragraph{Field: Heater Fuel Type}\label{field-heater-fuel-type} -The type of fuel used for heating. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. +The type of fuel used for heating. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam or \hyperref[districtheating]{DistrictHeatingWater}. \paragraph{Field: Heater Thermal Efficiency}\label{field-heater-thermal-efficiency} @@ -138,7 +138,7 @@ \subsubsection{Inputs}\label{inputs-052} \paragraph{Field: Off-Cycle Parasitic Fuel Type}\label{field-off-cycle-parasitic-fuel-type} -The type of fuel used by the off-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. +The type of fuel used by the off-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. \paragraph{Field: Off-Cycle Parasitic Heat Fraction to Tank}\label{field-off-cycle-parasitic-heat-fraction-to-tank} @@ -150,7 +150,7 @@ \subsubsection{Inputs}\label{inputs-052} \paragraph{Field: On-Cycle Parasitic Fuel Type}\label{field-on-cycle-parasitic-fuel-type} -The type of fuel used by the on-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. +The type of fuel used by the on-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. \paragraph{Field: On-Cycle Parasitic Heat Fraction to Tank}\label{field-on-cycle-parasitic-heat-fraction-to-tank} @@ -745,7 +745,7 @@ \subsubsection{Inputs}\label{inputs-1-049} \paragraph{Field: Heater Fuel Type}\label{field-heater-fuel-type-1} -The type of fuel used for both Heaters 1 and 2. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. +The type of fuel used for both Heaters 1 and 2. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam or \hyperref[districtheating]{DistrictHeating}. \paragraph{Field: Heater Thermal Efficiency}\label{field-heater-thermal-efficiency-1} @@ -757,7 +757,7 @@ \subsubsection{Inputs}\label{inputs-1-049} \paragraph{Field: Off-Cycle Parasitic Fuel Type}\label{field-off-cycle-parasitic-fuel-type-1} -The type of fuel used by the off-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. +The type of fuel used by the off-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam, or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. \paragraph{Field: Off-Cycle Parasitic Heat Fraction to Tank}\label{field-off-cycle-parasitic-heat-fraction-to-tank-1} @@ -773,7 +773,7 @@ \subsubsection{Inputs}\label{inputs-1-049} \paragraph{Field: On-Cycle Parasitic Fuel Type}\label{field-on-cycle-parasitic-fuel-type-1} -The type of fuel used by the on-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, Steam, OtherFuel1, OtherFuel2 or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. +The type of fuel used by the on-cycle parasitics. The fuel type can be Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Coal, Diesel, Gasoline, OtherFuel1, OtherFuel2, DistrictHeatingSteam or \hyperref[districtheating]{DistrictHeating}. The fuel type can be the same or different from the Heater Fuel Type. \paragraph{Field: On-Cycle Parasitic Heat Fraction to Tank}\label{field-on-cycle-parasitic-heat-fraction-to-tank-1} diff --git a/doc/input-output-reference/src/overview/group-water-systems.tex b/doc/input-output-reference/src/overview/group-water-systems.tex index daaf9a6f42c..7455dbaa074 100644 --- a/doc/input-output-reference/src/overview/group-water-systems.tex +++ b/doc/input-output-reference/src/overview/group-water-systems.tex @@ -249,7 +249,7 @@ \subsubsection{Outputs}\label{outputs-041} \paragraph{Water Use Equipment Heating Energy {[}J{]}}\label{water-use-equipment-heating-energy-j} -The heating energy accumulated by the heating rate above, in units of Joules (J). This output is also added to a meter with End Use Key = WaterSystems, Group Key = Plant. If the WaterUse:Equipment object is not included in WaterUse:Connections or modeled as stand-alone, then this output is reported with Resource Type = DistrictHeating, or else if the WaterUse:Equipment object is included in WaterUse:Connections (e.g., as part of plant loop), then this output is reported with Resource Type = EnergyTransfer. The sub-categories may be entered as any type (e.g., Laundry, Dish Washing, etc. defined in WaterUse:Equipment object input for End-Use Subcategory) with General being the default sub-category (ref. Output Meter). +The heating energy accumulated by the heating rate above, in units of Joules (J). This output is also added to a meter with End Use Key = WaterSystems, Group Key = Plant. If the WaterUse:Equipment object is not included in WaterUse:Connections or modeled as stand-alone, then this output is reported with Resource Type = DistrictHeatingWater, or else if the WaterUse:Equipment object is included in WaterUse:Connections (e.g., as part of plant loop), then this output is reported with Resource Type = EnergyTransfer. The sub-categories may be entered as any type (e.g., Laundry, Dish Washing, etc. defined in WaterUse:Equipment object input for End-Use Subcategory) with General being the default sub-category (ref. Output Meter). \paragraph{Water Use Equipment Zone Sensible Heat Gain Rate {[}W{]}}\label{water-use-equipment-zone-sensible-heat-gain-rate-w} diff --git a/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex b/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex index 8c9f169b093..45778edb650 100644 --- a/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex +++ b/doc/input-output-reference/src/overview/group-zone-forced-air-units.tex @@ -9,11 +9,11 @@ \subsection{ZoneHVAC:IdealLoadsAirSystem}\label{zonehvacidealloadsairsystem} This component can be operated with infinite or finite heating and cooling capacity. For either mode---infinite or limited capacity---the user can also specify on/off schedules for heating and cooling and outdoor air controls. There are also optional controls for dehumidification, humidification, economizer, and heat recovery. This component may be used in combination with other HVAC equipment serving the same zone. -This component can be thought of as an ideal unit that mixes air at the zone exhaust condition (or plenum outlet condition when a plenum is attached) with the specified amount of outdoor air and then adds or removes heat and moisture at 100\% efficiency in order to produce a supply air stream at the specified conditions. The energy required to condition the supply air is metered and reported as \hyperref[districtheating]{DistrictHeating} and \hyperref[districtcooling]{DistrictCooling}. +This component can be thought of as an ideal unit that mixes air at the zone exhaust condition (or plenum outlet condition when a plenum is attached) with the specified amount of outdoor air and then adds or removes heat and moisture at 100\% efficiency in order to produce a supply air stream at the specified conditions. The energy required to condition the supply air is metered and reported as \hyperref[districtheating]{DistrictHeatingWater} and \hyperref[districtcooling]{DistrictCooling}. \textbf{Notes:} The ideal loads system uses the zone return node or an optional zone exhaust node to extract air from the zone. When the AirloopHVAC:ReturnPlenum is used the inlet of the ideal loads system is connected to the plenum outlet air node while the outlet of the ideal loads system is connected to a zone inlet node. The node name connected between the zone exhaust air node and plenum inlet air node must match in the \hyperref[zonehvacequipmentconnections]{ZoneHVAC:EquipmentConnections} and AirloopHVAC:ReturnPlenum objects. Every zone served by an HVAC component must have a return air node, even though this node may not be connected to anything. If more than one ideals loads air systems are connected to the same AirloopHVAC:ReturnPlenum then one of the ideal loads air systems will connect to the ZoneHVAC:ReturnPlenum outlet air node and the remaining ideal loads air systems connected to the same return plenum will connect to the ZoneHVAC:ReturnPlenum induced air outlet nodes. -The ideal loads system was significantly expanded in version 7.0 (October 2011). As part of this upgrade, any change in the moisture content of the supply air stream results in a latent cooling (dehumidification) or latent heating (humidification) load which is metered as \hyperref[districtcooling]{DistrictCooling} and \hyperref[districtheating]{DistrictHeating} energy consumption. Prior to version 7.0, when the ideal loads system was in heating mode, only the energy for sensible heating was metered. This results in significant changes in reported energy use compared to earlier versions, especially when using the \textbf{\emph{ConstantSupplyHumidityRatio}} option for Humidification Control Type. +The ideal loads system was significantly expanded in version 7.0 (October 2011). As part of this upgrade, any change in the moisture content of the supply air stream results in a latent cooling (dehumidification) or latent heating (humidification) load which is metered as \hyperref[districtcooling]{DistrictCooling} and \hyperref[districtheating]{DistrictHeatingWater} energy consumption. Prior to version 7.0, when the ideal loads system was in heating mode, only the energy for sensible heating was metered. This results in significant changes in reported energy use compared to earlier versions, especially when using the \textbf{\emph{ConstantSupplyHumidityRatio}} option for Humidification Control Type. Older idf files which are transitioned to version 7.0 will automatically be set to use the \textbf{\emph{ConstantSupplyHumidityRatio}} option for both dehumidification and humidification controls, because this is equivalent to the controls used in the older version of this system. However, the user should review all of the humidity control options and select the one which best reflects the goal of the simulation. @@ -338,7 +338,7 @@ \subsubsection{Outputs}\label{outputs-043} \paragraph{Zone Ideal Loads Supply Air Total Heating Rate {[}W{]}}\label{zone-ideal-loads-supply-air-total-heating-rate-w} -The total (sensible and latent) heating energy (or rate) added to raise the mixed air stream to the temperature and humidity ratio of the supply air stream. \emph{Zone Ideal Loads Supply Air Total Heating Energy} is metered as DistrictHeating energy. +The total (sensible and latent) heating energy (or rate) added to raise the mixed air stream to the temperature and humidity ratio of the supply air stream. \emph{Zone Ideal Loads Supply Air Total Heating Energy} is metered as DistrictHeatingWater energy. \paragraph{Zone Ideal Loads Supply Air Sensible Cooling Energy {[}J{]}}\label{zone-ideal-loads-supply-air-sensible-cooling-energy-j} @@ -4383,13 +4383,13 @@ \subsubsection{Inputs} This numeric field specifies the minimum time that must pass before the hybrid unit can change mode. If the value in this field is larger than each timestep, the mode selected in one time step will persist in later time steps until the minimum time between mode change is satisfied. If the value in this field is smaller than each timestep, it will determine the minimum part runtime fraction allowed for any mode. Supply air mass flow rate and outdoor air fraction within a mode are not subject to minimum runtime and may change in every time step, or with any part runtime fraction. Mode 0 does not have a minimum time. If this field is blank, the default minimum time between mode change is 10 minutes. \paragraph{Field: First Fuel Type} -This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Electric Power Power Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeating} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default first fuel type is Electricity. +This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Electric Power Power Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeatingWater} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default first fuel type is Electricity. \paragraph{Field: Second Fuel Type} -This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Second Fuel Consumption Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeating} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default second fuel type is None. +This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Second Fuel Consumption Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeatingWater} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default second fuel type is None. \paragraph{Field: Third Fuel Type} -This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Third Fuel Consumption Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeating} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default second fuel type is None. +This alpha field specifies the fuel type associated with the \hyperref[tablelookup]{Table:Lookup} object specified in field ''System Third Fuel Consumption Lookup Table``. Valid choices include: None, Electricity, NaturalGas, Propane, FuelOilNo1, FuelOilNo2, Diesel, Gasoline, Coal, OtherFuel1, OtherFuel2, Steam, \hyperref[districtheating]{DistrictHeatingWater} and \hyperref[districtcooling]{DistrictCooling}. If this field is blank, the default second fuel type is None. \paragraph{Field: Objective Function to Minimize} In each time step ZoneHVAC:HybridUnitaryHVAC will choose one or more combinations of the controlled independent variables, subject to constraints, so as to best satisfy sensible load, latent load, and scheduled ventilation with the least amount of resource consumption. This alpha field specifies which resource will be minimized by the optimization. Valid choices include: Electricity Use, Second Fuel Use, Third Fuel Use, and Water Use. If this field is blank, the objective function will minimize electricity use. diff --git a/doc/input-output-reference/src/standard-output-reports/output-table-summaryreports.tex b/doc/input-output-reference/src/standard-output-reports/output-table-summaryreports.tex index e993c30e3f3..21cebcace62 100644 --- a/doc/input-output-reference/src/standard-output-reports/output-table-summaryreports.tex +++ b/doc/input-output-reference/src/standard-output-reports/output-table-summaryreports.tex @@ -666,9 +666,9 @@ \subsubsection{Predefined Monthly Summary Reports}\label{predefined-monthly-summ \item DistrictCooling:Facility (Maximum) \item - DistrictHeating:Facility (SumOrAverage) + DistrictHeatingWater:Facility (SumOrAverage) \item - DistrictHeating:Facility (Maximum) + DistrictHeatingWater:Facility (Maximum) \end{itemize} \paragraph{EnergyConsumptionCoalGasolineMonthly}\label{energyconsumptioncoalgasolinemonthly} From a335e07ddf09d32c216fb03e46ef06d0fa2ca3ef Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Tue, 19 Sep 2023 23:47:51 -0600 Subject: [PATCH 14/16] fix doc errors --- .../src/overview/group-plant-equipment.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/input-output-reference/src/overview/group-plant-equipment.tex b/doc/input-output-reference/src/overview/group-plant-equipment.tex index caa3d33366b..27cfe6eda20 100644 --- a/doc/input-output-reference/src/overview/group-plant-equipment.tex +++ b/doc/input-output-reference/src/overview/group-plant-equipment.tex @@ -6234,9 +6234,9 @@ \subsection{DistrictHeating:Steam}\label{districtheatingsteam} When the user is not interested in a plant simulation or there is some centralized source of steam (district heating steam), the following object can be used in the input. -\subsubsection{Inputs}\label{inputs-17-006} +\subsubsection{Inputs}\label{inputs-17-006-1} -\paragraph{Field: Name}\label{field-name-16-006} +\paragraph{Field: Name}\label{field-name-16-006-1} This alpha field contains the identifying name for the district heating steam (i.e., purchased steam). From 37b1e04b42da06ae4cd165857f02da10224b5738 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Wed, 20 Sep 2023 08:45:06 -0600 Subject: [PATCH 15/16] fix documentation --- .../district-heating.tex | 2 +- .../src/overview/group-plant-equipment.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex index 947d3bd6731..2763a0de554 100644 --- a/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex +++ b/doc/engineering-reference/src/simulation-models-encyclopedic-reference-003/district-heating.tex @@ -1,3 +1,3 @@ \section{District Heating }\label{district-heating} -When the user is not interested in a plant simulation or there is some centralized source of hot water, the following model can be used in the input.~ This allows the user to achieve a simulation without specifying operating parameters or curve fits for boiler models.~ This model only needs the connections to the loop and the nominal capacity to simulate.~ See the InputOutput Reference for additional information (Object: DistrictHeating:Water and DistrictHeating:Steam).~ DistrictHeating:Water calculates the output capacity necessary from the inlet temperature to the setpoint temperature for that loop with the given mass flow rate in Watts.~ DistrictHeating:Steam the output capacity necessary from the inlet condensate to the saturated steam. +When the user is not interested in a plant simulation or there is some centralized source of hot water, the following model can be used in the input.~ This allows the user to achieve a simulation without specifying operating parameters or curve fits for boiler models.~ This model only needs the connections to the loop and the nominal capacity to simulate.~ See the InputOutput Reference for additional information (Object: DistrictHeating:Water and DistrictHeating:Steam).~ DistrictHeating:Water calculates the output capacity necessary from the inlet temperature to the setpoint temperature for that loop with the given mass flow rate in Watts.~ DistrictHeating:Steam calculates the mass flow rate of steam and the output capacity necessary from the inlet condensate to the saturated steam for that loop. diff --git a/doc/input-output-reference/src/overview/group-plant-equipment.tex b/doc/input-output-reference/src/overview/group-plant-equipment.tex index 27cfe6eda20..f473900a7b5 100644 --- a/doc/input-output-reference/src/overview/group-plant-equipment.tex +++ b/doc/input-output-reference/src/overview/group-plant-equipment.tex @@ -6240,7 +6240,7 @@ \subsubsection{Inputs}\label{inputs-17-006-1} This alpha field contains the identifying name for the district heating steam (i.e., purchased steam). -\paragraph{Field:Steam Inlet Node Name}\label{field-steam-inlet-node-name-2} +\paragraph{Field: Steam Inlet Node Name}\label{field-steam-inlet-node-name-2} This alpha field contains the identifying name for the district heating inlet node. From f9c6e0c5ca8f09051251617b330aba819be3e265 Mon Sep 17 00:00:00 2001 From: Dareum Nam Date: Wed, 20 Sep 2023 08:57:27 -0600 Subject: [PATCH 16/16] fix the unit test --- tst/EnergyPlus/unit/EconomicLifeCycleCost.unit.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tst/EnergyPlus/unit/EconomicLifeCycleCost.unit.cc b/tst/EnergyPlus/unit/EconomicLifeCycleCost.unit.cc index 844b434c6f7..23f4c31af37 100644 --- a/tst/EnergyPlus/unit/EconomicLifeCycleCost.unit.cc +++ b/tst/EnergyPlus/unit/EconomicLifeCycleCost.unit.cc @@ -596,8 +596,10 @@ TEST_F(EnergyPlusFixture, EconomicLifeCycleCost_GetInput_EnsureFuelTypesAllRecog const json &resource_field = lcc_useprice_props.at("resource"); const json &enum_values = resource_field.at("enum"); - // Should support all fuels + Water + ElectricityXXX (Purchased, Produced, SurplusSold, Net) - constexpr size_t numResources = static_cast(Constant::eFuel::Num) + 5; + // Should support all fuels + ElectricityXXX (Purchased, Produced, SurplusSold, Net) + constexpr size_t numResources = static_cast(Constant::eFuel::Num) + 3; + // Constant::eFuel::Num has 15 fuel types including "None" (which is a fuel type for "OtherEquipment") + // "LifeCycleCost:UsePriceEscalation" has 18 fuel types including ElectricityXXX (Purchased, Produced, SurplusSold, Net) EXPECT_EQ(numResources, enum_values.size()); std::string idf_objects = delimited_string({ "LifeCycleCost:Parameters,",