Units Handling in Pyomo

Pyomo Units Container Module

This module provides support for including units within Pyomo expressions. This module can be used to define units on a model, and to check the consistency of units within the underlying constraints and expressions in the model. The module also supports conversion of units within expressions using the convert method to support construction of constraints that contain embedded unit conversions.

To use this package within your Pyomo model, you first need an instance of a PyomoUnitsContainer. You can use the module level instance already defined as ‘units’. This object ‘contains’ the units - that is, you can access units on this module using common notation.

>>> from pyomo.environ import units as u
>>> print(3.0*u.kg)
3.0*kg

Units can be assigned to Var, Param, and ExternalFunction components, and can be used directly in expressions (e.g., defining constraints). You can also verify that the units are consistent on a model, or on individual components like the objective function, constraint, or expression using assert_units_consistent (from pyomo.util.check_units). There are other methods there that may be helpful for verifying correct units on a model.

>>> from pyomo.environ import ConcreteModel, Var, Objective
>>> from pyomo.environ import units as u
>>> from pyomo.util.check_units import assert_units_consistent, assert_units_equivalent, check_units_equivalent
>>> model = ConcreteModel()
>>> model.acc = Var(initialize=5.0, units=u.m/u.s**2)
>>> model.obj = Objective(expr=(model.acc - 9.81*u.m/u.s**2)**2)
>>> assert_units_consistent(model.obj) # raise exc if units invalid on obj
>>> assert_units_consistent(model) # raise exc if units invalid anywhere on the model
>>> assert_units_equivalent(model.obj.expr, u.m**2/u.s**4) # raise exc if units not equivalent
>>> print(u.get_units(model.obj.expr)) # print the units on the objective
m**2/s**4
>>> print(check_units_equivalent(model.acc, u.m/u.s**2))
True

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.

If you need a unit that is not in the standard set of defined units, you can create your own units by adding to the unit definitions within pint. See PyomoUnitsContainer.load_definitions_from_file() or PyomoUnitsContainer.load_definitions_from_strings() for more information.

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.

This module does support conversion of offset units to absolute units numerically, using convert_value_K_to_C, convert_value_C_to_K, convert_value_R_to_F, convert_value_F_to_R. These are useful for converting input data to absolute units, and for converting data to convenient units for reporting.

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(pint_registry=NOTSET)[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 level units container units that is an instance of a PyomoUnitsContainer. This module instance should typically 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.

convert(src, to_units=None)[source]

This method returns an expression that contains the explicit conversion from one unit to another.

Parameters:
  • src (Pyomo expression) – The source value that will be converted. This could be a Pyomo Var, Pyomo Param, or a more complex expression.

  • to_units (Pyomo units expression) – The desired target units for the new expression

Returns:

ret

Return type:

Pyomo expression

convert_temp_C_to_K(value_in_C)[source]

Convert a value in degrees Celsius to Kelvin Note that this method converts a numerical value only. If you need temperature conversions in expressions, please work in absolute temperatures only.

convert_temp_F_to_R(value_in_F)[source]

Convert a value in degrees Fahrenheit to Rankine. Note that this method converts a numerical value only. If you need temperature conversions in expressions, please work in absolute temperatures only.

convert_temp_K_to_C(value_in_K)[source]

Convert a value in Kelvin to degrees Celsius. Note that this method converts a numerical value only. If you need temperature conversions in expressions, please work in absolute temperatures only.

convert_temp_R_to_F(value_in_R)[source]

Convert a value in Rankine to degrees Fahrenheit. Note that this method converts a numerical value only. If you need temperature conversions in expressions, please work in absolute temperatures only.

convert_value(num_value, from_units=None, to_units=None)[source]

This method performs explicit conversion of a numerical value from one unit to another, and returns the new value.

The argument “num_value” must be a native numeric type (e.g. float). Note that this method returns a numerical value only, and not an expression with units.

Parameters:
  • num_value (float or other native numeric type) – The value that will be converted

  • from_units (Pyomo units expression) – The units to convert from

  • to_units (Pyomo units expression) – The units to convert to

Returns:

float

Return type:

The converted value

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

load_definitions_from_file(definition_file)[source]

Load new units definitions from a file

This method loads additional units definitions from a user specified definition file. An example of a definitions file can be found at: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt

If we have a file called my_additional_units.txt with the following lines:

USD = [currency]

Then we can add this to the container with:

>>> u.load_definitions_from_file('my_additional_units.txt')
>>> print(u.USD)
USD
load_definitions_from_strings(definition_string_list)[source]

Load new units definitions from a string

This method loads additional units definitions from a list of strings (one for each line). An example of the definitions strings can be found at: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt

For example, to add the currency dimension and US dollars as a unit, use

>>> u.load_definitions_from_strings(['USD = [currency]'])
>>> print(u.USD)
USD
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 kg and y is in units of meter