Skip to content

Commit acab8ae

Browse files
authored
Merge pull request #26 from rd2/reset_uo
Harmonizes use of resetUo() in genConstruction() with pyOSut
2 parents 427aed1 + 4756630 commit acab8ae

5 files changed

Lines changed: 26 additions & 38 deletions

File tree

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 3-Clause License
22

3-
Copyright (c) 2022-2025, Denis Bourgeois
3+
Copyright (c) 2022-2026, Denis Bourgeois
44
All rights reserved.
55

66
Redistribution and use in source and binary forms, with or without

lib/osut.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# BSD 3-Clause License
22
#
3-
# Copyright (c) 2022-2025, Denis Bourgeois
3+
# Copyright (c) 2022-2026, Denis Bourgeois
44
# All rights reserved.
55
#
66
# Redistribution and use in source and binary forms, with or without

lib/osut/utils.rb

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# BSD 3-Clause License
22
#
3-
# Copyright (c) 2022-2025, Denis Bourgeois
3+
# Copyright (c) 2022-2026, Denis Bourgeois
44
# All rights reserved.
55
#
66
# Redistribution and use in source and binary forms, with or without
@@ -530,7 +530,7 @@ def resetUo(lc = nil, film = nil, index = nil, uo = nil, uniq = false)
530530
mt.setName(id)
531531

532532
unless mt.setThermalResistance(r)
533-
return invalid("Failed #{id}: RSi#{de_r.round(2)}", mth)
533+
return invalid("Failed #{id}: RSi#{r.round(2)}", mth)
534534
end
535535

536536
lc.setLayer(index, mt)
@@ -546,7 +546,7 @@ def resetUo(lc = nil, film = nil, index = nil, uo = nil, uniq = false)
546546
k = (m.thickness / (r + dR)).clamp(KMIN, KMAX)
547547
d = (k * (r + dR)).clamp(DMIN, DMAX)
548548
r = d / k
549-
id = "OSUT:K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
549+
id = "OSut:K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
550550
mt = lc.model.getStandardOpaqueMaterialByName(id)
551551

552552
# Existing material?
@@ -928,7 +928,6 @@ def genConstruction(model = nil, specs = {})
928928
if u and a[:glazing].empty?
929929
ro = 1 / u - film
930930

931-
932931
if ro > RMIN
933932
if specs[:type] == :door # 1x layer, adjust conductivity
934933
layer = c.getLayer(0).to_StandardOpaqueMaterial
@@ -944,27 +943,7 @@ def genConstruction(model = nil, specs = {})
944943
return invalid("#{id} construction", mth, 0) if lyr[:r ].to_i.zero?
945944

946945
index = lyr[:index]
947-
layer = c.getLayer(index).to_StandardOpaqueMaterial
948-
return invalid("#{id} material @#{index}", mth, 0) if layer.empty?
949-
950-
layer = layer.get
951-
952-
k = (layer.thickness / (ro - rsi(c) + lyr[:r])).clamp(KMIN, KMAX)
953-
d = (k * (ro - rsi(c) + lyr[:r])).clamp(DMIN, DMAX)
954-
955-
nom = "OSut:"
956-
nom += layer.nameString.gsub(/[^a-z]/i, "").gsub("OSut", "")
957-
nom += ":K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
958-
959-
lyr = model.getStandardOpaqueMaterialByName(nom)
960-
961-
if lyr.empty?
962-
layer.setName(nom)
963-
layer.setConductivity(k)
964-
layer.setThickness(d)
965-
else
966-
c.setLayer(index, lyr.get)
967-
end
946+
resetUo(c, film, index, u)
968947
end
969948
end
970949
end

lib/osut/version.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# BSD 3-Clause License
22
#
3-
# Copyright (c) 2022-2025, Denis Bourgeois
3+
# Copyright (c) 2022-2026, Denis Bourgeois
44
# All rights reserved.
55
#
66
# Redistribution and use in source and binary forms, with or without
@@ -29,5 +29,5 @@
2929
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030

3131
module OSut
32-
VERSION = "0.8.0".freeze
32+
VERSION = "0.8.1".freeze
3333
end

spec/osut_tests_spec.rb

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,19 @@
154154
expect(u).to be_within(TOL).of(uo2)
155155

156156
# Insulated, unfinished outdoor-facing plenum roof (polyiso above 4" slab).
157+
model = OpenStudio::Model::Model.new
157158
specs = {type: :roof, uo: uo2, frame: :medium, finish: :medium}
158159
surface = cls1.genConstruction(model, specs)
159160
expect(surface).to_not be_nil
160161
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)
161162
expect(surface.layers.size).to eq(3)
162163
u = 1 / cls1.rsi(surface, film[:roof])
163164
expect(u).to be_within(TOL).of(uo2)
164-
expect(surface.layers[1].nameString).to eq("OSut:polyiso:K0.023:100")
165+
expect(surface.layers[1].nameString).to eq("OSut:K0.023:100")
165166
expect(surface.layers[2].nameString).to eq("OSut:concrete:100")
166167

167168
# Roof above conditioned parking garage (polyiso under 8" slab).
169+
model = OpenStudio::Model::Model.new
168170
specs = {type: :roof, uo: uo2, clad: :heavy, frame: :medium, finish: :none}
169171
surface = cls1.genConstruction(model, specs)
170172
expect(surface).to_not be_nil
@@ -173,9 +175,10 @@
173175
u = 1 / cls1.rsi(surface, film[:roof])
174176
expect(u).to be_within(TOL).of(uo2)
175177
expect(surface.layers[0].nameString).to eq("OSut:concrete:200")
176-
expect(surface.layers[1].nameString).to eq("OSut:polyiso:K0.023:100")
178+
expect(surface.layers[1].nameString).to eq("OSut:K0.023:100")
177179

