Units Handling in Pyomo

Pyomo Units Container Module

Warning

This module is in beta and is not yet complete.

This module provides support for including units within Pyomo expressions, and provides methods for checking the consistency of units within those expresions.

To use this package within your Pyomo model, you first need an instance of a PyomoUnitsContainer. You can use the module level instance called units and use the pre-defined units in expressions or components.

Examples

To use a unit within an expression, simply reference the desired unit as an attribute on the module singleton units.

>>> from pyomo.environ import ConcreteModel, Var, Objective, units # import components and 'units' instance
>>> model = ConcreteModel()
>>> model.acc = Var()
>>> model.obj = Objective(expr=(model.acc*units.m/units.s**2 - 9.81*units.m/units.s**2)**2)
>>> print(units.get_units(model.obj.expr))
m ** 2 / s ** 4

Note

This module has a module level instance of a PyomoUnitsContainer called units that you should use for creating, retreiving, and checking units

Note

This is a work in progress. Once the components units implementations are complete, the units will eventually work similar to the following.

from pyomo.environ import ConcreteModel, Var, Objective, units
model = ConcreteModel()
model.x = Var(units=units.kg/units.m)
model.obj = Objective(expr=(model.x - 97.2*units.kg/units.m)**2)

Notes

  • The implementation is currently based on the pint package and supports all the units that are supported by pint.
  • The list of units that are supported by pint can be found at the following url: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt
  • Currently, we do NOT test units of unary functions that include native data types e.g. explicit float (3.0) since these are removed by the expression system before getting to the code that checks the units.

Note

In this implementation of units, “offset” units for temperature are not supported within expressions (i.e. the non-absolute temperature units including degrees C and degrees F). This is because there are many non-obvious combinations that are not allowable. This concern becomes clear if you first convert the non-absolute temperature units to absolute and then perform the operation. For example, if you write 30 degC + 30 degC == 60 degC, but convert each entry to Kelvin, the expression is not true (i.e., 303.15 K + 303.15 K is not equal to 333.15 K). Therefore, there are several operations that are not allowable with non-absolute units, including addition, multiplication, and division.

Please see the pint documentation here for more discussion. While pint implements “delta” units (e.g., delta_degC) to support correct unit conversions, it can be difficult to identify and guarantee valid operations in a general algebraic modeling environment. While future work may support units with relative scale, the current implementation requires use of absolute temperature units (i.e. K and R) within expressions and a direct conversion of numeric values using specific functions for converting input data and reporting.

class pyomo.core.base.units_container.PyomoUnitsContainer[source]

Bases: object

Class that is used to create and contain units in Pyomo.

This is the class that is used to create, contain, and interact with units in Pyomo. The module (pyomo.core.base.units_container) also contains a module attribute called units that is a singleton instance of a PyomoUnitsContainer. This singleton should be used instead of creating your own instance of a PyomoUnitsContainer. For an overview of the usage of this class, see the module documentation (pyomo.core.base.units_container)

This class is based on the “pint” module. Documentation for available units can be found at the following url: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt

Note: Pre-defined units can be accessed through attributes on the PyomoUnitsContainer class; however, these attributes are created dynamically through the __getattr__ method, and are not present on the class until they are requested.

check_units_consistency(expr, allow_exceptions=True)[source]

Check the consistency of the units within an expression. IF allow_exceptions is False, then this function swallows the exception and returns only True or False. Otherwise, it will throw an exception if the units are inconsistent.

Parameters:
  • expr (Pyomo expression) – The source expression to check.
  • allow_exceptions (bool) – True if you want any exceptions to be thrown, False if you only want a boolean (and the exception is ignored).
Returns:

True if units are consistent, and False if not

Return type:

bool

Raises:

pyomo.core.base.units_container.UnitsError, pyomo.core.base.units_container.InconsistentUnitsError

check_units_equivalent(expr1, expr2)[source]

Check if the units associated with each of the expressions are equivalent.

Parameters:
  • expr1 (Pyomo expression) – The first expression.
  • expr2 (Pyomo expression) – The second expression.
Returns:

True if the expressions have equivalent units, False otherwise.

Return type:

bool

Raises:

pyomo.core.base.units_container.UnitsError, pyomo.core.base.units_container.InconsistentUnitsError

get_units(expr)[source]

Return the Pyomo units corresponding to this expression (also performs validation and will raise an exception if units are not consistent).

Parameters:expr (Pyomo expression) – The expression containing the desired units
Returns:Returns the units corresponding to the expression
Return type:Pyomo unit (expression)
Raises:pyomo.core.base.units_container.UnitsError, pyomo.core.base.units_container.InconsistentUnitsError
class pyomo.core.base.units_container.UnitsError(msg)[source]

An exception class for all general errors/warnings associated with units

class pyomo.core.base.units_container.InconsistentUnitsError(exp1, exp2, msg)[source]

An exception indicating that inconsistent units are present on an expression.

E.g., x == y, where x is in units of units.kg and y is in units of units.meter