Closed kanekosh closed 2 years ago
Thanks for pointing this out. Definitely something odd going on, looking into it.
On my system the lower/upper for the boundary constraints are unaffected by the state ref0, but the value is unable to be satisfied, offset by the ref0.
This has to do with OpenMDAO providing an incorrect jacobian for linear constraints due to the interplay between the scaling on the design variable (state h) and the boundary constraint on state h. Please try to make the ref and ref0 the same for both of those, and I think it will work.
We should offer the ability to override the linearity of a constraint (at least to turn a linear constraint into a nonlinear one). An issue is posted for that and we'll address it shortly.
Hopefully either of those two approaches can serve as a workaround until we address the core issue.
Thank you for a quick response. Yes, it worked by setting the same ref0
for both add_state
and add_boundary_constraint
. Actually ref
doesn't seem to matter here: setting the same ref0
but different ref
also worked.
Yes we noticed that too. It has to do with ref0
(or adder
if you're using scaler/adder instead of ref/ref0). Thanks for bringing this to our attention and the good example cases.
It turns out that there is a fundamental problem with linear constraints in pyoptsparse, namely that it assumes that con = A * desvar
instead of con = A * desvar + b
. This explains why giving the state and the boundary constraint the same adder
worked, as it removed the bias.
I've opened an issue on the pyoptsparse repo. In the meantime, we will have to be careful how we use linear constraints (particularly, we'll have to check the ones we use in dymos).
Issue Type
Description
The boundary constraint on state variables seems not to work as it should when specifying
ref0
inphase.add_state()
. Specifically, the state boundary constraint seems to be shifted whenref0
is declared inadd_state
.Example
Here, I will try to demonstrate the potential bug using the supersonic minimum-time climb example.
Case 1 Please see here for the full running script.
For this case, I added
ref0=10
inphase.add_state('h', ...)
line. I believe this slight change in scaling should not change the optimization behavior that much. However, the optimizer fails saying the problem is infeasible (SNOPT exit code 10/14).Case 2 Please see here for the full running script, and this link for the pyOptSparse output.
For this case, I also modified the final boundary constraint of
h
to be19990 <= h <= 20000
(originally it was an equalityh=20000
). Then optimization converges to the same solution as the original example, where the final altitude ish=20000
. Therefore it hit the upper bound of the final boundary constraint ofh
.However, pyOptSparse output says it is hitting the lower bound of the boundary constraint:
Environment
Operating System: Ubuntu 20.04 Python environment: 3.7.4 Packages: Dymos 1.4.0, OpenMDAO 3.17.0, pyOptSparse 2.6.2.