You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was having problems with the "Bubble, dew, and critical point initialization" step in the generic property package initialization. I ended up finding out that the initial guess for temperature_bubble was higher than that of temperature_dew, which I suspect was the key cause of infeasibility. I then had a look through the estimate_Tbub and estimate_Tdew methods in idaes.models.properties.modular_properties.base.utility. These use Newton's method to converge on a guess for temperature_bubble and temperature_dew respectively. I eventually realized that I was hitting the iteration limit of 30, which meant I got a bad guess which would cause major issues.
I was able to resolve this by increasing the iteration limit via idaes.models.properties.modular_properties.base.utility.MAX_ITER = 1000. This ended up giving me a much better guess since I was actually converging rather than stopping early. Note, I don't have much chemical engineering knowledge, so I am not sure if this is a sign of a modelling error.
I decided to open this issue since it took me a while to debug.
Potential actions:
a) Log a warning:
At a minimum, I think a warning should be logged if MAX_ITER is reached in the estimate_Tbub and estimate_Tdew methods.
b) Increase default max iterations:
Assume that failing to converge in MAX_ITER iterations will cause major issues, so increase the default number of max iterations. The argument against this is that a poorly-defined model (ie. one that never manages to converge) would take extra time to end up reaching the same result. Also, I can imagine if MAX_ITER were set to something like 100 instead of 30, I never would have realized there was an issue (and then we get "flaky" initialization when a more complex model is used, which is not fun). However, some combination of a) and b) may be useful.
c) Switch to a solver instead of using Newton's method
Despite the added overhead, I was able to get increased performance (time-wise) by defining the model in pyomo and solving externally rather than solving directly in python. ipopt could solve in ~"3-5 iterations" compared to what was ~60 iterations when using Newton's method in python. I imagine it is more scalable too (for complex models).
For example,
def_custom_estimate_Tbub(blk, T_units, raoult_comps, henry_comps, liquid_phase):
""" Function to estimate bubble point temperature Args: blk: StateBlock to use T_units: units of temperature raoult_comps: list of components that follow Raoult's Law henry_comps: list of components that follow Henry's Law liquid_phase: name of liquid phase Returns: Estimated bubble point temperature as a float. """# Use lowest component temperature_crit as starting point# Starting high and moving down generally works better,# as it under-predicts next step due to exponential form of# Psat.# Subtract 1 to avoid potential singularities at TcritTbub_initial= (
min(blk.params.get_component(j).temperature_crit.valueforjinraoult_comps)
-1
)
blk.tbub_initialize=Block()
m=blk.tbub_initializem.Tbub=Var(initialize=Tbub_initial)
m.f=Expression(expr=(
sum(
get_method(blk, "pressure_sat_comp", j)(
blk, blk.params.get_component(j), m.Tbub*T_units
)
*blk.mole_frac_comp[j]
forjinraoult_comps
)
+sum(
blk.mole_frac_comp[j]
*blk.params.get_component(j)
.config.henry_component[liquid_phase]["method"]
.return_expression(blk, liquid_phase, j, m.Tbub*T_units)
forjinhenry_comps
)
-blk.pressure
))
m.df=Expression(expr=(
sum(
get_method(blk, "pressure_sat_comp", j)(
blk, blk.params.get_component(j), m.Tbub*T_units, dT=True
)
*blk.mole_frac_comp[j]
forjinraoult_comps
)
+sum(
blk.mole_frac_comp[j]
*blk.params.get_component(j)
.config.henry_component[liquid_phase]["method"]
.dT_expression(blk, liquid_phase, j, m.Tbub*T_units)
forjinhenry_comps
)
))
m.tbub_constraint=Constraint(rule=(
m.Tbub==m.Tbub-m.f/m.df
))
solver=get_solver("ipopt")
solver.options["tol"] =TOL# default currently 1e-1solver.options["max_iter"] =MAX_ITER# default currently 30solver.solve(m)
# probably need to check for infeasibility here# ...delblk.tbub_initialize# cleanupreturnm.Tbub.value
Feedback would be useful 🙂
The text was updated successfully, but these errors were encountered:
Summary
I was having problems with the "Bubble, dew, and critical point initialization" step in the generic property package initialization. I ended up finding out that the initial guess for
temperature_bubble
was higher than that oftemperature_dew
, which I suspect was the key cause of infeasibility. I then had a look through theestimate_Tbub
andestimate_Tdew
methods inidaes.models.properties.modular_properties.base.utility
. These use Newton's method to converge on a guess fortemperature_bubble
andtemperature_dew
respectively. I eventually realized that I was hitting the iteration limit of 30, which meant I got a bad guess which would cause major issues.I was able to resolve this by increasing the iteration limit via
idaes.models.properties.modular_properties.base.utility.MAX_ITER = 1000
. This ended up giving me a much better guess since I was actually converging rather than stopping early. Note, I don't have much chemical engineering knowledge, so I am not sure if this is a sign of a modelling error.I decided to open this issue since it took me a while to debug.
Potential actions:
a) Log a warning:
MAX_ITER
is reached in theestimate_Tbub
andestimate_Tdew
methods.b) Increase default max iterations:
MAX_ITER
iterations will cause major issues, so increase the default number of max iterations. The argument against this is that a poorly-defined model (ie. one that never manages to converge) would take extra time to end up reaching the same result. Also, I can imagine ifMAX_ITER
were set to something like 100 instead of 30, I never would have realized there was an issue (and then we get "flaky" initialization when a more complex model is used, which is not fun). However, some combination of a) and b) may be useful.c) Switch to a solver instead of using Newton's method
ipopt
could solve in ~"3-5 iterations" compared to what was ~60 iterations when using Newton's method in python. I imagine it is more scalable too (for complex models).For example,
Feedback would be useful 🙂
The text was updated successfully, but these errors were encountered: