Skip to content

Commit

Permalink
Merge 8d45f85 into 9a5cfee
Browse files Browse the repository at this point in the history
  • Loading branch information
DKilkenny committed Sep 29, 2020
2 parents 9a5cfee + 8d45f85 commit 15fb91f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 8 deletions.
17 changes: 10 additions & 7 deletions openmdao/core/group.py
Expand Up @@ -24,7 +24,8 @@
shape_to_len
from openmdao.utils.general_utils import ContainsAll, simple_warning, common_subpath, \
conditional_error, _is_slicer_op
from openmdao.utils.units import is_compatible, unit_conversion, _has_val_mismatch, _find_unit
from openmdao.utils.units import is_compatible, unit_conversion, _has_val_mismatch, _find_unit, \
_is_unitless
from openmdao.utils.mpi import MPI, check_mpi_exceptions
import openmdao.utils.coloring as coloring_mod
from openmdao.utils.array_utils import evenly_distrib_idxs
Expand Down Expand Up @@ -1662,9 +1663,10 @@ def _setup_connections(self):

if out_units:
if not in_units:
msg = f"{self.msginfo}: Output '{abs_out}' with units of '{out_units}' " + \
f"is connected to input '{abs_in}' which has no units."
simple_warning(msg)
if _is_unitless(out_units):
msg = f"{self.msginfo}: Output '{abs_out}' with units of '{out_units}' " + \
f"is connected to input '{abs_in}' which has no units."
simple_warning(msg)
elif not is_compatible(in_units, out_units):
msg = f"{self.msginfo}: Output units of '{out_units}' for '{abs_out}' " + \
f"are incompatible with input units of '{in_units}' for '{abs_in}'."
Expand All @@ -1673,9 +1675,10 @@ def _setup_connections(self):
else:
simple_warning(msg)
elif in_units is not None:
msg = f"{self.msginfo}: Input '{abs_in}' with units of '{in_units}' is " + \
f"connected to output '{abs_out}' which has no units."
simple_warning(msg)
if _is_unitless(in_units):
msg = f"{self.msginfo}: Input '{abs_in}' with units of '{in_units}' is " + \
f"connected to output '{abs_out}' which has no units."
simple_warning(msg)

fail = False

Expand Down
70 changes: 69 additions & 1 deletion openmdao/utils/tests/test_units.py
Expand Up @@ -2,11 +2,13 @@

import os
import unittest
import warnings

# from openmdao.utils.assert_utils import assert_near_equal
import openmdao.api as om
from openmdao.utils.units import NumberDict, PhysicalUnit, _find_unit, import_library, \
add_unit, add_offset_unit, unit_conversion, get_conversion
from openmdao.utils.assert_utils import assert_warning
from openmdao.utils.assert_utils import assert_warning, assert_near_equal


class TestNumberDict(unittest.TestCase):
Expand Down Expand Up @@ -289,6 +291,72 @@ def test_add_unit(self):
else:
self.fail("Expecting Key Error")

def test_connect_unitless_to_none(self):
import warnings
p = om.Problem()
ivc = p.model.add_subsystem('indeps', om.IndepVarComp())
ivc.add_output('x', val=5.0, units='1/s*s')
ivc.add_output('y', val=10.0, units='Hz*s')
p.model.add_subsystem('exec_comp', om.ExecComp('z = x + y', z={'units': None},
x={'units': None}, y={'units': None}))
p.model.connect('indeps.x', 'exec_comp.x')
p.model.connect('indeps.y', 'exec_comp.y')

with warnings.catch_warnings():
warnings.simplefilter("error")
p.setup()

p.run_model()
assert_near_equal(p.get_val('exec_comp.z'), 15.0)

def test_promote_unitless_and_none(self):
p = om.Problem()
ivc = p.model.add_subsystem('indeps', om.IndepVarComp(), promotes_outputs=['x', 'y'])
ivc.add_output('x', val=5.0, units='1/s*s')
ivc.add_output('y', val=10.0, units='Hz*s')
p.model.add_subsystem('exec_comp', om.ExecComp('z = x + y', z={'units': None},
x={'units': None}, y={'units': None}),
promotes_inputs=['x', 'y'])

with warnings.catch_warnings():
warnings.simplefilter("error")
p.setup()

p.run_model()
assert_near_equal(p.get_val('exec_comp.z'), 15.0)

def test_promote_unitless_ivc_to_exec_comp(self):
p = om.Problem()
ivc = p.model.add_subsystem('indeps', om.IndepVarComp())
ivc.add_output('x', val=5.0, units=None)
ivc.add_output('y', val=10.0, units='Hz*s')
p.model.add_subsystem('exec_comp', om.ExecComp('z = x + y', z={'units': None},
x={'units': '1/s*s'}, y={'units': None}))
p.model.connect('indeps.x', 'exec_comp.x')
p.model.connect('indeps.y', 'exec_comp.y')

with warnings.catch_warnings():
warnings.simplefilter("error")
p.setup()

p.run_model()
assert_near_equal(p.get_val('exec_comp.z'), 15.0)

def test_incompatible(self):
p = om.Problem()
ivc = p.model.add_subsystem('indeps', om.IndepVarComp(), promotes_outputs=['x', 'y'])
ivc.add_output('x', val=5.0, units='1/s*s')
ivc.add_output('y', val=10.0, units='Hz*s')
p.model.add_subsystem('exec_comp', om.ExecComp('z = x + y', z={'units': None},
x={'units': None}, y={'units': 'ft'}),
promotes_inputs=['x', 'y'])

msg = ("Group (<model>): Output units of 'Hz*s' for 'indeps.y' are incompatible with input "
"units of 'ft' for 'exec_comp.y'.")

with self.assertRaises(RuntimeError) as cm:
p.setup()
self.assertEqual(str(cm.exception), msg)

if __name__ == "__main__":
unittest.main()
5 changes: 5 additions & 0 deletions openmdao/utils/units.py
Expand Up @@ -845,6 +845,11 @@ def _update_library(cfg):
_UNIT_CACHE = {}


def _is_unitless(units):
unit_meta = _find_unit(units) if units else None
return not unit_meta.is_dimensionless()


def _find_unit(unit):
"""
Find unit helper function.
Expand Down

0 comments on commit 15fb91f

Please sign in to comment.