178180
# Uninsulated plenum ceiling tiles (alternative :shading).
181+
model = OpenStudio::Model::Model.new
179182
specs = {type: :roof, uo: nil, clad: :none, finish: :none}
180183
surface = cls1.genConstruction(model, specs)
181184
expect(surface).to_not be_nil
@@ -185,37 +188,41 @@
185188
expect(u).to be_within(TOL).of(uo6)
186189

187190
# Unfinished, insulated, framed attic floor (blown cellulose).
191+
model = OpenStudio::Model::Model.new
188192
specs = {type: :floor, uo: uo2, frame: :heavy, finish: :none}
189193
surface = cls1.genConstruction(model, specs)
190194
expect(surface).to_not be_nil
191195
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)
192196
expect(surface.layers.size).to eq(2)
193197
u = 1 / cls1.rsi(surface, film[:floor])
194198
expect(u).to be_within(TOL).of(uo2)
195-
expect(surface.layers[1].nameString).to eq("OSut:cellulose:K0.023:100")
199+
expect(surface.layers[1].nameString).to eq("OSut:K0.023:100")
196200

197201
# Finished, insulated exposed floor (e.g. wood-framed, residential).
202+
model = OpenStudio::Model::Model.new
198203
specs = {type: :floor, uo: uo2}
199204
surface = cls1.genConstruction(model, specs)
200205
expect(surface).to_not be_nil
201206
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)
202207
expect(surface.layers.size).to eq(3)
203208
u = 1 / cls1.rsi(surface, film[:floor])
204209
expect(u).to be_within(TOL).of(uo2)
205-
expect(surface.layers[1].nameString).to eq("OSut:mineral:K0.024:100")
210+
expect(surface.layers[1].nameString).to eq("OSut:K0.024:100")
206211

207212
# Finished, insulated exposed floor (e.g. 4" slab, steel web joists).
213+
model = OpenStudio::Model::Model.new
208214
specs = {type: :floor, uo: uo2, finish: :medium}
209215
surface = cls1.genConstruction(model, specs)
210216
expect(surface).to_not be_nil
211217
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)
212218
expect(surface.layers.size).to eq(3)
213219
u = 1 / cls1.rsi(surface, film[:floor])
214220
expect(u).to be_within(TOL).of(uo2)
215-
expect(surface.layers[1].nameString).to eq("OSut:mineral:K0.023:100")
221+
expect(surface.layers[1].nameString).to eq("OSut:K0.023:100")
216222
expect(surface.layers[2].nameString).to eq("OSut:concrete:100")
217223

218224
# Uninsulated slab-on-grade.
225+
model = OpenStudio::Model::Model.new
219226
specs = {type: :slab, frame: :none, finish: :none}
220227
surface = cls1::genConstruction(model, specs)
221228
expect(surface).to_not be_nil
@@ -225,6 +232,7 @@
225232
expect(surface.layers[1].nameString).to eq("OSut:concrete:100")
226233

227234
# Insulated slab-on-grade.
235+
model = OpenStudio::Model::Model.new
228236
specs = {type: :slab, uo: uo2, finish: :none}
229237
surface = cls1::genConstruction(model, specs)
230238
expect(surface).to_not be_nil
@@ -233,7 +241,7 @@
233241
u = 1 / cls1::rsi(surface, film[:slab])
234242
expect(u).to be_within(TOL).of(uo2)
235243
expect(surface.layers[0].nameString).to eq("OSut:sand:100")
236-
expect(surface.layers[1].nameString).to eq("OSut:polyiso:K0.010:043")
244+
expect(surface.layers[1].nameString).to eq("OSut:K0.010:043")
237245
expect(surface.layers[2].nameString).to eq("OSut:concrete:100")
238246

239247
# 8" uninsulated basement wall.
@@ -247,6 +255,7 @@
247255
expect(u).to be_within(TOL).of(uo7)
248256

249257
# 8" interior-insulated, finished basement wall.
258+
model = OpenStudio::Model::Model.new
250259
specs = {type: :basement, uo: 2 * uo2, clad: :none}
251260
surface = cls1::genConstruction(model, specs)
252261
expect(surface).to_not be_nil
@@ -255,7 +264,7 @@
255264
u = 1 / cls1::rsi(surface, film[:basement])
256265
expect(u).to be_within(TOL).of(2 * uo2)
257266
expect(surface.layers[0].nameString).to eq("OSut:concrete:200")
258-
expect(surface.layers[1].nameString).to eq("OSut:mineral:K0.037:075")
267+
expect(surface.layers[1].nameString).to eq("OSut:K0.037:075")
259268
expect(surface.layers[2].nameString).to eq("OSut:drywall:015")
260269

261270
# Standard, insulated steel door (default Uo = 1.8 W/K•m).
@@ -291,15 +300,15 @@
291300
u = 1 / cls1::rsi(surface)
292301
expect(u).to be_within(TOL).of(uo9)
293302

294-
# Invalid Uo (here, skylights and windows inherit default Uo values)
303+
# Invalid Uo (here, skylights and windows inherit default Uo values).
295304
specs = {type: :skylight, uo: nil}
296305
surface = cls1::genConstruction(model, specs)
297306
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)
298307
expect(surface.layers.size).to eq(1)
299308
u = 1 / cls1::rsi(surface)
300309
expect(u).to be_within(TOL).of(uo[:skylight])
301310

302-
# Invalid Uo (here, Uo-adjustments are ignored altogether)
311+
# Invalid Uo (here, Uo-adjustments are ignored altogether).
303312
specs = {type: :wall, uo: nil}
304313
surface = cls1::genConstruction(model, specs)
305314
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction)

0 commit comments

Comments
 (0)