Skip to content

Commit 0b8a1ea

Browse files
committed
Completes construction thickness test
1 parent 81a24cc commit 0b8a1ea

File tree

4 files changed

+143
-93
lines changed

4 files changed

+143
-93
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ __pycache__/
88

99
.DS_Store
1010

11+
tests/files/osms/out/*.osm
12+
1113
# Distribution / packaging
1214
.Python
1315
build/

src/osut/osut.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def are_standardOpaqueLayers(lc=None) -> bool:
228228
if not hasattr(lc, CN.NS):
229229
return oslg.invalid("layered construction", mth, 1, DBG, 0.0)
230230

231-
id = lc.nameString()
231+
id = oslg.trim(lc.nameString())
232232

233233
if not isinstance(lc, cl):
234234
return oslg.mismatch(id, lc, cl, mth, CN.DBG, 0.0)
@@ -252,19 +252,19 @@ def thickness(lc=None) -> float:
252252
253253
"""
254254
mth = "osut.thickness"
255-
cl = openStudio.model.LayeredConstruction
255+
cl = openstudio.model.LayeredConstruction
256256
d = 0.0
257257

258258
if not hasattr(lc, CN.NS):
259259
return oslg.invalid("layered construction", mth, 1, DBG, 0.0)
260260

261-
id = lc.nameString()
261+
id = oslg.trim(lc.nameString())
262262

263263
if not isinstance(lc, cl):
264264
return oslg.mismatch(id, lc, cl, mth, CN.DBG, 0.0)
265265

266-
if not osut.are_standardOpaqueLayers(lc):
267-
log(CN.ERR, "%s holds non-StandardOpaqueMaterial(s) %s" % (id, mth))
266+
if not are_standardOpaqueLayers(lc):
267+
oslg.log(CN.ERR, "%s holds non-StandardOpaqueMaterial(s) %s" % (id, mth))
268268
return d
269269

270270
for m in lc.layers(): d += m.thickness()

tests/files/osms/out/.gitkeep

Whitespace-only changes.

tests/test_osut.py

Lines changed: 136 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,53 @@ def test05_construction_thickness(self):
167167
self.assertTrue(plenum.isVolumeDefaulted())
168168
self.assertTrue(plenum.isVolumeAutocalculated())
169169

170+
self.assertEqual(round(plenum.volume(), 0), 50) # right answer
171+
self.assertTrue(thzone.isVolumeDefaulted())
172+
self.assertTrue(thzone.isVolumeAutocalculated())
173+
self.assertFalse(thzone.volume())
174+
175+
model.save("./tests/files/osms/out/seb2.osm", True)
176+
# End of cleanup.
177+
178+
for c in model.getConstructions():
179+
if not c.to_LayeredConstruction(): continue
180+
181+
c = c.to_LayeredConstruction().get()
182+
id = c.nameString()
183+
184+
# OSut 'thickness' method can only process layered constructions
185+
# built up with standard opaque layers, which exclude:
186+
#
187+
# - "Air Wall"-based construction
188+
# - "Double pane"-based construction
189+
#
190+
# The method returns '0' in such cases, logging ERROR messages.
191+
th = osut.thickness(c)
192+
193+
if "Air Wall" in id or "Double pane" in id:
194+
self.assertEqual(round(th, 0), 0)
195+
continue
196+
197+
self.assertTrue(th > 0)
198+
199+
self.assertTrue(o.is_error())
200+
self.assertTrue(o.clean(), DBG)
201+
self.assertEqual(o.status(), 0)
202+
self.assertFalse(o.logs())
203+
204+
for c in model.getConstructions():
205+
if c.to_LayeredConstruction(): continue
206+
207+
c = c.to_LayeredConstruction().get()
208+
id = c.nameString()
209+
if "Air Wall" in id or "Double pane" in id: continue
210+
211+
th = osut.thickness(c)
212+
self.assertTrue(th > 0)
213+
214+
self.assertEqual(o.status(), 0)
215+
self.assertFalse(o.logs())
216+
170217

171218
def test06_insulatingLayer(self):
172219
o = osut.oslg
@@ -176,89 +223,89 @@ def test06_insulatingLayer(self):
176223
self.assertEqual(o.status(), 0)
177224
# it "checks (opaque) insulating layers within a layered construction" do
178225
# translator = OpenStudio::OSVersion::VersionTranslator.new
179-
# expect(mod1.clean!).to eq(DBG)
226+
# self.assertTrue(mod1.clean!).to eq(DBG)
180227
#
181228
# file = File.join(__dir__, "files/osms/out/seb2.osm")
182229
# path = OpenStudio::Path.new(file)
183230
# model = translator.loadModel(path)
184-
# expect(model).to_not be_empty
231+
# self.assertTrue(model).to_not be_empty
185232
# model = model.get
186233
#
187234
# m = "OSut::insulatingLayer"
188235
# m1 = "Invalid 'lc' arg #1 (#{m})"
189236
#
190237
# model.getLayeredConstructions.each do |lc|
191238
# lyr = mod1.insulatingLayer(lc)
192-
# expect(lyr).to be_a(Hash)
193-
# expect(lyr).to have_key(:index)
194-
# expect(lyr).to have_key(:type )
195-
# expect(lyr).to have_key(:r)
239+
# self.assertTrue(lyr).to be_a(Hash)
240+
# self.assertTrue(lyr).to have_key(:index)
241+
# self.assertTrue(lyr).to have_key(:type )
242+
# self.assertTrue(lyr).to have_key(:r)
196243
#
197244
# if lc.isFenestration
198-
# expect(mod1.status).to be_zero
199-
# expect(lyr[:index]).to be_nil
200-
# expect(lyr[:type ]).to be_nil
201-
# expect(lyr[:r ]).to be_zero
245+
# self.assertTrue(mod1.status).to be_zero
246+
# self.assertTrue(lyr[:index]).to be_nil
247+
# self.assertTrue(lyr[:type ]).to be_nil
248+
# self.assertTrue(lyr[:r ]).to be_zero
202249
# next
203250
# end
204251
#
205252
# unless [:standard, :massless].include?(lyr[:type]) # air wall mat
206-
# expect(mod1.status).to be_zero
207-
# expect(lyr[:index]).to be_nil
208-
# expect(lyr[:type ]).to be_nil
209-
# expect(lyr[:r ]).to be_zero
253+
# self.assertTrue(mod1.status).to be_zero
254+
# self.assertTrue(lyr[:index]).to be_nil
255+
# self.assertTrue(lyr[:type ]).to be_nil
256+
# self.assertTrue(lyr[:r ]).to be_zero
210257
# next
211258
# end
212259
#
213-
# expect(lyr[:index] < lc.numLayers).to be true
260+
# self.assertTrue(lyr[:index] < lc.numLayers).to be true
214261
#
215262
# case lc.nameString
216263
# when "EXTERIOR-ROOF"
217-
# expect(lyr[:index]).to eq(2)
218-
# expect(lyr[:r ]).to be_within(TOL).of(5.08)
264+
# self.assertTrue(lyr[:index]).to eq(2)
265+
# self.assertTrue(lyr[:r ]).to be_within(TOL).of(5.08)
219266
# when "EXTERIOR-WALL"
220-
# expect(lyr[:index]).to eq(2)
221-
# expect(lyr[:r ]).to be_within(TOL).of(1.47)
267+
# self.assertTrue(lyr[:index]).to eq(2)
268+
# self.assertTrue(lyr[:r ]).to be_within(TOL).of(1.47)
222269
# when "Default interior ceiling"
223-
# expect(lyr[:index]).to be_zero
224-
# expect(lyr[:r ]).to be_within(TOL).of(0.12)
270+
# self.assertTrue(lyr[:index]).to be_zero
271+
# self.assertTrue(lyr[:r ]).to be_within(TOL).of(0.12)
225272
# when "INTERIOR-WALL"
226-
# expect(lyr[:index]).to eq(1)
227-
# expect(lyr[:r ]).to be_within(TOL).of(0.24)
273+
# self.assertTrue(lyr[:index]).to eq(1)
274+
# self.assertTrue(lyr[:r ]).to be_within(TOL).of(0.24)
228275
# else
229-
# expect(lyr[:index]).to be_zero
230-
# expect(lyr[:r ]).to be_within(TOL).of(0.29)
276+
# self.assertTrue(lyr[:index]).to be_zero
277+
# self.assertTrue(lyr[:r ]).to be_within(TOL).of(0.29)
231278
# end
232279
# end
233280
#
234281
# lyr = mod1.insulatingLayer(nil)
235-
# expect(mod1.debug?).to be true
236-
# expect(lyr[:index]).to be_nil
237-
# expect(lyr[:type ]).to be_nil
238-
# expect(lyr[:r ]).to be_zero
239-
# expect(mod1.debug?).to be true
240-
# expect(mod1.logs.size).to eq(1)
241-
# expect(mod1.logs.first[:message]).to eq(m1)
282+
# self.assertTrue(mod1.debug?).to be true
283+
# self.assertTrue(lyr[:index]).to be_nil
284+
# self.assertTrue(lyr[:type ]).to be_nil
285+
# self.assertTrue(lyr[:r ]).to be_zero
286+
# self.assertTrue(mod1.debug?).to be true
287+
# self.assertTrue(mod1.logs.size).to eq(1)
288+
# self.assertTrue(mod1.logs.first[:message]).to eq(m1)
242289
#
243-
# expect(mod1.clean!).to eq(DBG)
290+
# self.assertTrue(mod1.clean!).to eq(DBG)
244291
# lyr = mod1.insulatingLayer("")
245-
# expect(mod1.debug?).to be true
246-
# expect(lyr[:index]).to be_nil
247-
# expect(lyr[:type ]).to be_nil
248-
# expect(lyr[:r ]).to be_zero
249-
# expect(mod1.debug?).to be true
250-
# expect(mod1.logs.size).to eq(1)
251-
# expect(mod1.logs.first[:message]).to eq(m1)
292+
# self.assertTrue(mod1.debug?).to be true
293+
# self.assertTrue(lyr[:index]).to be_nil
294+
# self.assertTrue(lyr[:type ]).to be_nil
295+
# self.assertTrue(lyr[:r ]).to be_zero
296+
# self.assertTrue(mod1.debug?).to be true
297+
# self.assertTrue(mod1.logs.size).to eq(1)
298+
# self.assertTrue(mod1.logs.first[:message]).to eq(m1)
252299
#
253-
# expect(mod1.clean!).to eq(DBG)
300+
# self.assertTrue(mod1.clean!).to eq(DBG)
254301
# lyr = mod1.insulatingLayer(model)
255-
# expect(mod1.debug?).to be true
256-
# expect(lyr[:index]).to be_nil
257-
# expect(lyr[:type ]).to be_nil
258-
# expect(lyr[:r ]).to be_zero
259-
# expect(mod1.debug?).to be true
260-
# expect(mod1.logs.size).to eq(1)
261-
# expect(mod1.logs.first[:message]).to eq(m1)
302+
# self.assertTrue(mod1.debug?).to be true
303+
# self.assertTrue(lyr[:index]).to be_nil
304+
# self.assertTrue(lyr[:type ]).to be_nil
305+
# self.assertTrue(lyr[:r ]).to be_zero
306+
# self.assertTrue(mod1.debug?).to be true
307+
# self.assertTrue(mod1.logs.size).to eq(1)
308+
# self.assertTrue(mod1.logs.first[:message]).to eq(m1)
262309

263310
def test07_genConstruction(self):
264311
m1 = "'specs' list? expecting dict (osut.genConstruction)"
@@ -837,20 +884,20 @@ def test08_genShade(self):
837884
# file = File.join(__dir__, "files/osms/out/seb_ext4.osm")
838885
# path = OpenStudio::Path.new(file)
839886
# model = translator.loadModel(path)
840-
# expect(model).to_not be_empty
887+
# self.assertTrue(model).to_not be_empty
841888
# model = model.get
842889
# spaces = model.getSpaces
843890
#
844891
# slanted = mod1.facets(spaces, "Outdoors", "RoofCeiling", [:top, :north])
845-
# expect(slanted.size).to eq(1)
892+
# self.assertTrue(slanted.size).to eq(1)
846893
# slanted = slanted.first
847-
# expect(slanted.nameString).to eq("Openarea slanted roof")
894+
# self.assertTrue(slanted.nameString).to eq("Openarea slanted roof")
848895
# skylights = slanted.subSurfaces
849896
#
850897
# tilted = mod1.facets(spaces, "Outdoors", "Wall", :bottom)
851-
# expect(tilted.size).to eq(1)
898+
# self.assertTrue(tilted.size).to eq(1)
852899
# tilted = tilted.first
853-
# expect(tilted.nameString).to eq("Openarea tilted wall")
900+
# self.assertTrue(tilted.nameString).to eq("Openarea tilted wall")
854901
# windows = tilted.subSurfaces
855902
#
856903
# # 2x control groups:
@@ -862,38 +909,38 @@ def test08_genShade(self):
862909
# windows.each { |sub| wins << sub }
863910
#
864911
# if OpenStudio.openStudioVersion.split(".").join.to_i < 321
865-
# expect(mod1.genShade(skies)).to be false
866-
# expect(mod1.status).to be_zero
912+
# self.assertTrue(mod1.genShade(skies)).to be false
913+
# self.assertTrue(mod1.status).to be_zero
867914
# else
868-
# expect(mod1.genShade(skies)).to be true
869-
# expect(mod1.genShade(wins)).to be true
870-
# expect(mod1.status).to be_zero
915+
# self.assertTrue(mod1.genShade(skies)).to be true
916+
# self.assertTrue(mod1.genShade(wins)).to be true
917+
# self.assertTrue(mod1.status).to be_zero
871918
# ctls = model.getShadingControls
872-
# expect(ctls.size).to eq(2)
919+
# self.assertTrue(ctls.size).to eq(2)
873920
#
874921
# ctls.each do |ctl|
875-
# expect(ctl.shadingType).to eq("InteriorShade")
922+
# self.assertTrue(ctl.shadingType).to eq("InteriorShade")
876923
# type = "OnIfHighOutdoorAirTempAndHighSolarOnWindow"
877-
# expect(ctl.shadingControlType).to eq(type)
878-
# expect(ctl.isControlTypeValueNeedingSetpoint1).to be true
879-
# expect(ctl.isControlTypeValueNeedingSetpoint2).to be true
880-
# expect(ctl.isControlTypeValueAllowingSchedule).to be true
881-
# expect(ctl.isControlTypeValueRequiringSchedule).to be false
924+
# self.assertTrue(ctl.shadingControlType).to eq(type)
925+
# self.assertTrue(ctl.isControlTypeValueNeedingSetpoint1).to be true
926+
# self.assertTrue(ctl.isControlTypeValueNeedingSetpoint2).to be true
927+
# self.assertTrue(ctl.isControlTypeValueAllowingSchedule).to be true
928+
# self.assertTrue(ctl.isControlTypeValueRequiringSchedule).to be false
882929
# spt1 = ctl.setpoint
883930
# spt2 = ctl.setpoint2
884-
# expect(spt1).to_not be_empty
885-
# expect(spt2).to_not be_empty
931+
# self.assertTrue(spt1).to_not be_empty
932+
# self.assertTrue(spt2).to_not be_empty
886933
# spt1 = spt1.get
887934
# spt2 = spt2.get
888-
# expect(spt1).to be_within(TOL).of(18)
889-
# expect(spt2).to be_within(TOL).of(100)
890-
# expect(ctl.multipleSurfaceControlType).to eq("Group")
935+
# self.assertTrue(spt1).to be_within(TOL).of(18)
936+
# self.assertTrue(spt2).to be_within(TOL).of(100)
937+
# self.assertTrue(ctl.multipleSurfaceControlType).to eq("Group")
891938
#
892939
# ctl.subSurfaces.each do |sub|
893940
# surface = sub.surface
894-
# expect(surface).to_not be_empty
941+
# self.assertTrue(surface).to_not be_empty
895942
# surface = surface.get
896-
# expect([slanted, tilted]).to include(surface)
943+
# self.assertTrue([slanted, tilted]).to include(surface)
897944
# end
898945
# end
899946
# end
@@ -903,6 +950,7 @@ def test08_genShade(self):
903950

904951
def test09_internal_mass(self):
905952
o = osut.oslg
953+
print(o.logs())
906954
self.assertEqual(o.status(), 0)
907955
self.assertEqual(o.reset(DBG), DBG)
908956
self.assertEqual(o.level(), DBG)
@@ -938,42 +986,42 @@ def test09_internal_mass(self):
938986
#
939987
# model.getInternalMasss.each do |m|
940988
# d = m.internalMassDefinition
941-
# expect(d.designLevelCalculationMethod).to eq("SurfaceArea/Area")
989+
# self.assertTrue(d.designLevelCalculationMethod).to eq("SurfaceArea/Area")
942990
#
943991
# ratio = d.surfaceAreaperSpaceFloorArea
944-
# expect(ratio).to_not be_empty
992+
# self.assertTrue(ratio).to_not be_empty
945993
# ratio = ratio.get
946994
#
947995
# case ratio
948996
# when 0.1
949-
# expect(d.nameString).to eq("OSut|InternalMassDefinition|0.10")
950-
# expect(m.nameString.downcase).to include("entrance")
997+
# self.assertTrue(d.nameString).to eq("OSut|InternalMassDefinition|0.10")
998+
# self.assertTrue(m.nameString.downcase).to include("entrance")
951999
# when 0.3
952-
# expect(d.nameString).to eq("OSut|InternalMassDefinition|0.30")
953-
# expect(m.nameString.downcase).to include("lobby")
1000+
# self.assertTrue(d.nameString).to eq("OSut|InternalMassDefinition|0.30")
1001+
# self.assertTrue(m.nameString.downcase).to include("lobby")
9541002
# when 1.0
955-
# expect(d.nameString).to eq("OSut|InternalMassDefinition|1.00")
956-
# expect(m.nameString.downcase).to include("meeting")
1003+
# self.assertTrue(d.nameString).to eq("OSut|InternalMassDefinition|1.00")
1004+
# self.assertTrue(m.nameString.downcase).to include("meeting")
9571005
# else
958-
# expect(d.nameString).to eq("OSut|InternalMassDefinition|2.00")
959-
# expect(ratio).to eq(2.0)
1006+
# self.assertTrue(d.nameString).to eq("OSut|InternalMassDefinition|2.00")
1007+
# self.assertTrue(ratio).to eq(2.0)
9601008
# end
9611009
#
9621010
# c = d.construction
963-
# expect(c).to_not be_empty
1011+
# self.assertTrue(c).to_not be_empty
9641012
# c = c.get.to_Construction
965-
# expect(c).to_not be_empty
1013+
# self.assertTrue(c).to_not be_empty
9661014
# c = c.get
9671015
#
9681016
# construction = c if construction.nil?
969-
# expect(construction).to eq(c)
970-
# expect(c.nameString).to eq("OSut|MASS|Construction")
971-
# expect(c.numLayers).to eq(1)
1017+
# self.assertTrue(construction).to eq(c)
1018+
# self.assertTrue(c.nameString).to eq("OSut|MASS|Construction")
1019+
# self.assertTrue(c.numLayers).to eq(1)
9721020
#
9731021
# m = c.layers.first
9741022
#
9751023
# material = m if material.nil?
976-
# expect(material).to eq(m)
1024+
# self.assertTrue(material).to eq(m)
9771025
del(model)
9781026

9791027

0 commit comments

Comments
 (0)