honeybee-openstudio 2.5.3 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -49,6 +49,10 @@ module FromHoneybee
49
49
  @@schema[:components][:schemas][:FaceEnergyPropertiesAbridged][:properties]
50
50
  end
51
51
 
52
+ def crack_defaults
53
+ @@schema[:components][:schemas][:AFNCrack][:properties]
54
+ end
55
+
52
56
  def find_existing_openstudio_object(openstudio_model)
53
57
  model_surf = openstudio_model.getSurfaceByName(@hash[:identifier])
54
58
  return model_surf.get unless model_surf.empty?
@@ -56,16 +60,18 @@ module FromHoneybee
56
60
  end
57
61
 
58
62
  def to_openstudio(openstudio_model)
59
- # create the openstudio surface
63
+ # reorder the vertices to ensure they start from the upper-left corner
60
64
  os_vertices = OpenStudio::Point3dVector.new
61
65
  @hash[:geometry][:boundary].each do |vertex|
62
66
  os_vertices << OpenStudio::Point3d.new(vertex[0], vertex[1], vertex[2])
63
67
  end
64
68
  reordered_vertices = OpenStudio.reorderULC(os_vertices)
65
69
 
70
+ # create the openstudio surface and assign the type
66
71
  os_surface = OpenStudio::Model::Surface.new(reordered_vertices, openstudio_model)
67
72
  os_surface.setName(@hash[:identifier])
68
73
  os_surface.setSurfaceType(@hash[:face_type])
74
+
69
75
  # assign the construction if it is present
70
76
  if @hash[:properties][:energy][:construction]
71
77
  construction_identifier = @hash[:properties][:energy][:construction]
@@ -76,6 +82,32 @@ module FromHoneybee
76
82
  end
77
83
  end
78
84
 
85
+ # assign the AFN crack if it's specified and we are not using simple infiltration
86
+ if !$use_simple_vent && @hash[:properties][:energy][:vent_crack]
87
+ unless $interior_afn_srf_hash[@hash[:identifier]] # interior crack that's been accounted for
88
+ vent_crack = @hash[:properties][:energy][:vent_crack]
89
+ # create the crack object for using default values
90
+ flow_exponent = crack_defaults[:flow_exponent][:default].to_f
91
+ os_crack = OpenStudio::Model::AirflowNetworkCrack.new(
92
+ openstudio_model, vent_crack[:flow_coefficient], flow_exponent,
93
+ $afn_reference_crack)
94
+
95
+ # assign the flow exponent if it's specified
96
+ if vent_crack[:flow_exponent]
97
+ os_crack. setAirMassFlowExponent(vent_crack[:flow_exponent])
98
+ end
99
+
100
+ # if it's a Surface boundary condition ensure the neighbor is not written as a duplicate
101
+ if @hash[:boundary_condition][:type] == 'Surface'
102
+ $interior_afn_srf_hash[@hash[:boundary_condition][:boundary_condition_objects][0]] = true
103
+ end
104
+
105
+ # create the AirflowNetworkSurface
106
+ os_afn_srf = os_surface.getAirflowNetworkSurface(os_crack)
107
+
108
+ end
109
+ end
110
+
79
111
  # assign the boundary condition
80
112
  boundary_condition = (@hash[:boundary_condition][:type])
81
113
  case boundary_condition
@@ -43,6 +43,7 @@ require 'from_honeybee/load/ventilation'
43
43
  require 'from_honeybee/load/setpoint_thermostat'
44
44
  require 'from_honeybee/load/setpoint_humidistat'
45
45
  require 'from_honeybee/ventcool/opening'
46
+ require 'from_honeybee/ventcool/control'
46
47
 
47
48
  require 'openstudio'
48
49
 
@@ -185,17 +186,19 @@ module FromHoneybee
185
186
  os_surface.setConstruction(air_construction)
186
187
  end
187
188
  # add air mixing properties to the global list that tracks them
