openstudio-standards 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  3. data/data/standards/manage_OpenStudio_Standards.rb +2 -49
  4. data/data/standards/openstudio_standards_duplicates_log.csv +1 -7962
  5. data/data/standards/test_performance_expected_dd_results.csv +2005 -97
  6. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +47 -57
  7. data/lib/openstudio-standards/geometry/create.rb +8 -2
  8. data/lib/openstudio-standards/geometry/create_bar.rb +6 -3
  9. data/lib/openstudio-standards/geometry/create_shape.rb +1 -1
  10. data/lib/openstudio-standards/geometry/group.rb +1 -1
  11. data/lib/openstudio-standards/geometry/information.rb +1 -1
  12. data/lib/openstudio-standards/geometry/modify.rb +53 -1
  13. data/lib/openstudio-standards/infiltration/nist_infiltration.rb +1 -1
  14. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +11 -11
  15. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +11 -11
  16. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +2 -2
  17. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +44 -47
  18. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +43 -48
  19. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +1 -1
  20. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +44 -24
  21. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +24 -24
  22. data/lib/openstudio-standards/schedules/information.rb +1 -1
  23. data/lib/openstudio-standards/schedules/parametric.rb +1 -1
  24. data/lib/openstudio-standards/service_water_heating/create_piping_losses.rb +152 -0
  25. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +544 -0
  26. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +303 -0
  27. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +95 -0
  28. data/lib/openstudio-standards/space/space.rb +1 -1
  29. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +65 -70
  30. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +12 -14
  31. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +16 -5
  32. data/lib/openstudio-standards/standards/Standards.Model.rb +2 -2
  33. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +10 -2
  34. data/lib/openstudio-standards/{prototypes/common/objects/Prototype.Model.swh.rb → standards/Standards.ServiceWaterHeating.rb} +209 -139
  35. data/lib/openstudio-standards/standards/Standards.Surface.rb +1 -1
  36. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +4 -8
  37. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
  38. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +22251 -12963
  39. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +91 -91
  40. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8981 -5228
  41. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8935 -5182
  42. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7281 -5391
  43. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +91 -91
  44. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +9005 -15215
  45. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +136 -136
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +8717 -17168
  48. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +136 -136
  49. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1941 -651
  50. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_properties.json +135 -135
  51. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_properties.json +135 -135
  52. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.construction_properties.json +36 -36
  53. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.construction_properties.json +36 -36
  54. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +377 -99
  55. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +2 -2
  56. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +3 -3
  57. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6889 -4044
  58. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +108 -108
  59. data/lib/openstudio-standards/standards/cbes/cbes_pre_1978/data/cbes_pre_1978.construction_properties.json +16 -16
  60. data/lib/openstudio-standards/standards/cbes/cbes_t24_1978/data/cbes_t24_1978.construction_properties.json +16 -16
  61. data/lib/openstudio-standards/standards/cbes/cbes_t24_1992/data/cbes_t24_1992.construction_properties.json +16 -16
  62. data/lib/openstudio-standards/standards/cbes/cbes_t24_2001/data/cbes_t24_2001.construction_properties.json +16 -16
  63. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/data/cbes_t24_2005.construction_properties.json +16 -16
  64. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/data/cbes_t24_2008.construction_properties.json +16 -16
  65. data/lib/openstudio-standards/standards/cbes/data/cbes.constructions.json +142 -142
  66. data/lib/openstudio-standards/standards/deer/data/deer.constructions.json +5 -1551
  67. data/lib/openstudio-standards/standards/deer/data/deer.materials.json +40 -0
  68. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.motors.json +88 -8
  69. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.motors.json +88 -8
  70. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.motors.json +88 -8
  71. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.motors.json +88 -8
  72. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.motors.json +88 -8
  73. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.motors.json +88 -8
  74. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.motors.json +88 -8
  75. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.motors.json +88 -8
  76. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.motors.json +88 -8
  77. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.motors.json +88 -8
  78. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.motors.json +88 -8
  79. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.motors.json +88 -8
  80. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.motors.json +88 -8
  81. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.motors.json +88 -8
  82. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.motors.json +88 -8
  83. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.motors.json +88 -8
  84. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.motors.json +88 -8
  85. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.motors.json +88 -8
  86. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.motors.json +88 -8
  87. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.motors.json +88 -8
  88. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.motors.json +88 -8
  89. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +17 -0
  90. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +2 -1
  91. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +4 -4
  92. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +61 -88
  93. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +3 -2
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/boiler_fuel_type_sets.json +54 -0
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMidriseApartment.osm +1 -1
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +1 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPPointTower.osm +1 -1
  98. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +1 -1
  99. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +4 -4
  100. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +4 -4
  101. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +32 -24
  102. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +89 -15
  103. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +5 -1
  104. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +22 -65
  105. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +19 -0
  106. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +56 -2
  107. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +3 -1
  108. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +2 -2
  109. data/lib/openstudio-standards/standards/necb/docs/air_system_names_method.md +127 -0
  110. data/lib/openstudio-standards/thermal_zone/thermal_zone.rb +1 -1
  111. data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +1 -1
  112. data/lib/openstudio-standards/version.rb +1 -1
  113. data/lib/openstudio-standards/weather/information.rb +61 -5
  114. data/lib/openstudio-standards/weather/modify.rb +1 -1
  115. data/lib/openstudio-standards.rb +5 -3
  116. metadata +12 -63
  117. data/data/standards/OpenStudio_Standards-deer.xlsx +0 -0
  118. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +0 -1100
  119. data/lib/openstudio-standards/service_water_heating/component.rb +0 -189
