Options

gridFile: str = default.cgns

This is the grid file to use. It must be a multiblock structured or overset CGNS file containing all block-to-block information and boundary condition information.

restartFile: str or list or NoneType = None

Accepts a single string or a list of strings pointing to a CGNS file(s) which must be a volume solution file that was written by ADflow. For steady state restart, one CGNS file is sufficient and does not need to be provided as a list with a single item. For unsteady restart, you typically provide a list with 2 items for second order restart.

meshSurfaceFamily: str or NoneType = None

This is a custom family that can be defined to identify the surface mesh to ADflow. This variable is used to set self.meshFamilyGroup in pyADflow. If None, all wall surfaces are used as the surface mesh. This information is later used for mesh warping and surface output related operations.

designSurfaceFamily: str or NoneType = None

This is the custom family that is used to define what part of the surface mesh is the “design” surface, meaning that the surface might be modified geometrically. This variable is used to set self.designFamilyGroup in pyADflow. If None, all wall surfaces are used as the design surface. This can be useful when you want to distinguish between regular surface nodes and design surface nodes. The regular nodes will not change as the design is updated, but they are still included in meshFamilyGroup for mesh warping purposes.

closedSurfaceFamilies: list or NoneType = None

This is the set of surfaces that form a closed surface. This information is used in the overset initialization to figure out the wall cells. If None, all wall surfaces are used.

storeRindLayer: bool = True

Flag to write halo or “rind cell” information into CGNS files. This is required for some postprocessors (such as Tecplot) to compute contour lines correctly.

outputDirectory: str = ./

Directory where output files are written.

outputSurfaceFamily: str = allSurfaces

The family included in surface output files.

writeSurfaceSolution: bool = True

Flag to write surface solution (automatically) after the end of each solution call.

writeVolumeSolution: bool = True

Flag to write volume solution (automatically) after the end of each solution call.

writeSolutionEachIter: bool = False

Flag to write solution files after every nonlinear solver iteration. The solution files written depend on writeTecplotSurfaceSolution, writeVolumeSolution, and writeSurfaceSolution. This useful when debugging or developing the solver.

writeTecplotSurfaceSolution: bool = False

Flag to write a surface output in Tecplot format. This can be useful because it requires less tweaking in Tecplot to get the end result. This also includes the zipper mesh and only the active overset cells if a zipper mesh was created.

nSaveVolume: int = 1

When running unsteady simulations, the volume output will be written every this many unsteady iterations.

nSaveSurface: int = 1

When running unsteady simulations, the surface output will be written every this many unsteady iterations.

solutionPrecision: str = single

The precision used when writing volume solution files.

  • single: This is the best option if you are not planning on using restart files. The output files will be half the size, and the accuracy should be enough for visualization purposes.

  • double: This is best used for restart files.

gridPrecision: str = double

The precision used when writing the volume mesh in volume output files.

  • double: This is preferred, especially for RANS grids because lower precision can adversely affect the cells in the boundary layer.

  • single: This is not typically used.

solutionPrecisionSurface: str = single

The precision used when writing surface solution files.

  • single: This results in a smaller file at the cost of accuracy. The accuracy should be enough for visualization purposes.

  • double: This is preferred for running numerical analyses using the data from the output files.

gridPrecisionSurface: str = single

The precision used when writing the surface mesh in surface output files.

  • single: This results in a smaller file at the cost of accuracy. The accuracy should be enough for visualization purposes.

  • double: This is preferred for running numerical analyses using the data from the output files.

isosurface: dict = {}

Dictionary specifying the type and values to be used for isosurfaces. Any of the volumeVariables may be used. An example dictionary is : {"Vx":-0.001, "shock":1.0}. This will place an isosurface at (essentially) 0 x-velocity and an isosurface at the shock sensor value of 1 (used to visualize the shock region).

isoVariables: list = []

The state variables to be included on the isosurfaces requested with the isosurface option.

viscousSurfaceVelocities: bool = True

Only applicable for RANS and laminar NS computations. Write surface velocities as the value on the first cell off the wall. This means that the velocities on the surface will not be zero as enforced by the boundary conditions. This option enables postprocessing software to compute oil-flow surface streamline patterns.

discretization: str = central plus scalar dissipation

Set the discretization method. The default is generally recommended for both robustness and speed, at the cost of numerical accuracy.

  • central plus scalar dissipation: Uses a central finite volume scheme with JST scalar dissipation.

  • central plus matrix dissipation: Uses a central finite volume scheme with JST matrix dissipation. This scheme may be beneficial for poor meshes but might show minimal improvements on pyHyp meshes for a well posed problem. For convergence issues try lowering vis4 to 0.1 and lowering the CFL number.

  • upwind: Uses an upwind scheme.

coarseDiscretization: str = central plus scalar dissipation

Set the discretization method for the coarse grid. Generally should be the same as the discretization option.

  • central plus scalar dissipation: Uses a central finite volume scheme with JST scalar dissipation.

  • central plus matrix dissipation: Uses a central finite volume scheme with JST matrix dissipation. This scheme may be beneficial for poor meshes but might show minimal improvements on pyHyp meshes for a well posed problem. For convergence issues try lowering vis4 to 0.1 and lowering the CFL number.

  • upwind: Uses an upwind scheme.

limiter: str = van Albada

Type of flux limiter to use for the upwind scheme.

  • van Albada: van Albada

  • minmod: Minmod

  • no limiter: No limiter

smoother: str = DADI

Type of smoother to use with the multigrid solver.

  • DADI: Diagonalized diagonally dominant alternating direction implicit (D3ADI) scheme. This is typically faster than the Runge-Kutta scheme but may be less robust.

  • Runge-Kutta: Five-stage fourth-order low-memory explicit Runge–Kutta time stepping scheme.

equationType: str = RANS

The type of equations to solve.

  • RANS: Reynolds-averaged Navier-Stokes

  • Euler: Euler

  • laminar NS: laminar Navier-Stokes

equationMode: str = steady

The temporal mode of the equations to solve.

  • steady: Extensively tested

  • unsteady: Not well tested

  • time spectral: Extensively tested

flowType: str = external

Type of flow simulation.

  • external: Extensively tested

  • internal: Not well tested

turbulenceModel: str = SA

The turbulence model to use for RANS simulations.

  • SA: Spalart-Allmaras. This is the recommended option for external aerodynamic flow applications because it is the only turbulence model that has been differentiated. This is also the only turbulence model that is tested.

  • SA-Edwards: Spalart-Allmaras with Edwards Modification

  • k-omega Wilcox: Wilcox k-omega

  • k-omega modified: Wilcox modified k-omega

  • k-tau: k-tau

  • Menter SST: Menter SST k-omega

  • v2f: v2-f

turbulenceOrder: str = first order

The numerical order of accuracy of the turbulence model.

  • first order: The recommended approach because the adjoint systems are much easier to solve with the first order discretization

  • second order: Not typically used

turbResScale: float or list or NoneType = None

This parameter affects how the total residual is scaled. It is set automatically, depending on what turbulence model you select. The defaults are usually sufficient. Depending on the turbulence model, values can be a float scalar to a 4 element list of floats. Refer to the list below for the defaults and the type of input expected:

  • SA - Type: float scalar - Default: 10e4

  • SA-Edwards - NOT IMPLEMENTED

  • k-omega Wilcox - NOT IMPLEMENTED

  • k-omega modified - NOT IMPLEMENTED

  • k-tau - NOT IMPLEMENTED

  • Menter SST - Type: float list of 2 elements - Default: [1e3, 1e-6]

  • v2f - NOT IMPLEMENTED

meshMaxSkewness: float = 1.0

Adflow throws an error and fails if the skewness of the mesh is above this value. Skewness is defined as described here. Only used when useSkewnessCheck is active.

useSkewnessCheck: bool = False

When set to true, ADflow computes the skewness of each cell and throws an error if it is above meshMaxSkewness. See also printBadlySkewedCells.

turbulenceProduction: str = strain

How to compute the production term in the turbulent kinetic energy equation (k equation). Only valid for turbulence models that involve k.

  • strain: Use the strain formulation

  • vorticity: Use the vorticity formulation

  • Kato-Launder: Use the Kato-Launder formulation

useQCR: bool = False

Use the QCR2000 version of the Spalart-Allmaras turbulence model.

useRotationSA: bool = False

Use the rotation correction with the Spalart-Allmaras turbulence model.

useft2SA: bool = True

Include the ft2 term in the Spalart-Allmaras turbulence model.

eddyVisInfRatio: float = 0.009

Free stream value of eddy viscosity. See here for more details.

useWallFunctions: bool = False

Flag specifying if wall functions are to be used. This is generally not recommended since they give (potentially very) poor drag estimates. Furthermore, the required routines are not differentiated, so wall function simulations cannot be used for optimization.

useApproxWallDistance: bool = True

Flag to use a cheap wall distance calculation. When True, the exact wall distances are computed during initialization and the parametric location of the closest wall point is stored for each cell. After the geometry deforms (such as during an optimization) the spatial search algorithm is not run, but the distance between the (new) parametric location and the (new) grid cell center is computed and taken as the wall distance. This is substantially faster and permits efficient wall-distance updates for use in aerostructural analysis.

eulerWallTreatment: str = linear pressure extrapolation

Specifies how wall boundary conditions are implemented for inviscid simulations. Generally, the default value does not need to be changed.

  • linear pressure extrapolation: Known to work with the adjoint method

  • constant pressure extrapolation: Known to work with the adjoint method

  • quadratic pressure extrapolation: Not tested

  • normal momentum: Not tested

viscWallTreatment: str = constant pressure extrapolation

Specifies how wall boundary conditions are implemented for viscous simulations. Generally, the default value does not need to be changed.

  • constant pressure extrapolation: Standard

  • linear pressure extrapolation: Not typically used

dissipationScalingExponent: float = 0.67

Exponent factor to use in the JST dissipation scheme. This value typically will not need to be changed from the default. The value of 2/3 is the theoretical best value assuming an orthogonal 3-dimensional grid.

acousticScaleFactor: float = 1.0

A factor that multiplies the acoustic contribution in the spectral radius computation. This only applies to the central plus scalar dissipation discretization. The spectral radius is used to compute dissipation terms, so this option affects the amount of dissipation in the solution. A value of 1.0 will compute the spectral radius with acoustic and advective contributions weighted according to the standard JST scheme. Values lower than 1.0 will result in more accurate solutions for low Mach number flows, but using too small a value will slow down convergence. Setting this to the freestream Mach number tends to work well for most low Mach number cases. Values greater than 1.0 should not be used because this will compromise the accuracy of the solution. See “Improving the Performance of a Compressible RANS Solver for Low and High Mach Number Flows” (Seraj2022c) for details.

vis4: float = 0.0156

Coefficient of the fourth order dissipation used in the scalar and matrix JST dissipation scheme. The default value is generally recommended if a converged solution can be obtained. It may be raised slightly in the range of 0.02-0.025 which may help achieve better convergence properties at the expense of numerical accuracy.

vis2: float = 0.25

Coefficient of the second order dissipation used in the scalar and matrix JST dissipation schemes. This dissipation is only turned on at shocks, and thus may be set to 0.0 if the user knows a simulation will be entirely subsonic.

vis2Coarse: float = 0.5

The value of vis2 used for the coarse grid. This is typically larger than vis2. The default value of 0.5 is usually sufficient for most cases.

restrictionRelaxation: float = 0.8

The relaxation factor for the restriction operation in multigrid. The value must be between 0.0 and 1.0. A value of 1.0 will not perform any relaxation. On some problems, this may be faster, while slower on others. The default value of 0.80 appears to work well for a wide variety of cases.

liftIndex: int = 2

Specify the coordinate index that will be considered the lift direction.

  • 2: y-axis

  • 3: z-axis

lowSpeedPreconditioner: bool = False

Whether or not to use the low-speed preconditioner. This was previously used for very low Mach number cases but has been phased out in favor of the ANK solver.

wallDistCutoff: float = 1e+20

The cutoff value for distance where we stop computing the wall distance. For nodes that are farther than this distance away from any surface, the wall distance is set to a large constant.

infChangeCorrection: bool = True

Useful option. Setting this to True will adjust the flowfield everywhere if the angle of attack changes between optimization iterations. The idea is that when the angle of attack is changed after a converged simulation, the residuals can stay low since this value only initially affects the residuals of the farfield boundary cells. As a result, the solver logic can do weird stuff because it is often based on the L2 norm of the residual. If this option is set to True, we do a simple adjustment of the state vector with respect to the changes in the free stream conditions. The method to compute the correction is determined by infChangeCorrectionType. The correction is only run if the norm of the free stream state change is greater than infChangeCorrectionTol. As a result, the residuals jump up and the solver logic works as designed. This supersedes the RKReset approach.

infChangeCorrectionTol: float = 1e-12

The tolerance that determines if we will run a correction update when the infChangeCorrection option is set to True. We first compute the change in the free stream state vector and compute its norm. If this norm is greater than the tolerance set by this option, a correction update is performed. If the norm of the change is smaller than the tolerance, we don’t perform a correction update. The default value is appropriate for the default "offset" type update. When the "rotate" update type is used, users might want to select a higher tolerance because the vector rotation that determines the update might be ill conditioned with small state changes.

infChangeCorrectionType: str = offset

This option determines the method used for the correction update when the infChangeCorrection option is set to True.

  • offset: The default "offset" option simply adds the delta free stream state to every cell’s state.

  • rotate: The option "rotate" will rotate the cell velocities by the rotation in the free stream velocity, and add the delta in the free stream velocity to the cells’ density and energy values.

cavitationNumber: float = 1.4

The -Cp value used to trigger the cavitation sensor.

cpMinRho: float = 100.0

The rho parameter used for the KS aggregation used for computing minimum Cp. KS aggregation is used to compute the differentiable min Cp within the given family group. A higher rho value will approach the actual min Cp more accurately, at the cost of a more nonlinear function.

nCycles: int = 2000

The maximum number of “iterations” to run. Iterations are counted differently for the different solvers. For the multigrid solver, this refers to the number of multigrid cycles on the fine grid. For the ANK solver, this refers to the number of steps plus the number of KSP iterations. For the NK solver, this refers to the number of function evalautions either for matrix-vector products or during a line search. Each function evaluation corresponds roughly to single residual evaluation. The run will terminate once the combined number of iterations exceeds nCycles.

timeLimit: float = -1.0

If set to a positive value, this is the maximum number of seconds that the solver will run. The mechanism to trigger this internally is by setting the total number of iterations to the max number, so the solver will say analysis failed. It is up to the user to use this and manage the fail flags. This option can be useful when some cases take extremely long in optimizations, and we are okay with just calling it quits and going back to the line search.

nCyclesCoarse: int = 500

The maximum number of iterations to run on the coarse grid when performing a full-multigrid start-up procedure.

nSubiterTurb: int = 3