188
- air_hash = $air_boundary_hash[air_construction.name.to_s]
189
- if air_hash[:air_mixing_per_area]
190
- air_mix_area = air_hash[:air_mixing_per_area]
191
- else
192
- air_default = @@schema[:components][:schemas][:AirBoundaryConstructionAbridged]
193
- air_mix_area = air_default[:properties][:air_mixing_per_area][:default]
189
+ if $use_simple_vent # only use air mixing objects when simple ventilation is requested
190
+ air_hash = $air_boundary_hash[air_construction.name.to_s]
191
+ if air_hash[:air_mixing_per_area]
192
+ air_mix_area = air_hash[:air_mixing_per_area]
193
+ else
194
+ air_default = @@schema[:components][:schemas][:AirBoundaryConstructionAbridged]
195
+ air_mix_area = air_default[:properties][:air_mixing_per_area][:default]
196
+ end
197
+ flow_rate = os_surface.netArea * air_mix_area
198
+ flow_sch_id = air_hash[:air_mixing_schedule]
199
+ adj_zone_id = face[:boundary_condition][:boundary_condition_objects][-1]
200
+ $air_mxing_array << [os_thermal_zone, flow_rate, flow_sch_id, adj_zone_id]
194
201
  end
195
- flow_rate = os_surface.netArea * air_mix_area
196
- flow_sch_id = air_hash[:air_mixing_schedule]
197
- adj_zone_id = face[:boundary_condition][:boundary_condition_objects][-1]
198
- $air_mxing_array << [os_thermal_zone, flow_rate, flow_sch_id, adj_zone_id]
199
202
  end
200
203
  end
201
204
  end
@@ -265,7 +268,7 @@ module FromHoneybee
265
268
  end
266
269
 
267
270
  # assign infiltration if it exists
268
- if @hash[:properties][:energy][:infiltration]
271
+ if @hash[:properties][:energy][:infiltration] && $use_simple_vent # only use infiltration with simple ventilation
269
272
  infiltration = openstudio_model.getSpaceInfiltrationDesignFlowRateByName(
270
273
  @hash[:properties][:energy][:infiltration][:identifier])
271
274
  unless infiltration.empty?
@@ -308,7 +311,7 @@ module FromHoneybee
308
311
  end
309
312
 
310
313
  # assign window ventilation objects if they exist
311
- unless window_vent.empty?
314
+ if $use_simple_vent && !window_vent.empty? # write simple WindAndStack ventilation
312
315
  window_vent.each do |sub_f_id, opening|
313
316
  opt_sub_f = openstudio_model.getSubSurfaceByName(sub_f_id)
314
317
  unless opt_sub_f.empty?
@@ -319,6 +322,31 @@ module FromHoneybee
319
322
  os_window_vent.addToThermalZone(os_thermal_zone)
320
323
  end
321
324
  end
325
+ elsif !$use_simple_vent # we're using the AFN!
326
+ # write an AirflowNetworkZone object in for the Room
327
+ os_afn_room_node = os_thermal_zone.getAirflowNetworkZone
328
+ os_afn_room_node.setVentilationControlMode('NoVent')
329
+ # write the opening objects for each Aperture / Door
330
+ operable_subfs = [] # collect the sub-face objects for the EMS
331
+ opening_factors = [] # collect the maximum opening factors for the EMS
332
+ window_vent.each do |sub_f_id, opening|
333
+ opt_sub_f = openstudio_model.getSubSurfaceByName(sub_f_id)
334
+ unless opt_sub_f.empty?
335
+ sub_f = opt_sub_f.get
336
+ if sub_f.adjacentSubSurface.empty? # not an interior window that's already in the AFN
337
+ window_vent = VentilationOpening.new(opening)
338
+ open_fac = window_vent.to_openstudio_afn(openstudio_model, sub_f)
339
+ operable_subfs << sub_f
340
+ opening_factors << open_fac
341
+ end
342
+ end
343
+ end
344
+ # add the control startegy of the ventilation openings using the EMS
345
+ if @hash[:properties][:energy][:window_vent_control]
346
+ vent_control = VentilationControl.new(@hash[:properties][:energy][:window_vent_control])
347
+ vent_control.to_openstudio(
348
+ openstudio_model, os_thermal_zone, operable_subfs, opening_factors)
349
+ end
322
350
  end
