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

Pyomo AD fails with constant Expressions #2986

Closed
dallan-keylogic opened this issue Sep 5, 2023 · 4 comments · Fixed by #3017
Closed

Pyomo AD fails with constant Expressions #2986

dallan-keylogic opened this issue Sep 5, 2023 · 4 comments · Fixed by #3017
Assignees
Labels

Comments

@dallan-keylogic
Copy link

dallan-keylogic commented Sep 5, 2023

Summary

Pyomo AD raises an error when encountering Expressions with a constant value.

Steps to reproduce the issue

import pyomo.environ as pyo
from pyomo.core.expr.calculus.derivatives import Modes, differentiate

m = pyo.ConcreteModel()

m.x = pyo.Var(units=pyo.units.mol, initialize=0)

@m.Expression()
def y(blk):
    return 2

@m.Expression()
def product(blk):
    return blk.x * blk.y

diff_expr = differentiate(
                expr=m.product,
                wrt=m.x,
                mode=Modes.reverse_symbolic
            )
diff_expr.pprint()

Error Message

Exception has occurred: KeyError
"Component with id '1907001786672': 2.0"
  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\common\collections\component_map.py", line 71, in __getitem__
    return self._dict[id(obj)][1]
KeyError: 1907001786672

During handling of the above exception, another exception occurred:

  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\common\collections\component_map.py", line 73, in __getitem__
    raise KeyError("Component with id '%s': %s" % (id(obj), str(obj)))
  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\core\expr\calculus\diff_with_pyomo.py", line 331, in _diff_GeneralExpression
    der_dict[node.expr] += der_dict[node]
  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\core\expr\calculus\diff_with_pyomo.py", line 442, in _reverse_diff_helper
    _diff_GeneralExpression(e, val_dict, der_dict)
  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\core\expr\calculus\diff_with_pyomo.py", line 484, in reverse_sd
    return _reverse_diff_helper(expr, False)
  File "C:\Users\[REDACTED]\Repos\pyomo\pyomo\core\expr\calculus\derivatives.py", line 96, in differentiate
    res = reverse_sd(expr=expr)
  File "C:\Users\[REDACTED]\Desktop\diff_expr.py", line 16, in <module>
    diff_expr = differentiate(
KeyError: "Component with id '1907001786672': 2.0"

Information on your system

Pyomo version: 6.6.2
Python version: 3.10.10 | packaged by Anaconda, Inc. | (main, Mar 21 2023, 18:39:17) [MSC v.1916 64 bit (AMD64)]
Operating system: Windows 10
How Pyomo was installed (PyPI, conda, source): From sources
Solver (if applicable): n/a

@mrmundt
Copy link
Contributor

mrmundt commented Sep 5, 2023

@dallan-keylogic - please provide this information:

Information on your system

Pyomo version:
Python version:
Operating system:
How Pyomo was installed (PyPI, conda, source):
Solver (if applicable):

@dallan-keylogic
Copy link
Author

@mrmundt Added to the main issue.

@michaelbynum michaelbynum self-assigned this Sep 5, 2023
@dallan-keylogic
Copy link
Author

@michaelbynum , any idea when this is going to be fixed? I want to use AD for calculating excess enthalpy as part of the IDAES eNRTL models.

@dallan-keylogic
Copy link
Author

Previously, I was able to work around this issue by replacing every "0" in my code with a constant zero Param with appropriate units. Unfortunately, I ran into this issue again today because I want to use the eNRTL property package without ions (because I don't want to code up a separate NRTL property package), and the sum over an empty set evaluates to zero. My attempt to fix this by adding a dimensionless zero to the sum doesn't appear to be working.

        dimensionless_zero = Param(initialize=0.0, mutable=False, doc="Dimensionless zero to avoid issue with AD (Pyomo 6.6.2)")
        b.add_component(
            pname + "_dimensionless_zero",
            dimensionless_zero,
        )
        # Ionic Strength
        def rule_I(b):  # Eqn 62
            dimensionless_zero = getattr(b, pname + "_dimensionless_zero")
            return 0.5 * sum(
                b.mole_frac_phase_comp_true[pname, c]
                * b.params.get_component(c).config.charge ** 2
                for c in b.params.ion_set
            ) + dimensionless_zero # TODO get rid of this once Pyomo fixes their AD

b.Liq_ionic_strength.expr
<pyomo.core.expr.numvalue.NumericConstant object at 0x00000225F7B5E860>

It would be nice to have a fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants