tbd 3.2.1 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|