##############################################################################
# Institute for the Design of Advanced Energy Systems Process Systems
# Engineering Framework (IDAES PSE Framework) Copyright (c) 2018, by the
# software owners: The Regents of the University of California, through
# Lawrence Berkeley National Laboratory, National Technology & Engineering
# Solutions of Sandia, LLC, Carnegie Mellon University, West Virginia
# University Research Corporation, et al. All rights reserved.
#
# Please see the files COPYRIGHT.txt and LICENSE.txt for full copyright and
# license information, respectively. Both files are also available online
# at the URL "https://github.com/IDAES/idaes".
##############################################################################
"""Utility functions for working with Pyomo expressions."""
from __future__ import division
import logging
from pyomo.environ import Block, Constraint
from pyomo.gdp import Disjunct
logger = logging.getLogger()
[docs]def is_linear(expr):
"""Check if the Pyomo expression is linear.
TODO: There is the possibility for false negatives (if there is a nonlinear
expression of a mutable parameter). Need to test this.
Args:
expr (Expression): Pyomo expression
Returns:
bool: True if expression is linear; False otherwise.
Raises:
ValueError: if polynomial degree is negative
"""
deg = expr.polynomial_degree()
if deg is None or deg > 1:
return False
elif deg == 0 or deg == 1:
return True
else:
raise ValueError("Unexpected polynomial degree {} for expression {}."
.format(deg, expr))
[docs]def log_active_nonlinear_constraints(model, logger=logger):
"""Log names of the active nonlinear constraints."""
for constr in model.component_data_objects(
ctype=Constraint, active=True,
descend_into=(Block, Disjunct)):
if constr.body.polynomial_degree() not in [0, 1]:
logger.info(constr.name)