The number of iterations of the turbulent DADI solver to run. Only meaningful for RANS simulations. Increasing this parameter to 5-7 may lower the overall solution time for some cases.

nSubiter: int = 1

Number of RK or D3ADI iterations to perform in each nonlinear iteration (between turbulence updates). This does not do anything for the NK or ANK solvers.

CFL: float = 1.7

The Courant–Friedrichs–Lewy (CFL) number to use for the Runge-Kutta simulations. This is the main parameter that determines the overall speed and robustness of RK simulations. Lower CFL numbers give more robust solutions but are slower. The default value of 1.5 is a good place to start. Some experimentation is usually required to determine the maximum CFL for a particular simulation.

CFLCoarse: float = 1.0

The CFL number to use on the coarse grids of the multigrid simulations. It is often desirable to have this number somewhat lower than the CFL number of the fine grid.

MGCycle: str = sg

The type of multigrid cycle to use. The dimensions of the grid must be such that the requested multigrid level is possible. To run a single grid simulation (no multigrid) use sg. To run 3 multigrid levels with a ‘w’ cycle use 3w. To use a ‘v’ cycle use 3v, and so on.

MGStartLevel: int = -1

Specify the starting grid level. This is used to perform a “full multigrid startup” procedure. This can lead to significantly reduced simulation times since a good starting point can be obtained from approximate solutions on the coarser grids. A -1 indicates that the coarsest grid level should be used. For RANS simulations, it is often not possible to start on the coarsest grid, especially if the coarse grid has very few cells. This should be 1 for an unsteady simulation.

resAveraging: str = alternate

How frequently to perform residual averaging (also known as residual smoothing) for the RK solver.

  • alternate: On every second RK stage. This saves computation but with minimal impact on the convergence properties.

  • never: Never

  • always: On every RK stage

smoothParameter: float = 1.5

Parameter used in residual smoothing. This value will typically not need to be changed from the default.

CFLLimit: float = 1.5

The maximum CFL that can be run without residual smoothing. If the actual CFL is lower than this, no smoothing will be applied, regardless of the resAveraging option.

useBlockettes: bool = True

Helps speed up residual calculations by working with a smaller subset of data, reducing the number of cache misses. These subsets of data are fractions of the initial block size and thus are called blockettes. The amount of speedup is problem dependent but ranges from 2-3 times. This option has not been exhaustively tested and has been found to cause errors in the past. Verify that it does not change your results.

useLinResMonitor: bool = False

Enables the linear residual monitor for the NK and ANK solvers. The output should look like the linear residual output from the adjoint solver.

useDissContinuation: bool = False

Use dissipation-based continuation. This only applies to the central plus scalar dissipation discretization. This adds second order dissipation near shocks at the initial stages of the solution. The dissipation tapers off as a sigmoid function of the relative convergence. The continuation helps converge supersonic flows and can also help with some transonic flows. This will have no effect on purely subsonic flows. The solution needs to be well converged to ensure that the additional dissipation is reduced to a value that does not affect the converged result. For the default values of dissContMagnitude and dissContMidpoint, an L2 convergence of 1e-6 is sufficient. See “Improving the Performance of a Compressible RANS Solver for Low and High Mach Number Flows” (Seraj2022c) for details.

dissContMagnitude: float = 1.0

The magnitude of the additional dissipation for dissipation-based continuation. For large enough dissContMidpoint and dissContSharpness (such as the defaults), the initial dissipation is equal to this value plus vis2. Values between a fifth and a half of the freestream Mach number typically work well.

dissContMidpoint: float = 3.0

The number of orders of relative convergence at which the additional dissipation is half of dissContMagnitude. For example, a dissContMidpoint of 1.0 means that the additional dissipation is cut in half by the time the solver has decreased the initial residual by one order of magnitude. The default value typically works well. This value should be at most 4.0 to ensure that the additional dissipation does not affect the converged result for an L2 convergence of 1e-8.

dissContSharpness: float = 3.0

The sharpness of the dissipation-based continuation sigmoid function. Larger values will result in a steeper drop from the initial to final dissipation value. The default value typically works well. This value should be at least 2.0 to ensure that the additional dissipation does not affect the converged result for an L2 convergence of 1e-8.

nearWallDist: float = 0.1

Distance used to determine if a cell will be flagged as “nearWall”.

backgroundVolScale: float = 1.0

A factor that modifies the perceived quality of background cells. A higher value will discourage use of the background mesh during implicit hole cutting.

oversetProjTol: float = 1e-12

Tolerance used when projecting search points onto the surface definition of a block.

overlapFactor: float = 0.9

How much to derate cell volumes when looking for a donor. The value should be less than 1.0. For example, with an overlap factor of 0.9, a cell with volume 1.0 will not get a cell with volume 0.99 as a donor because 0.99 is greater than 1.0 multiplied by the overlap factor. This is designed to create smoother cuts in an overlap region with very similar cell sizes. Changing the overlap factor generally does not change the overlap much because there are checks for ensuring you have valid donors.

oversetLoadBalance: bool = True

Toggle whether to use load balancing for the implicit hole cutting connectivity algorithm. Results with and without load balancing are shown in “An Efficient Parallel Overset Method for Aerodynamic Shape Optimization” (Kenway2017a).

debugZipper: bool = False

Toggles verbose printing and writing of information that is useful for debugging issues with the zipper mesh.

zipperSurfaceFamily: str or NoneType = None

Surface families to use when creating the zipper meshes .

cutCallback: function or NoneType = None

A user-provided Python function that is used to explicitly blank a number of cells based on whatever pattern the user requires. A typical use case for this is to blank the cells that are on the wrong side of the symmetry plane. The mesh extrusion for a component with free edges may actually go to the other side of the symmetry plane, and we want to explicitly remove these cells from the overset mesh. To do this, ADflow internally sets the flagged cells as a flood seed cell. The cutCallback function is called from pyADflow and the user filled array flags is used to determine which cells are flagged. The function signature looks like this:

def cutCallback(xCen, CGNSZoneNameIDs, cellIDs, flags):
   flags[xCen[:, 1] < 0] = 1

The user would then provide this in the option dictionary as: "cutCallback": cutCallback. The xCen array returns the center coordinates of the cells. CGNSZoneNameIDs and cellIDs can also be used to figure out the blanking pattern. flags is the NumPy array we fill and return back to pyADflow. In this example, we have a symmetry plane on the x-z surface, and we want to only use the +y half of the 3D coordinate system. Therefore, we are flagging every cell where the y-component of the center coordinate (index 0:x, 1:y, 2:z) has a negative value. The flags array is initialized to zero internally by pyADflow, and a value of 1 for a cell tags it for flooding.

explicitSurfaceCallback: function or NoneType = None

