Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parallel constraint/variable check to report_numerical_issues #1385

Merged
merged 28 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ed3eb3a
update imports of native_types and pyomo_constant_types (which is dep…
Robbybp Mar 6, 2024
842650b
Adding next batch of diagnostics tests
Mar 8, 2024
6d09b5c
Next batch of daignsotics tests
Mar 10, 2024
1389783
Merge branch 'consttype-import' of https://github.com/Robbybp/idaes-p…
Mar 11, 2024
01e010c
Work around for ASL issue
Mar 14, 2024
cc9c240
Adding more diagnostics checks
Mar 14, 2024
2189347
Last unit model diagnostics tests
Mar 14, 2024
7755690
Merge branch 'main' into diagnostics_testing
Mar 14, 2024
8a9a7ee
Fixing typo
Mar 14, 2024
92b54f4
Merge branch 'diagnostics_testing' of https://github.com/andrewlee94/…
Mar 14, 2024
1b91594
Improving fix for ASL issue
Mar 15, 2024
7f4a976
Better implementation of fix
Mar 15, 2024
5af6d99
Merge branch 'main' of https://github.com/IDAES/idaes-pse into diagno…
Mar 15, 2024
448081a
Fixing pylint and Python 3.8 failures
Mar 15, 2024
2d8afda
Removing old implementation of workaround
Mar 15, 2024
a4a84dd
Fixing noisy test
Mar 15, 2024
4cf5fb2
Moving registration of external functions
Mar 18, 2024
55258cf
Reverting to version that works on Windows
Mar 18, 2024
cd47ae2
Trying another way to get binary files
Mar 18, 2024
dc7f8cc
add parallel variable/constraint checks to report_numerical_issues; c…
Robbybp Mar 19, 2024
6c5a6c4
update tests
Robbybp Mar 23, 2024
0a1894a
Merge branch 'main' of https://github.com/idaes/idaes-pse into diagno…
Robbybp Mar 23, 2024
06c239d
Merge branch 'main' of https://github.com/idaes/idaes-pse into diagno…
Robbybp Apr 10, 2024
ad00bf9
tighten parallel_component_tolerance to 1e-8
Robbybp Apr 10, 2024
69ba71f
adjust model to make parallel variable test less sensitive
Robbybp Apr 10, 2024
8960343
update test to reflect new default tolerance of 1e-8
Robbybp Apr 10, 2024
c34099b
consistent format for displaying parallel tolerance
Robbybp Apr 10, 2024
d088358
Merge branch 'main' into diagnostics-parallel
Robbybp Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions idaes/core/util/model_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,29 @@ def _collect_numerical_warnings(self, jac=None, nlp=None):
self.display_constraints_with_extreme_jacobians.__name__ + "()"
)

# Parallel variables and constraints
partol = self.config.parallel_component_tolerance
par_cons = check_parallel_jacobian(
self._model, tolerance=partol, direction="row", jac=jac, nlp=nlp
)
par_vars = check_parallel_jacobian(
self._model, tolerance=partol, direction="column", jac=jac, nlp=nlp
)
if par_cons:
p = "pair" if len(par_cons) == 1 else "pairs"
warnings.append(
f"WARNING: {len(par_cons)} {p} of constraints are parallel"
f" (to tolerance {partol})"
)
next_steps.append(self.display_near_parallel_constraints.__name__ + "()")
if par_vars:
p = "pair" if len(par_vars) == 1 else "pairs"
warnings.append(
f"WARNING: {len(par_vars)} {p} of variables are parallel"
f" (to tolerance {partol})"
)
next_steps.append(self.display_near_parallel_variables.__name__ + "()")

return warnings, next_steps

def _collect_numerical_cautions(self, jac=None, nlp=None):
Expand Down Expand Up @@ -1441,7 +1464,6 @@ def report_numerical_issues(self, stream=None):
lines_list=next_steps,
title="Suggested next steps:",
line_if_empty=f"If you still have issues converging your model consider:\n"
f"{TAB*2}display_near_parallel_constraints()\n{TAB*2}display_near_parallel_variables()"
f"\n{TAB*2}prepare_degeneracy_hunter()\n{TAB*2}prepare_svd_toolbox()",
footer="=",
)
Expand Down Expand Up @@ -3619,14 +3641,25 @@ def ipopt_solve_halt_on_error(model, options=None):
)


