Skip to content

Commit

Permalink
Improving fix for ASL issue
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewlee94 committed Mar 15, 2024
1 parent 92b54f4 commit 1b91594
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 22 deletions.
54 changes: 32 additions & 22 deletions idaes/core/util/model_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
__author__ = "Alexander Dowling, Douglas Allan, Andrew Lee, Robby Parker, Ben Knueven"

from operator import itemgetter
import os
import sys
from inspect import signature
from math import log, isclose, inf, isfinite
Expand Down Expand Up @@ -77,7 +76,6 @@
from pyomo.common.deprecation import deprecation_warning
from pyomo.common.errors import PyomoException
from pyomo.common.tempfiles import TempfileManager
from pyomo.common.fileutils import find_library

from idaes.core.util.model_statistics import (
activated_blocks_set,
Expand Down Expand Up @@ -441,23 +439,27 @@ def __init__(self, model: _BlockData, **kwargs):
self._model = model
self.config = CONFIG(kwargs)

# There appears to be a bug in the ASL which causes terminal failures
# if you try to create multiple ASL structs with different external
# functions in the same process. This causes pytest to crash during testing.
# To avoid this, register all known external functions before we call
# PyNumero.
ext_funcs = ["cubic_roots", "general_helmholtz_external", "functions"]
library_set = set()
libraries = []

for f in ext_funcs:
library = find_library(f)
if library not in library_set:
library_set.add(library)
libraries.append(library)

lib_str = "\n".join(libraries)
os.environ["AMPLFUNC"] = lib_str
# # There appears to be a bug in the ASL which causes terminal failures
# # if you try to create multiple ASL structs with different external
# # functions in the same process. This causes pytest to crash during testing.
# # To avoid this, register all known external functions before we call
# # PyNumero.
# ext_funcs = ["cubic_roots", "general_helmholtz_external", "functions"]
# library_set = set()
# libraries = []
#
# for f in ext_funcs:
# library = find_library(f)
# if library not in library_set:
# library_set.add(library)
# libraries.append(library)
#
# if "AMPLFUNC" in os.environ:
# env_str = "\n".join([os.environ["AMPLFUNC"], *libraries])
# else:
# env_str = "\n".join(libraries)
#
# os.environ["AMPLFUNC"] = env_str

@property
def model(self):
Expand Down Expand Up @@ -1430,9 +1432,17 @@ def report_numerical_issues(self, stream=None):
cautions = self._collect_numerical_cautions(jac=jac, nlp=nlp)

stats = []
stats.append(
f"Jacobian Condition Number: {jacobian_cond(jac=jac, scaled=False):.3E}"
)
try:
stats.append(
f"Jacobian Condition Number: {jacobian_cond(jac=jac, scaled=False):.3E}"
)
except RuntimeError as err:
if "Factor is exactly singular" in str(err):
_log.info(err)
stats.append(f"Jacobian Condition Number: Undefined (Exactly Singular)")
else:
raise

_write_report_section(
stream=stream, lines_list=stats, title="Model Statistics", header="="
)
Expand Down
25 changes: 25 additions & 0 deletions idaes/core/util/scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
__author__ = "John Eslick, Tim Bartholomew, Robert Parker, Andrew Lee"

import math
import os
import sys

import scipy.sparse.linalg as spla
Expand All @@ -49,12 +50,36 @@
from pyomo.core import expr as EXPR
from pyomo.common.numeric_types import native_types
from pyomo.core.base.units_container import _PyomoUnit
from pyomo.common.fileutils import find_library

import idaes.logger as idaeslog

_log = idaeslog.getLogger(__name__)


# There appears to be a bug in the ASL which causes terminal failures
# if you try to create multiple ASL structs with different external
# functions in the same process. This causes pytest to crash during testing.
# To avoid this, register all known external functions before we call
# PyNumero.
ext_funcs = ["cubic_roots", "general_helmholtz_external", "functions"]
library_set = set()
libraries = []

for f in ext_funcs:
library = find_library(f)
if library not in library_set:
library_set.add(library)
libraries.append(library)

if "AMPLFUNC" in os.environ:
env_str = "\n".join([os.environ["AMPLFUNC"], *libraries])
else:
env_str = "\n".join(libraries)

os.environ["AMPLFUNC"] = env_str


def __none_left_mult(x, y):
"""PRIVATE FUNCTION, If x is None return None, else return x * y"""
if x is not None:
Expand Down
41 changes: 41 additions & 0 deletions idaes/core/util/tests/test_model_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
acos,
sqrt,
Objective,
PositiveIntegers,
Set,
SolverFactory,
Suffix,
Expand Down Expand Up @@ -1342,6 +1343,46 @@ def test_report_numerical_issues_ok(self):
prepare_degeneracy_hunter()
prepare_svd_toolbox()
====================================================================================
"""

assert stream.getvalue() == expected

@pytest.mark.component
def test_report_numerical_issues_exactly_singular(self):
m = ConcreteModel()
m.x = Var([1, 2], initialize=1.0)
m.eq = Constraint(PositiveIntegers)
m.eq[1] = m.x[1] * m.x[2] == 1.5
m.eq[2] = m.x[2] * m.x[1] == 1.5
m.obj = Objective(expr=m.x[1] ** 2 + 2 * m.x[2] ** 2)

dt = DiagnosticsToolbox(m)
dt.report_numerical_issues()

stream = StringIO()
dt.report_numerical_issues(stream)

expected = """====================================================================================
Model Statistics
Jacobian Condition Number: Undefined (Exactly Singular)
------------------------------------------------------------------------------------
1 WARNINGS
WARNING: 2 Constraints with large residuals (>1.0E-05)
------------------------------------------------------------------------------------
0 Cautions
No cautions found!
------------------------------------------------------------------------------------
Suggested next steps:
display_constraints_with_large_residuals()
====================================================================================
"""

Expand Down

0 comments on commit 1b91594

Please sign in to comment.