323
351
 
324
352
  os_space
@@ -75,6 +75,9 @@ require 'from_honeybee/schedule/ruleset'
75
75
  require 'from_honeybee/load/setpoint_thermostat'
76
76
  require 'from_honeybee/load/setpoint_humidistat'
77
77
 
78
+ # import the ventilative cooling objects
79
+ require 'from_honeybee/ventcool/simulation'
80
+
78
81
  require 'openstudio'
79
82
 
80
83
 
@@ -158,11 +161,23 @@ module FromHoneybee
158
161
  building = @openstudio_model.getBuilding
159
162
  building.setStandardsBuildingType('MediumOffice')
160
163
 
164
+ # initialize a global variable for whether the AFN is used instead of simple ventilation
165
+ $use_simple_vent = true
166
+ if @hash[:properties][:energy][:ventilation_simulation_control]
167
+ vent_sim_control = @hash[:properties][:energy][:ventilation_simulation_control]
168
+ if vent_sim_control[:vent_control_type] && vent_sim_control[:vent_control_type] != 'SingleZone'
169
+ $use_simple_vent = false
170
+ vsim_cntrl = VentilationSimulationControl.new(vent_sim_control)
171
+ $afn_reference_crack = vsim_cntrl.to_openstudio(@openstudio_model)
172
+ end
173
+ end
174
+
161
175
  # initialize global hashes for various model properties
162
176
  $gas_gap_hash = Hash.new # hash to track gas gaps in case they are split by shades
163
177
  $air_boundary_hash = Hash.new # hash to track any air boundary constructions
164
178
  $window_shade_hash = Hash.new # hash to track any window constructions with shade
165
179
  $programtype_setpoint_hash = Hash.new # hash to track Setpoint objects
180
+ $interior_afn_srf_hash = Hash.new # track whether an adjacent surface is already in the AFN
166
181
 
167
182
  # create all of the non-geometric model elements
168
183
  if log_report
@@ -94,14 +94,14 @@ module FromHoneybee
94
94
  os_gas_equipment = gas_equipment.to_openstudio(openstudio_model)
95
95
  os_gas_equipment.setSpaceType(os_space_type)
96
96
  end
97
-
97
+
98
98
  # assign infiltration
99
- if @hash[:infiltration]
99
+ if @hash[:infiltration] && $use_simple_vent # only use infiltration with simple ventilation
100
100
  infiltration = InfiltrationAbridged.new(@hash[:infiltration])
101
101
  os_infiltration = infiltration.to_openstudio(openstudio_model)
102
102
  os_infiltration.setSpaceType(os_space_type)
103
103
  end
104
-
104
+
105
105
  # assign ventilation
106
106
  if @hash[:ventilation]
107
107
  ventilation = VentilationAbridged.new(@hash[:ventilation])
