NACA airfoil max. camber as opti.variable #110
-
|
Dear @peterdsharpe and colleagues, I'm trying to optimize wing camber distribution along it span. I'm using asb.VortexLatticeMethod to evaluate wing CL and CDi. But there is a problem when I set max_camber of NACA as opti.variable. I get the error message shown below. So I'm wondering if this is implemented in AeroSandBox? (It worked fine when I used wing twist as opti.variable). My code is as follows: Thanks. Kind regards, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Hey Jan, Thanks for writing in! A good question. CauseThe high-level cause of this error is that:
Solution for Immediate ProblemFirst, for the immediate question - the fix here is to use Implemented, the fixed code looks like: import aerosandbox as asb
import aerosandbox.numpy as np
af_thickness_mode = asb.Airfoil(
name="NACA Thickness",
coordinates=asb.geometry.airfoil.airfoil_families.get_NACA_coordinates(max_camber=0, camber_loc=0.5, thickness=0.1)
).to_kulfan_airfoil()
af_camber_mode = asb.Airfoil(
name="NACA Camber",
coordinates=asb.geometry.airfoil.airfoil_families.get_NACA_coordinates(max_camber=0.01, camber_loc=0.5, thickness=0)
).to_kulfan_airfoil()
def get_aero(Nsa, camber, alpha):
# depsg = np.concatenate((0, depsg), axis=0)
xtip = 0 # m
ytip = 1.9 # m
ztip = 0 # m
croot = 0.6
ctip = 0.6
epsg = np.zeros(Nsa)
xmac = 0
cmac = 0.6
xsa = np.linspace(0, xtip, Nsa)
ysa = np.linspace(0, ytip, Nsa)
zsa = np.linspace(0, ztip, Nsa)
csa = np.linspace(croot, ctip, Nsa)
af = asb.KulfanAirfoil(
**{
k: camber / 0.01 * af_camber_mode.kulfan_parameters[k] + af_thickness_mode.kulfan_parameters[k]
for k in af_camber_mode.kulfan_parameters.keys()
}
)
aero_model = asb.Airplane(
name="Bwing",
xyz_ref=[xmac + 0.25 * cmac, 0, 0],
wings=[
asb.Wing(
name="Wing",
xyz_le=[0, 0, 0],
symmetric=True,
xsecs=[
asb.WingXSec(
xyz_le=[xsa[i], ysa[i], zsa[i]],
chord=csa[i],
twist=epsg[i],
airfoil=af
) for i in range(Nsa)
]
)
]
)
vlm = asb.VortexLatticeMethod( # NOTE: Recommend substituting this for asb.LiftingLine for this particular problem
airplane=aero_model,
op_point=asb.OperatingPoint(
velocity=21.3, # m/s
alpha=alpha # degree
),
spanwise_resolution=3,
spanwise_spacing_function=np.linspace,
verbose=True
)
return vlm.run()
def main():
print(asb.__version__)
Nsa = 9
CLw = 0.609
opti = asb.Opti()
alpha = opti.variable(init_guess=5.3, lower_bound=2., upper_bound=9.)
camber_init = 0.02 # * np.ones((Nsa,))
camber_lo = 0.02 # np.ones((Nsa,)) * 0.02
camber_up = 0.08 # np.ones((Nsa,)) * 0.08
camber_sec = opti.variable(init_guess=camber_init, lower_bound=camber_lo, upper_bound=camber_up)
aero = get_aero(Nsa, camber_sec, alpha)
opti.subject_to(aero["CL"] == CLw)
opti.minimize((-1 * aero["CL"] ** 3 / 2) / aero["CD"])
# opti.set_value()
sol = opti.solve(max_iter=15, behavior_on_failure="return_last")
print(sol.value(camber_sec))
print(sol.value(alpha))
return
if __name__ == "__main__":
print("Running test")
main()Basically what we're doing here is pre-computing Kulfan-parameterized airfoil mode shapes representing "thickness" and "camber", then linearly combining them to achieve the desired NACA airfoil shape. Finally, on a physics level, you may want to substitute Notes for ASB DevsFrom this issue, there are a few actionable outcomes the team can work on:
|
Beta Was this translation helpful? Give feedback.
Hey Jan,
Thanks for writing in! A good question.
Cause
The high-level cause of this error is that:
asb.VortexLatticeMethod,asb.LiftingLine, and similar aero analyses need to discretize the wing geometry to work (i.e., make a surface mesh).asb.Airfoilobject), this meshing logic currently needs to be able to identify which index of the airfoil coordinates array is the leading edge.asb.Airfoil.coordinatesvariable is an optimization variable (as opposed to a non-changing NumPy array), the solver can't "guarantee" that the leading edge index won't change throughout airfoil shape optimization as coordinates move aro…