22
33class Airflow
44 def self . apply ( model , runner , weather , spaces , hpxml , cfa , nbeds ,
5- ncfl_ag , duct_systems , nv_clg_ssn_sensor , hvac_map , eri_version ,
5+ ncfl_ag , duct_systems , clg_ssn_sensor , hvac_map , eri_version ,
66 frac_windows_operable , apply_ashrae140_assumptions )
77
88 # Global variables
@@ -106,10 +106,10 @@ def self.apply(model, runner, weather, spaces, hpxml, cfa, nbeds,
106106 vented_crawl = foundation
107107 end
108108
109- apply_natural_ventilation_and_whole_house_fan ( model , weather , hpxml . site , vent_fans_whf , open_window_area , nv_clg_ssn_sensor )
109+ apply_natural_ventilation_and_whole_house_fan ( model , weather , hpxml . site , vent_fans_whf , open_window_area , clg_ssn_sensor )
110110 apply_infiltration_and_ventilation_fans ( model , weather , hpxml . site , vent_fans_mech , vent_fans_kitchen , vent_fans_bath , vented_dryers ,
111111 hpxml . building_construction . has_flue_or_chimney , hpxml . air_infiltration_measurements ,
112- vented_attic , vented_crawl , hvac_map )
112+ vented_attic , vented_crawl , hvac_map , clg_ssn_sensor )
113113 end
114114
115115 def self . get_default_fraction_of_windows_operable ( )
@@ -1486,6 +1486,8 @@ def self.calculate_fan_loads(model, infil_program, vent_mech_erv_hrv_tot, hrv_er
14861486 # Calculate mass flow rate based on outdoor air density
14871487 # Address load with flow-weighted combined effectiveness
14881488 infil_program . addLine ( "Set Fan_MFR = #{ q_var } * OASupRho" )
1489+ infil_program . addLine ( 'Set ZoneInEnth = OASupInEnth' )
1490+ infil_program . addLine ( 'Set ZoneInTemp = OASupInTemp' )
14891491 if not vent_mech_erv_hrv_tot . empty?
14901492 # ERV/HRV EMS load model
14911493 # E+ ERV model is using standard density for MFR calculation, caused discrepancy with other system types.
@@ -1502,14 +1504,12 @@ def self.calculate_fan_loads(model, infil_program, vent_mech_erv_hrv_tot, hrv_er
15021504 infil_program . addLine ( 'Set ERVTotalHeatTrans = Fan_MFR * (ERVSupOutEnth - OASupInEnth)' )
15031505 infil_program . addLine ( 'Set ERVLatHeatTrans = ERVTotalHeatTrans - ERVSensHeatTrans' )
15041506 # ERV/HRV Load calculation
1505- infil_program . addLine ( 'Set FanTotalToLv = Fan_MFR * (ERVSupOutEnth - ZoneAirEnth)' )
1506- infil_program . addLine ( 'Set FanSensToLv = Fan_MFR * ZoneCp * (ERVSupOutTemp - ZoneTemp)' )
1507- infil_program . addLine ( 'Set FanLatToLv = FanTotalToLv - FanSensToLv' )
1508- else
1509- infil_program . addLine ( 'Set FanTotalToLv = Fan_MFR * (OASupInEnth - ZoneAirEnth)' )
1510- infil_program . addLine ( 'Set FanSensToLv = Fan_MFR * ZoneCp * (OASupInTemp - ZoneTemp)' )
1511- infil_program . addLine ( 'Set FanLatToLv = FanTotalToLv - FanSensToLv' )
1507+ infil_program . addLine ( 'Set ZoneInEnth = ERVSupOutEnth' )
1508+ infil_program . addLine ( 'Set ZoneInTemp = ERVSupOutTemp' )
15121509 end
1510+ infil_program . addLine ( 'Set FanTotalToLv = Fan_MFR * (ZoneInEnth - ZoneAirEnth)' )
1511+ infil_program . addLine ( 'Set FanSensToLv = Fan_MFR * ZoneCp * (ZoneInTemp - ZoneTemp)' )
1512+ infil_program . addLine ( 'Set FanLatToLv = FanTotalToLv - FanSensToLv' )
15131513
15141514 # Actuator,
15151515 # If preconditioned, handle actuators later in calculate_precond_loads
@@ -1519,11 +1519,23 @@ def self.calculate_fan_loads(model, infil_program, vent_mech_erv_hrv_tot, hrv_er
15191519 end
15201520 end
15211521
1522- def self . calculate_precond_loads ( model , infil_program , vent_mech_preheat , vent_mech_precool , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , hvac_map )
1522+ def self . calculate_precond_loads ( model , infil_program , vent_mech_preheat , vent_mech_precool , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , hvac_map , clg_ssn_sensor )
15231523 # Preconditioning
15241524 # Assume introducing no sensible loads to zone if preconditioned
1525+ if not vent_mech_preheat . empty?
1526+ htg_stp_sensor = OpenStudio ::Model ::EnergyManagementSystemSensor . new ( model , 'Zone Thermostat Heating Setpoint Temperature' )
1527+ htg_stp_sensor . setName ( "#{ Constants . ObjectNameAirflow } htg stp s" )
1528+ htg_stp_sensor . setKeyName ( @living_zone . name . to_s )
1529+ infil_program . addLine ( "Set HtgStp = #{ htg_stp_sensor . name } " ) # heating thermostat setpoint
1530+ end
1531+ if not vent_mech_precool . empty?
1532+ clg_stp_sensor = OpenStudio ::Model ::EnergyManagementSystemSensor . new ( model , 'Zone Thermostat Cooling Setpoint Temperature' )
1533+ clg_stp_sensor . setName ( "#{ Constants . ObjectNameAirflow } clg stp s" )
1534+ clg_stp_sensor . setKeyName ( @living_zone . name . to_s )
1535+ infil_program . addLine ( "Set ClgStp = #{ clg_stp_sensor . name } " ) # cooling thermostat setpoint
1536+ end
15251537 vent_mech_preheat . each_with_index do |f_preheat , i |
1526- infil_program . addLine ( ' If OASupInTemp < ZoneTemp' )
1538+ infil_program . addLine ( " If ( OASupInTemp < HtgStp) && ( #{ clg_ssn_sensor . name } < 1)" )
15271539 htg_energy_actuator = create_other_equipment_object_and_actuator ( model : model , name : "shared mech vent preheating energy #{ i } " , space : @living_space , frac_lat : 0.0 , frac_lost : 1.0 , hpxml_fuel_type : f_preheat . preheating_fuel , end_use : Constants . ObjectNameMechanicalVentilationPreconditioning )
15281540 hvac_map [ "#{ f_preheat . id } _preheat" ] = [ htg_energy_actuator . actuatedComponent . get ]
15291541 infil_program . addLine ( " Set Qpreheat = #{ UnitConversions . convert ( f_preheat . average_oa_unit_flow_rate , 'cfm' , 'm^3/s' ) . round ( 4 ) } " )
@@ -1534,16 +1546,21 @@ def self.calculate_precond_loads(model, infil_program, vent_mech_preheat, vent_m
15341546 end
15351547 calculate_fan_loads ( model , infil_program , vent_mech_erv_hrv_tot , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , 'Qpreheat' , true )
15361548
1537- infil_program . addLine ( " Set PreHeatingEnergy = (-FanSensToLv) * #{ f_preheat . preheating_fraction_load_served } " )
1538- infil_program . addLine ( " Set #{ fan_sens_load_actuator . name } = #{ fan_sens_load_actuator . name } + PreHeatingEnergy" )
1539- infil_program . addLine ( " Set #{ fan_lat_load_actuator . name } = #{ fan_lat_load_actuator . name } - FanLatToLv" )
1540- infil_program . addLine ( " Set #{ htg_energy_actuator . name } = PreHeatingEnergy / #{ f_preheat . preheating_efficiency_cop } " )
1549+ infil_program . addLine ( ' If ZoneInTemp < HtgStp' )
1550+ infil_program . addLine ( ' Set FanSensToSpt = Fan_MFR * ZoneCp * (ZoneInTemp - HtgStp)' )
1551+ infil_program . addLine ( " Set PreHeatingWatt = (-FanSensToSpt) * #{ f_preheat . preheating_fraction_load_served } " )
1552+ infil_program . addLine ( " Set #{ fan_sens_load_actuator . name } = #{ fan_sens_load_actuator . name } + PreHeatingWatt" )
1553+ infil_program . addLine ( " Set #{ fan_lat_load_actuator . name } = #{ fan_lat_load_actuator . name } - FanLatToLv" ) # Fixme:Does this assumption still apply?
1554+ infil_program . addLine ( ' Else' )
1555+ infil_program . addLine ( ' Set PreHeatingWatt = 0.0' )
1556+ infil_program . addLine ( ' EndIf' )
15411557 infil_program . addLine ( 'Else' )
1542- infil_program . addLine ( " Set #{ htg_energy_actuator . name } = 0.0" )
1558+ infil_program . addLine ( ' Set PreHeatingWatt = 0.0' )
15431559 infil_program . addLine ( 'EndIf' )
1560+ infil_program . addLine ( "Set #{ htg_energy_actuator . name } = PreHeatingWatt / #{ f_preheat . preheating_efficiency_cop } " )
15441561 end
15451562 vent_mech_precool . each_with_index do |f_precool , i |
1546- infil_program . addLine ( ' If OASupInTemp > ZoneTemp' )
1563+ infil_program . addLine ( " If ( OASupInTemp > ClgStp) && ( #{ clg_ssn_sensor . name } > 0)" )
15471564 clg_energy_actuator = create_other_equipment_object_and_actuator ( model : model , name : "shared mech vent precooling energy #{ i } " , space : @living_space , frac_lat : 0.0 , frac_lost : 1.0 , hpxml_fuel_type : f_precool . precooling_fuel , end_use : Constants . ObjectNameMechanicalVentilationPreconditioning )
15481565 hvac_map [ "#{ f_precool . id } _precool" ] = [ clg_energy_actuator . actuatedComponent . get ]
15491566 infil_program . addLine ( " Set Qprecool = #{ UnitConversions . convert ( f_precool . average_oa_unit_flow_rate , 'cfm' , 'm^3/s' ) . round ( 4 ) } " )
@@ -1554,18 +1571,23 @@ def self.calculate_precond_loads(model, infil_program, vent_mech_preheat, vent_m
15541571 end
15551572 calculate_fan_loads ( model , infil_program , vent_mech_erv_hrv_tot , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , 'Qprecool' , true )
15561573
1557- infil_program . addLine ( " Set PreCoolingEnergy = FanSensToLv * #{ f_precool . precooling_fraction_load_served } " )
1558- infil_program . addLine ( " Set #{ fan_sens_load_actuator . name } = #{ fan_sens_load_actuator . name } - PreCoolingEnergy" )
1559- infil_program . addLine ( " Set #{ fan_lat_load_actuator . name } = #{ fan_lat_load_actuator . name } - FanLatToLv" )
1560- infil_program . addLine ( " Set #{ clg_energy_actuator . name } = PreCoolingEnergy / #{ f_precool . precooling_efficiency_cop } " )
1574+ infil_program . addLine ( ' If ZoneInTemp > ClgStp' )
1575+ infil_program . addLine ( ' Set FanSensToSpt = Fan_MFR * ZoneCp * (ZoneInTemp - ClgStp)' )
1576+ infil_program . addLine ( " Set PreCoolingWatt = FanSensToSpt * #{ f_precool . precooling_fraction_load_served } " )
1577+ infil_program . addLine ( " Set #{ fan_sens_load_actuator . name } = #{ fan_sens_load_actuator . name } - PreCoolingWatt" )
1578+ infil_program . addLine ( " Set #{ fan_lat_load_actuator . name } = #{ fan_lat_load_actuator . name } - FanLatToLv" ) # Fixme:Does this assumption still apply?
1579+ infil_program . addLine ( ' Else' )
1580+ infil_program . addLine ( ' Set PreCoolingWatt = 0.0' )
1581+ infil_program . addLine ( ' EndIf' )
15611582 infil_program . addLine ( 'Else' )
1562- infil_program . addLine ( " Set #{ clg_energy_actuator . name } = 0.0" )
1583+ infil_program . addLine ( ' Set PreCoolingWatt = 0.0' )
15631584 infil_program . addLine ( 'EndIf' )
1585+ infil_program . addLine ( "Set #{ clg_energy_actuator . name } = PreCoolingWatt / #{ f_precool . precooling_efficiency_cop } " )
15641586 end
15651587 end
15661588
15671589 def self . apply_infiltration_and_mechanical_ventilation ( model , site , vent_fans_mech , living_ach50 , living_const_ach , weather , vent_fans_kitchen , vent_fans_bath , vented_dryers ,
1568- range_sch_sensors_map , bath_sch_sensors_map , dryer_exhaust_sch_sensors_map , has_flue_chimney , hvac_map )
1590+ range_sch_sensors_map , bath_sch_sensors_map , dryer_exhaust_sch_sensors_map , has_flue_chimney , hvac_map , clg_ssn_sensor )
15691591 # Categorize fans into different types
15701592 vent_mech_preheat = vent_fans_mech . select { |vent_mech | ( not vent_mech . preheating_efficiency_cop . nil? ) }
15711593 vent_mech_precool = vent_fans_mech . select { |vent_mech | ( not vent_mech . precooling_efficiency_cop . nil? ) }
@@ -1640,7 +1662,7 @@ def self.apply_infiltration_and_mechanical_ventilation(model, site, vent_fans_me
16401662 calculate_fan_loads ( model , infil_program , vent_mech_erv_hrv_tot , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , 'Qload' )
16411663
16421664 # Address preconditioning
1643- calculate_precond_loads ( model , infil_program , vent_mech_preheat , vent_mech_precool , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , hvac_map )
1665+ calculate_precond_loads ( model , infil_program , vent_mech_preheat , vent_mech_precool , hrv_erv_effectiveness_map , fan_sens_load_actuator , fan_lat_load_actuator , hvac_map , clg_ssn_sensor )
16441666
16451667 program_calling_manager = OpenStudio ::Model ::EnergyManagementSystemProgramCallingManager . new ( model )
16461668 program_calling_manager . setName ( "#{ infil_program . name } calling manager" )
@@ -1649,7 +1671,7 @@ def self.apply_infiltration_and_mechanical_ventilation(model, site, vent_fans_me
16491671 end
16501672
16511673 def self . apply_infiltration_and_ventilation_fans ( model , weather , site , vent_fans_mech , vent_fans_kitchen , vent_fans_bath , vented_dryers ,
1652- has_flue_chimney , air_infils , vented_attic , vented_crawl , hvac_map )
1674+ has_flue_chimney , air_infils , vented_attic , vented_crawl , hvac_map , clg_ssn_sensor )
16531675 # Get living space infiltration
16541676 living_ach50 = nil
16551677 living_const_ach = nil
@@ -1687,7 +1709,7 @@ def self.apply_infiltration_and_ventilation_fans(model, weather, site, vent_fans
16871709
16881710 # Get mechanical ventilation
16891711 apply_infiltration_and_mechanical_ventilation ( model , site , vent_fans_mech , living_ach50 , living_const_ach , weather , vent_fans_kitchen , vent_fans_bath , vented_dryers ,
1690- range_sch_sensors_map , bath_sch_sensors_map , dryer_exhaust_sch_sensors_map , has_flue_chimney , hvac_map )
1712+ range_sch_sensors_map , bath_sch_sensors_map , dryer_exhaust_sch_sensors_map , has_flue_chimney , hvac_map , clg_ssn_sensor )
16911713 end
16921714
16931715 def self . apply_infiltration_to_living ( site , living_ach50 , living_const_ach , infil_program , weather , has_flue_chimney )
0 commit comments