@@ -0,0 +1,161 @@
1
+ # *******************************************************************************
2
+ # Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
3
+ # Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # (1) Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # (3) Neither the name of the copyright holder nor the names of any contributors
16
+ # may be used to endorse or promote products derived from this software without
17
+ # specific prior written permission from the respective party.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
23
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
24
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ # *******************************************************************************
31
+
32
+ require 'from_honeybee/model_object'
33
+
34
+ require 'openstudio'
35
+
36
+ module FromHoneybee
37
+ class VentilationControl < ModelObject
38
+ attr_reader :errors, :warnings
39
+ @@outdoor_node = nil
40
+ @@program_manager = nil
41
+
42
+ def initialize(hash = {})
43
+ super(hash)
44
+ end
45
+
46
+ def defaults
47
+ @@schema[:components][:schemas][:VentilationControlAbridged][:properties]
48
+ end
49
+
50
+ def get_outdoor_node(openstudio_model)
51
+ # get the EMS sensor for the outdoor node if it exists or generate it if it doesn't
52
+ if @@outdoor_node.nil?
53
+ out_var = OpenStudio::Model::OutputVariable.new(
54
+ 'Site Outdoor Air Drybulb Temperature', openstudio_model)
55
+ out_var.setReportingFrequency('Timestep')
56
+ out_var.setKeyValue('Environment')
57
+ @@outdoor_node = OpenStudio::Model::EnergyManagementSystemSensor.new(
58
+ openstudio_model, out_var)
59
+ @@outdoor_node.setName('Outdoor_Sensor')
60
+ end
61
+ @@outdoor_node
62
+ end
63
+
64
+ def get_program_manager(openstudio_model)
65
+ # get the EMS Program Manager for all window opening if it exists or generate it if it doesn't
66
+ if @@program_manager.nil?
67
+ @@program_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(
68
+ openstudio_model)
69
+ @@program_manager.setName('Temperature_Controlled_Window_Opening')
70
+ @@program_manager.setCallingPoint('BeginTimestepBeforePredictor')
71
+ end
72
+ @@program_manager
73
+ end
74
+
75
+ def to_openstudio(openstudio_model, parent_zone, vent_opening_surfaces, vent_opening_factors)
76
+ # Get the outdoor temperature sensor and the room air temperature sensor
77
+ out_air_temp = get_outdoor_node(openstudio_model)
78
+ in_var = OpenStudio::Model::OutputVariable.new('Zone Air Temperature', openstudio_model)
79
+ in_var.setReportingFrequency('Timestep')
80
+ zone_name = parent_zone.name
81
+ os_zone_name = 'Indoor'
82
+ unless zone_name.empty?
83
+ os_zone_name = zone_name.get
84
+ in_var.setKeyValue(os_zone_name)
85
+ end
86
+ in_air_temp = OpenStudio::Model::EnergyManagementSystemSensor.new(openstudio_model, in_var)
87
+ in_sensor_name = os_zone_name.delete(' ').delete('.') + '_Sensor'
88
+ in_air_temp.setName(in_sensor_name)
89
+
90
+ # create the actuators for each of the operaable windows
91
+ actuator_names = []
92
+ vent_opening_surfaces.each do |vent_srf|
93
+ window_act = OpenStudio::Model::EnergyManagementSystemActuator.new(
94
+ vent_srf, 'AirFlow Network Window/Door Opening', 'Venting Opening Factor')
95
+ vent_srf_name = vent_srf.name
96
+ unless vent_srf_name.empty?
97
+ act_name = vent_srf_name.get.delete(' ').delete('.') + '_OpenFactor'
98
+ window_act.setName(act_name)
99
+ actuator_names << act_name
100
+ end
101
+ end
102
+
103
+ # create the first line of the EMS Program to open each window according to the control logic
104
+ logic_statements = []
105
+ # check the minimum indoor tempertaure for ventilation
106
+ min_in = @hash[:min_indoor_temperature]
107
+ if min_in && min_in != defaults[:min_indoor_temperature][:default]
108
+ logic_statements << '(' + in_sensor_name + ' > ' + min_in.to_s + ')'
109
+ end
110
+ # check the maximum indoor tempertaure for ventilation
111
+ max_in = @hash[:max_indoor_temperature]
112
+ if max_in && max_in != defaults[:max_indoor_temperature][:default]
113
+ logic_statements << '(' + in_sensor_name + ' < ' + max_in.to_s + ')'
114
+ end
115
+ # check the minimum outdoor tempertaure for ventilation
116
+ min_out = @hash[:min_outdoor_temperature]
117
+ if min_out && min_out != defaults[:min_outdoor_temperature][:default]
118
+ logic_statements << '(Outdoor_Sensor > ' + min_out.to_s + ')'
119
+ end
120
+ # check the maximum outdoor tempertaure for ventilation
121
+ max_out = @hash[:max_outdoor_temperature]
122
+ if max_out && max_out != defaults[:max_outdoor_temperature][:default]
123
+ logic_statements << '(Outdoor_Sensor < ' + max_out.to_s + ')'
124
+ end
125
+ # check the delta tempertaure for ventilation
126
+ delta_in_out = @hash[:delta_temperature]
127
+ if delta_in_out && delta_in_out != defaults[:delta_temperature][:default]
128
+ logic_statements << '((' + in_sensor_name + ' - Outdoor_Sensor) > ' + delta_in_out.to_s + ')'
129
+ end
130
+ # create the complete logic statement for opening windows
131
+ if logic_statements.empty?
132
+ complete_logic = 'IF (Outdoor_Sensor < 100)' # no logic has been provided; always open windows
133
+ else
134
+ complete_logic = 'IF ' + logic_statements.join(' && ')
135
+ end
136
+
137
+ # initialize the program and add the complete logic
138
+ ems_program = OpenStudio::Model::EnergyManagementSystemProgram.new(openstudio_model)
139
+ ems_program.setName(os_zone_name.delete(' ').delete('.') + '_WindowOpening')
140
+ ems_program.addLine(complete_logic)
141
+
142
+ # loop through each of the actuators and open each window
143
+ actuator_names.zip(vent_opening_factors).each do |act_name, open_factor|
144
+ ems_program.addLine('SET ' + act_name + ' = ' + open_factor.to_s)
145
+ end
146
+ # loop through each of the actuators and close each window
147
+ ems_program.addLine('ELSE')
148
+ actuator_names.each do |act_name|
149
+ ems_program.addLine('SET ' + act_name + ' = 0')
150
+ end
151
+ ems_program.addLine('ENDIF')
152
+
153
+ # add the program object the the global program manager for all window opening
154
+ prog_manager = get_program_manager(openstudio_model)
155
+ prog_manager.addProgram(ems_program)
156
+
157
+ ems_program
158
+ end
159
+
160
+ end #VentilationControl
161
+ end #FromHoneybee
@@ -46,8 +46,8 @@ module FromHoneybee
46
46
  end
