urbanopt-cli 0.2.0.pre6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +0 -1
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +30 -1
- data/Gemfile +8 -6
- data/README.md +23 -4
- data/Rakefile +4 -2
- data/bin/console +3 -3
- data/developer_nrel_key.rb +31 -0
- data/example_files/Gemfile +4 -4
- data/example_files/mappers/Baseline.rb +360 -204
- data/example_files/mappers/HighEfficiency.rb +25 -29
- data/example_files/mappers/base_workflow.osw +2 -2
- data/example_files/reopt/base_assumptions.json +146 -0
- data/example_files/reopt/multiPV_assumptions.json +181 -0
- data/lib/change_log.rb +9 -4
- data/lib/uo_cli/version.rb +1 -1
- data/lib/uo_cli.rb +345 -295
- data/uo_cli.gemspec +26 -26
- metadata +31 -13
@@ -1,32 +1,32 @@
|
|
1
|
-
|
2
|
-
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
1
|
+
# *********************************************************************************
|
2
|
+
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
3
3
|
# contributors. All rights reserved.
|
4
|
-
#
|
5
|
-
# Redistribution and use in source and binary forms, with or without modification,
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
6
6
|
# are permitted provided that the following conditions are met:
|
7
|
-
#
|
8
|
-
# Redistributions of source code must retain the above copyright notice, this list
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
9
9
|
# of conditions and the following disclaimer.
|
10
|
-
#
|
11
|
-
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
-
# list of conditions and the following disclaimer in the documentation and/or other
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
13
13
|
# materials provided with the distribution.
|
14
|
-
#
|
15
|
-
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
-
# used to endorse or promote products derived from this software without specific
|
14
|
+
#
|
15
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without specific
|
17
17
|
# prior written permission.
|
18
|
-
#
|
19
|
-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
|
-
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
|
-
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
22
|
-
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
23
|
-
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
24
|
-
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26
|
-
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
27
|
-
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
22
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
23
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
24
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
27
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
28
28
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
|
29
|
+
# *********************************************************************************
|
30
30
|
|
31
31
|
require 'urbanopt/scenario'
|
32
32
|
require 'openstudio/common_measures'
|
@@ -37,87 +37,258 @@ require 'json'
|
|
37
37
|
module URBANopt
|
38
38
|
module Scenario
|
39
39
|
class BaselineMapper < SimulationMapperBase
|
40
|
-
|
41
40
|
# class level variables
|
42
41
|
@@instance_lock = Mutex.new
|
43
42
|
@@osw = nil
|
44
43
|
@@geometry = nil
|
45
|
-
|
46
|
-
def initialize
|
47
|
-
|
44
|
+
|
45
|
+
def initialize
|
48
46
|
# do initialization of class variables in thread safe way
|
49
47
|
@@instance_lock.synchronize do
|
50
|
-
if @@osw.nil?
|
48
|
+
if @@osw.nil?
|
51
49
|
|
52
50
|
# load the OSW for this class
|
53
51
|
osw_path = File.join(File.dirname(__FILE__), 'base_workflow.osw')
|
54
52
|
File.open(osw_path, 'r') do |file|
|
55
53
|
@@osw = JSON.parse(file.read, symbolize_names: true)
|
56
54
|
end
|
57
|
-
|
55
|
+
|
58
56
|
# add any paths local to the project
|
59
57
|
@@osw[:file_paths] << File.join(File.dirname(__FILE__), '../weather/')
|
60
|
-
|
61
|
-
# configures OSW with extension gem paths for measures and files, all extension gems must be
|
58
|
+
|
59
|
+
# configures OSW with extension gem paths for measures and files, all extension gems must be
|
62
60
|
# required before this
|
63
61
|
@@osw = OpenStudio::Extension.configure_osw(@@osw)
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
67
|
-
|
65
|
+
|
66
|
+
def lookup_building_type(building_type, template, footprint_area, number_of_stories)
|
67
|
+
if template.include? 'DEER'
|
68
|
+
case building_type
|
69
|
+
when 'Education'
|
70
|
+
'EPr'
|
71
|
+
when 'Enclosed mall'
|
72
|
+
'RtL'
|
73
|
+
when 'Food sales'
|
74
|
+
'RSD'
|
75
|
+
when 'Food service'
|
76
|
+
'RSD'
|
77
|
+
when 'Inpatient health care'
|
78
|
+
'Nrs'
|
79
|
+
when 'Laboratory'
|
80
|
+
'Hsp'
|
81
|
+
when 'Lodging'
|
82
|
+
'Htl'
|
83
|
+
when 'Mixed use'
|
84
|
+
'ECC'
|
85
|
+
when 'Mobile Home'
|
86
|
+
'DMo'
|
87
|
+
when 'Multifamily (2 to 4 units)'
|
88
|
+
'MFm'
|
89
|
+
when 'Multifamily (5 or more units)'
|
90
|
+
'MFm'
|
91
|
+
when 'Nonrefrigerated warehouse'
|
92
|
+
'SUn'
|
93
|
+
when 'Nursing'
|
94
|
+
'Nrs'
|
95
|
+
when 'Office'
|
96
|
+
if footprint_area
|
97
|
+
if footprint_area.to_f > 100_000
|
98
|
+
'OfL'
|
99
|
+
else
|
100
|
+
'OfS'
|
101
|
+
end
|
102
|
+
else
|
103
|
+
raise 'footprint_area required to map office building type'
|
104
|
+
end
|
105
|
+
when 'Outpatient health care'
|
106
|
+
'Nrs'
|
107
|
+
when 'Public assembly'
|
108
|
+
'Asm'
|
109
|
+
when 'Public order and safety'
|
110
|
+
'Asm'
|
111
|
+
when 'Refrigerated warehouse'
|
112
|
+
'WRf'
|
113
|
+
when 'Religious worship'
|
114
|
+
'Asm'
|
115
|
+
when 'Retail other than mall'
|
116
|
+
'RtS'
|
117
|
+
when 'Service'
|
118
|
+
'MLI'
|
119
|
+
when 'Single-Family'
|
120
|
+
'MFm'
|
121
|
+
when 'Strip shopping mall'
|
122
|
+
'RtL'
|
123
|
+
when 'Vacant'
|
124
|
+
'SUn'
|
125
|
+
else
|
126
|
+
raise "building type #{building_type} cannot be mapped to a DEER building type"
|
127
|
+
end
|
128
|
+
|
129
|
+
else
|
130
|
+
# default: ASHRAE
|
131
|
+
case building_type
|
132
|
+
when 'Education'
|
133
|
+
'SecondarySchool'
|
134
|
+
when 'Enclosed mall'
|
135
|
+
'RetailStripmall'
|
136
|
+
when 'Food sales'
|
137
|
+
'FullServiceRestaurant'
|
138
|
+
when 'Food service'
|
139
|
+
'FullServiceRestaurant'
|
140
|
+
when 'Inpatient health care'
|
141
|
+
'Hospital'
|
142
|
+
when 'Laboratory'
|
143
|
+
'Hospital'
|
144
|
+
when 'Lodging'
|
145
|
+
if number_of_stories
|
146
|
+
if number_of_stories.to_i > 3
|
147
|
+
return 'LargeHotel'
|
148
|
+
else
|
149
|
+
return 'SmallHotel'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
'LargeHotel'
|
153
|
+
when 'Mixed use'
|
154
|
+
'Mixed use'
|
155
|
+
when 'Mobile Home'
|
156
|
+
'MidriseApartment'
|
157
|
+
when 'Multifamily (2 to 4 units)'
|
158
|
+
'MidriseApartment'
|
159
|
+
when 'Multifamily (5 or more units)'
|
160
|
+
'MidriseApartment'
|
161
|
+
when 'Nonrefrigerated warehouse'
|
162
|
+
'Warehouse'
|
163
|
+
when 'Nursing'
|
164
|
+
'Outpatient'
|
165
|
+
when 'Office'
|
166
|
+
if footprint_area
|
167
|
+
value = if footprint_area.to_f < 20_000
|
168
|
+
'SmallOffice'
|
169
|
+
elsif footprint_area.to_f > 100_000
|
170
|
+
'LargeOffice'
|
171
|
+
else
|
172
|
+
'MediumOffice'
|
173
|
+
end
|
174
|
+
else
|
175
|
+
raise 'Floor area required to map office building type'
|
176
|
+
end
|
177
|
+
when 'Outpatient health care'
|
178
|
+
'Outpatient'
|
179
|
+
when 'Public assembly'
|
180
|
+
'MediumOffice'
|
181
|
+
when 'Public order and safety'
|
182
|
+
'MediumOffice'
|
183
|
+
when 'Refrigerated warehouse'
|
184
|
+
'Warehouse'
|
185
|
+
when 'Religious worship'
|
186
|
+
'MediumOffice'
|
187
|
+
when 'Retail other than mall'
|
188
|
+
'RetailStandalone'
|
189
|
+
when 'Service'
|
190
|
+
'MediumOffice'
|
191
|
+
when 'Single-Family'
|
192
|
+
'MidriseApartment'
|
193
|
+
when 'Strip shopping mall'
|
194
|
+
'RetailStripmall'
|
195
|
+
when 'Vacant'
|
196
|
+
'Warehouse'
|
197
|
+
else
|
198
|
+
raise "building type #{building_type} cannot be mapped to an ASHRAE building type"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def lookup_template_by_year_built(template, year_built)
|
204
|
+
if template.include? 'DEER'
|
205
|
+
if year_built <= 1996
|
206
|
+
'DEER 1985'
|
207
|
+
elsif year_built <= 2003
|
208
|
+
'DEER 1996'
|
209
|
+
elsif year_built <= 2007
|
210
|
+
'DEER 2003'
|
211
|
+
elsif year_built <= 2011
|
212
|
+
'DEER 2007'
|
213
|
+
elsif year_built <= 2014
|
214
|
+
'DEER 2011'
|
215
|
+
elsif year_built <= 2015
|
216
|
+
'DEER 2014'
|
217
|
+
elsif year_built <= 2017
|
218
|
+
'DEER 2015'
|
219
|
+
elsif year_built <= 2020
|
220
|
+
'DEER 2017'
|
221
|
+
else
|
222
|
+
'DEER 2020'
|
223
|
+
end
|
224
|
+
else
|
225
|
+
# ASHRAE
|
226
|
+
if year_built < 1980
|
227
|
+
'DOE Ref Pre-1980'
|
228
|
+
elsif year_built <= 2004
|
229
|
+
'DOE Ref 1980-2004'
|
230
|
+
elsif year_built <= 2007
|
231
|
+
'90.1-2004'
|
232
|
+
elsif year_built <= 2010
|
233
|
+
'90.1-2007'
|
234
|
+
elsif year_built <= 2013
|
235
|
+
'90.1-2010'
|
236
|
+
else
|
237
|
+
'90.1-2013'
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
68
242
|
def create_osw(scenario, features, feature_names)
|
69
|
-
|
70
243
|
if features.size != 1
|
71
|
-
raise
|
244
|
+
raise 'TestMapper1 currently cannot simulate more than one feature'
|
72
245
|
end
|
73
246
|
feature = features[0]
|
74
247
|
feature_id = feature.id
|
75
|
-
feature_type = feature.type
|
248
|
+
feature_type = feature.type
|
76
249
|
feature_name = feature.name
|
77
|
-
if feature_names.size == 1
|
78
|
-
|
79
|
-
end
|
80
|
-
|
250
|
+
feature_name = feature_names[0] if feature_names.size == 1
|
251
|
+
|
81
252
|
# deep clone of @@osw before we configure it
|
82
253
|
osw = Marshal.load(Marshal.dump(@@osw))
|
83
|
-
|
254
|
+
|
84
255
|
# now we have the feature, we can look up its properties and set arguments in the OSW
|
85
256
|
osw[:name] = feature_name
|
86
257
|
osw[:description] = feature_name
|
87
|
-
|
258
|
+
|
88
259
|
if feature_type == 'Building'
|
89
260
|
|
90
261
|
# set_run_period
|
91
262
|
begin
|
92
|
-
timesteps_per_hour = feature.timesteps_per_hour
|
93
|
-
|
263
|
+
timesteps_per_hour = feature.timesteps_per_hour
|
264
|
+
unless timesteps_per_hour.empty?
|
94
265
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'timesteps_per_hour', timesteps_per_hour)
|
95
266
|
end
|
96
|
-
rescue
|
267
|
+
rescue StandardError
|
97
268
|
end
|
98
269
|
begin
|
99
270
|
begin_date = feature.begin_date
|
100
|
-
|
101
|
-
|
271
|
+
unless feature.begin_date.empty?
|
272
|
+
# check date-only YYYY-MM-DD
|
102
273
|
if feature.begin_date.length > 10
|
103
274
|
feature.begin_date = feature.begin_date[0, 10]
|
104
275
|
end
|
105
276
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'begin_date', begin_date)
|
106
277
|
end
|
107
|
-
rescue
|
278
|
+
rescue StandardError
|
108
279
|
end
|
109
280
|
begin
|
110
281
|
end_date = feature.end_date
|
111
|
-
|
282
|
+
unless feature.end_date.empty?
|
112
283
|
# check date-only YYYY-MM-DD
|
113
284
|
if feature.end_date.length > 10
|
114
285
|
feature.end_date = feature.end_date[0, 10]
|
115
286
|
end
|
116
287
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'end_date', end_date)
|
117
288
|
end
|
118
|
-
rescue
|
289
|
+
rescue StandardError
|
119
290
|
end
|
120
|
-
|
291
|
+
|
121
292
|
# convert to hash
|
122
293
|
building_hash = feature.to_hash
|
123
294
|
# check for detailed model filename
|
@@ -131,94 +302,10 @@ module URBANopt
|
|
131
302
|
|
132
303
|
# in case detailed model filename is not present
|
133
304
|
else
|
305
|
+
|
134
306
|
building_type_1 = building_hash[:building_type]
|
135
|
-
|
136
|
-
|
137
|
-
building_type_1 = 'MidriseApartment'
|
138
|
-
when 'Multifamily (2 to 4 units)'
|
139
|
-
building_type_1 = 'MidriseApartment'
|
140
|
-
when 'Single-Family'
|
141
|
-
building_type_1 = 'MidriseApartment'
|
142
|
-
when 'Office'
|
143
|
-
building_type_1 = 'MediumOffice'
|
144
|
-
when 'Outpatient health care'
|
145
|
-
building_type_1 = 'Outpatient'
|
146
|
-
when 'Inpatient health care'
|
147
|
-
building_type_1 = 'Hospital'
|
148
|
-
when 'Lodging'
|
149
|
-
building_type_1 = 'LargeHotel'
|
150
|
-
when 'Food service'
|
151
|
-
building_type_1 = 'FullServiceRestaurant'
|
152
|
-
when 'Strip shopping mall'
|
153
|
-
building_type_1 = 'RetailStripmall'
|
154
|
-
when 'Retail other than mall'
|
155
|
-
building_type_1 = 'RetailStandalone'
|
156
|
-
when 'Education'
|
157
|
-
building_type_1 = 'SecondarySchool'
|
158
|
-
when 'Nursing'
|
159
|
-
building_type_1 = 'MidriseApartment'
|
160
|
-
when 'Mixed use'
|
161
|
-
mixed_type_1 = building_hash[:mixed_type_1]
|
162
|
-
mixed_type_2 = building_hash[:mixed_type_2]
|
163
|
-
mixed_type_2_percentage = building_hash[:mixed_type_2_percentage]
|
164
|
-
mixed_type_2_fract_bldg_area = mixed_type_2_percentage*0.01
|
165
|
-
|
166
|
-
mixed_type_3 = building_hash[:mixed_type_3]
|
167
|
-
mixed_type_3_percentage = building_hash[:mixed_type_3_percentage]
|
168
|
-
mixed_type_3_fract_bldg_area = mixed_type_3_percentage*0.01
|
169
|
-
|
170
|
-
mixed_type_4 = building_hash[:mixed_type_4]
|
171
|
-
mixed_type_4_percentage = building_hash[:mixed_type_4_percentage]
|
172
|
-
mixed_type_4_fract_bldg_area = mixed_type_4_percentage*0.01
|
173
|
-
|
174
|
-
mixed_use_types = []
|
175
|
-
mixed_use_types << mixed_type_1
|
176
|
-
mixed_use_types << mixed_type_2
|
177
|
-
mixed_use_types << mixed_type_3
|
178
|
-
mixed_use_types << mixed_type_4
|
179
|
-
|
180
|
-
openstudio_mixed_use_types = []
|
181
|
-
|
182
|
-
mixed_use_types.each do |mixed_use_type|
|
183
|
-
|
184
|
-
case mixed_use_type
|
185
|
-
when 'Multifamily (5 or more units)'
|
186
|
-
mixed_use_type = 'MidriseApartment'
|
187
|
-
when 'Multifamily (2 to 4 units)'
|
188
|
-
mixed_use_type = 'MidriseApartment'
|
189
|
-
when 'Single-Family'
|
190
|
-
mixed_use_type = 'MidriseApartment'
|
191
|
-
when 'Office'
|
192
|
-
mixed_use_type = 'MediumOffice'
|
193
|
-
when 'Outpatient health care'
|
194
|
-
mixed_use_type = 'Outpatient'
|
195
|
-
when 'Inpatient health care'
|
196
|
-
mixed_use_type = 'Hospital'
|
197
|
-
when 'Lodging'
|
198
|
-
mixed_use_type = 'LargeHotel'
|
199
|
-
when 'Food service'
|
200
|
-
mixed_use_type = 'FullServiceRestaurant'
|
201
|
-
when 'Strip shopping mall'
|
202
|
-
mixed_use_type = 'RetailStripmall'
|
203
|
-
when 'Retail other than mall'
|
204
|
-
mixed_use_type = 'RetailStandalone'
|
205
|
-
when 'Education'
|
206
|
-
mixed_use_type = 'SecondarySchool'
|
207
|
-
when 'Nursing'
|
208
|
-
mixed_use_type = 'MidriseApartment'
|
209
|
-
end
|
210
|
-
|
211
|
-
openstudio_mixed_use_types << mixed_use_type
|
212
|
-
end
|
213
|
-
|
214
|
-
openstudio_mixed_type_1 = openstudio_mixed_use_types[0]
|
215
|
-
openstudio_mixed_type_2 = openstudio_mixed_use_types[1]
|
216
|
-
openstudio_mixed_type_3 = openstudio_mixed_use_types[2]
|
217
|
-
openstudio_mixed_type_4 = openstudio_mixed_use_types[3]
|
218
|
-
|
219
|
-
end
|
220
|
-
footprint_area = building_hash[:footprint_area]
|
221
|
-
floor_height = 10
|
307
|
+
|
308
|
+
# lookup/map building type
|
222
309
|
number_of_stories = building_hash[:number_of_stories]
|
223
310
|
if building_hash.key?(:number_of_stories_above_ground)
|
224
311
|
number_of_stories_above_ground = building_hash[:number_of_stories_above_ground]
|
@@ -227,111 +314,182 @@ module URBANopt
|
|
227
314
|
number_of_stories_above_ground = number_of_stories
|
228
315
|
number_of_stories_below_ground = 0
|
229
316
|
end
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
317
|
+
template = building_hash.key?(:template) ? building_hash[:template] : nil
|
318
|
+
footprint_area = building_hash[:footprint_area]
|
319
|
+
|
320
|
+
mapped_building_type_1 = lookup_building_type(building_type_1, template, footprint_area, number_of_stories)
|
321
|
+
|
322
|
+
# process Mixed Use (for create_bar measure)
|
323
|
+
if building_type_1 == 'Mixed use'
|
324
|
+
# map mixed use types
|
325
|
+
running_fraction = 0
|
326
|
+
mixed_type_1 = building_hash[:mixed_type_1]
|
327
|
+
mixed_type_2 = building_hash.key?(:mixed_type_2) ? building_hash[:mixed_type_2] : nil
|
328
|
+
unless mixed_type_2.nil?
|
329
|
+
mixed_type_2_percentage = building_hash[:mixed_type_2_percentage]
|
330
|
+
mixed_type_2_fract_bldg_area = mixed_type_2_percentage * 0.01
|
331
|
+
running_fraction += mixed_type_2_fract_bldg_area
|
332
|
+
end
|
333
|
+
|
334
|
+
mixed_type_3 = building_hash.key?(:mixed_type_3) ? building_hash[:mixed_type_3] : nil
|
335
|
+
unless mixed_type_3.nil?
|
336
|
+
mixed_type_3_percentage = building_hash[:mixed_type_3_percentage]
|
337
|
+
mixed_type_3_fract_bldg_area = mixed_type_3_percentage * 0.01
|
338
|
+
running_fraction += mixed_type_3_fract_bldg_area
|
339
|
+
end
|
340
|
+
|
341
|
+
mixed_type_4 = building_hash.key?(:mixed_type_4) ? building_hash[:mixed_type_4] : nil
|
342
|
+
unless mixed_type_4.nil?
|
343
|
+
mixed_type_4_percentage = building_hash[:mixed_type_4_percentage]
|
344
|
+
mixed_type_4_fract_bldg_area = mixed_type_4_percentage * 0.01
|
345
|
+
running_fraction += mixed_type_4_fract_bldg_area
|
346
|
+
end
|
347
|
+
|
348
|
+
# potentially calculate from other inputs
|
349
|
+
mixed_type_1_fract_bldg_area = building_hash.key?(:mixed_type_1_percentage) ? building_hash[:mixed_type_1_percentage] : (1 - running_fraction)
|
350
|
+
|
351
|
+
# lookup mixed_use types
|
352
|
+
footprint_1 = footprint_area * mixed_type_1_fract_bldg_area
|
353
|
+
openstudio_mixed_type_1 = lookup_building_type(mixed_type_1, template, footprint_1, number_of_stories)
|
354
|
+
unless mixed_type_2.nil?
|
355
|
+
footprint_2 = footprint_area * mixed_type_2_fract_bldg_area
|
356
|
+
openstudio_mixed_type_2 = lookup_building_type(mixed_type_2, template, footprint_2, number_of_stories)
|
357
|
+
end
|
358
|
+
unless mixed_type_3.nil?
|
359
|
+
footprint_3 = footprint_area * mixed_type_3_fract_bldg_area
|
360
|
+
openstudio_mixed_type_3 = lookup_building_type(mixed_type_3, template, footprint_3, number_of_stories)
|
361
|
+
end
|
362
|
+
unless mixed_type_4.nil?
|
363
|
+
footprint_4 = footprint_area * mixed_type_4_fract_bldg_area
|
364
|
+
openstudio_mixed_type_4 = lookup_building_type(mixed_type_4, template, footprint_4, number_of_stories)
|
365
|
+
end
|
234
366
|
end
|
235
367
|
|
368
|
+
floor_height = 10
|
369
|
+
system_type = if building_hash.key?(:system_type)
|
370
|
+
building_hash[:system_type]
|
371
|
+
else
|
372
|
+
'Inferred'
|
373
|
+
end
|
374
|
+
|
236
375
|
def time_mapping(time)
|
237
376
|
hour = time.split(':')[0]
|
238
377
|
minute = time.split(':')[1]
|
239
|
-
fraction = minute.to_f/60
|
378
|
+
fraction = minute.to_f / 60
|
240
379
|
fraction_roundup = fraction.round(2)
|
241
380
|
minute_fraction = fraction_roundup.to_s.split('.')[1]
|
242
381
|
new_time = [hour, minute_fraction].join('.')
|
243
|
-
|
382
|
+
new_time
|
244
383
|
end
|
245
384
|
|
246
|
-
|
247
385
|
# ChangeBuildingLocation
|
248
|
-
# set skip
|
386
|
+
# set skip to false for change building location
|
249
387
|
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', '__SKIP__', false)
|
250
388
|
|
251
389
|
# cec climate zone takes precedence
|
252
390
|
cec_found = false
|
253
391
|
begin
|
254
392
|
cec_climate_zone = feature.cec_climate_zone
|
255
|
-
|
256
|
-
cec_climate_zone =
|
393
|
+
unless cec_climate_zone.empty?
|
394
|
+
cec_climate_zone = 'T24-CEC' + cec_climate_zone
|
257
395
|
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'climate_zone', cec_climate_zone)
|
258
396
|
cec_found = true
|
259
397
|
end
|
260
|
-
rescue
|
398
|
+
rescue StandardError
|
261
399
|
end
|
262
|
-
|
400
|
+
unless cec_found
|
263
401
|
begin
|
264
402
|
climate_zone = feature.climate_zone
|
265
|
-
|
266
|
-
climate_zone =
|
403
|
+
unless climate_zone.empty?
|
404
|
+
climate_zone = 'ASHRAE 169-2013-' + climate_zone
|
267
405
|
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'climate_zone', climate_zone)
|
268
406
|
end
|
269
|
-
rescue
|
407
|
+
rescue StandardError
|
270
408
|
end
|
271
409
|
end
|
272
410
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
411
|
+
# set weather file
|
412
|
+
begin
|
413
|
+
weather_filename = feature.weather_filename
|
414
|
+
if !feature.weather_filename.nil? && !feature.weather_filename.empty?
|
415
|
+
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'weather_file_name', weather_filename)
|
416
|
+
puts "Setting weather_file_name to #{weather_filename} as specified in the FeatureFile"
|
417
|
+
end
|
418
|
+
rescue StandardError
|
419
|
+
puts 'No weather_file specified on feature'
|
420
|
+
epw_file_path = Dir.glob(File.join(File.dirname(__FILE__), '../weather/*.epw'))[0]
|
421
|
+
if !epw_file_path.nil? && !epw_file_path.empty?
|
422
|
+
epw_file_name = File.basename(epw_file_path)
|
423
|
+
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'weather_file_name', epw_file_name)
|
424
|
+
puts "Setting weather_file_name to first epw file found in the weather folder: #{epw_file_name}"
|
425
|
+
else
|
426
|
+
puts 'NO WEATHER FILES SPECIFIED...SIMULATIONS MAY FAIL'
|
427
|
+
end
|
277
428
|
end
|
278
|
-
rescue
|
279
|
-
end
|
280
429
|
|
281
|
-
#set weekday start time
|
430
|
+
# set weekday start time
|
282
431
|
begin
|
283
432
|
weekday_start_time = feature.weekday_start_time
|
284
|
-
|
433
|
+
unless feature.weekday_start_time.empty?
|
285
434
|
new_weekday_start_time = time_mapping(weekday_start_time)
|
286
435
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wkdy_op_hrs_start_time', new_weekday_start_time, 'create_typical_building_from_model 1')
|
287
436
|
end
|
288
|
-
rescue
|
437
|
+
rescue StandardError
|
289
438
|
end
|
290
439
|
|
291
440
|
# set weekday duration
|
292
441
|
begin
|
293
442
|
weekday_duration = feature.weekday_duration
|
294
|
-
|
443
|
+
unless feature.weekday_duration.empty?
|
295
444
|
new_weekday_duration = time_mapping(weekday_duration)
|
296
445
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wkdy_op_hrs_duration', new_weekday_duration, 'create_typical_building_from_model 1')
|
297
446
|
end
|
298
|
-
rescue
|
447
|
+
rescue StandardError
|
299
448
|
end
|
300
|
-
|
449
|
+
|
301
450
|
# set weekend start time
|
302
451
|
begin
|
303
452
|
weekend_start_time = feature.weekend_start_time
|
304
|
-
|
453
|
+
unless feature.weekend_start_time.empty?
|
305
454
|
new_weekend_start_time = time_mapping(weekend_start_time)
|
306
455
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wknd_op_hrs_start_time', new_weekend_start_time, 'create_typical_building_from_model 1')
|
307
456
|
end
|
308
|
-
rescue
|
457
|
+
rescue StandardError
|
309
458
|
end
|
310
|
-
|
459
|
+
|
311
460
|
# set weekend duration
|
312
461
|
begin
|
313
462
|
weekend_duration = feature.weekend_duration
|
314
|
-
|
463
|
+
unless feature.weekend_duration.empty?
|
315
464
|
new_weekend_duration = time_mapping(weekend_duration)
|
316
465
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wknd_op_hrs_duration', new_weekend_duration, 'create_typical_building_from_model 1')
|
317
466
|
end
|
318
|
-
rescue
|
467
|
+
rescue StandardError
|
319
468
|
end
|
320
469
|
|
321
470
|
# template
|
322
471
|
begin
|
472
|
+
new_template = nil
|
323
473
|
template = feature.template
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
474
|
+
|
475
|
+
# can we override template with year_built info? (keeping same template family)
|
476
|
+
if building_hash.key?(:year_built) && !building_hash[:year_built].nil? && !feature.template.empty?
|
477
|
+
new_template = lookup_template_by_year_built(template, year_built)
|
478
|
+
elsif !feature.template.empty?
|
479
|
+
new_template = template
|
480
|
+
end
|
481
|
+
|
482
|
+
if new_template
|
483
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'template', new_template)
|
484
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'template', new_template, 'create_typical_building_from_model 1')
|
485
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'template', new_template, 'create_typical_building_from_model 2')
|
328
486
|
end
|
329
|
-
rescue
|
487
|
+
rescue StandardError
|
330
488
|
end
|
331
|
-
|
489
|
+
|
332
490
|
# TODO: surface_elevation has no current mapping
|
333
491
|
# TODO: tariff_filename has no current mapping
|
334
|
-
|
492
|
+
|
335
493
|
# create a bar building, will have spaces tagged with individual space types given the
|
336
494
|
# input building types
|
337
495
|
# set skip measure to false
|
@@ -341,24 +499,24 @@ module URBANopt
|
|
341
499
|
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'num_stories_above_grade', number_of_stories_above_ground)
|
342
500
|
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'num_stories_below_grade', number_of_stories_below_ground)
|
343
501
|
|
344
|
-
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_a',
|
502
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_a', mapped_building_type_1)
|
345
503
|
|
346
504
|
if building_type_1 == 'Mixed use'
|
347
505
|
|
348
506
|
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_a', openstudio_mixed_type_1)
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
507
|
+
|
508
|
+
unless mixed_type_2.nil?
|
509
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_b', openstudio_mixed_type_2)
|
510
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_b_fract_bldg_area', mixed_type_2_fract_bldg_area)
|
511
|
+
end
|
512
|
+
unless mixed_type_3.nil?
|
513
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_c', openstudio_mixed_type_3)
|
514
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_c_fract_bldg_area', mixed_type_3_fract_bldg_area)
|
515
|
+
end
|
516
|
+
unless mixed_type_4.nil?
|
517
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_d', openstudio_mixed_type_4)
|
518
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'bldg_type_d_fract_bldg_area', mixed_type_4_fract_bldg_area)
|
519
|
+
end
|
362
520
|
end
|
363
521
|
|
364
522
|
# calling create typical building the first time will create space types
|
@@ -366,32 +524,30 @@ module URBANopt
|
|
366
524
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'add_hvac', false, 'create_typical_building_from_model 1')
|
367
525
|
|
368
526
|
# create a blended space type for each story
|
369
|
-
OpenStudio::Extension.set_measure_argument(osw,
|
370
|
-
|
371
|
-
OpenStudio::Extension.set_measure_argument(osw,
|
372
|
-
|
527
|
+
OpenStudio::Extension.set_measure_argument(osw,
|
528
|
+
'blended_space_type_from_model', '__SKIP__', false)
|
529
|
+
OpenStudio::Extension.set_measure_argument(osw,
|
530
|
+
'blended_space_type_from_model', 'blend_method', 'Building Story')
|
373
531
|
|
374
532
|
# create geometry for the desired feature, this will reuse blended space types in the model for each story and remove the bar geometry
|
375
533
|
OpenStudio::Extension.set_measure_argument(osw, 'urban_geometry_creation', '__SKIP__', false)
|
376
534
|
OpenStudio::Extension.set_measure_argument(osw, 'urban_geometry_creation', 'geojson_file', scenario.feature_file.path)
|
377
535
|
OpenStudio::Extension.set_measure_argument(osw, 'urban_geometry_creation', 'feature_id', feature_id)
|
378
536
|
OpenStudio::Extension.set_measure_argument(osw, 'urban_geometry_creation', 'surrounding_buildings', 'ShadingOnly')
|
379
|
-
|
537
|
+
|
380
538
|
# call create typical building a second time, do not touch space types, only add hvac
|
381
539
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', '__SKIP__', false)
|
382
540
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'system_type', system_type, 'create_typical_building_from_model 2')
|
383
541
|
end
|
384
542
|
|
385
|
-
|
386
543
|
# call the default feature reporting measure
|
387
544
|
OpenStudio::Extension.set_measure_argument(osw, 'default_feature_reports', 'feature_id', feature_id)
|
388
545
|
OpenStudio::Extension.set_measure_argument(osw, 'default_feature_reports', 'feature_name', feature_name)
|
389
546
|
OpenStudio::Extension.set_measure_argument(osw, 'default_feature_reports', 'feature_type', feature_type)
|
390
|
-
end
|
391
|
-
|
392
|
-
|
393
|
-
end
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
end #URBANopt
|
547
|
+
end
|
548
|
+
|
549
|
+
osw
|
550
|
+
end
|
551
|
+
end # BaselineMapper
|
552
|
+
end # Scenario
|
553
|
+
end # URBANopt
|