Reputation: 13
If multiple solvers are attached to the model as external code components (complete black boxes) is there a way to implement adjoint method?
Many of the usages of openMDAO that I have seen so far seems to use some black box flow solvers or structural solvers etc.
But I dont see how one can implement an adjoint method without touching the source codes.
As it is also unlikely to implement a complex step method. The only way is finite difference if one wants to use a gradient based optimizer?
Upvotes: 1
Views: 335
Reputation: 5710
You can implement a semi-analytic adjoint method, even if you don't have any analytic derivatives in your model. Assume you have a single black-bock code, that has an internal solver to converge some implicit equations before computing some set of output values. You wrap the code in OpenMDAO as an ImplicitComponent, using custom file wrapper. (note: You can't use the ExternalCode component because it is a sub-class of ExplicitComponent)
In your new wrapper, you will implement two methods in your custom ImplicitComponent:
The first method is simply the normal run of your code. The second method however takes the input values and given output values and computes a residual.
Then in order to get partial derivatives, OpenMDAO will finite-difference the apply_linear
method to compute dResidaul_dinputs and dResidual_dOutputs, which it can then use to compute total derivatives using reverse (or adjoint) mode.
This approach is typically both more efficient and more accurate then wrapping the code as an ExplicitComponent. First of all, the apply_nonlinear
method (residual evaluation) should be very significantly less expensive the solve_nonlinear
method, so the finite-difference should be much cheaper. Perhaps more importantly though, finite-difference across a residual evaluation should be much more accurate than when you finite-difference around a full solver convergence loop (see this technical paper for an example of why that is).
There are a few things to note in this approach. First, there may be a large number of residual equations and implicit variables. So you may be doing many more finite-difference calls than if you wrapped your code as an ExplicitComponent. However, since the residual evaluation is much cheaper it should be acceptable. Second, not all codes have the ability to return residual evaluations, so that might require some modification of the black-box. Without the residual evaluation, you can't use an adjoint method.
One other general approach is to mix codes with analytic derivatives and finite-difference partial derivatives. Lets say you have an expensive CFD analysis that does have an existing adjoint, and you want to couple in a inexpensive black-box code. You can finite-difference the black-box code to compute its partials, and then OpenMDAO will use those with the exisiing adjoint to compute semi-analytic total derivatives.
Upvotes: 1