tbd 3.2.1 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/measures/tbd/measure.xml +14 -14
- data/lib/measures/tbd/resources/geo.rb +7 -3
- data/lib/measures/tbd/resources/ua.rb +154 -145
- data/lib/tbd/geo.rb +7 -3
- data/lib/tbd/ua.rb +154 -145
- data/lib/tbd/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 858b576df6d2a7c00b547c1bcb86fcae917f441c236f012610309b5df96f2d19
|
4
|
+
data.tar.gz: ee47f03ce21e7ef8d95968aa0d159a39875ca546c32b48c8f96d7779b1ef341d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d7d4ad54c0d8d06776b868037a717d8efc11d4f1e1290cbf972202bae04ef4e6e6ea21cf227a8405c508c1d31f1bbb9e5667a21af9186984b28eee19a5e4395
|
7
|
+
data.tar.gz: eaae502337964abffe89643e4c1e6070f3a228db3ef6d87983f0cc7c9218f124e72eae6e502bd06ff7119fd594ed784d3f4232a3bd1ddb03c1d23f7bcce1c951
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.0</schema_version>
|
4
4
|
<name>tbd_measure</name>
|
5
5
|
<uid>8890787b-8c25-4dc8-8641-b6be1b6c2357</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>
|
6
|
+
<version_id>ca5db4f4-8624-4699-a544-609690a03d14</version_id>
|
7
|
+
<version_modified>20230322T224647Z</version_modified>
|
8
8
|
<xml_checksum>99772807</xml_checksum>
|
9
9
|
<class_name>TBDMeasure</class_name>
|
10
10
|
<display_name>Thermal Bridging and Derating - TBD</display_name>
|
@@ -429,24 +429,12 @@
|
|
429
429
|
<usage_type>test</usage_type>
|
430
430
|
<checksum>58ED6635</checksum>
|
431
431
|
</file>
|
432
|
-
<file>
|
433
|
-
<filename>geo.rb</filename>
|
434
|
-
<filetype>rb</filetype>
|
435
|
-
<usage_type>resource</usage_type>
|
436
|
-
<checksum>F447D8CE</checksum>
|
437
|
-
</file>
|
438
432
|
<file>
|
439
433
|
<filename>README.md</filename>
|
440
434
|
<filetype>md</filetype>
|
441
435
|
<usage_type>readme</usage_type>
|
442
436
|
<checksum>B836C43A</checksum>
|
443
437
|
</file>
|
444
|
-
<file>
|
445
|
-
<filename>ua.rb</filename>
|
446
|
-
<filetype>rb</filetype>
|
447
|
-
<usage_type>resource</usage_type>
|
448
|
-
<checksum>19193778</checksum>
|
449
|
-
</file>
|
450
438
|
<file>
|
451
439
|
<filename>psi.rb</filename>
|
452
440
|
<filetype>rb</filetype>
|
@@ -465,5 +453,17 @@
|
|
465
453
|
<usage_type>resource</usage_type>
|
466
454
|
<checksum>A3BB982A</checksum>
|
467
455
|
</file>
|
456
|
+
<file>
|
457
|
+
<filename>geo.rb</filename>
|
458
|
+
<filetype>rb</filetype>
|
459
|
+
<usage_type>resource</usage_type>
|
460
|
+
<checksum>8242FCEF</checksum>
|
461
|
+
</file>
|
462
|
+
<file>
|
463
|
+
<filename>ua.rb</filename>
|
464
|
+
<filetype>rb</filetype>
|
465
|
+
<usage_type>resource</usage_type>
|
466
|
+
<checksum>695F5AC2</checksum>
|
467
|
+
</file>
|
468
468
|
</files>
|
469
469
|
</measure>
|
@@ -292,28 +292,31 @@ module TBD
|
|
292
292
|
|
293
293
|
return mismatch("model", model, cl1, mth) unless model.is_a?(cl1)
|
294
294
|
return mismatch("surface", surface, cl2, mth) unless surface.is_a?(cl2)
|
295
|
-
|
296
|
-
return nil unless validate(surface)
|
295
|
+
return nil unless validate(surface)
|
297
296
|
|
298
297
|
nom = surface.nameString
|
299
298
|
surf = {}
|
300
299
|
subs = {}
|
301
300
|
fd = false
|
302
301
|
return empty("'#{nom}' space", mth, ERR) if surface.space.empty?
|
302
|
+
|
303
303
|
space = surface.space.get
|
304
304
|
stype = space.spaceType
|
305
305
|
story = space.buildingStory
|
306
306
|
tr = transforms(model, space)
|
307
307
|
return invalid("'#{nom}' transform", mth, 0, FTL) unless tr[:t] && tr[:r]
|
308
|
+
|
308
309
|
t = tr[:t]
|
309
310
|
n = trueNormal(surface, tr[:r])
|
310
311
|
return invalid("'#{nom}' normal", mth, 0, FTL) unless n
|
312
|
+
|
311
313
|
type = surface.surfaceType.downcase
|
312
314
|
facing = surface.outsideBoundaryCondition
|
313
315
|
|
314
316
|
if facing.downcase == "surface"
|
315
317
|
empty = surface.adjacentSurface.empty?
|
316
|
-
return invalid("'#{nom}': adjacent surface", mth, 0, ERR)
|
318
|
+
return invalid("'#{nom}': adjacent surface", mth, 0, ERR) if empty
|
319
|
+
|
317
320
|
facing = surface.adjacentSurface.get.nameString
|
318
321
|
end
|
319
322
|
|
@@ -350,6 +353,7 @@ module TBD
|
|
350
353
|
surf[:story ] = story.get unless story.empty?
|
351
354
|
surf[:n ] = n
|
352
355
|
surf[:gross ] = surface.grossArea
|
356
|
+
surf[:filmRSI ] = surface.filmResistance
|
353
357
|
|
354
358
|
surface.subSurfaces.sort_by { |s| s.nameString }.each do |s|
|
355
359
|
next unless validate(s)
|
@@ -39,13 +39,14 @@ module TBD
|
|
39
39
|
cl1 = OpenStudio::Model::Model
|
40
40
|
cl2 = OpenStudio::Model::LayeredConstruction
|
41
41
|
cl3 = Numeric
|
42
|
+
cl4 = String
|
42
43
|
|
43
|
-
return mismatch("model", model, cl1, mth, DBG, res)
|
44
|
-
return mismatch("id",
|
45
|
-
return mismatch("lc",
|
46
|
-
return mismatch("hloss", hloss, cl3, mth, DBG, res)
|
47
|
-
return mismatch("film",
|
48
|
-
return mismatch("Ut",
|
44
|
+
return mismatch("model", model, cl1, mth, DBG, res) unless model.is_a?(cl1)
|
45
|
+
return mismatch("id" , id, cl4, mth, DBG, res) unless id.is_a?(cl4)
|
46
|
+
return mismatch("lc" , lc, cl2, mth, DBG, res) unless lc.is_a?(cl2)
|
47
|
+
return mismatch("hloss", hloss, cl3, mth, DBG, res) unless hloss.is_a?(cl3)
|
48
|
+
return mismatch("film" , film, cl3, mth, DBG, res) unless film.is_a?(cl3)
|
49
|
+
return mismatch("Ut" , ut, cl3, mth, DBG, res) unless ut.is_a?(cl3)
|
49
50
|
|
50
51
|
loss = 0.0 # residual heatloss (not assigned) [W/K]
|
51
52
|
area = lc.getNetArea
|
@@ -54,12 +55,12 @@ module TBD
|
|
54
55
|
lyr[:index] = nil unless lyr[:index] >= 0
|
55
56
|
lyr[:index] = nil unless lyr[:index] < lc.layers.size
|
56
57
|
|
57
|
-
return invalid("'#{id}' layer index", mth, 0, ERR, res)
|
58
|
-
return zero("'#{id}': heatloss", mth,
|
59
|
-
return zero("'#{id}': films", mth,
|
60
|
-
return zero("'#{id}': Ut", mth,
|
61
|
-
return invalid("'#{id}': Ut", mth, 0, WRN, res)
|
62
|
-
return zero("'#{id}': net area (m2)", mth,
|
58
|
+
return invalid("'#{id}' layer index", mth, 0, ERR, res) unless lyr[:index]
|
59
|
+
return zero("'#{id}': heatloss" , mth, WRN, res) unless hloss > TOL
|
60
|
+
return zero("'#{id}': films" , mth, WRN, res) unless film > TOL
|
61
|
+
return zero("'#{id}': Ut" , mth, WRN, res) unless ut > TOL
|
62
|
+
return invalid("'#{id}': Ut" , mth, 0, WRN, res) unless ut < 5.678
|
63
|
+
return zero("'#{id}': net area (m2)", mth, ERR, res) unless area > TOL
|
63
64
|
|
64
65
|
# First, calculate initial layer RSi to initially meet Ut target.
|
65
66
|
rt = 1 / ut # target construction Rt
|
@@ -76,7 +77,7 @@ module TBD
|
|
76
77
|
|
77
78
|
if lyr[:type] == :massless
|
78
79
|
m = lc.getLayer(lyr[:index]).to_MasslessOpaqueMaterial
|
79
|
-
return invalid("'#{id}' massless layer?", mth, 0)
|
80
|
+
return invalid("'#{id}' massless layer?", mth, 0, DBG, res) if m.empty?
|
80
81
|
|
81
82
|
m = m.get.clone(model).to_MasslessOpaqueMaterial.get
|
82
83
|
m.setName("#{id} uprated")
|
@@ -85,7 +86,7 @@ module TBD
|
|
85
86
|
m.setThermalResistance(new_r)
|
86
87
|
else # type == :standard
|
87
88
|
m = lc.getLayer(lyr[:index]).to_StandardOpaqueMaterial
|
88
|
-
return invalid("'#{id}' standard layer?", mth, 0)
|
89
|
+
return invalid("'#{id}' standard layer?", mth, 0, DBG, res) if m.empty?
|
89
90
|
|
90
91
|
m = m.get.clone(model).to_StandardOpaqueMaterial.get
|
91
92
|
m.setName("#{id} uprated")
|
@@ -141,11 +142,12 @@ module TBD
|
|
141
142
|
mth = "TBD::#{__callee__}"
|
142
143
|
cl1 = OpenStudio::Model::Model
|
143
144
|
cl2 = Hash
|
145
|
+
cl3 = OpenStudio::Model::LayeredConstruction
|
144
146
|
a = false
|
145
147
|
|
146
|
-
return mismatch("model", model, cl1, mth, DBG, a)
|
147
|
-
return mismatch("surfaces",
|
148
|
-
return mismatch("argh", model, cl1, mth, DBG, a)
|
148
|
+
return mismatch("model" , model, cl1, mth, DBG, a) unless model.is_a?(cl1)
|
149
|
+
return mismatch("surfaces", s, cl2, mth, DBG, a) unless s.is_a?(cl2)
|
150
|
+
return mismatch("argh" , model, cl1, mth, DBG, a) unless argh.is_a?(cl2)
|
149
151
|
|
150
152
|
argh[:uprate_walls ] = false unless argh.key?(:uprate_walls )
|
151
153
|
argh[:uprate_roofs ] = false unless argh.key?(:uprate_roofs )
|
@@ -168,11 +170,13 @@ module TBD
|
|
168
170
|
groups[:roof ][:op] = argh[:roof_option ]
|
169
171
|
groups[:floor][:op] = argh[:floor_option ]
|
170
172
|
|
171
|
-
groups.each do |
|
173
|
+
groups.each do |type, g|
|
172
174
|
next unless g[:up]
|
173
175
|
next unless g[:ut].is_a?(Numeric)
|
174
176
|
next unless g[:ut] < 5.678
|
175
177
|
|
178
|
+
typ = type
|
179
|
+
typ = :ceiling if typ == :roof # fix in future revision. TO-DO.
|
176
180
|
coll = {}
|
177
181
|
area = 0
|
178
182
|
film = 100000000000000
|
@@ -183,86 +187,81 @@ module TBD
|
|
183
187
|
g[:op].downcase == "all floor constructions"
|
184
188
|
|
185
189
|
if g[:op].empty?
|
186
|
-
log(ERR, "Construction to uprate? (#{mth})")
|
190
|
+
log(ERR, "Construction (#{type}) to uprate? (#{mth})")
|
187
191
|
elsif all
|
188
|
-
|
189
|
-
next unless
|
190
|
-
next unless
|
191
|
-
next
|
192
|
-
next
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
192
|
+
s.each do |nom, surface|
|
193
|
+
next unless surface.key?(:deratable )
|
194
|
+
next unless surface.key?(:type )
|
195
|
+
next unless surface.key?(:construction)
|
196
|
+
next unless surface.key?(:filmRSI )
|
197
|
+
next unless surface.key?(:index )
|
198
|
+
next unless surface.key?(:ltype )
|
199
|
+
next unless surface.key?(:r )
|
200
|
+
next unless surface[:deratable ]
|
201
|
+
next unless surface[:type ] == typ
|
202
|
+
next unless surface[:construction].is_a?(cl3)
|
203
|
+
next if surface[:index ].nil?
|
204
|
+
|
205
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
206
|
+
c = surface[:construction]
|
207
|
+
i = c.nameString
|
208
|
+
aire = c.getNetArea
|
209
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
210
|
+
|
211
|
+
# Retain construction covering largest area. The following conditional
|
212
|
+
# is reliable UNLESS linked to other deratable surface types e.g. both
|
213
|
+
# floors AND walls (see "elsif lc" corrections below).
|
214
|
+
if aire > area
|
200
215
|
lc = c
|
216
|
+
area = aire
|
201
217
|
id = i
|
202
218
|
end
|
203
219
|
|
204
|
-
|
205
|
-
nom
|
206
|
-
coll[i] = { area: c.getNetArea, lc: c, s: {} } unless coll.key?(i)
|
207
|
-
coll[i][:s][nom] = { a: sss.netArea } unless coll[i][:s].key?(nom)
|
220
|
+
coll[i] = { area: aire, lc: c, s: {} } unless coll.key?(i)
|
221
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
208
222
|
end
|
209
223
|
else
|
210
224
|
id = g[:op]
|
211
|
-
|
212
|
-
|
213
|
-
if
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
225
|
+
lc = model.getConstructionByName(id)
|
226
|
+
log(ERR, "Construction '#{id}'? (#{mth})") if lc.empty?
|
227
|
+
next if lc.empty?
|
228
|
+
|
229
|
+
lc = lc.get.to_LayeredConstruction
|
230
|
+
log(ERR, "'#{id}' layered construction? (#{mth})") if lc.empty?
|
231
|
+
next if lc.empty?
|
232
|
+
|
233
|
+
lc = lc.get
|
234
|
+
area = lc.getNetArea
|
235
|
+
coll[id] = { area: area, lc: lc, s: {} }
|
236
|
+
|
237
|
+
s.each do |nom, surface|
|
238
|
+
next unless surface.key?(:deratable )
|
239
|
+
next unless surface.key?(:type )
|
240
|
+
next unless surface.key?(:construction)
|
241
|
+
next unless surface.key?(:filmRSI )
|
242
|
+
next unless surface.key?(:index )
|
243
|
+
next unless surface.key?(:ltype )
|
244
|
+
next unless surface.key?(:r )
|
245
|
+
next unless surface[:deratable ]
|
246
|
+
next unless surface[:type ] == typ
|
247
|
+
next unless surface[:construction].is_a?(cl3)
|
248
|
+
next if surface[:index ].nil?
|
249
|
+
|
250
|
+
i = surface[:construction].nameString
|
251
|
+
next unless i == id
|
252
|
+
|
253
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
254
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
255
|
+
|
256
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
238
257
|
end
|
239
258
|
end
|
240
259
|
|
241
260
|
if coll.empty?
|
242
|
-
log(ERR, "No #{
|
261
|
+
log(ERR, "No #{type} construction to uprate - skipping (#{mth})")
|
243
262
|
next
|
244
|
-
elsif lc
|
245
|
-
#
|
246
|
-
model.getSurfaces.each do |sss|
|
247
|
-
next if sss.construction.empty?
|
248
|
-
next if sss.construction.get.to_LayeredConstruction.empty?
|
249
|
-
c = sss.construction.get.to_LayeredConstruction.get
|
250
|
-
i = c.nameString
|
251
|
-
next unless coll.key?(i)
|
252
|
-
|
253
|
-
unless sss.surfaceType.downcase.include?(label.to_s)
|
254
|
-
log(ERR, "Uprating #{label.to_s}, not '#{sss.nameString}' (#{mth})")
|
255
|
-
cloned = c.clone(model).to_LayeredConstruction.get
|
256
|
-
cloned.setName("'#{i}' cloned")
|
257
|
-
sss.setConstruction(cloned)
|
258
|
-
ok = s.key?(sss.nameString)
|
259
|
-
s[sss.nameString][:construction] = cloned if ok
|
260
|
-
coll[i][:s].delete(sss.nameString)
|
261
|
-
coll[i][:area] = c.getNetArea
|
262
|
-
next
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
263
|
+
elsif lc
|
264
|
+
# Valid layered construction - good to uprate!
|
266
265
|
lyr = insulatingLayer(lc)
|
267
266
|
lyr[:index] = nil unless lyr[:index].is_a?(Numeric)
|
268
267
|
lyr[:index] = nil unless lyr[:index] >= 0
|
@@ -270,64 +269,81 @@ module TBD
|
|
270
269
|
|
271
270
|
log(ERR, "Insulation index for '#{id}'? (#{mth})") unless lyr[:index]
|
272
271
|
next unless lyr[:index]
|
273
|
-
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
274
272
|
|
275
|
-
|
276
|
-
|
277
|
-
|
273
|
+
# Ensure lc is exclusively linked to deratable surfaces of right type.
|
274
|
+
# If not, assign new lc clone to non-targeted surfaces.
|
275
|
+
s.each do |nom, surface|
|
276
|
+
next unless surface.key?(:type )
|
277
|
+
next unless surface.key?(:deratable )
|
278
|
+
next unless surface.key?(:construction)
|
279
|
+
next unless surface[:construction].is_a?(cl3)
|
280
|
+
next unless surface[:construction] == lc
|
281
|
+
|
282
|
+
ok = true
|
283
|
+
ok = false unless surface[:type ] == typ
|
284
|
+
ok = false unless surface[:deratable]
|
285
|
+
ok = false unless coll.key?(id)
|
286
|
+
ok = false unless coll[id][:s].key?(nom)
|
287
|
+
|
288
|
+
unless ok
|
289
|
+
log(WRN, "Cloning '#{nom}' construction - not '#{id}' (#{mth})")
|
290
|
+
sss = model.getSurfaceByName(nom)
|
291
|
+
next if sss.empty?
|
292
|
+
|
293
|
+
sss = sss.get
|
294
|
+
cloned = lc.clone(model).to_LayeredConstruction.get
|
295
|
+
cloned.setName("#{nom} - cloned")
|
296
|
+
sss.setConstruction(cloned)
|
297
|
+
surface[:construction] = cloned
|
298
|
+
coll[id][:s].delete(nom)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
278
303
|
|
304
|
+
# Tally applicable psi + khi losses. Possible construction reassignment.
|
305
|
+
coll.each do |i, col|
|
279
306
|
col[:s].keys.each do |nom|
|
280
307
|
next unless s.key?(nom)
|
281
|
-
next unless s[nom].key?(:deratable )
|
282
308
|
next unless s[nom].key?(:construction)
|
283
309
|
next unless s[nom].key?(:index )
|
284
310
|
next unless s[nom].key?(:ltype )
|
285
311
|
next unless s[nom].key?(:r )
|
286
|
-
next unless s[nom].key?(:type )
|
287
|
-
|
288
|
-
next unless s[nom][:deratable]
|
289
|
-
type = s[nom][:type].to_s.downcase
|
290
|
-
type = "roof" if type == "ceiling"
|
291
|
-
next unless type.include?(label.to_s)
|
292
312
|
|
293
313
|
# Tally applicable psi + khi.
|
294
|
-
hloss += s[nom][:heatloss] if s[nom].key?(:heatloss)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
sss = sss.get
|
301
|
-
|
302
|
-
if sss.isConstructionDefaulted
|
303
|
-
set = defaultConstructionSet(model, sss)
|
304
|
-
constructions = set.defaultExteriorSurfaceConstructions.get
|
305
|
-
|
306
|
-
case sss.surfaceType.downcase
|
307
|
-
when "roofceiling"
|
308
|
-
constructions.setRoofCeilingConstruction(lc)
|
309
|
-
when "floor"
|
310
|
-
constructions.setFloorConstruction(lc)
|
311
|
-
else
|
312
|
-
constructions.setWallConstruction(lc)
|
313
|
-
end
|
314
|
-
else
|
315
|
-
sss.setConstruction(lc)
|
316
|
-
end
|
314
|
+
hloss += s[nom][:heatloss ] if s[nom].key?(:heatloss)
|
315
|
+
next if s[nom][:construction] == lc
|
316
|
+
|
317
|
+
# Reassign construction unless referencing lc.
|
318
|
+
sss = model.getSurfaceByName(nom)
|
319
|
+
next if sss.empty?
|
317
320
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
321
|
+
sss = sss.get
|
322
|
+
|
323
|
+
if sss.isConstructionDefaulted
|
324
|
+
set = defaultConstructionSet(model, sss) # building? story?
|
325
|
+
constructions = set.defaultExteriorSurfaceConstructions
|
326
|
+
|
327
|
+
unless constructions.empty?
|
328
|
+
constructions = constructions.get
|
329
|
+
constructions.setWallConstruction(lc) if typ == :wall
|
330
|
+
constructions.setFloorConstruction(lc) if typ == :floor
|
331
|
+
constructions.setRoofCeilingConstruction(lc) if typ == :ceiling
|
332
|
+
end
|
333
|
+
else
|
334
|
+
sss.setConstruction(lc)
|
322
335
|
end
|
336
|
+
|
337
|
+
s[nom][:construction] = lc # reset TBD attributes
|
338
|
+
s[nom][:index ] = lyr[:index]
|
339
|
+
s[nom][:ltype ] = lyr[:type ]
|
340
|
+
s[nom][:r ] = lyr[:r ] # temporary
|
323
341
|
end
|
324
342
|
end
|
325
343
|
|
326
344
|
# Merge to ensure a single entry for coll Hash.
|
327
345
|
coll.each do |i, col|
|
328
346
|
next if i == id
|
329
|
-
next unless coll.key?(id)
|
330
|
-
coll[id][:area] += col[:area]
|
331
347
|
|
332
348
|
col[:s].each do |nom, sss|
|
333
349
|
coll[id][:s][nom] = sss unless coll[id][:s].key?(nom)
|
@@ -338,6 +354,8 @@ module TBD
|
|
338
354
|
log(DBG, "Collection == 1? for '#{id}' (#{mth})") unless coll.size == 1
|
339
355
|
next unless coll.size == 1
|
340
356
|
|
357
|
+
area = lc.getNetArea
|
358
|
+
coll[id][:area] = area
|
341
359
|
res = uo(model, lc, id, hloss, film, g[:ut])
|
342
360
|
log(ERR, "Unable to uprate '#{id}' (#{mth})") unless res[:uo] && res[:m]
|
343
361
|
next unless res[:uo] && res[:m]
|
@@ -347,27 +365,18 @@ module TBD
|
|
347
365
|
# Loop through coll :s, and reset :r - likely modified by uo().
|
348
366
|
coll.values.first[:s].keys.each do |nom|
|
349
367
|
next unless s.key?(nom)
|
350
|
-
next unless s[nom].key?(:
|
351
|
-
next unless s[nom].key?(:
|
352
|
-
next unless s[nom].key?(:
|
353
|
-
next unless s[nom]
|
354
|
-
next unless s[nom]
|
355
|
-
|
356
|
-
|
357
|
-
next unless s[nom][:construction] == lc
|
358
|
-
next unless s[nom][:index ] == lyr[:index]
|
359
|
-
next unless s[nom][:ltype ] == lyr[:type]
|
360
|
-
|
361
|
-
type = s[nom][:type].to_s.downcase
|
362
|
-
type = "roof" if type == "ceiling"
|
363
|
-
next unless type.include?(label.to_s)
|
364
|
-
next unless s[nom].key?(:r)
|
365
|
-
s[nom][:r] = lyr[:r] # final
|
368
|
+
next unless s[nom].key?(:index)
|
369
|
+
next unless s[nom].key?(:ltype)
|
370
|
+
next unless s[nom].key?(:r )
|
371
|
+
next unless s[nom][:index] == lyr[:index]
|
372
|
+
next unless s[nom][:ltype] == lyr[:type ]
|
373
|
+
|
374
|
+
s[nom][:r] = lyr[:r] # uprated insulating RSi factor, before derating
|
366
375
|
end
|
367
376
|
|
368
|
-
argh[:wall_uo ] = res[:uo] if
|
369
|
-
argh[:roof_uo ] = res[:uo] if
|
370
|
-
argh[:floor_uo] = res[:uo] if
|
377
|
+
argh[:wall_uo ] = res[:uo] if typ == :wall
|
378
|
+
argh[:roof_uo ] = res[:uo] if typ == :ceiling
|
379
|
+
argh[:floor_uo] = res[:uo] if typ == :floor
|
371
380
|
else
|
372
381
|
log(ERR, "Nilled construction to uprate - (#{mth})")
|
373
382
|
return false
|
@@ -920,7 +929,7 @@ module TBD
|
|
920
929
|
model = "* modèle : #{ua[:file]}" if ua.key?(:file) && lang == :fr
|
921
930
|
model += " (v#{ua[:version]})" if ua.key?(:version)
|
922
931
|
report << model unless model.empty?
|
923
|
-
report << "* TBD : v3.2.
|
932
|
+
report << "* TBD : v3.2.2"
|
924
933
|
report << "* date : #{ua[:date]}"
|
925
934
|
|
926
935
|
if lang == :en
|
data/lib/tbd/geo.rb
CHANGED
@@ -292,28 +292,31 @@ module TBD
|
|
292
292
|
|
293
293
|
return mismatch("model", model, cl1, mth) unless model.is_a?(cl1)
|
294
294
|
return mismatch("surface", surface, cl2, mth) unless surface.is_a?(cl2)
|
295
|
-
|
296
|
-
return nil unless validate(surface)
|
295
|
+
return nil unless validate(surface)
|
297
296
|
|
298
297
|
nom = surface.nameString
|
299
298
|
surf = {}
|
300
299
|
subs = {}
|
301
300
|
fd = false
|
302
301
|
return empty("'#{nom}' space", mth, ERR) if surface.space.empty?
|
302
|
+
|
303
303
|
space = surface.space.get
|
304
304
|
stype = space.spaceType
|
305
305
|
story = space.buildingStory
|
306
306
|
tr = transforms(model, space)
|
307
307
|
return invalid("'#{nom}' transform", mth, 0, FTL) unless tr[:t] && tr[:r]
|
308
|
+
|
308
309
|
t = tr[:t]
|
309
310
|
n = trueNormal(surface, tr[:r])
|
310
311
|
return invalid("'#{nom}' normal", mth, 0, FTL) unless n
|
312
|
+
|
311
313
|
type = surface.surfaceType.downcase
|
312
314
|
facing = surface.outsideBoundaryCondition
|
313
315
|
|
314
316
|
if facing.downcase == "surface"
|
315
317
|
empty = surface.adjacentSurface.empty?
|
316
|
-
return invalid("'#{nom}': adjacent surface", mth, 0, ERR)
|
318
|
+
return invalid("'#{nom}': adjacent surface", mth, 0, ERR) if empty
|
319
|
+
|
317
320
|
facing = surface.adjacentSurface.get.nameString
|
318
321
|
end
|
319
322
|
|
@@ -350,6 +353,7 @@ module TBD
|
|
350
353
|
surf[:story ] = story.get unless story.empty?
|
351
354
|
surf[:n ] = n
|
352
355
|
surf[:gross ] = surface.grossArea
|
356
|
+
surf[:filmRSI ] = surface.filmResistance
|
353
357
|
|
354
358
|
surface.subSurfaces.sort_by { |s| s.nameString }.each do |s|
|
355
359
|
next unless validate(s)
|
data/lib/tbd/ua.rb
CHANGED
@@ -39,13 +39,14 @@ module TBD
|
|
39
39
|
cl1 = OpenStudio::Model::Model
|
40
40
|
cl2 = OpenStudio::Model::LayeredConstruction
|
41
41
|
cl3 = Numeric
|
42
|
+
cl4 = String
|
42
43
|
|
43
|
-
return mismatch("model", model, cl1, mth, DBG, res)
|
44
|
-
return mismatch("id",
|
45
|
-
return mismatch("lc",
|
46
|
-
return mismatch("hloss", hloss, cl3, mth, DBG, res)
|
47
|
-
return mismatch("film",
|
48
|
-
return mismatch("Ut",
|
44
|
+
return mismatch("model", model, cl1, mth, DBG, res) unless model.is_a?(cl1)
|
45
|
+
return mismatch("id" , id, cl4, mth, DBG, res) unless id.is_a?(cl4)
|
46
|
+
return mismatch("lc" , lc, cl2, mth, DBG, res) unless lc.is_a?(cl2)
|
47
|
+
return mismatch("hloss", hloss, cl3, mth, DBG, res) unless hloss.is_a?(cl3)
|
48
|
+
return mismatch("film" , film, cl3, mth, DBG, res) unless film.is_a?(cl3)
|
49
|
+
return mismatch("Ut" , ut, cl3, mth, DBG, res) unless ut.is_a?(cl3)
|
49
50
|
|
50
51
|
loss = 0.0 # residual heatloss (not assigned) [W/K]
|
51
52
|
area = lc.getNetArea
|
@@ -54,12 +55,12 @@ module TBD
|
|
54
55
|
lyr[:index] = nil unless lyr[:index] >= 0
|
55
56
|
lyr[:index] = nil unless lyr[:index] < lc.layers.size
|
56
57
|
|
57
|
-
return invalid("'#{id}' layer index", mth, 0, ERR, res)
|
58
|
-
return zero("'#{id}': heatloss", mth,
|
59
|
-
return zero("'#{id}': films", mth,
|
60
|
-
return zero("'#{id}': Ut", mth,
|
61
|
-
return invalid("'#{id}': Ut", mth, 0, WRN, res)
|
62
|
-
return zero("'#{id}': net area (m2)", mth,
|
58
|
+
return invalid("'#{id}' layer index", mth, 0, ERR, res) unless lyr[:index]
|
59
|
+
return zero("'#{id}': heatloss" , mth, WRN, res) unless hloss > TOL
|
60
|
+
return zero("'#{id}': films" , mth, WRN, res) unless film > TOL
|
61
|
+
return zero("'#{id}': Ut" , mth, WRN, res) unless ut > TOL
|
62
|
+
return invalid("'#{id}': Ut" , mth, 0, WRN, res) unless ut < 5.678
|
63
|
+
return zero("'#{id}': net area (m2)", mth, ERR, res) unless area > TOL
|
63
64
|
|
64
65
|
# First, calculate initial layer RSi to initially meet Ut target.
|
65
66
|
rt = 1 / ut # target construction Rt
|
@@ -76,7 +77,7 @@ module TBD
|
|
76
77
|
|
77
78
|
if lyr[:type] == :massless
|
78
79
|
m = lc.getLayer(lyr[:index]).to_MasslessOpaqueMaterial
|
79
|
-
return invalid("'#{id}' massless layer?", mth, 0)
|
80
|
+
return invalid("'#{id}' massless layer?", mth, 0, DBG, res) if m.empty?
|
80
81
|
|
81
82
|
m = m.get.clone(model).to_MasslessOpaqueMaterial.get
|
82
83
|
m.setName("#{id} uprated")
|
@@ -85,7 +86,7 @@ module TBD
|
|
85
86
|
m.setThermalResistance(new_r)
|
86
87
|
else # type == :standard
|
87
88
|
m = lc.getLayer(lyr[:index]).to_StandardOpaqueMaterial
|
88
|
-
return invalid("'#{id}' standard layer?", mth, 0)
|
89
|
+
return invalid("'#{id}' standard layer?", mth, 0, DBG, res) if m.empty?
|
89
90
|
|
90
91
|
m = m.get.clone(model).to_StandardOpaqueMaterial.get
|
91
92
|
m.setName("#{id} uprated")
|
@@ -141,11 +142,12 @@ module TBD
|
|
141
142
|
mth = "TBD::#{__callee__}"
|
142
143
|
cl1 = OpenStudio::Model::Model
|
143
144
|
cl2 = Hash
|
145
|
+
cl3 = OpenStudio::Model::LayeredConstruction
|
144
146
|
a = false
|
145
147
|
|
146
|
-
return mismatch("model", model, cl1, mth, DBG, a)
|
147
|
-
return mismatch("surfaces",
|
148
|
-
return mismatch("argh", model, cl1, mth, DBG, a)
|
148
|
+
return mismatch("model" , model, cl1, mth, DBG, a) unless model.is_a?(cl1)
|
149
|
+
return mismatch("surfaces", s, cl2, mth, DBG, a) unless s.is_a?(cl2)
|
150
|
+
return mismatch("argh" , model, cl1, mth, DBG, a) unless argh.is_a?(cl2)
|
149
151
|
|
150
152
|
argh[:uprate_walls ] = false unless argh.key?(:uprate_walls )
|
151
153
|
argh[:uprate_roofs ] = false unless argh.key?(:uprate_roofs )
|
@@ -168,11 +170,13 @@ module TBD
|
|
168
170
|
groups[:roof ][:op] = argh[:roof_option ]
|
169
171
|
groups[:floor][:op] = argh[:floor_option ]
|
170
172
|
|
171
|
-
groups.each do |
|
173
|
+
groups.each do |type, g|
|
172
174
|
next unless g[:up]
|
173
175
|
next unless g[:ut].is_a?(Numeric)
|
174
176
|
next unless g[:ut] < 5.678
|
175
177
|
|
178
|
+
typ = type
|
179
|
+
typ = :ceiling if typ == :roof # fix in future revision. TO-DO.
|
176
180
|
coll = {}
|
177
181
|
area = 0
|
178
182
|
film = 100000000000000
|
@@ -183,86 +187,81 @@ module TBD
|
|
183
187
|
g[:op].downcase == "all floor constructions"
|
184
188
|
|
185
189
|
if g[:op].empty?
|
186
|
-
log(ERR, "Construction to uprate? (#{mth})")
|
190
|
+
log(ERR, "Construction (#{type}) to uprate? (#{mth})")
|
187
191
|
elsif all
|
188
|
-
|
189
|
-
next unless
|
190
|
-
next unless
|
191
|
-
next
|
192
|
-
next
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
192
|
+
s.each do |nom, surface|
|
193
|
+
next unless surface.key?(:deratable )
|
194
|
+
next unless surface.key?(:type )
|
195
|
+
next unless surface.key?(:construction)
|
196
|
+
next unless surface.key?(:filmRSI )
|
197
|
+
next unless surface.key?(:index )
|
198
|
+
next unless surface.key?(:ltype )
|
199
|
+
next unless surface.key?(:r )
|
200
|
+
next unless surface[:deratable ]
|
201
|
+
next unless surface[:type ] == typ
|
202
|
+
next unless surface[:construction].is_a?(cl3)
|
203
|
+
next if surface[:index ].nil?
|
204
|
+
|
205
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
206
|
+
c = surface[:construction]
|
207
|
+
i = c.nameString
|
208
|
+
aire = c.getNetArea
|
209
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
210
|
+
|
211
|
+
# Retain construction covering largest area. The following conditional
|
212
|
+
# is reliable UNLESS linked to other deratable surface types e.g. both
|
213
|
+
# floors AND walls (see "elsif lc" corrections below).
|
214
|
+
if aire > area
|
200
215
|
lc = c
|
216
|
+
area = aire
|
201
217
|
id = i
|
202
218
|
end
|
203
219
|
|
204
|
-
|
205
|
-
nom
|
206
|
-
coll[i] = { area: c.getNetArea, lc: c, s: {} } unless coll.key?(i)
|
207
|
-
coll[i][:s][nom] = { a: sss.netArea } unless coll[i][:s].key?(nom)
|
220
|
+
coll[i] = { area: aire, lc: c, s: {} } unless coll.key?(i)
|
221
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
208
222
|
end
|
209
223
|
else
|
210
224
|
id = g[:op]
|
211
|
-
|
212
|
-
|
213
|
-
if
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
225
|
+
lc = model.getConstructionByName(id)
|
226
|
+
log(ERR, "Construction '#{id}'? (#{mth})") if lc.empty?
|
227
|
+
next if lc.empty?
|
228
|
+
|
229
|
+
lc = lc.get.to_LayeredConstruction
|
230
|
+
log(ERR, "'#{id}' layered construction? (#{mth})") if lc.empty?
|
231
|
+
next if lc.empty?
|
232
|
+
|
233
|
+
lc = lc.get
|
234
|
+
area = lc.getNetArea
|
235
|
+
coll[id] = { area: area, lc: lc, s: {} }
|
236
|
+
|
237
|
+
s.each do |nom, surface|
|
238
|
+
next unless surface.key?(:deratable )
|
239
|
+
next unless surface.key?(:type )
|
240
|
+
next unless surface.key?(:construction)
|
241
|
+
next unless surface.key?(:filmRSI )
|
242
|
+
next unless surface.key?(:index )
|
243
|
+
next unless surface.key?(:ltype )
|
244
|
+
next unless surface.key?(:r )
|
245
|
+
next unless surface[:deratable ]
|
246
|
+
next unless surface[:type ] == typ
|
247
|
+
next unless surface[:construction].is_a?(cl3)
|
248
|
+
next if surface[:index ].nil?
|
249
|
+
|
250
|
+
i = surface[:construction].nameString
|
251
|
+
next unless i == id
|
252
|
+
|
253
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
254
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
255
|
+
|
256
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
238
257
|
end
|
239
258
|
end
|
240
259
|
|
241
260
|
if coll.empty?
|
242
|
-
log(ERR, "No #{
|
261
|
+
log(ERR, "No #{type} construction to uprate - skipping (#{mth})")
|
243
262
|
next
|
244
|
-
elsif lc
|
245
|
-
#
|
246
|
-
model.getSurfaces.each do |sss|
|
247
|
-
next if sss.construction.empty?
|
248
|
-
next if sss.construction.get.to_LayeredConstruction.empty?
|
249
|
-
c = sss.construction.get.to_LayeredConstruction.get
|
250
|
-
i = c.nameString
|
251
|
-
next unless coll.key?(i)
|
252
|
-
|
253
|
-
unless sss.surfaceType.downcase.include?(label.to_s)
|
254
|
-
log(ERR, "Uprating #{label.to_s}, not '#{sss.nameString}' (#{mth})")
|
255
|
-
cloned = c.clone(model).to_LayeredConstruction.get
|
256
|
-
cloned.setName("'#{i}' cloned")
|
257
|
-
sss.setConstruction(cloned)
|
258
|
-
ok = s.key?(sss.nameString)
|
259
|
-
s[sss.nameString][:construction] = cloned if ok
|
260
|
-
coll[i][:s].delete(sss.nameString)
|
261
|
-
coll[i][:area] = c.getNetArea
|
262
|
-
next
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
263
|
+
elsif lc
|
264
|
+
# Valid layered construction - good to uprate!
|
266
265
|
lyr = insulatingLayer(lc)
|
267
266
|
lyr[:index] = nil unless lyr[:index].is_a?(Numeric)
|
268
267
|
lyr[:index] = nil unless lyr[:index] >= 0
|
@@ -270,64 +269,81 @@ module TBD
|
|
270
269
|
|
271
270
|
log(ERR, "Insulation index for '#{id}'? (#{mth})") unless lyr[:index]
|
272
271
|
next unless lyr[:index]
|
273
|
-
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
274
272
|
|
275
|
-
|
276
|
-
|
277
|
-
|
273
|
+
# Ensure lc is exclusively linked to deratable surfaces of right type.
|
274
|
+
# If not, assign new lc clone to non-targeted surfaces.
|
275
|
+
s.each do |nom, surface|
|
276
|
+
next unless surface.key?(:type )
|
277
|
+
next unless surface.key?(:deratable )
|
278
|
+
next unless surface.key?(:construction)
|
279
|
+
next unless surface[:construction].is_a?(cl3)
|
280
|
+
next unless surface[:construction] == lc
|
281
|
+
|
282
|
+
ok = true
|
283
|
+
ok = false unless surface[:type ] == typ
|
284
|
+
ok = false unless surface[:deratable]
|
285
|
+
ok = false unless coll.key?(id)
|
286
|
+
ok = false unless coll[id][:s].key?(nom)
|
287
|
+
|
288
|
+
unless ok
|
289
|
+
log(WRN, "Cloning '#{nom}' construction - not '#{id}' (#{mth})")
|
290
|
+
sss = model.getSurfaceByName(nom)
|
291
|
+
next if sss.empty?
|
292
|
+
|
293
|
+
sss = sss.get
|
294
|
+
cloned = lc.clone(model).to_LayeredConstruction.get
|
295
|
+
cloned.setName("#{nom} - cloned")
|
296
|
+
sss.setConstruction(cloned)
|
297
|
+
surface[:construction] = cloned
|
298
|
+
coll[id][:s].delete(nom)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
278
303
|
|
304
|
+
# Tally applicable psi + khi losses. Possible construction reassignment.
|
305
|
+
coll.each do |i, col|
|
279
306
|
col[:s].keys.each do |nom|
|
280
307
|
next unless s.key?(nom)
|
281
|
-
next unless s[nom].key?(:deratable )
|
282
308
|
next unless s[nom].key?(:construction)
|
283
309
|
next unless s[nom].key?(:index )
|
284
310
|
next unless s[nom].key?(:ltype )
|
285
311
|
next unless s[nom].key?(:r )
|
286
|
-
next unless s[nom].key?(:type )
|
287
|
-
|
288
|
-
next unless s[nom][:deratable]
|
289
|
-
type = s[nom][:type].to_s.downcase
|
290
|
-
type = "roof" if type == "ceiling"
|
291
|
-
next unless type.include?(label.to_s)
|
292
312
|
|
293
313
|
# Tally applicable psi + khi.
|
294
|
-
hloss += s[nom][:heatloss] if s[nom].key?(:heatloss)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
sss = sss.get
|
301
|
-
|
302
|
-
if sss.isConstructionDefaulted
|
303
|
-
set = defaultConstructionSet(model, sss)
|
304
|
-
constructions = set.defaultExteriorSurfaceConstructions.get
|
305
|
-
|
306
|
-
case sss.surfaceType.downcase
|
307
|
-
when "roofceiling"
|
308
|
-
constructions.setRoofCeilingConstruction(lc)
|
309
|
-
when "floor"
|
310
|
-
constructions.setFloorConstruction(lc)
|
311
|
-
else
|
312
|
-
constructions.setWallConstruction(lc)
|
313
|
-
end
|
314
|
-
else
|
315
|
-
sss.setConstruction(lc)
|
316
|
-
end
|
314
|
+
hloss += s[nom][:heatloss ] if s[nom].key?(:heatloss)
|
315
|
+
next if s[nom][:construction] == lc
|
316
|
+
|
317
|
+
# Reassign construction unless referencing lc.
|
318
|
+
sss = model.getSurfaceByName(nom)
|
319
|
+
next if sss.empty?
|
317
320
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
321
|
+
sss = sss.get
|
322
|
+
|
323
|
+
if sss.isConstructionDefaulted
|
324
|
+
set = defaultConstructionSet(model, sss) # building? story?
|
325
|
+
constructions = set.defaultExteriorSurfaceConstructions
|
326
|
+
|
327
|
+
unless constructions.empty?
|
328
|
+
constructions = constructions.get
|
329
|
+
constructions.setWallConstruction(lc) if typ == :wall
|
330
|
+
constructions.setFloorConstruction(lc) if typ == :floor
|
331
|
+
constructions.setRoofCeilingConstruction(lc) if typ == :ceiling
|
332
|
+
end
|
333
|
+
else
|
334
|
+
sss.setConstruction(lc)
|
322
335
|
end
|
336
|
+
|
337
|
+
s[nom][:construction] = lc # reset TBD attributes
|
338
|
+
s[nom][:index ] = lyr[:index]
|
339
|
+
s[nom][:ltype ] = lyr[:type ]
|
340
|
+
s[nom][:r ] = lyr[:r ] # temporary
|
323
341
|
end
|
324
342
|
end
|
325
343
|
|
326
344
|
# Merge to ensure a single entry for coll Hash.
|
327
345
|
coll.each do |i, col|
|
328
346
|
next if i == id
|
329
|
-
next unless coll.key?(id)
|
330
|
-
coll[id][:area] += col[:area]
|
331
347
|
|
332
348
|
col[:s].each do |nom, sss|
|
333
349
|
coll[id][:s][nom] = sss unless coll[id][:s].key?(nom)
|
@@ -338,6 +354,8 @@ module TBD
|
|
338
354
|
log(DBG, "Collection == 1? for '#{id}' (#{mth})") unless coll.size == 1
|
339
355
|
next unless coll.size == 1
|
340
356
|
|
357
|
+
area = lc.getNetArea
|
358
|
+
coll[id][:area] = area
|
341
359
|
res = uo(model, lc, id, hloss, film, g[:ut])
|
342
360
|
log(ERR, "Unable to uprate '#{id}' (#{mth})") unless res[:uo] && res[:m]
|
343
361
|
next unless res[:uo] && res[:m]
|
@@ -347,27 +365,18 @@ module TBD
|
|
347
365
|
# Loop through coll :s, and reset :r - likely modified by uo().
|
348
366
|
coll.values.first[:s].keys.each do |nom|
|
349
367
|
next unless s.key?(nom)
|
350
|
-
next unless s[nom].key?(:
|
351
|
-
next unless s[nom].key?(:
|
352
|
-
next unless s[nom].key?(:
|
353
|
-
next unless s[nom]
|
354
|
-
next unless s[nom]
|
355
|
-
|
356
|
-
|
357
|
-
next unless s[nom][:construction] == lc
|
358
|
-
next unless s[nom][:index ] == lyr[:index]
|
359
|
-
next unless s[nom][:ltype ] == lyr[:type]
|
360
|
-
|
361
|
-
type = s[nom][:type].to_s.downcase
|
362
|
-
type = "roof" if type == "ceiling"
|
363
|
-
next unless type.include?(label.to_s)
|
364
|
-
next unless s[nom].key?(:r)
|
365
|
-
s[nom][:r] = lyr[:r] # final
|
368
|
+
next unless s[nom].key?(:index)
|
369
|
+
next unless s[nom].key?(:ltype)
|
370
|
+
next unless s[nom].key?(:r )
|
371
|
+
next unless s[nom][:index] == lyr[:index]
|
372
|
+
next unless s[nom][:ltype] == lyr[:type ]
|
373
|
+
|
374
|
+
s[nom][:r] = lyr[:r] # uprated insulating RSi factor, before derating
|
366
375
|
end
|
367
376
|
|
368
|
-
argh[:wall_uo ] = res[:uo] if
|
369
|
-
argh[:roof_uo ] = res[:uo] if
|
370
|
-
argh[:floor_uo] = res[:uo] if
|
377
|
+
argh[:wall_uo ] = res[:uo] if typ == :wall
|
378
|
+
argh[:roof_uo ] = res[:uo] if typ == :ceiling
|
379
|
+
argh[:floor_uo] = res[:uo] if typ == :floor
|
371
380
|
else
|
372
381
|
log(ERR, "Nilled construction to uprate - (#{mth})")
|
373
382
|
return false
|
@@ -920,7 +929,7 @@ module TBD
|
|
920
929
|
model = "* modèle : #{ua[:file]}" if ua.key?(:file) && lang == :fr
|
921
930
|
model += " (v#{ua[:version]})" if ua.key?(:version)
|
922
931
|
report << model unless model.empty?
|
923
|
-
report << "* TBD : v3.2.
|
932
|
+
report << "* TBD : v3.2.2"
|
924
933
|
report << "* date : #{ua[:date]}"
|
925
934
|
|
926
935
|
if lang == :en
|
data/lib/tbd/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tbd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Bourgeois & Dan Macumber
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: topolys
|
@@ -161,7 +161,7 @@ licenses:
|
|
161
161
|
- MIT
|
162
162
|
metadata:
|
163
163
|
homepage_uri: https://github.com/rd2/tbd
|
164
|
-
source_code_uri: https://github.com/rd2/tbd/tree/v3.2.
|
164
|
+
source_code_uri: https://github.com/rd2/tbd/tree/v3.2.2
|
165
165
|
bug_tracker_uri: https://github.com/rd2/tbd/issues
|
166
166
|
post_install_message:
|
167
167
|
rdoc_options: []
|