openstudio-extension 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,259 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_Cofee
37
+
38
+ # create def to use later to make bar
39
+ def OsLib_Cofee.createBar(model, spaceTypeHash,lengthXTarget,lengthYTarget,totalFloorArea,numStories,midFloorMultiplier,xmin,ymin,lengthX,lengthY,zmin,zmax,endZones)
40
+
41
+ # floor to floor height
42
+ floor_to_floor_height = (zmax-zmin)/numStories
43
+
44
+ # perimeter depth
45
+ perimeterDepth = OpenStudio::convert(12,"ft","m").get
46
+ perimeterBufferFactor = 1.5 # this is a margin below which I won't bother splitting the two largest spaces
47
+
48
+ # create an array to control sort order of spaces in bar
49
+ customSpaceTypeBar = []
50
+ counter = 0
51
+ spaceTypeHash.sort_by {|key, value| value}.reverse.each do |k,v|
52
+ next if v == 0 # this line adds support for fractional values of 0
53
+ if counter == 1
54
+ if lengthXTarget*(v/totalFloorArea) > perimeterDepth * perimeterBufferFactor and endZones
55
+ customSpaceTypeBar << [k,totalFloorArea * (perimeterDepth/lengthXTarget)]
56
+ customSpaceTypeBar << [k,v - (totalFloorArea * (perimeterDepth/lengthXTarget))]
57
+ else
58
+ customSpaceTypeBar << [k,v]
59
+ end
60
+ elsif counter > 1
61
+ customSpaceTypeBar << [k,v]
62
+ end
63
+ counter += 1
64
+ end
65
+
66
+ # add the largest space type to the end
67
+ counter = 0
68
+ spaceTypeHash.sort_by {|key, value| value}.reverse.each do |k,v|
69
+ if counter == 0
70
+ # if width is greater than 1.5x perimeter depth then split in half
71
+ if lengthXTarget*(v/totalFloorArea) > perimeterDepth * perimeterBufferFactor and endZones
72
+ customSpaceTypeBar << [k,v - (totalFloorArea * (perimeterDepth/lengthXTarget))]
73
+ customSpaceTypeBar << [k,totalFloorArea * (perimeterDepth/lengthXTarget)]
74
+ else
75
+ customSpaceTypeBar << [k,v]
76
+ end
77
+ end
78
+ break
79
+ end
80
+
81
+ # starting z level
82
+ z = zmin
83
+ storyCounter = 0
84
+ barSpaceArray = []
85
+
86
+ # create new stories and then add spaces
87
+ [numStories,3].min.times do # no more than tree loops through this
88
+ story = OpenStudio::Model::BuildingStory.new(model)
89
+ story.setNominalFloortoFloorHeight(floor_to_floor_height)
90
+ story.setNominalZCoordinate(z)
91
+
92
+ # starting position for first space
93
+ x = (lengthX - lengthXTarget)*0.5 + xmin
94
+ y = (lengthY - lengthYTarget)*0.5 + ymin
95
+
96
+ # temp array of spaces (this is to change floor boundary when there is mid floor multiplier)
97
+ tempSpaceArray = []
98
+
99
+ # loop through space types making diagram and spaces.
100
+ #spaceTypeHash.sort_by {|key, value| value}.reverse.each do |k,v|
101
+ customSpaceTypeBar.each do |object|
102
+
103
+ # get values from what was hash
104
+ k = object[0]
105
+ v = object[1]
106
+
107
+ # get proper zone multiplier value
108
+ if storyCounter == 1 and midFloorMultiplier > 1
109
+ thermalZoneMultiplier = midFloorMultiplier
110
+ else
111
+ thermalZoneMultiplier = 1
112
+ end
113
+
114
+ options = {
115
+ "name" => nil,
116
+ "spaceType" => k,
117
+ "story" => story,
118
+ "makeThermalZone" => true,
119
+ "thermalZone" => nil,
120
+ "thermalZoneMultiplier" => thermalZoneMultiplier,
121
+ "floor_to_floor_height" => floor_to_floor_height,
122
+ }
123
+
124
+ # three paths for spaces depending upon building depth (3, 2 or one cross slices)
125
+ if lengthYTarget > perimeterDepth * 3 # slice into core and perimeter
126
+
127
+ # perimeter polygon a
128
+ perim_polygon_a = OpenStudio::Point3dVector.new
129
+ perim_origin_a = OpenStudio::Point3d.new(x,y,z)
130
+ perim_polygon_a << perim_origin_a
131
+ perim_polygon_a << OpenStudio::Point3d.new(x,y + perimeterDepth,z)
132
+ perim_polygon_a << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + perimeterDepth,z)
133
+ perim_polygon_a << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y,z)
134
+
135
+ # create core polygon
136
+ core_polygon = OpenStudio::Point3dVector.new
137
+ core_origin = OpenStudio::Point3d.new(x,y + perimeterDepth,z)
138
+ core_polygon << core_origin
139
+ core_polygon << OpenStudio::Point3d.new(x,y + lengthYTarget - perimeterDepth,z)
140
+ core_polygon << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget - perimeterDepth,z)
141
+ core_polygon << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + perimeterDepth,z)
142
+
143
+ # perimeter polygon b w
144
+ perim_polygon_b = OpenStudio::Point3dVector.new
145
+ perim_origin_b = OpenStudio::Point3d.new(x,y + lengthYTarget - perimeterDepth,z)
146
+ perim_polygon_b << perim_origin_b
147
+ perim_polygon_b << OpenStudio::Point3d.new(x,y + lengthYTarget,z)
148
+ perim_polygon_b << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget,z)
149
+ perim_polygon_b << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget - perimeterDepth,z)
150
+
151
+ # run method to make spaces
152
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,perim_origin_a,perim_polygon_a,options) # model, origin, polygon, options
153
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,core_origin,core_polygon,options) # model, origin, polygon, options
154
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,perim_origin_b,perim_polygon_b,options) # model, origin, polygon, options
155
+
156
+ elsif lengthYTarget > perimeterDepth * 2 # slice into two peremeter zones but no core
157
+
158
+ # perimeter polygon a
159
+ perim_polygon_a = OpenStudio::Point3dVector.new
160
+ perim_origin_a = OpenStudio::Point3d.new(x,y,z)
161
+ perim_polygon_a << perim_origin_a
162
+ perim_polygon_a << OpenStudio::Point3d.new(x,y + lengthYTarget/2,z)
163
+ perim_polygon_a << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget/2,z)
164
+ perim_polygon_a << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y,z)
165
+
166
+ # perimeter polygon b
167
+ perim_polygon_b = OpenStudio::Point3dVector.new
168
+ perim_origin_b = OpenStudio::Point3d.new(x,y + lengthYTarget/2,z)
169
+ perim_polygon_b << perim_origin_b
170
+ perim_polygon_b << OpenStudio::Point3d.new(x,y + lengthYTarget,z)
171
+ perim_polygon_b << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget,z)
172
+ perim_polygon_b << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget/2,z)
173
+
174
+ # run method to make spaces
175
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,perim_origin_a,perim_polygon_a,options) # model, origin, polygon, options
176
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,perim_origin_b,perim_polygon_b,options) # model, origin, polygon, options
177
+
178
+ else # don't slice into core and perimeter
179
+
180
+ # create polygon
181
+ core_polygon = OpenStudio::Point3dVector.new
182
+ core_origin = OpenStudio::Point3d.new(x,y,z)
183
+ core_polygon << core_origin
184
+ core_polygon << OpenStudio::Point3d.new(x,y + lengthYTarget,z)
185
+ core_polygon << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y + lengthYTarget,z)
186
+ core_polygon << OpenStudio::Point3d.new(x + lengthXTarget*(v/totalFloorArea),y,z)
187
+
188
+ # run method to make space
189
+ tempSpaceArray << OsLib_Geometry.makeSpaceFromPolygon(model,core_origin,core_polygon,options) # model, origin, polygon, options
190
+
191
+ end
192
+
193
+ # update points for next run
194
+ x += lengthXTarget*(v/totalFloorArea)
195
+
196
+ end
197
+
198
+ # set flags for adiabatic surfaces
199
+ floorAdiabatic = false
200
+ ceilingAdiabatic = false
201
+
202
+ # update z
203
+ if midFloorMultiplier == 1
204
+ z += floor_to_floor_height
205
+ else
206
+ z += floor_to_floor_height * midFloorMultiplier - floor_to_floor_height
207
+
208
+ if storyCounter == 0
209
+ ceilingAdiabatic = true
210
+ elsif storyCounter == 1
211
+ floorAdiabatic = true
212
+ ceilingAdiabatic = true
213
+ else
214
+ floorAdiabatic = true
215
+ end
216
+
217
+ # alter surfaces boundary conditions and constructions as described above
218
+ tempSpaceArray.each do |space|
219
+ space.surfaces.each do |surface|
220
+ if surface.surfaceType == "RoofCeiling" and ceilingAdiabatic
221
+ construction = surface.construction # todo - this isn't really the construction I want since it wasn't an interior one, but will work for now
222
+ surface.setOutsideBoundaryCondition("Adiabatic")
223
+ if not construction.empty?
224
+ surface.setConstruction(construction.get)
225
+ end
226
+ end
227
+ if surface.surfaceType == "Floor" and floorAdiabatic
228
+ construction = surface.construction # todo - this isn't really the construction I want since it wasn't an interior one, but will work for now
229
+ surface.setOutsideBoundaryCondition("Adiabatic")
230
+ if not construction.empty?
231
+ surface.setConstruction(construction.get)
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ # populate bar space array from temp array
238
+ barSpaceArray << tempSpaceArray
239
+
240
+ end
241
+
242
+ # update storyCounter
243
+ storyCounter += 1
244
+
245
+ end
246
+
247
+ # surface matching (seems more complex than necessary)
248
+ spaces = OpenStudio::Model::SpaceVector.new
249
+ model.getSpaces.each do |space|
250
+ spaces << space
251
+ end
252
+ OpenStudio::Model.matchSurfaces(spaces)
253
+
254
+ result = barSpaceArray
255
+ return result
256
+
257
+ end
258
+
259
+ end