47
47
 
48
48
  def defaults_control
49
- @@schema[:components][:schemas][:VentilationControlAbridged][:properties]
50
- end
49
+ @@schema[:components][:schemas][:VentilationControlAbridged][:properties]
50
+ end
51
51
 
52
52
  def to_openstudio(openstudio_model, parent, vent_control_hash)
53
53
  # create wind and stack object and set identifier
@@ -140,6 +140,48 @@ module FromHoneybee
140
140
  os_opening
141
141
  end
142
142
 
143
+ def to_openstudio_afn(openstudio_model, parent)
144
+ # process the flow_coefficient_closed and set it to a very small number if it's 0
145
+ if @hash[:flow_coefficient_closed] and @hash[:flow_coefficient_closed] != 0
146
+ flow_coefficient = @hash[:flow_coefficient_closed]
147
+ else
148
+ flow_coefficient = 1.0e-09 # set it to a very small number
149
+ end
150
+
151
+ # create the simple opening object for the Aperture or Door using default values
152
+ flow_exponent = defaults[:flow_exponent_closed][:default].to_f
153
+ two_way_thresh= defaults[:two_way_threshold][:default].to_f
154
+ discharge_coeff = defaults[:discharge_coefficient][:default].to_f
155
+ os_opening = OpenStudio::Model::AirflowNetworkSimpleOpening.new(
156
+ openstudio_model, flow_coefficient, flow_exponent, two_way_thresh, discharge_coeff)
157
+
158
+ # assign the flow exponent when the opening is closed
159
+ if @hash[:flow_exponent_closed]
160
+ os_opening.setAirMassFlowExponentWhenOpeningisClosed(@hash[:flow_exponent_closed])
161
+ end
162
+ # assign the minimum difference for two-way flow
163
+ if @hash[:two_way_threshold]
164
+ os_opening.setMinimumDensityDifferenceforTwoWayFlow(@hash[:two_way_threshold])
165
+ end
166
+ # assign the discharge coefficient
167
+ if @hash[:discharge_coefficient]
168
+ os_opening.setDischargeCoefficient(@hash[:discharge_coefficient])
169
+ end
170
+
171
+ # create the AirflowNetworkSurface
172
+ os_afn_srf = parent.getAirflowNetworkSurface(os_opening)
173
+
174
+ # assign the opening area
175
+ if @hash[:fraction_area_operable]
176
+ open_fac = @hash[:fraction_area_operable]
177
+ else
178
+ open_fac = defaults[:fraction_area_operable][:default]
179
+ end
180
+ os_afn_srf.setWindowDoorOpeningFactorOrCrackFactor(open_fac)
181
+
182
+ open_fac
183
+ end
184
+
143
185
  def compute_height(surface)