A user-provided Python function that is used as a callback method to pass the information required for the explicit surface blanking method. To be able to understand what this option does, you should really understand how the overset flooding method works. With some configurations, the automatic flooding algorithm makes it extremely challenging to prevent the entire mesh from flooding. The overlap of volume blocks can even be such that setting the "oversetPriority" option for each block is not enough. To handle these extreme cases, we have a surface based explicit blanking method. The idea is very similar to the cutCallback option above; this option is used to tag cells that are inside a closed geometry provided by the user. This way, we try to eliminate as much of the flood seeds and flooded cells as possible. The approach is not perfect; we only tag the cells that have at least one vertex inside the provided surface geometry as explicitly blanked (-4). This results in two layers of fringe cells that are automatically added, which prevent flooding under most cases. However, the flooding algorithm is actually more involved than this; normally, potential wall donors are tagged as flood seeds, not just the cells that have a vertex inside a wall BC. Regardless, the method works well enough that it can give you a valid hole cutting with cases that are practically impossible to get a valid hole cutting with just the default approach. The way user interacts with this method is through this callback function. The reason we have the callback function is that we need the CGNS block names for each “computational block”. These names are used to determine which volume blocks will be explicitly blanked by which surface; we do not want every surface to act on every computational domain because that would result in most near wall cells getting tagged and would be very error prone. To understand how this option is used, consider an example where we have a wing and a fuselage, in an overset mesh. The wing and fuselage component meshes are joined together with a collar mesh and a background cartesian mesh. Some of the wing mesh is inside the fuselage surface, and some of the fuselage mesh is overlapping with the wing surface. Normally, this case would be handled by the automatic flooding, which works fairly well for most applications including this example, but here, we are just demonstrating the alternative approach. With the regular flooding algorithm, some cells in these overlap regions would get tagged as flood seeds on both the wing and the fuselage. Then, these flood seeds are used to flood the cells that are located inside these geometries; e.g. all of the wing volume cells that are inside the fuselage surface. Instead of relying on the flooding, here, we want to explicitly blank cells that are inside the other component’s surface. To do this, we want to explicitly tag the wing mesh volume cells that have at least one vertex inside the fuselage surface, and similarly, tag the fuselage volume cells that have at least one vertex inside the wing surface. The explicitSurfaceCallback option that would achieve this would look something like this:

def explicitSurfaceCallback(CGNSZoneNameIDs):
   # arrays to save the integer CGNS block IDs for each component
   fuselage_blocks = []
   wing_blocks = []

   for name, id in CGNSZoneNameIDs.items():
       # We can only get the blocks we want by checking the CGNS blocks' name.
       # In this example, we don't want the explicit blanking algorithm to work
       # on the cartesian background or the collar meshes.
       if "wing" in name:
           wing_blocks.append(id)
       elif "fuselage" in name:
           fuselage_blocks.append(id)

   surf_dict = {
       "wing": {
           # The surface file for each entry must be provided.
           # This is a closed plot3d surface mesh. It does not
           # necessarily need to be closed; we project the cell
           # vertices on this mesh and if the projection direction
           # is coming from the inside of the surface, the cell is
           # tagged. So a CFD mesh with a symmetry plane can
           # have a plot3d surface thats open at the symmetry plane.
           # The normals must always point outside. An easy way to
           # obtain this surface file is to convert the surface
           # CGNS grid used to generate the mesh into the plot3d
           # format using the cgns2plot3d method in cgnsutils.
           "surfFile": "wing_surface.x",

           # The block IDs we will search and blank using this surface.
           # Here, we only blank the fuselage cells that are inside the wing
           # and don't want to consider the background or collar meshes.
           "blockIDs": fuselage_blocks,

           # Optional entry: coordXfer
           # This is another callback function that performs a coordinate
           # transformation on the loaded plot3d mesh nodes. See the
           # addPointSet method in DVGeo.py at
           # https://github.com/mdolab/pygeo for the call signature.
           # We use this approach so that the users can have complete
           # control over the surface mesh nodes after they are loaded.
           "coordXfer": coordXfer,
       },

       # Similar entries for the fuselage.
       "fuselage": {
           "surfFile": "fuselage_surface.x",
           "blockIDs": wing_blocks,
       },

       # We can have multiple entries with the same surface to blank different
       # subsets of CGNS blocks. The entries of this top level dictionary
       # is just for bookkeeping, and is not important. The code prints
       # which entry it is blanking as it works through the dictionary.
       # With large meshes (millions of cells) on few number of processors (<10)
       # this process can take up to a minute or so. The process should run quicker
       # with more processors. The surface mesh is loaded on all processors
       # so there is a memory limit on the surface mesh refinement.
       "wing_self": {
           # Here, assume we also want to blank some of the wing cells because
           # they intersect the wing geometry itself somehow. E.g. very large splay.
           # However, we only want to blank cells that have a k-index that is
           # larger than 32 to avoid tagging cells near the wall. The
           # optional "kMin" entry is used to achieve this.
           "surfFile": "wing_surface.x",
           "blockIDs": wing_blocks,
           "kMin": 32,
       },
   }

   # pyADflow will loop over the entries of this dictionary and perform the
   # explicit blanking with the information provided.
   return surf_dict

The call signature of the coordXfer option is documented in the DVGeometry’s addPointset method: addPointset

oversetUpdateMode: str = frozen

How to update the overset connectivity after mesh warping.

  • frozen: The overset connectivity is not updated after initialization. This is the cheapest option to use when the entire overset mesh is warped together, such as with USMesh in IDWarp.

  • fast: Only the weights are updated and the donors are unchanged. This is used when the entire overset mesh is warped together, such as with USMesh in IDWarp. This is fast to run but only works for small design changes. Large design changes can shift the position of interpolate cells relative to their donors enough to cause nonphysical interpolation weights. In this case, an error is raised.

  • full: The overset connectivity is recomputed from stratch. This is usually only used when the component meshes are warped independently, such as with MultiUSMesh in IDWarp. The hole cutting is likely to fail if there are large design changes. Even if the hole cutting works, the aerodynamic derivatives will be inaccurate because the hole cutting routines are not differentiated.

nRefine: int = 10

The maximum number of refinement loop iterations used in the implicit hole cutting method.

nFloodIter: int = -1

Number of iterations for the flooding algorithm at each overset hole cutting iteration. Only useful for debugging meshes that flood completely on the first iteration of the overset. The default is set to -1, which will be inactive and run the flooding algorithm until the flooded cells stop changing. Setting a positive integer value will stop the flooding algorithm at the prescribed number of iterations.

useZipperMesh: bool = True

Determine whether a zipper mesh will be used. Zipper meshes are required to accurately compute integrated quantities (such as lift and drag) when the surface meshes of interest overlap.

useOversetWallScaling: bool = False

Modifies the perceived quality of cells during implicit hole cutting to favor cells that are aligned with viscous walls.

selfZipCutoff: float = 120.0

The cutoff angle in degrees used in the self-zip step of the zipper mesh gap triangulation. Triangulation is triggered if the angle between adjacent substrings is less than the cutoff. This value is only used for the first self-zip iteration at each node. The cutoff angle is 90 degrees for all subsequent iterations.

oversetPriority: dict = {}

Modifies the perceived quality of cells in block. The dictionary keys are the block IDs, and the values are the multipliers for quality. A higher factor will discourage use of that block mesh. A lower factor will encourage the usage of that block mesh. This option may be required to get the flooding algorithm working properly.

oversetDebugPrint: bool = False

Flag to enable or disable the debug printout from the overset algorithm when a hole cutting process fails. This information is not useful anymore and users should obtain the volume solution after an unsuccessful hole cutting and debug the mesh by plotting the cells with incomplete connectivities, which receive an iblank value of -5.

timeIntegrationScheme: str = BDF

The type of time integration scheme to use for unsteady analysis.

  • BDF: Backward differentiation formula (BDF). Second order BDF is currently the only option known to work.

  • explicit RK: Explicit Runge-Kutta

  • implicit RK: Implicit Runge-Kutta

timeAccuracy: int = 2

Order of accuracy of the time integration scheme.

  • 2: Second order

  • 1: First order

  • 3: Third order

nTimeStepsCoarse: int = 48

Number of time steps to be done on the coarse mesh. Only useful for periodic problems where full multigrid can be performed.

nTimeStepsFine: int = 400

Number of time steps to run in an unsteady simulation.

deltaT: float = 0.01

