tbd 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +3 -0
  3. data/.github/workflows/pull_request.yml +72 -0
  4. data/.gitignore +23 -0
  5. data/.rspec +3 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.md +21 -0
  8. data/README.md +154 -0
  9. data/Rakefile +60 -0
  10. data/json/midrise.json +64 -0
  11. data/json/tbd_5ZoneNoHVAC.json +19 -0
  12. data/json/tbd_5ZoneNoHVAC_btap.json +91 -0
  13. data/json/tbd_seb_n2.json +41 -0
  14. data/json/tbd_seb_n4.json +57 -0
  15. data/json/tbd_warehouse10.json +24 -0
  16. data/json/tbd_warehouse5.json +37 -0
  17. data/lib/measures/tbd/LICENSE.md +21 -0
  18. data/lib/measures/tbd/README.md +136 -0
  19. data/lib/measures/tbd/README.md.erb +42 -0
  20. data/lib/measures/tbd/docs/.gitkeep +1 -0
  21. data/lib/measures/tbd/measure.rb +327 -0
  22. data/lib/measures/tbd/measure.xml +460 -0
  23. data/lib/measures/tbd/resources/geo.rb +714 -0
  24. data/lib/measures/tbd/resources/geometry.rb +351 -0
  25. data/lib/measures/tbd/resources/model.rb +1431 -0
  26. data/lib/measures/tbd/resources/oslog.rb +381 -0
  27. data/lib/measures/tbd/resources/psi.rb +2229 -0
  28. data/lib/measures/tbd/resources/tbd.rb +55 -0
  29. data/lib/measures/tbd/resources/transformation.rb +121 -0
  30. data/lib/measures/tbd/resources/ua.rb +986 -0
  31. data/lib/measures/tbd/resources/utils.rb +1636 -0
  32. data/lib/measures/tbd/resources/version.rb +3 -0
  33. data/lib/measures/tbd/tests/tbd_full_PSI.json +17 -0
  34. data/lib/measures/tbd/tests/tbd_tests.rb +222 -0
  35. data/lib/tbd/geo.rb +714 -0
  36. data/lib/tbd/psi.rb +2229 -0
  37. data/lib/tbd/ua.rb +986 -0
  38. data/lib/tbd/version.rb +25 -0
  39. data/lib/tbd.rb +93 -0
  40. data/sponsors/canada.png +0 -0
  41. data/sponsors/quebec.png +0 -0
  42. data/tbd.gemspec +43 -0
  43. data/tbd.schema.json +571 -0
  44. data/v291_MacOS.md +110 -0
  45. metadata +191 -0