@@ -0,0 +1,303 @@
1
+ module OpenstudioStandards
2
+ # The ServiceWaterHeating module provides methods to create, modify, and get information about service water heating
3
+ module ServiceWaterHeating
4
+ # @!group Create Loop
5
+ # Methods to add service water heating loops
6
+
7
+ # Creates a service water heating loop.
8
+ #
9
+ # @param model [OpenStudio::Model::Model] OpenStudio model object
10
+ # @param system_name [String] the name of the system. nil results in the default.
11
+ # @param service_water_temperature [Double] water heater temperature, in degrees C. Default is 60 C / 140 F.
12
+ # @param service_water_pump_head [Double] service water pump head, in Pa. Default is 29861 Pa / 10 ft.
13
+ # @param service_water_pump_motor_efficiency [Double] service water pump motor efficiency, as decimal.
14
+ # @param water_heater_capacity [Double] water heater capacity, in W. Defaults to 58.6 kW / 200 kBtu/hr
15
+ # @param water_heater_volume [Double] water heater volume, in m^3. Defaults to 0.378 m^3 / 100 gal
16
+ # @param water_heater_fuel [String] water heating fuel. Valid choices are 'NaturalGas', 'Electricity', 'FuelOilNo2', 'SimpleHeatPump', 'HeatPump', or 'None'.
17
+ # If 'None', no water heater will be added.
18
+ # @param on_cycle_parasitic_fuel_consumption_rate [Double] water heater on cycle parasitic fuel consumption rate, in W
19
+ # @param off_cycle_parasitic_fuel_consumption_rate [Double] water heater off cycle parasitic fuel consumption rate, in W
20
+ # @param water_heater_thermal_zone [OpenStudio::Model::ThermalZone] Thermal zone for ambient heat loss.
21
+ # If nil, will assume 71.6 F / 22 C ambient air temperature.
22
+ # @param number_of_water_heaters [Integer] the number of water heaters represented by the capacity and volume inputs.
23
+ # Used to modify efficiencies for water heaters based on individual component size while avoiding having to model lots of individual water heaters (for runtime sake).
24
+ # @param add_piping_losses [Boolean] if true, add piping and associated heat losses to system. If false, add no pipe heat losses.
25
+ # @param pipe_insulation_thickness [Double] the thickness of the pipe insulation, in m. Default is 0.0127 m / 0.5 inches.
26
+ # @param floor_area [Double] the area of building served by the service water heating loop, in m^2
27
+ # If nil, will use the total building floor area. Only used if piping losses is true and the system is circulating.
28
+ # @param number_of_stories [Integer] the number of stories served by the service water heating loop
29
+ # If nil, will use the total building number of stories. Only used if piping losses is true and the system is circulating.
30
+ # @return [OpenStudio::Model::PlantLoop] OpenStudio PlantLoop object of the service water loop
31
+ def self.create_service_water_heating_loop(model,
32
+ system_name: 'Service Water Loop',
33
+ service_water_temperature: 60.0,
34
+ service_water_pump_head: 29861.0,
35
+ service_water_pump_motor_efficiency: 0.3,
36
+ water_heater_capacity: nil,
37
+ water_heater_volume: nil,
38
+ water_heater_fuel: 'Electricity',
39
+ on_cycle_parasitic_fuel_consumption_rate: 0.0,
40
+ off_cycle_parasitic_fuel_consumption_rate: 0.0,
41
+ water_heater_thermal_zone: nil,
42
+ number_of_water_heaters: 1,
43
+ add_piping_losses: false,
44
+ pipe_insulation_thickness: 0.0127,
45
+ floor_area: nil,
46
+ number_of_stories: nil)
47
+
48
+ # create service water heating loop
49
+ service_water_loop = OpenStudio::Model::PlantLoop.new(model)
50
+ service_water_loop.setMinimumLoopTemperature(10.0)
51
+ if service_water_temperature > 60.0
52
+ service_water_loop.setMaximumLoopTemperature(service_water_temperature)
53
+ else
54
+ service_water_loop.setMaximumLoopTemperature(60.0)
55
+ end
56
+
57
+ if system_name.nil?
58
+ system_name = 'Service Water Loop'
59
+ end
60
+ service_water_loop.setName(system_name)
61
+
62
+ # service water heating loop controls
63
+ swh_temp_f = OpenStudio.convert(service_water_temperature, 'C', 'F').get
64
+ swh_delta_t_r = 9.0 # 9F delta-T
65
+ swh_delta_t_k = OpenStudio.convert(swh_delta_t_r, 'R', 'K').get
66
+ swh_temp_sch = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
67
+ service_water_temperature,
68
+ name: "Service Water Loop Temp - #{swh_temp_f.round}F",
69
+ schedule_type_limit: 'Temperature')
70
+ swh_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, swh_temp_sch)
71
+ swh_stpt_manager.setName('Service hot water setpoint manager')
72
+ swh_stpt_manager.addToNode(service_water_loop.supplyOutletNode)
73
+ sizing_plant = service_water_loop.sizingPlant
74
+ sizing_plant.setLoopType('Heating')
75
+ sizing_plant.setDesignLoopExitTemperature(service_water_temperature)
76
+ sizing_plant.setLoopDesignTemperatureDifference(swh_delta_t_k)
77
+
78
+ # determine if circulating or non-circulating based on supplied head pressure
79
+ if service_water_pump_head.nil? || service_water_pump_head <= 1
80
+ # set pump head pressure to near zero if there is no circulation pump
81
+ service_water_pump_head = 0.001
82
+ service_water_pump_motor_efficiency = 1
83
+ circulating = false
84
+ else
85
+ circulating = true
86
+ end
87
+
88
+ # add pump
89
+ if circulating
90
+ swh_pump = OpenStudio::Model::PumpConstantSpeed.new(model)
91
+ swh_pump.setName("#{service_water_loop.name} Circulator Pump")
92
+ swh_pump.setPumpControlType('Intermittent')
93
+ else
94
+ swh_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
95
+ swh_pump.setName("#{service_water_loop.name} Water Mains Pressure Driven")
96
+ swh_pump.setPumpControlType('Continuous')
97
+ end
98
+ swh_pump.setRatedPumpHead(service_water_pump_head.to_f)
99
+ swh_pump.setMotorEfficiency(service_water_pump_motor_efficiency)
100
+ swh_pump.addToNode(service_water_loop.supplyInletNode)
101
+
102
+ # add water heater
103
+ case water_heater_fuel
104
+ when 'None'
105
+ # don't add a water heater
106
+ when 'HeatPump'
107
+ OpenstudioStandards::ServiceWaterHeating.create_heatpump_water_heater(model,
108
+ water_heater_capacity: water_heater_capacity,
109
+ water_heater_volume: water_heater_volume,
110
+ on_cycle_parasitic_fuel_consumption_rate: on_cycle_parasitic_fuel_consumption_rate,
111
+ off_cycle_parasitic_fuel_consumption_rate: off_cycle_parasitic_fuel_consumption_rate,
112
+ service_water_temperature: service_water_temperature,
113
+ service_water_temperature_schedule: swh_temp_sch,
114
+ set_peak_use_flowrate: false,
115
+ peak_flowrate: 0.0,
116
+ flowrate_schedule: nil,
117
+ water_heater_thermal_zone: water_heater_thermal_zone,
118
+ service_water_loop: service_water_loop,
119
+ use_ems_control: false)
120
+ else
121
+ OpenstudioStandards::ServiceWaterHeating.create_water_heater(model,
122
+ water_heater_capacity: water_heater_capacity,
123
+ water_heater_volume: water_heater_volume,
124
+ water_heater_fuel: water_heater_fuel,
125
+ on_cycle_parasitic_fuel_consumption_rate: on_cycle_parasitic_fuel_consumption_rate,
126
+ off_cycle_parasitic_fuel_consumption_rate: off_cycle_parasitic_fuel_consumption_rate,
127
+ service_water_temperature: service_water_temperature,
128
+ service_water_temperature_schedule: swh_temp_sch,
129
+ set_peak_use_flowrate: false,
130
+ peak_flowrate: 0.0,
131
+ flowrate_schedule: nil,
132
+ water_heater_thermal_zone: water_heater_thermal_zone,
133
+ number_of_water_heaters: number_of_water_heaters,
134
+ service_water_loop: service_water_loop)
135
+ end
136
+
137
+ # add pipe losses if requested
138
+ if add_piping_losses
139
+ OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_piping_losses(model,
140
+ service_water_loop,
141
+ circulating: circulating,
142
+ pipe_insulation_thickness: pipe_insulation_thickness,
143
+ floor_area: floor_area,
144
+ number_of_stories: number_of_stories)
145
+ end
146
+
147
+ # service water heating loop bypass pipes
148
+ water_heater_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
149
+ service_water_loop.addSupplyBranchForComponent(water_heater_bypass_pipe)
150
+ coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
151
+ service_water_loop.addDemandBranchForComponent(coil_bypass_pipe)
152
+ supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
153
+ supply_outlet_pipe.addToNode(service_water_loop.supplyOutletNode)
154
+ demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
155
+ demand_outlet_pipe.addToNode(service_water_loop.demandOutletNode)
156
+
157
+ if circulating
158
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ServiceWaterHeating', "Added circulating SWH loop called #{service_water_loop.name}")
159
+ else
160
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ServiceWaterHeating', "Added non-circulating SWH loop called #{service_water_loop.name}")
161
+ end
162
+
163
+ return service_water_loop
164
+ end
165
+
166
+ # Creates a booster water heater on its own loop and attaches it to the main service water heating loop.
167
+ #
168
+ # @param model [OpenStudio::Model::Model] OpenStudio model object
169
+ # @param water_heater_capacity [Double] water heater capacity, in W. Defaults to 8 kW / 27.283 kBtu/hr
170
+ # @param water_heater_volume [Double] water heater volume, in m^3. Defaults to 0.0227 m^3 / 6 gal
171
+ # @param water_heater_fuel [String] water heating fuel. Valid choices are 'NaturalGas', 'Electricity'.
172
+ # @param on_cycle_parasitic_fuel_consumption_rate [Double] water heater on cycle parasitic fuel consumption rate, in W
173
+ # @param off_cycle_parasitic_fuel_consumption_rate [Double] water heater off cycle parasitic fuel consumption rate, in W
174
+ # @param service_water_temperature [Double] water heater temperature, in degrees C. Default is 82.2 C / 180 F.
175
+ # @param service_water_temperature_schedule [OpenStudio::Model::Schedule] the service water heating schedule.
176
+ # If nil, will be defaulted to a constant temperature schedule based on the service_water_temperature
177
+ # @param water_heater_thermal_zone [OpenStudio::Model::ThermalZone] Thermal zone for ambient heat loss.
178
+ # If nil, will assume 71.6 F / 22 C ambient air temperature.
179
+ # @param service_water_loop [OpenStudio::Model::PlantLoop] if provided, add the water heater to this loop
180
+ # @return [OpenStudio::Model::PlantLoop] The booster water loop OpenStudio PlantLoop object
181
+ def self.create_booster_water_heating_loop(model,
182
+ water_heater_capacity: 8000.0,
183
+ water_heater_volume: OpenStudio.convert(6.0, 'gal', 'm^3').get,
184
+ water_heater_fuel: 'Electricity',
185
+ on_cycle_parasitic_fuel_consumption_rate: 0.0,
186
+ off_cycle_parasitic_fuel_consumption_rate: 0.0,
187
+ service_water_temperature: 82.2,
188
+ service_water_temperature_schedule: nil,
189
+ water_heater_thermal_zone: nil,
190
+ service_water_loop: nil)
191
+ if service_water_loop.nil?
192
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.ServiceWaterHeating', "#{_method_} requires the service_water_loop argument to couple the booster water heating loop with a heat exchanger.")
193
+ return nil
194
+ else
195
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ServiceWaterHeating', "Adding booster water heater to #{service_water_loop.name}")
196
+ end
197
+
198
+ water_heater_volume_gal = OpenStudio.convert(water_heater_volume, 'm^3', 'gal').get
199
+ water_heater_capacity_kbtu_per_hr = OpenStudio.convert(water_heater_capacity, 'W', 'kBtu/hr').get
200
+
201
+ # Booster water heating loop
202
+ booster_service_water_loop = OpenStudio::Model::PlantLoop.new(model)
203
+ booster_service_water_loop.setName('Booster Service Water Loop')
204
+
205
+ # create and add booster water heater to loop
206
+ booster_water_heater = OpenstudioStandards::ServiceWaterHeating.create_water_heater(model,
207
+ water_heater_capacity: water_heater_capacity,
208
+ water_heater_volume: water_heater_volume,
209
+ water_heater_fuel: water_heater_fuel,
210
+ on_cycle_parasitic_fuel_consumption_rate: on_cycle_parasitic_fuel_consumption_rate,
211
+ off_cycle_parasitic_fuel_consumption_rate: off_cycle_parasitic_fuel_consumption_rate,
212
+ service_water_temperature: service_water_temperature,
213
+ service_water_temperature_schedule: service_water_temperature_schedule,
214
+ water_heater_thermal_zone: water_heater_thermal_zone,
215
+ service_water_loop: booster_service_water_loop)
216
+ booster_water_heater.setName("#{water_heater_volume_gal}gal #{water_heater_fuel} Booster Water Heater - #{water_heater_capacity_kbtu_per_hr.round}kBtu/hr")
217
+ booster_water_heater.setEndUseSubcategory('Booster')
218
+
219
+ # Service water heating loop controls
220
+ swh_temp_f = OpenStudio.convert(service_water_temperature, 'C', 'F').get
221
+ swh_delta_t_r = 9.0 # 9F delta-T
222
+ swh_delta_t_k = OpenStudio.convert(swh_delta_t_r, 'R', 'K').get
223
+ swh_temp_sch = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
224
+ service_water_temperature,
225
+ name: "Service Water Booster Temp - #{swh_temp_f.round}F",
226
+ schedule_type_limit: 'Temperature')
227
+ swh_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, swh_temp_sch)
228
+ swh_stpt_manager.setName('Hot water booster setpoint manager')
229
+ swh_stpt_manager.addToNode(booster_service_water_loop.supplyOutletNode)
230
+ sizing_plant = booster_service_water_loop.sizingPlant
231
+ sizing_plant.setLoopType('Heating')
232
+ sizing_plant.setDesignLoopExitTemperature(service_water_temperature)
233
+ sizing_plant.setLoopDesignTemperatureDifference(swh_delta_t_k)
234
+
235
+ # Booster water heating pump
236
+ swh_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
237
+ swh_pump.setName('Booster Water Loop Pump')
238
+ swh_pump.setRatedPumpHead(0.0) # As if there is no circulation pump
239
+ swh_pump.setRatedPowerConsumption(0.0) # As if there is no circulation pump
240
+ swh_pump.setMotorEfficiency(1)
241
+ swh_pump.setPumpControlType('Continuous')
242
+ swh_pump.setMinimumFlowRate(0.0)
243
+ swh_pump.addToNode(booster_service_water_loop.supplyInletNode)
244
+
245
+ # Service water heating loop bypass pipes
246
+ water_heater_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
247
+ booster_service_water_loop.addSupplyBranchForComponent(water_heater_bypass_pipe)
248
+ coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
249
+ booster_service_water_loop.addDemandBranchForComponent(coil_bypass_pipe)
250
+ supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
251
+ supply_outlet_pipe.addToNode(booster_service_water_loop.supplyOutletNode)
252
+ demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
253
+ demand_inlet_pipe.addToNode(booster_service_water_loop.demandInletNode)
254
+ demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
255
+ demand_outlet_pipe.addToNode(booster_service_water_loop.demandOutletNode)
256
+
257
+ # Heat exchanger to supply the booster water heater with normal hot water from the main service water loop
258
+ hx = OpenStudio::Model::HeatExchangerFluidToFluid.new(model)
259
+ hx.setName('Booster Water Heating Heat Exchanger')
260
+ hx.setHeatExchangeModelType('Ideal')
261
+ hx.setControlType('UncontrolledOn')
262
+ hx.setHeatTransferMeteringEndUseType('LoopToLoop')
263
+
264
+ # Add the HX to the supply side of the booster loop
265
+ hx.addToNode(booster_service_water_loop.supplyInletNode)
266
+
267
+ # Add the HX to the demand side of the main service water loop
268
+ service_water_loop.addDemandBranchForComponent(hx)
269
+
270
+ # Add a plant component temperature source to the demand outlet
271
+ # of the HX to represent the fact that the water used by the booster
272
+ # would in reality be at the mains temperature.
273
+ mains_src = OpenStudio::Model::PlantComponentTemperatureSource.new(model)
274
+ mains_src.setName('Mains Water Makeup for SWH Booster')
275
+ mains_src.addToNode(hx.demandOutletModelObject.get.to_Node.get)
276
+
277
+ # use the site water mains temperature schedule if available,
278
+ # otherwise use the annual average outdoor air temperature
279
+ site_water_mains = model.getSiteWaterMainsTemperature
280
+ if site_water_mains.temperatureSchedule.is_initialized
281
+ water_mains_temp_sch = site_water_mains.temperatureSchedule.get
282
+ elsif site_water_mains.annualAverageOutdoorAirTemperature.is_initialized
283
+ mains_src_temp_c = site_water_mains.annualAverageOutdoorAirTemperature.get
284
+ mains_src.setSourceTemperature(mains_src_temp_c)
285
+ water_mains_temp_sch = OpenStudio::Model::ScheduleConstant.new(model)
286
+ water_mains_temp_sch.setName('Booster Water Makeup Temperature')
287
+ water_mains_temp_sch.setValue(mains_src_temp_c)
288
+ else # assume 50F
289
+ mains_src_temp_c = OpenStudio.convert(50.0, 'F', 'C').get
290
+ mains_src.setSourceTemperature(mains_src_temp_c)
291
+ water_mains_temp_sch = OpenStudio::Model::ScheduleConstant.new(model)
292
+ water_mains_temp_sch.setName('Booster Water Makeup Temperature')
293
+ water_mains_temp_sch.setValue(mains_src_temp_c)
294
+ end
295
+ mains_src.setTemperatureSpecificationType('Scheduled')
296
+ mains_src.setSourceTemperatureSchedule(water_mains_temp_sch)
297
+
298
+ return booster_service_water_loop
299
+ end
300
+
301
+ # @!endgroup Create Loop
302
+ end
303
+ end
@@ -0,0 +1,95 @@
1
+ module OpenstudioStandards
2
+ # The ServiceWaterHeating module provides methods to create, modify, and get information about service water heating
3
+ module ServiceWaterHeating
4
+ # @!group Create Water Use
5
+ # Methods to add service water uses
6
+
7
+ # Creates a water use and attaches it to a service water loop and a space, if provided
8
+ #
9
+ # @param model [OpenStudio::Model::Model] OpenStudio model object
10
+ # @param name [String] Use name of the water use object, e.g. main or laundry
11
+ # @param flow_rate [Double] the peak flow rate of the water use in m^3/s
12
+ # @param flow_rate_fraction_schedule [OpenStudio::Model::Schedule] the flow rate fraction schedule
13
+ # @param water_use_temperature [Double] mixed water use temperature at the fixture, in degrees C. Default is 43.3 C / 110 F.
14
+ # @param water_use_temperature_schedule [OpenStudio::Model::Schedule] water use temperature schedule.
15
+ # If nil, will be defaulted to a constant temperature schedule based on the water_use_temperature
16
+ # @param sensible_fraction [Double] the water use equipment sensible fraction to the space
17
+ # @param latent_fraction [Double] the water use equipment latent fraction to the space
18
+ # @param service_water_loop [OpenStudio::Model::PlantLoop] if provided, add the water use fixture to this loop
19
+ # @param space [OpenStudio::Model::Space] OpenStudio Space object
20
+ # @return [OpenStudio::Model::WaterUseEquipment] OpenStudio WaterUseEquipment object
21
+ def self.create_water_use(model,
22
+ name: 'Main Water Use',
23
+ flow_rate: 0.0,
24
+ flow_rate_fraction_schedule: nil,
25
+ water_use_temperature: 43.3,
26
+ water_use_temperature_schedule: nil,
27
+ sensible_fraction: 0.2,
28
+ latent_fraction: 0.05,
29
+ service_water_loop: nil,
30
+ space: nil)
31
+ # IP conversions for naming
32
+ flow_rate_gpm = OpenStudio.convert(flow_rate, 'm^3/s', 'gal/min').get
33
+ water_use_temperature_f = OpenStudio.convert(water_use_temperature, 'C', 'F').get
34
+
35
+ # default name
36
+ name = 'Main Water Use' if name.nil?
37
+
38
+ # water use definition
39
+ water_use_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(model)
40
+
41
+ # set sensible and latent fractions
42
+ water_use_sensible_frac_sch = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
43
+ sensible_fraction,
44
+ name: "Fraction Sensible - #{sensible_fraction}",
45
+ schedule_type_limit: 'Fractional')
46
+ water_use_latent_frac_sch = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
47
+ latent_fraction,
48
+ name: "Fraction Latent - #{latent_fraction}",
49
+ schedule_type_limit: 'Fractional')
50
+ water_use_def.setSensibleFractionSchedule(water_use_sensible_frac_sch)
51
+ water_use_def.setLatentFractionSchedule(water_use_latent_frac_sch)
52
+ water_use_def.setPeakFlowRate(flow_rate)
53
+ water_use_def.setName("#{name} #{flow_rate_gpm.round(2)}gpm #{water_use_temperature_f.round}F")
54
+
55
+ # target mixed water temperature
56
+ if water_use_temperature_schedule.nil?
57
+ water_use_temperature_schedule = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
58
+ water_use_temperature,
59
+ name: "Mixed Water At Faucet Temp - #{water_use_temperature_f.round}F",
60
+ schedule_type_limit: 'Temperature')
61
+ end
62
+ water_use_def.setTargetTemperatureSchedule(water_use_temperature_schedule)
63
+
64
+ # create water use equipment
65
+ water_fixture = OpenStudio::Model::WaterUseEquipment.new(water_use_def)
66
+ water_fixture.setFlowRateFractionSchedule(flow_rate_fraction_schedule)
67
+
68
+ # create water use connection
69
+ swh_connection = OpenStudio::Model::WaterUseConnections.new(model)
70
+ swh_connection.addWaterUseEquipment(water_fixture)
71
+
72
+ # add to the space if provided
73
+ if space.nil?
74
+ water_fixture.setName("#{name} Service Water Use #{flow_rate_gpm.round(2)}gpm #{water_use_temperature_f.round}F")
75
+ swh_connection.setName("#{name} WUC #{flow_rate_gpm.round(2)}gpm #{water_use_temperature_f.round}F")
76
+ else
77
+ water_fixture.setName("#{space.name} Service Water Use #{flow_rate_gpm.round(2)}gpm #{water_use_temperature_f.round}F")
78
+ swh_connection.setName("#{space.name} WUC #{flow_rate_gpm.round(2)}gpm #{water_use_temperature_f.round}F")
79
+ water_fixture.setSpace(space)
80
+ end
81
+
82
+ # add to the service water loop if provided
83
+ unless service_water_loop.nil?
84
+ service_water_loop.addDemandBranchForComponent(swh_connection)
85
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ServiceWaterHeating', "Adding water fixture to #{service_water_loop.name}.")
86
+ end
87
+
88
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ServiceWaterHeating', "Added #{water_fixture.name}.")
89
+
90
+ return water_fixture
91
+ end
92
+
93
+ # @!endgroup Create Water Use
94
+ end
95
+ end
@@ -1,5 +1,5 @@
1
- # Methods to obtain information about model spaces
2
1
  module OpenstudioStandards
2
+ # The Space module provides methods get information about model spaces
3
3
  module Space
4
4
  # @!group Space
5
5