peterdsharpe / AeroSandbox

Aircraft design optimization made fast through computational graph transformations (e.g., automatic differentiation). Composable analysis tools for aerodynamics, propulsion, structures, trajectory design, and much more.
https://peterdsharpe.github.io/AeroSandbox/
MIT License
761 stars 126 forks source link

Airfoil control surface / hinged geometry not smooth #131

Closed benberry3d closed 4 months ago

benberry3d commented 8 months ago

Bug Description / Observed Behavior

When adding a deflected control surface (flap) to an Airfoil object, the resulting geometry / coordinates have more of an abrupt curvature discontinuity than Xfoil's method of adding a circular arc. Not necessarily a bug/wrong, but it does end up giving coefficient results that differ from the Xfoil-created flapped geometry by >10% even at modest deflections. It threw me off for a while when validating the hinged-airfoil results with a pure Xfoil check.

Steps to Reproduce

import aerosandbox as asb
af = asb.Airfoil(name="naca0016").add_control_surface(
    deflection=15.0,
    hinge_point_x=0.7
)
af.draw()

The extended upper-surface "gap" is nearly linear / not filled in smoothly. !

Expected Behavior

Overlayed against Xfoil's GDES routine (blue/green is aerosandbox's geometry), where Xfoil fills in with a smoother circular arc. naca0016_flap_compare

System Information

Other Information

See subroutine FLAP in xfoil (6.99) xgdes.f source file for how Xfoil adds a circular arc: was this approach considered for hinged airfoil geometry in asb?

peterdsharpe commented 7 months ago

Hi Ben,

Thanks for reporting this, and a good question! Tl;dr is that I agree that the circular-arc method is probably the better way to go these days, but there were older motivations back when this AeroSandbox flap handling code was written that motivated this choice.


The original motivation behind the AeroSandbox flap handling was that it preserves the dimensions of the coordinates array (i.e., no new points are deleted and created). This contrasts with XFoil's approach, which both creates new points on the "expanding" side and deletes points on the "contracting" side. The problem with this is that this makes XFoil's logic inherently $C^1$-discontinuous, which causes issues with gradient-based optimization. (As an illustration, if you plot $C_m$ vs flap deflection in pure-XFoil, and you zoom in far enough, that plot is only $C^0$-continuous - it has "sharp peaks" when points are created or destroyed.)

This also causes issues with automatic differentiation in static-graph backends (e.g., CasADi, JAX), which require array shapes to remain static.

A practical example of where both problems might arise would be iteratively varying the deflection to satisfy a trim condition. Another example would be differentiable meshing for a VLM simulation with varying control surface deflections.


Nowadays, the asb.KulfanAirfoil class is recommended to be used instead of the asb.Airfoil class for most cases where the airfoil shape (or control deflections) are not frozen at runtime. For a lot of reasons, asb.KulfanAirfoil is more optimization-friendly than asb.Airfoil (reasons are detailed in one of the tutorials).

Because of that, it would be reasonable to go back to asb.Airfoil.add_control_surface() and add a new keyword argument to optionally support XFoil-like flap behavior, now that breaking differentiability here is potentially less critical. I'm not sure which behavior (current approach or the XFoil circular-arc approach) would be best to have as the default, but it'd probably be best to keep both as options since they both have utility in different use-cases.


I probably don't have time to implement this logic in the near-term, but leaving this issue open in case anyone wants to open a pull request supporting this!

benberry3d commented 7 months ago

Ah ok that all makes sense, for some reason I thought the Xfoil approach was maintaining c1 continuity, thanks for the correction.

I was coming at it more from wanted to evaluate hinge moments than optimization, and Aerosandbox was just a handier/ready-made way to run those sweeps parametrically in Xfoil vs. Xfoil itself!

I'm fine with closing this but up to you.