Reputation: 83
I'm using the pyOptSparseDriver
and my optimizer is SLSQP
. I have a design variable A
defined with
ivc = om.IndepVarComp()
ivc.add_output("A", 2.00)
...
prob.model.add_design_var("A", lower=1.6, upper=5.00, ref=1.6)
A
represents the aspect ratio of a torus, so it always needs to be larger than 1 to make physical sense; here I've given it a slightly higher 'reasonable' lower bound.
In a component -- actually the first component in the first group in the model -- I see that A
is being given negative values in its input, and even nan
(which results in errors and eventually halting the code). The component is an ExplicitComponent
and the group that it's in does not have a specific solver attached; the n2
shows that it's LN:RUNONCE
.
Is this expected behavior? Is there a way to prevent this from happening?
Changing from pyOptSparseDriver
to ScipyOptimizerDriver
results in not raising this issue, but I might like to use the former for other reasons.
I have other variables named A
elsewhere in the model (but encapsulated within groups) so I suspected this might be a bug related to naming; I tried renaming A
to Asp
(which is unique in my model) but the issue still occurred.
I tried removing parts of the model after this initial group, but in doing so I had to change the objective function. Then, the issue no longer occurred.
Later in the model I have a group with a NewtonSolver
, which I'll call secondsolver
. It uses a Armijo linesearch with the default parameters for rho
and c
.
newton.linesearch = om.ArmijoGoldsteinLS(retry_on_analysis_error=True,
rho=0.5, c=0.1, method="Armijo", bound_enforcement="vector")
I added a print
statement the component's compute function; when I run the code it outputs
...
===========
thirdsolver
===========
NL: Newton 0 ; 6.54500652 1
| LS: BCHK 0 ; 0.000394994169 6.03504623e-05
NL: Newton 1 ; 4.4408921e-17 6.7851607e-18
NL: Newton Converged
A in compute is [-37490.25190183]
A in compute is [-18743.90453135]
A in compute is [-9370.73084611]
A in compute is [-4684.1440035]
A in compute is [-2340.85058219]
A in compute is [-1169.20387153]
A in compute is [-583.3805162]
A in compute is [-290.46883854]
A in compute is [-144.01299971]
A in compute is [-70.78508029]
A in compute is [-34.17112058]
<test.py>:104: RuntimeWarning: invalid value encountered in power
<problematic line here; it's from the
analytic derivative of this first component, where A is being raised to a small, constant, nonzero power>
A in compute is [nan]
Here thirdsolver
is a NewtonSolver
later in the model. Maybe the printing is occurring out-of-order? Anyway, the values for A
each differ by a factor of 2 (at least at the higher values), so perhaps that's related to rho=0.5
. If I change the parameters rho
or c
on that linesearch the error no longer occurs.
I can slightly change one of those parameters and move on, but if there's a better explanation for what's going on, I'd like to be able to avoid it in the future.
Upvotes: 1
Views: 186
Reputation: 5710
In older versions of SLSQP, there were bugs in the design variable bounds enforcement. This was fixed in the scipy SLSQP code base, but never in the pyoptsparse one. In other words the SLSQP code in the two code bases is not the same, and has diverged a bit. That explains why ScipyOptimizerDriver is respecting your bounds and pyOptSparseDriver is not (when using SLSQP). If you switch to IPOPT in pyOptSparse, then it would respect your bounds.
Upvotes: 1