Time step to use for unsteady simulation.

useALE: bool = True

Use the arbitrary Lagrangian-Eulerian (ALE) formulation for unsteady mesh deformations.

useGridMotion: bool = False

Whether or not a rigid body motion of the grid has been specified.

coupledSolution: bool = False

Flag that determines if ADflow is coupled to other solvers, but only in unsteady mode. Previously used for aerothermoelastic analysis.

timeIntervals: int = 1

The number of “spectral instances” to use for a time spectral simulation. This option is only meaningful when equationMode is time spectral.

alphaMode: bool = False

Use a specified alpha motion for the time spectral analysis.

betaMode: bool = False

Use a specified beta motion for the time spectral analysis. Untested.

machMode: bool = False

Use a specified Mach number motion for the time spectral analysis. Untested.

pMode: bool = False

Use a specified p-motion (roll) for the time spectral analysis. Untested.

qMode: bool = False

Use a specified q-motion (pitch) for the time spectral analysis.

rMode: bool = False

Use a specified r-motion (yaw) for the time spectral analysis. Untested.

altitudeMode: bool = False

Use a specified h-variation motion for the time spectral analysis. Untested.

windAxis: bool = False

The wind axis used for time spectral stability derivative computations.

alphaFollowing: bool = True

Whether or not alpha follows the body in p, q, r mode.

TSStability: bool = False

Flag to compute time spectral stability information from a time-spectral CFD solution.

useTSInterpolatedGridVelocity: bool = False

Use spectral differentiation to compute the grid velocity for the time spectral equation.

useExternalDynamicMesh: bool = False

Use externally provided deformed mesh for the time spectral equation. Each time instance gets its own deformed grid. This can be used for both an aerodynamic case or an aeroelastic case.

L2Convergence: float = 1e-08

This specifies the desired convergence factor. For the multigrid solver, this is taken relative to the initial residual on the fine grid. Since this prolonged solution may be a fairly good starting point, the actual convergence relative to the freestream residual may be 1 to 2 orders of magnitudes lower. For the NK solver, this option also determines the convergence, but the reference is taken as the freestream residual.

L2ConvergenceRel: float = 1e-16

This option is typically only used when ADflow is used in conjunction with an aerostructural solver. This specifies the relative tolerance in relation to the current starting point.

L2ConvergenceCoarse: float = 0.01

The convergence factor on the coarse grids during multigrid startup. Most of the benefits of the start-up procedure is obtained after converging between 2 and 3 orders of magnitude so this option is typically 1e-2 to 1e-3.

maxL2DeviationFactor: float = 1.0

If the solver runs out of iterations, the maximum factor the residual can be above the target residual (determined by L2Convergence) and still be considered “converged”.

useNKSolver: bool = False

Flag to turn on the Newton–Krylov (NK) solver. If False, the remainder of the options that begin with “NK” will have no effect.

NKSwitchTol: float = 1e-05

The relative tolerance to converge before the switch is made to the NK solver. This must be low enough that most of the difficult transients have been passed. If the NK solver stalls, this value can be set to a lower value which will run the startup procedure for longer before switching.

NKSubspaceSize: int = 60

The size of the GMRES subspace for the NK solver. For difficult problems, convergence may be improved by increasing this value at the expense of more memory.

NKLinearSolveTol: float = 0.3

The initial tolerance to solve the linear system resulting from the Newton approximation. This value is only used for the first iteration if NKUseEW is True.

NKUseEW: bool = True

Flag to use the Eisenstat-Walker algorithm to determine linear convergence at each iteration. If False, the NK solver will always try to converge the linear system to NKLinearSolveTol. If True, only the initial iteration will target the prescribed NKLinearSolveTol. The following iterations will pick a new linear tolerance based on the nonlinear convergence of the previous iteration. This is done to avoid wasting computation when we are far away from the nonlinear solution and also to nail down the linear solution when we are near the nonlinear solution. See this paper for more details. If the algorithm works as expected, the NK solver should converge in a few (or maybe tens) of iterations. However, the algorithm might pick a very low linear convergence repeatedly and get stuck in a loop. For these cases, it might be better to disable this option, but the better approach would be to switch to the NK solver later in the nonlinear convergence.

NKADPC: bool = False

Flag determines if the AD version of the NK preconditioner is used. If False, we use finite-difference. Using AD improves preconditioner accuracy and linear solver performance at the cost of more expensive preconditioner computations.

NKViscPC: bool = False

Flag that determines if the full viscous stencil is used for the NK preconditioner. This will have a memory and cost penalty, but the resulting preconditioner will be more accurate. Users should experiment with other linear solver options as a smaller stencil preconditioner is usually good enough.

NKGlobalPreconditioner: str = additive Schwarz

Similar to the globalPreconditioner option but for the NK solver.

  • additive Schwarz: Restricted additive Schwarz method (ASM)

  • multigrid: Algebraic multigrid (AMG)

NKASMOverlap: int = 1

The number of overlap levels in the additive Schwarz preconditioner for the NK solver. More overlap levels result in a stronger preconditioner, at the expense of more expensive iterations and more memory. Typical values range from 1 for easy cases and up to 2 or 3 for more difficult cases.

NKPCILUFill: int = 2

The number of levels of fill to use on the local Incomplete LU (ILU) factorization in the NK solver. Typical values are 1 for easy cases and up to 3 for more difficult cases. More levels of fill result in a stronger preconditioner which will result in fewer (linear) iterations, but individual iterations will be more costly and consume more memory.

NKJacobianLag: int = 20

The option determines the frequency at which the NK preconditioner is reformed. In other words, the Jacobian used for the preconditioner is “lagged” behind the actual solution by this many iterations. For simple problems, it may be possible to increase the Jacobian lag to such a high value that the preconditioner is never reformed at all during a solution. For more difficult cases, a lower value may help convergence. A lower value will result in more preconditioner Jacobian assemblies, which are fairly costly in ADflow.

applyPCSubspaceSize: int = 10

This option is only used when ADflow is used in an aerostructural analysis. This parameter determines the subspace size and the total number of iterations to run when ADflow is only being used to precondition residuals via the globalNKPrecon function.

NKInnerPreconIts: int = 1

Number of local preconditioning iterations for the NK solver. More iterations may help converge the linear system faster. This should be left at 1 unless a very difficult problem is encountered.

NKOuterPreconIts: int = 1

Number of global preconditioning iterations for the NK solver adjoint solution. More iterations may help converge the linear system faster. Typical values are from 1 to 3.

NKAMGLevels: int = 2

Similar to the adjointAMGLevels option but for the NK solver.

NKAMGNSmooth: int = 1

Similar to the adjointAMGNSmooth option but for the NK solver.

NKLS: str = cubic

The type of line search used with the NK solver.

  • cubic: Cubic interpolation

  • none: No line search

  • non-monotone: Non-monotone line search

NKFixedStep: float = 0.25

The step size for the NK solver with no line search ("NKLS": "none").

RKReset: bool = False

Option to run nRKReset Runge-Kutta startup iterations when using the NK solver and restarting from a previously converged solution. This allows the residual to increase and prevents the NK solver from stalling.

nRKReset: int = 5

The number of Runge-Kutta startup iterations to run when RKReset is True.

useANKSolver: bool = True

Flag to enable the ANK solver.

ANKUseTurbDADI: bool = True

Flag to determine if turbulence variables are solved with the DADI solver. Only applies to decoupled ANK. If False, an internal ANK-like solver is used for the turbulence in the decoupled mode.

ANKUseApproxSA: bool = False

