diff --git a/HPXMLtoOpenStudio/resources/airflow.rb b/HPXMLtoOpenStudio/resources/airflow.rb index aea809e285..595518718d 100644 --- a/HPXMLtoOpenStudio/resources/airflow.rb +++ b/HPXMLtoOpenStudio/resources/airflow.rb @@ -2325,6 +2325,14 @@ def self.apply_infiltration_adjustment_to_conditioned(runner, model, spaces, hpx ) infil_flow.additionalProperties.setFeature('ObjectType', Constants::ObjectTypeInfiltration) + # Warmup workaround, see https://github.com/NatLabRockies/EnergyPlus/pull/11409 + ['Qducts', 'Qexhaust', 'Qsupply'].each do |var| + Model.add_ems_global_var( + model, + var_name: var + ) + end + # Average in-unit CFMs (include recirculation from in unit CFMs for shared systems) sup_cfm_tot = vent_fans[:mech_supply].map { |vent_mech| vent_mech.average_unit_flow_rate }.sum(0.0) exh_cfm_tot = vent_fans[:mech_exhaust].map { |vent_mech| vent_mech.average_unit_flow_rate }.sum(0.0) diff --git a/HPXMLtoOpenStudio/resources/output.rb b/HPXMLtoOpenStudio/resources/output.rb index b3fa98fa76..8494fd7247 100644 --- a/HPXMLtoOpenStudio/resources/output.rb +++ b/HPXMLtoOpenStudio/resources/output.rb @@ -799,6 +799,8 @@ def self.apply_component_loads_ems_program(model, hpxml_osm_map, loads_data, sea end end + unit_multiplier = hpxml_bldg.building_construction.number_of_units + # EMS program: Internal Gains, Lighting, Infiltration, Natural Ventilation, Mechanical Ventilation, Ducts { 'intgains' => intgains_sensors, 'lighting' => lightings_sensors, @@ -824,7 +826,7 @@ def self.apply_component_loads_ems_program(model, hpxml_osm_map, loads_data, sea end intgains_dhw_sensors.each do |sensor, vals| off_loss, on_loss, rtf_sensor = vals - program.addLine("Set hr_intgains = hr_intgains + #{sensor.name} * (#{off_loss}*(1-#{rtf_sensor.name}) + #{on_loss}*#{rtf_sensor.name})") # Water heater tank losses to zone + program.addLine("Set hr_intgains = hr_intgains + (#{sensor.name} * (#{off_loss}*(1-#{rtf_sensor.name}) + #{on_loss}*#{rtf_sensor.name})) / #{unit_multiplier}") # Water heater tank losses to zone end if (not ducts_mix_loss_sensor.nil?) && (not ducts_mix_gain_sensor.nil?) program.addLine("Set hr_ducts = hr_ducts + (#{ducts_mix_loss_sensor.name} - #{ducts_mix_gain_sensor.name})") @@ -900,7 +902,6 @@ def self.apply_component_loads_ems_program(model, hpxml_osm_map, loads_data, sea program.addLine(' EndIf') program.addLine('EndIf') - unit_multiplier = hpxml_bldg.building_construction.number_of_units [:htg, :clg].each do |mode| if mode == :htg sign = '' diff --git a/HPXMLtoOpenStudio/resources/waterheater.rb b/HPXMLtoOpenStudio/resources/waterheater.rb index 54f0425e73..e42cd73e6c 100644 --- a/HPXMLtoOpenStudio/resources/waterheater.rb +++ b/HPXMLtoOpenStudio/resources/waterheater.rb @@ -838,8 +838,8 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) storage_tank.setHeaterThermalEfficiency(1) storage_tank.ambientTemperatureSchedule.get.remove apply_ambient_temperature(loc_space, loc_schedule, storage_tank) - storage_tank.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - storage_tank.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) + storage_tank.setSkinLossFractiontoZone(1.0) + storage_tank.setOffCycleFlueLossFractiontoZone(1.0) storage_tank.setUseSideEffectiveness(1) storage_tank.setUseSideInletHeight(0) storage_tank.setSourceSideOutletHeight(0) @@ -1111,8 +1111,8 @@ def self.apply_hpwh_stratified_tank(model, water_heating_system, obj_name, solar tank.setSourceSideFlowControlMode('') tank.setSourceSideInletHeight(0) tank.setSourceSideOutletHeight(0) - tank.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - tank.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) + tank.setSkinLossFractiontoZone(1.0) + tank.setOffCycleFlueLossFractiontoZone(1.0) apply_stratified_tank_losses(tank, tank_u, unit_multiplier) tank.additionalProperties.setFeature('HPXML_ID', water_heating_system.id) # Used by reporting measure @@ -1990,8 +1990,8 @@ def self.apply_water_heater(runner, model, name:, water_heating_system: nil, act water_heater.setSourceSideFlowControlMode('') water_heater.setSourceSideInletHeight((1.0 - (1 - 0.5) / 15) * h_tank) # in the 1st node of a 15-node tank (counting from top) water_heater.setSourceSideOutletHeight((1.0 - (15 - 0.5) / 15) * h_tank) # in the 15th node of a 15-node tank (counting from top) - water_heater.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - water_heater.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) + water_heater.setSkinLossFractiontoZone(1.0) + water_heater.setOffCycleFlueLossFractiontoZone(1.0) apply_stratified_tank_losses(water_heater, tank_u, unit_multiplier) else water_heater = OpenStudio::Model::WaterHeaterMixed.new(model) @@ -2028,8 +2028,8 @@ def self.apply_water_heater(runner, model, name:, water_heating_system: nil, act skinlossfrac = 0.96 # Condensing end end - water_heater.setOffCycleLossFractiontoThermalZone(skinlossfrac / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - water_heater.setOnCycleLossFractiontoThermalZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here + water_heater.setOffCycleLossFractiontoThermalZone(skinlossfrac) + water_heater.setOnCycleLossFractiontoThermalZone(1.0) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(UnitConversions.convert(tank_ua, 'Btu/(hr*F)', 'W/K')) water_heater.setOffCycleLossCoefficienttoAmbientTemperature(UnitConversions.convert(tank_ua, 'Btu/(hr*F)', 'W/K'))