Adjoint-based optimization