The ANK solver switches from the approximate to the exact SA implicit formulation when the solver switches from the first order to the second order routines (printed as SANK or CSANK). Setting this flag to false will force the SA implicit treatment to always use the approximate formulation with the ANK solver variants. This should have no effect on the final solution, but can help with convergence with challenging cases.

ANKSwitchTol: float = 1000.0

Relative convergence in the residual norm before we switch to the ANK solver. For most cases, the default value should ensure that the ANK solver is used from the first iteration, even after design changes.

ANKSubspaceSize: int = -1

A positive value sets the subspace size for the ANK solver. Otherwise, the maximum iteration value is taken as the subspace size.

ANKMaxIter: int = 40

Maximum number of linear iterations at each ANK step.

ANKLinearSolveTol: float = 0.05

Linear solver tolerance for the ANK solver.

ANKLinearSolveBuffer: float = 0.01

Do not modify this option unless you know what you are doing with petsc linear tolerances used for the ANK solver. The absolute linear solver convergence in PETSc needs to be set to a value lower than the final residual convergence norm. This is because the linear residual is the linearization of the nonlinear residual, and solving the linear system in a Newton solver to an absolute linear tolerance does not guarantee that the same reduction will be achieved in the nonlinear residual as well. Because of this, if we were to solve for an absolute tolerance that was based on the nonlinear absolute tolerance, the linear solver might exit right before the nonlinear system fully converges. This can cause other problems where the linear system refuses to make any further progress due to the absolute tolerance, or simply, it would have been much more efficient to just do a handful more linear iterations to get some extra linear convergence that makes sure the nonlinear system would also converge. The second scenario is what this option is useful for; this option is used to further offset the absolute linear solver tolerance in the ANK solver. This option only really makes a difference very close to the final L2 convergence target. For example, setting a value of 0.01 will force the linear solver to converge the linear system more tightly, in the cases where the absolute linear convergence is achieved before the relative target. Reducing the value here to 1e-4 or 1e-6 may result in “extra” nonlinear convergence in the final iteration, at the cost of more linear solver effort. Increasing the value here to 1e-1 will reduce this buffer and the solver is more likely to end closer to the final L2 convergence target, but a too large of a value might cause issues with the final iterations where several smaller additional Newton steps are required.

ANKLinResMax: float = 0.1

A parameter that is used to adaptively adjust the CFL number so that the linear residual with the ANK solver does not go above the prescribed value. The target linear convergence may not be reached during nonlinear iterations with the given linear solver options, and this may be fine. However, we want to manage the CFL number so that the linear residual after we run out of linear iterations is still below this target value. This can be seen as the maximum allowed linear residual at each iteration.

ANKGlobalPreconditioner: str = additive Schwarz

Similar to the globalPreconditioner option but for the ANK solver.

  • additive Schwarz: Restricted additive Schwarz method (ASM)

  • multigrid: Algebraic multigrid (AMG)

ANKASMOverlap: int = 1

Similar to the NKASMOverlap option but for the ANK solver.

ANKPCILUFill: int = 2

Similar to the NKPCILUFill option but for the ANK solver.

ANKJacobianLag: int = 10

Number of nonlinear iterations between every preconditioner update. The preconditioner update is determined by an adaptive algorithm, so the updates can happen more frequently. This option sets the upper limit. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKInnerPreconIts: int = 1

Similar to the NKInnerPreconIts option but for the ANK solver.

ANKOuterPreconIts: int = 1

Similar to the NKOuterPreconIts option but for the ANK solver.

ANKAMGLevels: int = 2

Similar to the adjointAMGLevels option but for the ANK solver.

ANKAMGNSmooth: int = 1

Similar to the adjointAMGNSmooth option but for the ANK solver.

ANKCFL0: float = 5.0

The initial CFL number for the ANK solver.

ANKCFLMin: float = 1.0

The coefficient in the minimum CFL algorithm for the ANK solver. The minimum CFL number increases as the simulation converges, and this is the initial value. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKCFLLimit: float = 100000.0

Upper limit for the CFL number in the ANK solver. A larger CFL number will be better for nonlinear convergence at the cost of robustness and expensive linear solutions.

ANKCFLFactor: float = 10.0

Multiplication factor used in the CFL ramping algorithm for the ANK solver. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKCFLExponent: float = 0.5

The exponent used in the CFL ramping algorithm for the ANK solver. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKCFLCutback: float = 0.5

The cutback factor for the CFL number in the ANK solver. This is the factor used when the CFL is adaptively reduced.

ANKCFLReset: bool = True

Flag that determines if the ANK CFL is reset to ANKCFL0 at first ANK iterations. Each aero problem saves the last ANK CFL, and if this flag is set to false, subsequent solutions with the same aero problem starts at the last ANK CFL. If the flag is set to true, then ANK CFL is always reset to the initial value of ANKCFL0.

ANKStepFactor: float = 1.0

The initial step size taken by the ANK solver. This value will be used to initialize the line searches in ANK. The actual step size can be lower than this but not higher.

ANKStepMin: float = 0.01

The minimum step size in the ANK solver. If a step less than this value is required, then the CFL is cut back.

ANKConstCFLStep: float = 0.4

If the step size in the ANK solver is lower than this value, we do not ramp up the CFL and keep it constant. If the step size from the last iteration is larger than this (implying that the solver can make progress), we ramp us the CFL.

ANKPhysicalLSTol: float = 0.2

The physical line search parameter in the ANK solver. A value of 0.2 means that the physical parameters (density and energy) are allowed to change by 20% at each iteration for each cell. The line search adjusts the step size to obey this change globally.

ANKPhysicalLSTolTurb: float = 0.99

The physicality check parameter for the turbulence model in the ANK solver. The turbulence model variable is allowed to increase freely, but it is only allowed to decrease by the specified amount at each iteration. A value of 0.99 means that the turbulence model variable can decrease by 99% at each iteration. Because the initial value of the turbulence model is always positive, this effectively prevents negative values.

ANKUnsteadyLSTol: float = 1.0

The reduction factor used in the unsteady line search for the ANK solver. A value of 1.0 means that the unsteady line search will accept any step that does not increase the unsteady residual norm. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKSecondOrdSwitchTol: float = 1e-16

The relative convergence target where the ANK solver switches to a second order accurate implicit formulation. For transonic flows, this target should be set to be right after the shocks are settled in the solution, which is typically around relative convergence of 1e-4 to 1e-6.

ANKCoupledSwitchTol: float = 1e-16

The relative convergence target where the ANK solver switches to a coupled turbulence formulation. In the coupled formulation, the flow and turbulence variables are all solved together. This improves nonlinear convergence but reduces robustness. This should be used after 5 to 6 orders of magnitude of nonlinear convergence.

ANKTurbCFLScale: float = 1.0

The scaling value for the CFL value used for the separate turbulence solver in the ANK solver.

ANKUseFullVisc: bool = True

Flag to use the full viscous terms in the implicit formulation for the ANK solver. Setting this to True results in the R1 residual approximation level. See “A Jacobian-free approximate Newton–Krylov startup strategy for RANS simulations” (Yildirim2019b) for more details.

ANKPCUpdateTol: float = 0.5

If the ANK solver converges by this amount relative to the last nonlinear iteration where the preconditioner was updated, the preconditioner is updated again.

ANKPCUpdateCutoff: float = 1e-16

