I am setting up a multi-fidelity optimiztion routine using OpenMDAO, with all computations done by a high-fidelity solver and gradient computations done by a low-fidelity solver.
So far I have set it up with three components in a group: component 1 performs the high-fidelity calculations; component 2 performs the low-fidelity calculations at three design points - one point is used for calculation of a tunning factor between high and low fidelity, and the other two are used to compute the derivatives with a central difference (coded "by hand"). The outputs of component 1 (some absolute responses) and derivatives from component 2 are then passed to component 3, which defines design objectives and constraints. In this component, I declare the partials of objectives and constraints w.r.t. design variables as analytic, but then in the compute_partials I simply set them to the values passed from component 2.
Is there a more elegant way to handle this kind of setup in OpenMDAO?
I would like to also ensure that OpenMDAO does not compute other derivatives and only uses the ones provided "analytically". My understanding is that if I skip the setup_partials on components 1 and 2, these will not be computed in any way. Is that correct?
Happy to provide more information if needed.
I would appreciate any advice.
I don't think skipping the
setup_partialson the two upstream components will work here. OpenMDAO's derivatives solvers, in the absence of any solver loops or cyclic data connections, can be thought of as equivalent to the chain rule. By leaving out thesetup_partialsof the upstream components you're essentially setting those to 0, so the chain rule will zero everything out.OpenMDAO wasn't designed to support the approach you're using here. Its definitely possible to trick it into doing it by setting some partials in the upstream components to 1 (so the chain rule basically ignores them), but the result would be a dirty hack and I hesitate to even write up a sample. You would be able to get "correct" totals, but all your partials would look wrong and I just think its a bad idea.
Instead, I'd suggest you combine your high/low fidelity solvers into a single OM component. Implement both the high and low solves in
computeand then do the necessary derivative calculations in thecompute_partials(or implicit component equivalents).If you provide a sample toy script, Id be willing to modify it to show you what I mean in more detail. But generally, "hidding" the multi-fidelity behavior all inside a single component is the better approach IMO.