Three related bugs in osut 0.9.0, found while building a Python port of the TBD
gem on top of pyOSut. Each makes pyOSut diverge from the Ruby osut behaviour
(and two of them crash) for constructions containing a MasslessOpaqueMaterial,
which are extremely common.
Environment: osut 0.9.0, openstudio 3.11.0, Python 3.12.
1. insulatingLayer — NameError on a massless layer
osut/osut.py:579 (massless branch):
res["r"] = m.thermalResistance()
The loop variable is l, not m, so m is undefined and any construction whose
insulating layer is a MasslessOpaqueMaterial raises
NameError: name 'm' is not defined.
Fix: m → l.
2. insulatingLayer — hardcoded thresholds instead of RMIN/DMIN/KMAX
The qualifying tests are hardcoded as < 0.001 (thermalResistance), < 0.003
(thickness) and > 3.0 (conductivity), whereas Ruby osut uses the constants
RMIN (0.005), DMIN (0.01) and KMAX (2.0). This selects a different
insulating layer than the Ruby gem. Example: a ~0.15 m normalweight-concrete floor
(k ≈ 2.31) is excluded by Ruby (k > KMAX = 2.0) but kept by pyOSut (k > 3.0),
which then changes any downstream U-factor / derating result for that surface.
Fix: use CN.RMIN / CN.DMIN / CN.KMAX (matching osut.rb).
3. rsi — accumulates an Optional instead of a resistance
osut/osut.py:536 (massless branch):
rsi += m.to_MasslessOpaqueMaterial()
Missing .get().thermalResistance(), so rsi raises
TypeError: unsupported operand type(s) for +=: 'float' and 'OptionalMasslessOpaqueMaterial'
for any construction with a massless layer.
Fix: rsi += m.to_MasslessOpaqueMaterial().get().thermalResistance().
Repro
import openstudio
from osut import osut
m = openstudio.model.Model()
lc = openstudio.model.Construction(m)
lc.insertLayer(0, openstudio.model.MasslessOpaqueMaterial(m, "Smooth", 2.0))
osut.insulatingLayer(lc) # -> NameError (bug 1)
osut.rsi(lc, 0.15) # -> TypeError (bug 3)
Downstream tracking issue (with the drop-in fixes used as a temporary shim):
canmet-energy/py-tbd#1
Happy to open a PR with the three one-line fixes if that's helpful.
Three related bugs in
osut0.9.0, found while building a Python port of the TBDgem on top of pyOSut. Each makes pyOSut diverge from the Ruby
osutbehaviour(and two of them crash) for constructions containing a
MasslessOpaqueMaterial,which are extremely common.
Environment:
osut0.9.0,openstudio3.11.0, Python 3.12.1.
insulatingLayer—NameErroron a massless layerosut/osut.py:579(massless branch):The loop variable is
l, notm, somis undefined and any construction whoseinsulating layer is a
MasslessOpaqueMaterialraisesNameError: name 'm' is not defined.Fix:
m→l.2.
insulatingLayer— hardcoded thresholds instead of RMIN/DMIN/KMAXThe qualifying tests are hardcoded as
< 0.001(thermalResistance),< 0.003(thickness) and
> 3.0(conductivity), whereas Rubyosutuses the constantsRMIN(0.005),DMIN(0.01) andKMAX(2.0). This selects a differentinsulating layer than the Ruby gem. Example: a ~0.15 m normalweight-concrete floor
(k ≈ 2.31) is excluded by Ruby (
k > KMAX = 2.0) but kept by pyOSut (k > 3.0),which then changes any downstream U-factor / derating result for that surface.
Fix: use
CN.RMIN/CN.DMIN/CN.KMAX(matching osut.rb).3.
rsi— accumulates an Optional instead of a resistanceosut/osut.py:536(massless branch):Missing
.get().thermalResistance(), sorsiraisesTypeError: unsupported operand type(s) for +=: 'float' and 'OptionalMasslessOpaqueMaterial'for any construction with a massless layer.
Fix:
rsi += m.to_MasslessOpaqueMaterial().get().thermalResistance().Repro
Downstream tracking issue (with the drop-in fixes used as a temporary shim):
canmet-energy/py-tbd#1
Happy to open a PR with the three one-line fixes if that's helpful.