idaes-pse
idaes-pse copied to clipboard
Dealing with bound_relax_factor
Repeatedly, IPOPT and AMPL cause problems with certain functions for which function evaluation errors are possible (fractional powers, logs, etc). Fortunately, we have display_potential_evaluation_errors in order to avoid these situations. However, even if the user has properly bounded these functions below by zero (or some eps>0), we can still run into problems because IPOPT has the option bound_relax_factor set to 1e-8 by default. I even got caught off-guard today because I bounded a variable below by 1e-7, but that value was transformed to 1e-11 when the Pyomo scaling transformation was applied.
There are two options to deal with this problem:
- Set the default option
bound_relax_factor=0in the IDAES solver config. - Update
display_potential_evaluation_errorsto not just evaluation errors, but also near-evaluation errors.
Option (2) is probably what we'll end up doing. It would be nice to have some discussion, though.
I agree that (2) is probably preferable. However, I think the primary motivation for the bound relaxation is to ensure there is a strict interior to the feasible region. This most often is needed when the lower and upper bounds of a variable are too close (e.g., equal). I think that the presolve in the NL writer should now catch and resolve a lot of these situations, so option (1) might not be a bad idea. Having said all that, I would still favor option (2). Thoughts, @jsiirola?
Not sure if this will be of use, but @bknueven had done some work that involved tweaking bound_relax_factor for ipopt-watertap, which now lives here:
https://github.com/watertap-org/watertap-solvers/blob/main/src/watertap_solvers/_base.py
From one of the older PRs: https://github.com/watertap-org/watertap-solvers/commit/343b99b6794e1d49c4918452ace776e2292e177b
Here is the original PR: https://github.com/watertap-org/watertap/pull/1162. We've had bound_relax_factor turned off in WaterTAP for over a year without issue, as far as I am aware. Users typically explicitly fix the variable if that's what they want. Variables fixed implicitly through bounds and not through a constraint or by calling fix also make the degrees of freedom calculation incorrect, so I imagine it should generally be avoided.
Often times in WaterTAP we wanted a strict inequality anyways, which is what bound_relax_factor == 0 essentially gets you. We had to modify a few bounds on variables as a result in a few places in the codebase, but the number of changes overall was small considering the number of models WaterTAP hosts.
That is super helpful. Thanks @bknueven and @adam-a-a!
So we probably want to implement option (1). However, option (2) could also be useful.
Another thought is to look for possible singularities not just in function evaluations, but also their derivatives. That might be too complex, however.