linearize and make_dual_shadow accept a BodyAerodynamics with more than one wing
Split out of #330 (stability derivatives and trim search on linearize), which needs it to cover multi-wing bodies.
linearize (src/solver.jl, the length(body_aero.wings) == 1 guard) and make_dual_shadow (its own one-wing guard) reject a body with two wings. The va and omega columns need nothing per wing; theta_idxs/delta_idxs are one entry per unrefined section of the one wing, so for several wings they would run over the unrefined sections of all wings in order, matching moment_unrefined_dist, which the solver already sizes by the sum over wings.
Test: the two-wing bodies in test/body_aerodynamics/test_body_aerodynamics.jl (solve! on a two-wing body), Jacobian against AutoFiniteDiff as test/solver/test_forwarddiff.jl does for one wing.
linearize and make_dual_shadow accept a BodyAerodynamics with more than one wing
Split out of #330 (stability derivatives and trim search on linearize), which needs it to cover multi-wing bodies.
linearize(src/solver.jl, thelength(body_aero.wings) == 1guard) andmake_dual_shadow(its own one-wing guard) reject a body with two wings. Thevaandomegacolumns need nothing per wing;theta_idxs/delta_idxsare one entry per unrefined section of the one wing, so for several wings they would run over the unrefined sections of all wings in order, matchingmoment_unrefined_dist, which the solver already sizes by the sum over wings.Test: the two-wing bodies in
test/body_aerodynamics/test_body_aerodynamics.jl(solve! on a two-wing body), Jacobian against AutoFiniteDiff astest/solver/test_forwarddiff.jldoes for one wing.