The cutoff tolerance below which we adjust the tolerance for the PC update based on nonlinear convergence introduced with the option ANKPCUpdateTol. When the L2 convergence is above the value set in this option, the ANK PC updates are triggered if the relative convergence since the last PC update is below ANKPCUpdateTol. When the L2 convergence is below the value defined in this option, the code uses the tolerance set in ANKPCUpdateTolAfterCutoff to determine PC updates based on relative convergence. This is useful when CSANK is used, which can take steps that converge the L2 norm by multiple orders of magnitude in each iteration towards the end of the convergence. Here, we do not need to update the PC at each solver iteration, and may want to delay the PC updates based on relative convergence.

ANKPCUpdateTolAfterCutoff: float = 0.0001

The ANK PC update tolerance used after we reach the ANKPCUpdateCutoff convergence. Before the cutoff, the regular ANKPCUpdateTol is used.

ANKADPC: bool = False

Whether or not to use the AD-based preconditioner for the ANK solver. The finite-difference preconditioner is usually good enough and is cheaper to compute.

ANKNSubiterTurb: int = 1

The number of turbulent subiterations between each ANK iteration if ANK turbKSP is used ("ANKUseTurbDADI": False). This should be kept at 1 for most cases because the turbKSP solver is more effective and expensive.

ANKTurbKSPDebug: bool = False

Enables debug printout from the ANK turbKSP solver. If turbDADI is disabled, turbKSP is used to solve the turbulence. Without this option also set to true, you will not get any diagnostic output for the turbulence solver.

ANKUseMatrixFree: bool = True

Use the matrix-free Jacobian for the ANK solver. If True, we use the approximate Jacobian formulated for the preconditioner matrix as the implicit formulation.

ANKCharTimeStepType: str = None

This applies characteristic-based preconditioning to the ANK time step matrix. This can accelerate convergence for low Mach number flows. The amount of speedup will depend on how low the local Mach number is across the entire flowfield. This option is mainly useful for cases with freestream Mach numbers of 0.4 or lower. In most cases, this should be used in combination with acousticScaleFactor. See “Improving the Performance of a Compressible RANS Solver for Low and High Mach Number Flows” (Seraj2022c) for details.

  • None: No characteristic time stepping

  • Turkel: Turkel preconditioner. This can be used for all flows, but the preconditioner will only be applied to locally subsonic flow.

  • VLR: van Leer-Lee-Roe preconditioner. This preconditioner applies to locally subsonic and supersonic flow but is mainly useful for subsonic cases. This usually performs slightly better than Turkel.

blockSplitting: bool = True

Flag determining if the block may be split to obtain better load balancing.

loadImbalance: float = 0.1

This is the allowable load imbalance. The tolerated load imbalance between processors when mapping the blocks onto these processors. A value of 0.1 means there is 10 percent load imbalance.

loadBalanceIter: int = 10

Number of METIS graph partitioning iterations. Increasing this number will give you better load balancing. However, it will also tend to split up blocks more often. Therefore, there is a penalty on communication cost.

partitionOnly: bool = False

Flag determines whether to only run the partitioning algorithm, not the flow solution. This is used when checking the load balancing of a grid without running a CFD solution.

partitionLikeNProc: int = -1

If this is set to a positive value, the solver partitions the grid like it has that many processors. Useful to recreate a partition-related issue that shows up on a large number of procs using a smaller number of procs. This is a purely debug option. When it is used, the number of processor partitions will be greater than the number of procs. As a result, the remainder partitions will be distributed to procs, and you will likely get a load imbalance of 1.0, which is bad for performance.

numberSolutions: bool = True

Flag to set whether to attach the numbering of the AeroProblem to the grid solution file.

writeSolutionDigits: int = 3

Number of digits in the solution output filenames. A value of 4 will give, for example, 0023, while a value of 3 will give 023.

printIterations: bool = True

Flag to set whether to print out the monitoring values at each iteration.

printTiming: bool = True

Flag to set whether to print the time taken for the initialization, flow solution, function evaluations, and adjoint solution.

printIntro: bool = True

Flag to set whether to print the ADflow intro message during initialization.

printAllOptions: bool = True

Flag to set whether to print all the options during initialization.

setMonitor: bool = True

Flag to set whether to monitor the adjoint iterations.

printWarnings: bool = True

Flag to print warning messages like for bad quality volumes, etc.

printNegativeVolumes: bool = False

Flag to print the block indices, cell center coordinates, and volume for each negative volume cell in the mesh.

printBadlySkewedCells: bool = False

Flag to print the block indices, cell center coordinates, and skewness for each cell whose skewness is above the value defined in meshMaxSkewness. Only used when useSkewnessCheck is active.

monitorVariables: list = ['cpu', 'resrho', 'resturb', 'cl', 'cd']

List of the variables whose convergence should be monitored. The possible monitoring variables are:

  • resrho (density residual)

  • resmom (momentum residuals)

  • resrhoe (total energy residual)

  • resturb (turbulence residuals)

  • cl (lift coefficient)

  • clp (pressure part of cl)

  • clv (viscous part of cl)

  • cd (drag coefficient)

  • cdp (pressure part of cd)

  • cdv (viscous part of cd)

  • cfx (force coefficient in x-direction)

  • cfy (force coefficient in y-direction)

  • cfz (force coefficient in z-direction)

  • cmx (moment coefficient in x-direction)

  • cmy (moment coefficient in y-direction)

  • cmz (moment coefficient in z-direction)

  • hdiff (maximum relative difference between H and Hinf)

  • mach (maximum mach number)

  • yplus (maximum y+ value)

  • eddyv (maximum ratio of eddy viscosity and laminar viscosity)

surfaceVariables: list = ['cp', 'vx', 'vy', 'vz', 'mach']

The variables which are written to the CGNS surface solution file. The available keywords are:

  • rho (density)

  • p (pressure)

  • temp (temperature)

  • vx (velocity in x-direction)

  • vy (velocity in y-direction)

  • vz (velocity in z-direction)

  • cp (pressure coefficient)

  • ptloss (relative total pressure loss)

  • mach (mach number)

  • cf (magnitude of the skin friction)

  • cfx (x-component of the skin friction)

  • cfy (y-component of the skin friction)

  • cfz (z-component of the skin friction)

  • ch (Stanton number)

  • yplus (y+ value of the cell center of the first cell)

  • lift (lift force)

  • blank (cell iblank values used for visualization or other post-processing)

volumeVariables: list = ['resrho']

The variables which are, in addition to the variables needed for the restart, written to the CGNS volume solution file. The available keywords are:

  • mx (momentum in x-direction)

  • my (momentum in y-direction)

  • mz (momentum in z-direction)

  • rhoe (total energy)

  • temp (temperature)

  • vort (magnitude of the vorticity)

  • vortx (x-component of the vorticity)

  • vorty (y-component of the vorticity)

  • vortz (z-component of the vorticity)

  • cp (pressure coefficient)

  • mach (Mach number)

  • macht (turbulent Mach number)

  • ptloss (relative total pressure loss)

  • eddy (eddy viscosity)

  • eddyratio (ratio of eddy viscosity and laminar viscosity)

  • dist (wall distance to the nearest viscous wall)

  • resrho (density residual)

  • resmom (momentum residuals)

  • resrhoe (total energy residual)

  • resturb (turbulence residuals)

  • blank (cell iblank values used for visualization or other post-processing)

storeConvHist: bool = True

Flag to save convergence history information into fortran arrays. This data can be accessed after the solve using getConvergenceHistory.

forcesAsTractions: bool = True

Flag to return tractions instead of forces.

adjointL2Convergence: float = 1e-06

