Aerodynamic Shape Optimization

Now that we have set up the geometry parameterization, the top-level run script, aero_opt.py, closely resembles a wing-only aerodynamic shape optimization case. We set up the MACH modules by calling the setup functions in sequence.

# ======================================================================
# Set up MACH modules
# ======================================================================

# Set up AeroProblem
ap = setup_aeroproblem.setup()

# Set up ADflow
CFDSolver, CFDPointSetKwargs = setup_adflow.setup(comm, gridFile, outDir)

# Set up IDWarp
mesh = setup_idwarp.setup(comm, gridFile)
CFDSolver.setMesh(mesh)

# Set up DVGeometry
DVGeo = setup_dvgeo.setup(args.inputdir, args.dvs)

# Add DVGeometry object to CFD solver
CFDSolver.setDVGeo(DVGeo, CFDPointSetKwargs)

# Set up DVConstraints
DVCon = setup_dvcon.setup(comm, outDir, DVGeo, CFDSolver, args.dvs)

One difference from a more conventional optimization is that we pass CFDPointSetKwargs to the ADflow object when setting the DVGeometry object. This dictionary is defined in SETUP/setup_adflow.py.

    # Set point set arguments for DVGeoMulti
    CFDPointSetKwargs = {
        "applyIC": True,
        "comm": comm,
    }

Important

You must set applyIC if you want the intersection method to work! It is False by default so the DVConstraints do not get affected by the intersection method.

Setting applyIC tells DVGeometryMulti that the CFD surface mesh must follow the intersection curves. This ensures that the outer mold line remains watertight when the intersection is updated. The comm argument tells DVGeometryMulti that the CFD point set is distributed across the processors on the specified communicator object.

We can run the optimization with several combinations of geometric design variables by passing the dvs argument to aero_opt.py. The possible values for the argument are defined with permutations from the itertools module in Python.

# Get all possible permutations of the DV string
all_DVs = "ftshv"
all_DV_permutations = []

for i in range(1, len(all_DVs) + 1):
    for perm in permutations(all_DVs, i):
        all_DV_permutations.append("".join(perm))

parser.add_argument("--dvs", default="fts", choices=all_DV_permutations)

For example, we can optimize with fuselage and twist variables using python aero_opt.py --dvs=ft. Running an optimization with this configuration in a reasonable time will most likely require using HPC resources.