144
186
  # derive the height (difference in z values) of a surface
145
187
  verts = surface.vertices
@@ -0,0 +1,110 @@
1
+ # *******************************************************************************
2
+ # Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
3
+ # Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # (1) Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # (3) Neither the name of the copyright holder nor the names of any contributors
16
+ # may be used to endorse or promote products derived from this software without
17
+ # specific prior written permission from the respective party.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
23
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
24
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ # *******************************************************************************
31
+
32
+ require 'from_honeybee/model_object'
33
+
34
+ require 'openstudio'
35
+
36
+ module FromHoneybee
37
+ class VentilationSimulationControl < ModelObject
38
+ attr_reader :errors, :warnings
39
+
40
+ def initialize(hash = {})
41
+ super(hash)
42
+ end
43
+
44
+ def defaults
45
+ @@schema[:components][:schemas][:VentilationSimulationControl][:properties]
46
+ end
47
+
48
+ def to_openstudio(openstudio_model)
49
+ # create the AirflowNetworkSimulationControl object
50
+ os_vsim_control = openstudio_model.getAirflowNetworkSimulationControl
51
+ os_vsim_control.setName('Window Based Ventilative Cooling')
52
+
53
+ # assign the control type
54
+ if @hash[:vent_control_type]
55
+ os_vsim_control.setAirflowNetworkControl(@hash[:vent_control_type])
56
+ else
57
+ os_vsim_control.setAirflowNetworkControl('MultizoneWithoutDistribution')
58
+ end
59
+
60
+ # assign the building type
61
+ if @hash[:building_type]
62
+ os_vsim_control.setBuildingType(@hash[:building_type])
63
+ else
64
+ os_vsim_control.setBuildingType(defaults[:building_type][:default])
65
+ end
66
+
67
+ # assign the long axis azimth angle of the building
68
+ if @hash[:long_axis_angle]
69
+ os_vsim_control.setAzimuthAngleofLongAxisofBuilding(@hash[:long_axis_angle])
70
+ else
71
+ os_vsim_control.setAzimuthAngleofLongAxisofBuilding(defaults[:long_axis_angle][:default])
72
+ end
73
+
74
+ # assign the aspect ratio of the building
75
+ if @hash[:aspect_ratio]
76
+ os_vsim_control.setBuildingAspectRatio(@hash[:aspect_ratio])
77
+ else
78
+ os_vsim_control.setBuildingAspectRatio(defaults[:aspect_ratio][:default])
79
+ end
80
+
81
+ # create the AirflowNetworkReferenceCrackConditions object that all other cracks reference
82
+ os_ref_crack = OpenStudio::Model::AirflowNetworkReferenceCrackConditions.new(openstudio_model)
83
+ os_ref_crack.setName('Reference Crack Conditions')
84
+
85
+ # assign the reference temperature
86
+ if @hash[:reference_temperature]
87
+ os_ref_crack.setTemperature(@hash[:reference_temperature])
88
+ else
89
+ os_ref_crack.setTemperature(defaults[:reference_temperature][:default])
90
+ end
91
+
92
+ # assign the reference pressure
93
+ if @hash[:reference_pressure]
94
+ os_ref_crack.setBarometricPressure(@hash[:reference_pressure])
95
+ else
96
+ os_ref_crack.setBarometricPressure(defaults[:reference_pressure][:default])
97
+ end
98
+
99
+ # assign the reference humidity ratio
100
+ if @hash[:reference_humidity_ratio]
101
+ os_ref_crack.setHumidityRatio(@hash[:reference_humidity_ratio])
102
+ else
103
+ os_ref_crack.setHumidityRatio(defaults[:reference_humidity_ratio][:default])
104
+ end
105
+
106
+ os_ref_crack
107
+ end
108
+
109
+ end #VentilationSimulationControl
110
+ end #FromHoneybee