def check_parallel_jacobian(model, tolerance: float = 1e-4, direction: str = "row"):
def check_parallel_jacobian(
model,
tolerance: float = 1e-4,
direction: str = "row",
jac=None,
nlp=None,
):
"""
Check for near-parallel rows or columns in the Jacobian.

Near-parallel rows or columns indicate a potential degeneracy in the model,
as this means that the associated constraints or variables are (near)
duplicates of each other.

For efficiency, the ``jac`` and ``nlp`` arguments may be provided if they are
already available. If these are provided, the provided model is not used. If
either ``jac`` or ``nlp`` is not provided, a Jacobian and ``PyomoNLP`` are
computed using the model.

This method is based on work published in:

Klotz, E., Identification, Assessment, and Correction of Ill-Conditioning and
Expand All @@ -3637,6 +3670,8 @@ def check_parallel_jacobian(model, tolerance: float = 1e-4, direction: str = "ro
model: model to be analysed
tolerance: tolerance to use to determine if constraints/variables are parallel
direction: 'row' (default, constraints) or 'column' (variables)
jac: model Jacobian as a ``scipy.sparse.coo_matrix``, optional
nlp: ``PyomoNLP`` of model, optional

Returns:
list of 2-tuples containing parallel Pyomo components
Expand All @@ -3651,7 +3686,8 @@ def check_parallel_jacobian(model, tolerance: float = 1e-4, direction: str = "ro
"Must be 'row' or 'column'."
)

jac, nlp = get_jacobian(model, scaled=False)
if jac is None or nlp is None:
jac, nlp = get_jacobian(model, scaled=False)

# Get vectors that we will check, and the Pyomo components
# they correspond to.
Expand Down
17 changes: 11 additions & 6 deletions idaes/core/util/tests/test_model_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ def test_collect_numerical_warnings_jacobian(self):

warnings, next_steps = dt._collect_numerical_warnings()

assert len(warnings) == 3
assert len(warnings) == 4
assert (
"WARNING: 2 Variables with extreme Jacobian values (<1.0E-08 or >1.0E+08)"
in warnings
Expand All @@ -1132,7 +1132,7 @@ def test_collect_numerical_warnings_jacobian(self):
)
assert "WARNING: 1 Constraint with large residuals (>1.0E-05)" in warnings

assert len(next_steps) == 3
assert len(next_steps) == 4
assert "display_variables_with_extreme_jacobians()" in next_steps
assert "display_constraints_with_extreme_jacobians()" in next_steps
assert "display_constraints_with_large_residuals()" in next_steps
Expand Down Expand Up @@ -1338,8 +1338,7 @@ def test_report_numerical_issues_ok(self):
Suggested next steps:

If you still have issues converging your model consider:
display_near_parallel_constraints()
display_near_parallel_variables()

prepare_degeneracy_hunter()
prepare_svd_toolbox()

Expand Down Expand Up @@ -1369,9 +1368,11 @@ def test_report_numerical_issues_exactly_singular(self):
Jacobian Condition Number: Undefined (Exactly Singular)

------------------------------------------------------------------------------------
1 WARNINGS
3 WARNINGS

WARNING: 2 Constraints with large residuals (>1.0E-05)
WARNING: 1 pair of constraints are parallel (to tolerance 0.0001)
WARNING: 1 pair of variables are parallel (to tolerance 0.0001)

------------------------------------------------------------------------------------
0 Cautions
Expand All @@ -1382,6 +1383,8 @@ def test_report_numerical_issues_exactly_singular(self):
Suggested next steps:

display_constraints_with_large_residuals()
display_near_parallel_constraints()
display_near_parallel_variables()

====================================================================================
"""
Expand Down Expand Up @@ -1448,11 +1451,12 @@ def test_report_numerical_issues_jacobian(self):
Jacobian Condition Number: 1.407E+18

------------------------------------------------------------------------------------
3 WARNINGS
4 WARNINGS

WARNING: 1 Constraint with large residuals (>1.0E-05)
WARNING: 2 Variables with extreme Jacobian values (<1.0E-08 or >1.0E+08)
WARNING: 1 Constraint with extreme Jacobian values (<1.0E-08 or >1.0E+08)
WARNING: 1 pair of variables are parallel (to tolerance 0.0001)

------------------------------------------------------------------------------------
4 Cautions
Expand All @@ -1468,6 +1472,7 @@ def test_report_numerical_issues_jacobian(self):
display_constraints_with_large_residuals()
display_variables_with_extreme_jacobians()
display_constraints_with_extreme_jacobians()
display_near_parallel_variables()

====================================================================================
"""
Expand Down
Loading