Adjoint solution tolerance relative to the residual for a zero initial guess. In some cases (such as with zipper meshes), the adjoint solution can stall well before a typical relative convergence value is reached. For these cases, running the adjoint solution until the absolute residual reaches a minimum should still give accurate derivatives.

adjointL2ConvergenceRel: float = 1e-16

Adjoint solution tolerance relative to the residual at the start of the adjoint call (including a possible non-zero restart).

adjointL2ConvergenceAbs: float = 1e-16

Adjoint solution absolute tolerance.

adjointDivTol: float = 100000.0

The relative amount the adjoint residual can increase before the solver concludes that the method is diverging.

adjointMaxL2DeviationFactor: float = 1.0

Similar to maxL2DeviationFactor but for the adjoint solution. This factor is only applied to adjointL2Convergence.

approxPC: bool = True

Whether or not to use the approximate Jacobian for the adjoint preconditioner.

ADPC: bool = False

Whether or not to use AD for the adjoint preconditioner.

viscPC: bool = False

Whether or not to keep cross derivative terms in the adjoint preconditioner.

useDiagTSPC: bool = True

Whether or not the off-time instance terms are included in the time spectral adjoint preconditioner.

restartAdjoint: bool = True

Whether or not we want to restart the adjoint from the previous solution.

adjointSolver: str = GMRES

Type of linear solver for the adjoint. See PETSc documentation for details.

  • GMRES: GMRES. Typically gives the best performance.

  • TFQMR: Transpose free QMR

  • Richardson: Preconditioned Richardson iterative method

  • BCGS: BiCGStab

  • IBCGS: Improved BiCGStab

adjointMaxIter: int = 500

Maximum number of iterations for the adjoint solution.

adjointSubspaceSize: int = 100

The size of the Krylov subspace for the adjoint solution.

GMRESOrthogonalizationType: str = modified Gram-Schmidt

Which orthogonalization method to use with GMRES. This will affect the adjoint solver the most, but the same option is also used in the linear solvers in the ANK and NK solvers.

  • modified Gram-Schmidt: Modified Gram-Schmidt. This typically gives the best accuracy (relative to complex step for the adjoint) and performance.

  • CGS never refine: Classical Gram-Schmidt with no refinement. Fast but not the most accurate.

  • CGS refine if needed: Classical Gram-Schmidt with refinement as needed. Slow and inaccurate.

  • CGS always refine: Classical Gram-Schmidt with refinement at every iteration. Slow and inaccurate.

adjointMonitorStep: int = 10

The adjoint residual norm is written out every this many iterations.

dissipationLumpingParameter: float = 6.0

Scaling parameter for dissipation lumping in the approximate preconditioner for the adjoint solution.

preconditionerSide: str = right

Which side to apply the adjoint preconditioner.

  • right: Right side

  • left: Left side

matrixOrdering: str = RCM

The matrix ordering algorithm used for the adjoint preconditioner. See PETSc documentation for details.

  • RCM: reverse Cuthill-McKee

  • natural: natural

  • nested dissection: nested dissection

  • one way dissection: one way dissection

  • quotient minimum degree: quotient minimum degree

globalPreconditioner: str = additive Schwarz

The type of (global) preconditioner to use for the adjoint system.

  • additive Schwarz: Restricted additive Schwarz method (ASM)

  • multigrid: Algebraic multigrid (AMG). This method can be much faster than ASM for large meshes. The smoothing iterations and coarse level solutions are done with the standard ASM and ILU combination.

localPreconditioner: str = ILU

The type of preconditioner to use for the local preconditioning iteration in the adjoint solution.

  • ILU: Incomplete LU (ILU) factorization. Currently the only supported option.

ILUFill: int = 2

The number of levels of fill to use on the local Incomplete LU (ILU) factorization in the adjoint solution. Typical values are 1 for easy cases and up to 3 for more difficult cases. More levels of fill result in a stronger preconditioner which will result in fewer (linear) iterations, but individual iterations will be more costly and consume more memory.

ASMOverlap: int = 1

The number of overlap levels in the additive Schwarz preconditioner for the adjoint solution. More overlap levels result in a stronger preconditioner, at the expense of more expensive iterations and more memory. Typical values range from 1 for easy cases and up to 2 or 3 for more difficult cases.

innerPreconIts: int = 1

Number of local preconditioning iterations for the adjoint solution. Increasing this number may help with difficult problems. However, each iteration will take more time.

outerPreconIts: int = 3

Number of global preconditioning iterations for the adjoint solution. Increasing this number may help with difficult problems. However, each iteration will take more time. The default should be sufficient for most problems.

adjointAMGLevels: int = 2

The number of levels to use for the adjoint solver’s algebraic multigrid preconditioner.

adjointAMGNSmooth: int = 1

The number of smoothing iterations at each level for the adjoint solver’s algebraic multigrid preconditioner.

applyAdjointPCSubspaceSize: int = 20

The Krylov subspace size for the adjoint preconditioner.

frozenTurbulence: bool = False

Flag to set whether to use frozen turbulence assumption in the adjoint. Frozen turbulence neglects the linearization of the turbulence model. Currently, only the Spalart-Allmaras model is ADed. Using this flag may help with convergence for high transonic flows. However, the resulting sensitivity is less accurate.

useMatrixFreedrdw: bool = True

Flag that determines if ADflow will use the matrix-free routines to compute mat-vec products with the full Jacobian. If False, ADflow will form the full matrix exactly and mat-vec multiplications will be matrix-based. This should always be True for overset meshes, otherwise the gradients will be inaccurate. This is a known bug in ADflow (see https://github.com/mdolab/adflow/issues/204). The matrix-free routines have lower memory usage. For runtime, there is a tradeoff between the Jacobian assembly and adjoint solution times. See “Effective Adjoint Approaches for Computational Fluid Dynamics” (Kenway2019a) for more details.

skipAfterFailedAdjoint: bool = True

If this option is True, and one of the adjoints fail in the current sensitivity evaluation, the rest of the adjoints will be skipped for the sake of efficiency. The user should use the checkAdjointFailure method to get the correct fail flag in the dictionary passed back to the optimizer for these cases. In the following design evaluation, ADflow will try to solve the adjoints again. If this option is set to False, all of the adjoints will be solved (to whatever tolerance possible with the given options), and the (possibly) partially converged solutions will be used for total derivative computations. It is again up to the user to decide if this is the behavior they want.

firstRun: bool = True

This option is for debugging the adjoint only. Setting this to False will turn on the Tapenade debugger.

verifyState: bool = True

This option is for debugging the adjoint only. It is used to verify dRdw.

verifySpatial: bool = True

This option is for debugging the adjoint only. It is used to verify dRdx.

verifyExtra: bool = True

This option is for debugging the adjoint only. It is used to verify dIda.

sepSensorOffset: float = 0.0

The offset value used for the separation sensor. See “Buffet-Onset Constraint Formulation for Aerodynamic Shape Optimization” (Kenway2017b) for more details.

sepSensorSharpness: float = 10.0

The sharpness parameter for the separation sensor. See “Buffet-Onset Constraint Formulation for Aerodynamic Shape Optimization” (Kenway2017b) for more details.

cavSensorOffset: float = 0.0

The offset value used for the cavitation sensor. Similar to sepSensorOffset.

cavSensorSharpness: float = 10.0

The sharpness parameter for the cavitation sensor. Similar to sepSensorSharpness.

cavExponent: int = 0

The exponent for the numerator term (- Cp - cavitationnumber) of the cavitation sensor.

computeCavitation: bool = False

Whether or not to compute cavitation related cost functions, which are cavitation and cpMin. If this option is not set to True, the code will return zero for these two cost functions.