@@ -0,0 +1,37 @@
1
+ {
2
+ "schema": "https://github.com/rd2/tbd/blob/master/tbd.schema.json",
3
+ "description": "test_warehouse.osm with spacetype PSI values",
4
+ "psis": [{
5
+ "id": "Warehouse Office",
6
+ "rimjoist": 0.300,
7
+ "parapet": 0.300,
8
+ "fenestration": 0.300,
9
+ "corner": 0.300,
10
+ "balcony": 0.300,
11
+ "party": 0.300,
12
+ "grade": 0.300
13
+ },
14
+ {
15
+ "id": "Warehouse Fine",
16
+ "rimjoist": 0.500,
17
+ "parapet": 0.500,
18
+ "fenestration": 0.500,
19
+ "corner": 0.500,
20
+ "balcony": 0.500,
21
+ "party": 0.500,
22
+ "grade": 0.500
23
+ }
24
+ ],
25
+ "building": {
26
+ "psi": "regular (BETBG)"
27
+ },
28
+ "spacetypes": [{
29
+ "id": "Warehouse Office",
30
+ "psi": "Warehouse Office"
31
+ },
32
+ {
33
+ "id": "Warehouse Fine",
34
+ "psi": "Warehouse Fine"
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2022 Denis Bourgeois & Dan Macumber
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,136 @@
1
+
2
+
3
+ ###### (Automatically generated documentation)
4
+
5
+ # Thermal Bridging and Derating - TBD
6
+
7
+ ## Description
8
+ Derates opaque constructions from major thermal bridges.
9
+
10
+ ## Modeler Description
11
+ Check out rd2.github.io/tbd
12
+
13
+ ## Measure Type
14
+ ModelMeasure
15
+
16
+ ## Taxonomy
17
+
18
+
19
+ ## Arguments
20
+
21
+
22
+ ### Alter OpenStudio model (Apply Measures Now)
23
+ For EnergyPlus simulations, leave CHECKED. For iterative exploration with Apply Measures Now, UNCHECK to preserve original OpenStudio model.
24
+ **Name:** alter_model,
25
+ **Type:** Boolean,
26
+ **Units:** ,
27
+ **Required:** false,
28
+ **Model Dependent:** false
29
+
30
+ ### Load 'tbd.json'
31
+ Loads existing 'tbd.json' file (under '/files'), may override 'default thermal bridge' set.
32
+ **Name:** load_tbd_json,
33
+ **Type:** Boolean,
34
+ **Units:** ,
35
+ **Required:** false,
36
+ **Model Dependent:** false
37
+
38
+ ### Default thermal bridge set
39
+ e.g. 'poor', 'regular', 'efficient', 'code' (may be overridden by 'tbd.json' file).
40
+ **Name:** option,
41
+ **Type:** Choice,
42
+ **Units:** ,
43
+ **Required:** false,
44
+ **Model Dependent:** false
45
+
46
+ ### Write 'tbd.out.json'
47
+ Write out 'tbd.out.json' file e.g., to customize for subsequent runs (edit, and place under '/files' as 'tbd.json').
48
+ **Name:** write_tbd_json,
49
+ **Type:** Boolean,
50
+ **Units:** ,
51
+ **Required:** false,
52
+ **Model Dependent:** false
53
+
54
+ ### Wall construction(s) to 'uprate'
55
+ Target 1x (or 'ALL') wall construction(s) to 'uprate', to achieve wall Ut target below.
56
+ **Name:** wall_option,
57
+ **Type:** Choice,
58
+ **Units:** ,
59
+ **Required:** false,
60
+ **Model Dependent:** false
61
+
62
+ ### Roof construction(s) to 'uprate'
63
+ Target 1x (or 'ALL') roof construction(s) to 'uprate', to achieve roof Ut target below.
64
+ **Name:** roof_option,
65
+ **Type:** Choice,
66
+ **Units:** ,
67
+ **Required:** false,
68
+ **Model Dependent:** false
69
+
70
+ ### Floor construction(s) to 'uprate'
71
+ Target 1x (or 'ALL') floor construction(s) to 'uprate', to achieve floor Ut target below.
72
+ **Name:** floor_option,
73
+ **Type:** Choice,
74
+ **Units:** ,
75
+ **Required:** false,
76
+ **Model Dependent:** false
77
+
78
+ ### Wall Ut target (W/m2•K)
79
+ Overall Ut target to meet for wall construction(s). Ignored if previous wall 'uprate' option is set to 'NONE'.
80
+ **Name:** wall_ut,
81
+ **Type:** Double,
82
+ **Units:** ,
83
+ **Required:** false,
84
+ **Model Dependent:** false
85
+
86
+ ### Roof Ut target (W/m2•K)
87
+ Overall Ut target to meet for roof construction(s). Ignored if previous roof 'uprate' option is set to 'NONE'.
88
+ **Name:** roof_ut,
89
+ **Type:** Double,
90
+ **Units:** ,
91
+ **Required:** false,
92
+ **Model Dependent:** false
93
+
94
+ ### Floor Ut target (W/m2•K)
95
+ Overall Ut target to meet for floor construction(s). Ignored if previous floor 'uprate' option is set to 'NONE'.
96
+ **Name:** floor_ut,
97
+ **Type:** Double,
98
+ **Units:** ,
99
+ **Required:** false,
100
+ **Model Dependent:** false
101
+
102
+ ### Generate UA' report
103
+ Compare ∑U•A + ∑PSI•L + ∑KHI•n : 'Design' vs UA' reference (see pull-down option below).
104
+ **Name:** gen_UA_report,
105
+ **Type:** Boolean,
106
+ **Units:** ,
107
+ **Required:** false,
108
+ **Model Dependent:** false
109
+
110
+ ### UA' reference
111
+ e.g. 'poor', 'regular', 'efficient', 'code'.
112
+ **Name:** ua_reference,
113
+ **Type:** Choice,
114
+ **Units:** ,
115
+ **Required:** true,
116
+ **Model Dependent:** false
117
+
118
+ ### Generate Kiva inputs
119
+ Generates Kiva settings & objects for surfaces with 'foundation' boundary conditions (not 'ground').
120
+ **Name:** gen_kiva,
121
+ **Type:** Boolean,
122
+ **Units:** ,
123
+ **Required:** false,
124
+ **Model Dependent:** false
125
+
126
+ ### Force-generate Kiva inputs
127
+ Overwrites 'ground' boundary conditions as 'foundation' before generating Kiva inputs (recommended).
128
+ **Name:** gen_kiva_force,
129
+ **Type:** Boolean,
130
+ **Units:** ,
131
+ **Required:** false,
132
+ **Model Dependent:** false
133
+
134
+
135
+
136
+
@@ -0,0 +1,42 @@
1
+ <%#= README.md.erb is used to auto-generate README.md. %>
2
+ <%#= To manually maintain README.md throw away README.md.erb and manually edit README.md %>
3
+ ###### (Automatically generated documentation)
4
+
5
+ # <%= name %>
6
+
7
+ ## Description
8
+ <%= description %>
9
+
10
+ ## Modeler Description
11
+ <%= modelerDescription %>
12
+
13
+ ## Measure Type
14
+ <%= measureType %>
15
+
16
+ ## Taxonomy
17
+ <%= taxonomy %>
18
+
19
+ ## Arguments
20
+
21
+ <% arguments.each do |argument| %>
22
+ ### <%= argument[:display_name] %>
23
+ <%= argument[:description] %>
24
+ **Name:** <%= argument[:name] %>,
25
+ **Type:** <%= argument[:type] %>,
26
+ **Units:** <%= argument[:units] %>,
27
+ **Required:** <%= argument[:required] %>,
28
+ **Model Dependent:** <%= argument[:model_dependent] %>
29
+ <% end %>
30
+
31
+ <% if arguments.size == 0 %>
32
+ <%= "This measure does not have any user arguments" %>
33
+ <% end %>
34
+
35
+ <% if outputs.size > 0 %>
36
+ ## Outputs
37
+ <% output_names = [] %>
38
+ <% outputs.each do |output| %>
39
+ <% output_names << output[:display_name] %>
40
+ <% end %>
41
+ <%= output_names.join(", ") %>
42
+ <% end %>
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,327 @@
1
+ # MIT License
2
+ #
3
+ # Copyright (c) 2020-2022 Denis Bourgeois & Dan Macumber
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require_relative "resources/tbd"
24
+
25
+ class TBDMeasure < OpenStudio::Measure::ModelMeasure
26
+ def name
27
+ return "Thermal Bridging and Derating - TBD"
28
+ end
29
+
30
+ def description
31
+ return "Derates opaque constructions from major thermal bridges."
32
+ end
33
+
34
+ def modeler_description
35
+ return "Check out rd2.github.io/tbd"
36
+ end
37
+
38
+ def arguments(model = nil)
39
+ args = OpenStudio::Measure::OSArgumentVector.new
40
+
41
+ arg = "alter_model"
42
+ dsc = "For EnergyPlus simulations, leave CHECKED. For iterative " \
43
+ "exploration with Apply Measures Now, UNCHECK to preserve " \
44
+ "original OpenStudio model."
45
+ alter = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
46
+ alter.setDisplayName("Alter OpenStudio model (Apply Measures Now)")
47
+ alter.setDescription(dsc)
48
+ alter.setDefaultValue(true)
49
+ args << alter
50
+
51
+ arg = "load_tbd_json"
52
+ dsc = "Loads existing 'tbd.json' file (under '/files'), may override " \
53
+ "'default thermal bridge' set."
54
+ load_tbd = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
55
+ load_tbd.setDisplayName("Load 'tbd.json'")
56
+ load_tbd.setDescription(dsc)
57
+ load_tbd.setDefaultValue(false)
58
+ args << load_tbd
59
+
60
+ chs = OpenStudio::StringVector.new
61
+ psi = TBD::PSI.new
62
+ psi.set.keys.each { |k| chs << k.to_s }
63
+
64
+ arg = "option"
65
+ dsc = "e.g. 'poor', 'regular', 'efficient', 'code' (may be overridden by " \
66
+ "'tbd.json' file)."
67
+ option = OpenStudio::Measure::OSArgument.makeChoiceArgument(arg, chs, false)
68
+ option.setDisplayName("Default thermal bridge set")
69
+ option.setDescription(dsc)
70
+ option.setDefaultValue("poor (BETBG)")
71
+ args << option
72
+
73
+ arg = "write_tbd_json"
74
+ dsc = "Write out 'tbd.out.json' file e.g., to customize for subsequent " \
75
+ "runs (edit, and place under '/files' as 'tbd.json')."
76
+ write_tbd = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
77
+ write_tbd.setDisplayName("Write 'tbd.out.json'")
78
+ write_tbd.setDescription(dsc)
79
+ write_tbd.setDefaultValue(false)
80
+ args << write_tbd
81
+
82
+ none = "NONE"
83
+ all_walls = "ALL wall constructions"
84
+ all_roofs = "ALL roof constructions"
85
+ all_flors = "ALL floor constructions"
86
+ walls = {c: {}}
87
+ roofs = {c: {}}
88
+ flors = {c: {}}
89
+ walls[:c][none] = {a: 0}
90
+ roofs[:c][none] = {a: 0}
91
+ flors[:c][none] = {a: 0}
92
+ walls[:c][all_walls] = {a: 100000000000000}
93
+ roofs[:c][all_roofs] = {a: 100000000000000}
94
+ flors[:c][all_flors] = {a: 100000000000000}
95
+ walls[:chx] = OpenStudio::StringVector.new
96
+ roofs[:chx] = OpenStudio::StringVector.new
97
+ flors[:chx] = OpenStudio::StringVector.new
98
+
99
+ if model
100
+ model.getSurfaces.each do |s|
101
+ type = s.surfaceType.downcase
102
+ next unless type == "wall" || type == "roofceiling" || type == "floor"
103
+ next unless s.outsideBoundaryCondition.downcase == "outdoors"
104
+ next if s.construction.empty?
105
+ next if s.construction.get.to_LayeredConstruction.empty?
106
+ lc = s.construction.get.to_LayeredConstruction.get
107
+ next if walls[:c].key?(lc.nameString)
108
+ next if roofs[:c].key?(lc.nameString)
109
+ next if flors[:c].key?(lc.nameString)
110
+ walls[:c][lc.nameString] = {a: lc.getNetArea} if type == "wall"
111
+ roofs[:c][lc.nameString] = {a: lc.getNetArea} if type == "roofceiling"
112
+ flors[:c][lc.nameString] = {a: lc.getNetArea} if type == "floor"
113
+ end
114
+
115
+ walls[:c] = walls[:c].sort_by{ |k,v| v[:a] }.reverse!.to_h
116
+ walls[:c][all_walls][:a] = 0
117
+ walls[:c].keys.each { |id| walls[:chx] << id }
118
+
119
+ roofs[:c] = roofs[:c].sort_by{ |k,v| v[:a] }.reverse!.to_h
120
+ roofs[:c][all_roofs][:a] = 0
121
+ roofs[:c].keys.each { |id| roofs[:chx] << id }
122
+
123
+ flors[:c] = flors[:c].sort_by{ |k,v| v[:a] }.reverse!.to_h
124
+ flors[:c][all_flors][:a] = 0
125
+ flors[:c].keys.each { |id| flors[:chx] << id }
126
+ end
127
+
128
+ arg = "wall_option"
129
+ dsc = "Target 1x (or 'ALL') wall construction(s) to 'uprate', to achieve " \
130
+ "wall Ut target below."
131
+ chx = walls[:chx]
132
+ wall = OpenStudio::Measure::OSArgument.makeChoiceArgument(arg, chx, false)
133
+ wall.setDisplayName("Wall construction(s) to 'uprate'")
134
+ wall.setDescription(dsc)
135
+ wall.setDefaultValue(chx.to_a.last)
136
+ args << wall
137
+
138
+ arg = "roof_option"
139
+ dsc = "Target 1x (or 'ALL') roof construction(s) to 'uprate', to achieve " \
140
+ "roof Ut target below."
141
+ chx = roofs[:chx]
142
+ roof = OpenStudio::Measure::OSArgument.makeChoiceArgument(arg, chx, false)
143
+ roof.setDisplayName("Roof construction(s) to 'uprate'")
144
+ roof.setDescription(dsc)
145
+ roof.setDefaultValue(chx.to_a.last)
146
+ args << roof
147
+
148
+ arg = "floor_option"
149
+ dsc = "Target 1x (or 'ALL') floor construction(s) to 'uprate', to achieve "\
150
+ "floor Ut target below."
151
+ chx = flors[:chx]
152
+ floor = OpenStudio::Measure::OSArgument.makeChoiceArgument(arg, chx, false)
153
+ floor.setDisplayName("Floor construction(s) to 'uprate'")
154
+ floor.setDescription(dsc)
155
+ floor.setDefaultValue(chx.to_a.last)
156
+ args << floor
157
+
158
+ arg = "wall_ut"
159
+ dsc = "Overall Ut target to meet for wall construction(s). Ignored if " \
160
+ "previous wall 'uprate' option is set to 'NONE'."
161
+ wall_ut = OpenStudio::Measure::OSArgument.makeDoubleArgument(arg, false)
162
+ wall_ut.setDisplayName("Wall Ut target (W/m2•K)")
163
+ wall_ut.setDescription(dsc)
164
+ wall_ut.setDefaultValue(0.210) # (NECB 2017, climate zone 7)
165
+ args << wall_ut
166
+
167
+ arg = "roof_ut"
168
+ dsc = "Overall Ut target to meet for roof construction(s). Ignored if " \
169
+ "previous roof 'uprate' option is set to 'NONE'."
170
+ roof_ut = OpenStudio::Measure::OSArgument.makeDoubleArgument(arg, false)
171
+ roof_ut.setDisplayName("Roof Ut target (W/m2•K)")
172
+ roof_ut.setDescription(dsc)
173
+ roof_ut.setDefaultValue(0.138) # (NECB 2017, climate zone 7)
174
+ args << roof_ut
175
+
176
+ arg = "floor_ut"
177
+ dsc = "Overall Ut target to meet for floor construction(s). Ignored if " \
178
+ "previous floor 'uprate' option is set to 'NONE'."
179
+ floor_ut = OpenStudio::Measure::OSArgument.makeDoubleArgument(arg, false)
180
+ floor_ut.setDisplayName("Floor Ut target (W/m2•K)")
181
+ floor_ut.setDescription(dsc)
182
+ floor_ut.setDefaultValue(0.162) # (NECB 2017, climate zone 7)
183
+ args << floor_ut
184
+
185
+ arg = "gen_UA_report"
186
+ dsc = "Compare ∑U•A + ∑PSI•L + ∑KHI•n : 'Design' vs UA' reference (see " \
187
+ "pull-down option below)."
188
+ gen_ua_report = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
189
+ gen_ua_report.setDisplayName("Generate UA' report")
190
+ gen_ua_report.setDescription(dsc)
191
+ gen_ua_report.setDefaultValue(false)
192
+ args << gen_ua_report
193
+
194
+ arg = "ua_reference"
195
+ dsc = "e.g. 'poor', 'regular', 'efficient', 'code'."
196
+ ua_ref = OpenStudio::Measure::OSArgument.makeChoiceArgument(arg, chs, true)
197
+ ua_ref.setDisplayName("UA' reference")
198
+ ua_ref.setDescription(dsc)
199
+ ua_ref.setDefaultValue("code (Quebec)")
200
+ args << ua_ref
201
+
202
+ arg = "gen_kiva"
203
+ dsc = "Generates Kiva settings & objects for surfaces with 'foundation' " \
204
+ "boundary conditions (not 'ground')."
205
+ gen_kiva = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
206
+ gen_kiva.setDisplayName("Generate Kiva inputs")
207
+ gen_kiva.setDescription(dsc)
208
+ gen_kiva.setDefaultValue(false)
209
+ args << gen_kiva
210
+
211
+ arg = "gen_kiva_force"
212
+ dsc = "Overwrites 'ground' boundary conditions as 'foundation' before " \
213
+ "generating Kiva inputs (recommended)."
214
+ kiva_force = OpenStudio::Measure::OSArgument.makeBoolArgument(arg, false)
215
+ kiva_force.setDisplayName("Force-generate Kiva inputs")
216
+ kiva_force.setDescription(dsc)
217
+ kiva_force.setDefaultValue(false)
218
+ args << kiva_force
219
+
220
+ return args
221
+ end
222
+
223
+ def run(mdl, runner, args)
224
+ super(mdl, runner, args)
225
+
226
+ argh = {}
227
+ argh[:alter ] = runner.getBoolArgumentValue("alter_model", args)
228
+ argh[:load_tbd ] = runner.getBoolArgumentValue("load_tbd_json", args)
229
+ argh[:option ] = runner.getStringArgumentValue("option", args)
230
+ argh[:write_tbd ] = runner.getBoolArgumentValue("write_tbd_json", args)
231
+ argh[:wall_ut ] = runner.getDoubleArgumentValue("wall_ut", args)
232
+ argh[:roof_ut ] = runner.getDoubleArgumentValue("roof_ut", args)
233
+ argh[:floor_ut ] = runner.getDoubleArgumentValue("floor_ut", args)
234
+ argh[:wall_option ] = runner.getStringArgumentValue("wall_option", args)
235
+ argh[:roof_option ] = runner.getStringArgumentValue("roof_option", args)
236
+ argh[:floor_option ] = runner.getStringArgumentValue("floor_option", args)
237
+ argh[:gen_ua ] = runner.getBoolArgumentValue("gen_UA_report", args)
238
+ argh[:ua_ref ] = runner.getStringArgumentValue("ua_reference", args)
239
+ argh[:gen_kiva ] = runner.getBoolArgumentValue("gen_kiva", args)
240
+ argh[:kiva_force ] = runner.getBoolArgumentValue("gen_kiva_force", args)
241
+
242
+ argh[:uprate_walls ] = argh[:wall_option ] != "NONE"
243
+ argh[:uprate_roofs ] = argh[:roof_option ] != "NONE"
244
+ argh[:uprate_floors] = argh[:floor_option] != "NONE"
245
+
246
+ return false unless runner.validateUserArguments(arguments(mdl), args)
247
+
248
+ if argh[:wall_ut] < TBD::TOL
249
+ runner.registerError("Wall Ut must be greater than 0 W/m2•K - Halting")
250
+ return false
251
+ elsif argh[:wall_ut] > 5.678 - TBD::TOL
252
+ runner.registerError("Wall Ut must be lower than 5.678 W/m2•K - Halting")
253
+ return false
254
+ end
255
+
256
+ if argh[:roof_ut] < TBD::TOL
257
+ runner.registerError("Roof Ut must be greater than 0 W/m2•K - Halting")
258
+ return false
259
+ elsif argh[:roof_ut] > 5.678 - TBD::TOL
260
+ runner.registerError("Roof Ut must be lower than 5.678 W/m2•K - Halting")
261
+ return false
262
+ end
263
+
264
+ if argh[:floor_ut] < TBD::TOL
265
+ runner.registerError("Floor Ut must be greater than 0 W/m2•K - Halting")
266
+ return false
267
+ elsif argh[:floor_ut] > 5.678 - TBD::TOL
268
+ runner.registerError("Floor Ut must be lower than 5.678 W/m2•K - Halting")
269
+ return false
270
+ end
271
+
272
+ TBD.clean!
273
+ argh[:schema_path] = nil
274
+ argh[:io_path ] = nil
275
+
276
+ if argh[:load_tbd]
277
+ argh[:io_path] = runner.workflow.findFile('tbd.json')
278
+
279
+ if argh[:io_path].empty?
280
+ TBD.log(TBD::FTL, "Can't find 'tbd.json' - simulation halted")
281
+ return TBD.exit(runner, argh)
282
+ else
283
+ argh[:io_path] = argh[:io_path].get.to_s
284
+ # TBD.log(TBD::INF, "Using inputs from #{argh[:io_path]}") # debugging
285
+ # runner.registerInfo("Using inputs from #{argh[:io_path]}") # debugging
286
+ end
287
+ end
288
+
289
+ # Process all ground-facing surfaces as foundation-facing.
290
+ if argh[:kiva_force]
291
+ argh[:gen_kiva] = true
292
+
293
+ mdl.getSurfaces.each do |s|
294
+ next unless s.isGroundSurface
295
+ construction = s.construction.get
296
+ s.setOutsideBoundaryCondition("Foundation")
297
+ s.setConstruction(construction)
298
+ end
299
+ end
300
+
301
+ str = "temp_measure_manager.osm"
302
+ seed = runner.workflow.seedFile
303
+ seed = File.basename(seed.get.to_s) unless seed.empty?
304
+ seed = "OpenStudio model" if seed.empty? || seed == str
305
+ argh[:seed] = seed
306
+
307
+ if argh[:alter]
308
+ model = mdl
309
+ else
310
+ model = OpenStudio::Model::Model.new
311
+ model.addObjects(mdl.toIdfFile.objects)
312
+ end
313
+
314
+ argh[:version ] = model.getVersion.versionIdentifier
315
+ tbd = TBD.process(model, argh)
316
+ argh[:io ] = tbd[:io]
317
+ argh[:surfaces] = tbd[:surfaces]
318
+ setpoints = TBD.heatingTemperatureSetpoints?(model)
319
+ setpoints = TBD.coolingTemperatureSetpoints?(model) || setpoints
320
+ argh[:setpoints] = setpoints
321
+
322
+ return TBD.exit(runner, argh)
323
+ end
324
+ end
325
+
326
+ # register the measure to be used by the application
327
+ TBDMeasure.new.registerWithApplication