6. Adaptation and Error Estimation

6.1. Capabilities

Fun3D has three basic types of adaptation available, listed here in order of complexity.

  • Mesh movement via spring analogy
  • General adaptation using flow solution gradients for adapation metric
  • General adaptation using an adjoint-based error estimation

All-tetrahedral meshes are required for each of the adaptation strategies. The mesh movement scheme is easy to use and computationally inexpensive. It is primarily used to align the mesh with strong shocks in the flow field. The general adaptation schemes are more complex to use, and much more computationally intensive. They require an additional library, refine, which can be requested via the same channels as FUN3D (send an email). The adaptation mechanics for the general adaptation provide for node insertion and removal, node movement, and improvement of element quality via edge swapping. The criteria for adaptation is provided by either flow solution gradients (typically called feature-based) or by the error estimate developed by solving the adjoint equations in addition to the flow equations.

These methodologies are available for evaluation by users, but are still very much in development. The documentation for adaptation is incomplete at best. Please share your experiences with us so we can improve the adaptation further.

6.2. Mesh Movement via Spring Analogy

The mesh movement scheme within FUN3D is simple to use, and inexpensive computationally. We have had good experience with it in the generic gas path, and very little experience within the standard compressible perfect gas path. The methodology can be used for both viscous and inviscid flows.

To invoke, use the command line options:

--adapt_spring

--adapt_freq <num of itns between adapts>

Typically, a flow solution is run without the mesh movement for enough iterations to properly set up the flow features. The flow solution is then restarted with the mesh movement turned on, and the movement run every 50-100 iterations, for 1000-3000 iterations. The length of time to run the spring adaptation will be problem dependent. The algorithm is designed to move the mesh a little bit at a time, and at some point the movement will essentially have converged. The flow solution is then restarted again without the mesh movement, and allowed to fully converge on the final mesh.

6.3. Requirements and Configuring to use refine

Using the grid adaptation features within FUN3D requires the refine libraries. At present, this must be requested separately through the same channels as requesting FUN3D. Contact FUN3D Support for more details.

General

There are 3 functions for the adaptation codes:
  • Provide metrics on when and where to adapt. For the adjoint-based, this functionality is provided using using the adjoint solver. For the feature-based, this functionality is provided using the adapt code
  • Adaptation mechanics (how to alter/add/reconnect, etc): This is the refine library, used for both adjoint and gradient-based adaptation.
  • Constrain points in boundary faces to the surface geometry. This requires some knowledge of the geometry by the refine library, and can be accomplished (listed in decreasing complexity) by linking to a CAD-based geometry engine via CAPrI and GridEx, linking to a simplified geometry engine that can only handle planar surfaces (FAUXGeom), or by freezing the surface triangulation of specified boundary faces.

Setting up your geometry

To adapt a mesh on any surface, you must have some sort of geometry definition. refine can handle several types of geometry:

No geometry, where the surface nodes are frozen.

refine cannot adapt in the viscous layers, and so boundary faces that have high aspect ratio layers growing off of them must be frozen, along with the mesh for a specified distance away from the surface to maintain grid quality. This is invoked with the --adapt_freezebl <real>, where the real argument is a distance away from the no slip surfaces to freeze the mesh. This distance is chosen by the user, usually after probing the mesh to determine the maximum boundary layer height.

Additionally, specific surfaces that do not have a viscous boundary condition can be frozen by listing the surface numbers in the file project.freeze. This is useful for curved outer boundary surfaces, where there is not an analytical definition handled by FAUXGeom. An example of its use is freezing the curved outer boundary of our example hypersonic cylinder problem.

FAUXGeom, for planar boundary surfaces

For viscous problems, where the mesh on the complex geometry of the body is frozen, FAUXGeom can be used to provide an analytical definition of the boundary surface. This allows adaptation to occur on the outer box and symmetry plane surfaces of the mesh, even though the body mesh is frozen, and is particularly important for the symmetry plane. At present, FAUXGeom can only handle planar surfaces, with normals in the x, y, and z directions.

FAUXGeom reads the file faux_input. Here is an example file:

6
1 zplane  1.0
2 zplane  3.0
3 yplane -1.0
4 yplane  1.0
5 xplane -5.0
6 xplane  5.0

The first line is how many faux faces are being defined. The subsequent lines have a face number, type of face, and then the coordinate value for the plane. Therefore, the first faux face defined corresponds to surface 1 in the mesh, and is a z=1.0 constant plane.

Real geometry, linked with GridEx
For tangency surfaces, you really do want to adapt the mesh on the surface. For this case, we have to link to the SDK libraries within GridEx, to satisfy requests from refine such as place_point_on_surface. So, adapting an inviscid case requires:
  • GridEx (another form, another piece of software)
  • Constructing your geometry such that it can be handled in GridEx. This requires some sort of CAD definition, and the ability to link GridEx to the CAD engine you have (Pro-E, Unigraphics, etc.). There is also a “native” CAD definition that GridEx can handle, which can be generated via gridTool
  • Generating your mesh within GridEx so that your surface nodes are parameterized on your CAD surfaces.

In short, it is quite a learning curve to get to adapt on tangency surfaces if you are not already using GridEx for mesh generation..

Configuring

The refine package itself uses AutoTools, just like FUN3D versions 10.4 and higher. See the README and INSTALL files in the refine distribution for details.

The FUN3D AutoTools configure script will requre the following flags:

  • Tell FUN3D where refine is installed

--with-refine=/my/path/to/refine/installation

  • To use FAUXGeom geometry, specify

--with-refineFAKEGeom=-lFAUXGeom

  • To use the full-blown CAPRI-GridEx CAD geometry, contact FUN3D Support. It is not trivial to set up.

Pre-processing meshes that will be adapted.

  • Do NOT lump boundaries.
  • When using party, use the command line option --no_renum to ensure consistent numbering with the original mesh (required for CAPRI-GridEx only)

Command-line and namelist options for adaptation

The following command-line options are common to all applications (adjoint and feature adaptation) that use the refine library.

--skip_qsave: The adaptation writes out an abbreviated flow file, in that there aren’t additional time step levels available. you MUST use --skip_qsave for ALL subsequent uses of the interpolated flowfield data (party --skip_qsave for visualization, nodet --skip_qsave to run the solver on the adapted mesh as a restart.)

--adapt_project <name> : name for adapted grid, default is to append a _R to current project, current_project_name_R.

--adapt_freezebl : This is a distance above the surface, in your grid units. You will need to look at the mesh (tecplot) to pick an appropriate value. There will be no adaptation between the surface and this value above the surface, and this is used to keep the boundary layer mesh looking like a boundary layer mesh. Eventually, we will have adaptation that will be able to add boundary layer points while keeping the desired stretching, but refine isn’t there yet.

--adapt_smooth_surface : This option should almost always be used. Without it, no movement of nodes will occur on boundaries (including planar boundaries), so the resulting mesh with inserted points will be not smooth.

--adapt_cycles 3 : number of adaptation cycles to run. 2 or 3 is a good place to start, default is 6.

The remaining options are problem/grid size dependent, so some trial & error is usually required

--output_error <real> : This is target maximum value for the adaptation parameter, either adjoint- or feature-based. The smaller the number, the more new mesh you get.

--adapt_maxedge 1.0 : This is the maximum edge size you want to allow in your mesh. It should be consistent with the size of the elements in your outer boundary, or you will see lots of refinement out there.

--adapt_maxratio 10 : maximum aspect ratio allowed in adapted cells. Mike says you can go up to 100, Karen usually goes up to 30. It is more of an issue as to what you want the flow solver to try to deal with.

6.4. Adjoint-Based Adaptation

To appear… for now, please see the publications and examples areas.

6.5. Gradient/Feature-Based Adaptation

Command-line and namelist options for adapt

The following options apply only to the feature-based adaptation, using adapt.

--adapt_feature_type <0> : This option controls the general formulation of the adpatation metric. The default formulation constructs the adaptation metric by combining a scalar quantity for the adaptation strength with the hessian of another flow-based quantity to provide stretching of the resulting mesh. The formulation of the scalar and hessian quantities is controlled by additional command line arguments.

Additional, more complex, formulations of the metric are planned. Currently, only the default formulation, <0>, is allowed.

--adapt_feature_scalar_key <density>: Flow quantity to be used in computing the scalar adapation magnitude. density is the default quantity. Allowed options are:

mach, pressure, temp (temperature), density, and manufact

--adapt_feature_scalar_form <delta>: Method for computing the adapation scalar from the flow quantity. Available options are:

delta: max delta across edges at each node, default

delta-l: max (delta * edgeLength^exp), to provide some scaling with mesh size

ratio: max ratio of flow quantity across an edge, typically used for a pressure ratio.

hess_max: max eigenvalue of hessian of key_var at each node, used to scale mesh size with 2nd derivative.

--adapt_feature_length_exp <0.5>: used with delta-l to set how to scale the scalar parameter with edge length. The default is 1/2, to scale by sqrt(edge length).

--adapt_feature_hess_key <mach>: Flow quantity to be used in the hessian (2nd derivative) computation. Allowed options are the same as for --adapt_feature_scalar_key. The default for the hessian is mach

--adapt_felisa : Use this option if you are adapting from a FELISA flow solution, so that the flow variables are mapped properly.

Using Feature Adaptation with other flow solvers.

adapt can theoretically be used with other flow solvers that use tetrahedral meshes. Currently, Karen uses adapt regularly with the FELISA inviscid solver. Interfaces for other codes could be developed. Contact FUN3D Support for more information.

User test case

This section will describe how to set up 2 test cases for adapt_mpi. The files for running this case are available upon request (from FUN3D Support), and with versions of fun3d after 10.4.1.

The first case (no_flow) will exercise the adapt_mpi code without requiring a flow solution. This case will just show that the adaptation code is compiled and running correctly. The second case will run the solver for a few iterations, adapt to that flow solution, and then run the solver for more iterations. Again, this case demonstrates the process for running adapt_mpi, but does not itself produce complete, converged results.

Files
fun3d-10.4.2/examples/adapt_feature:
  check_flow.lay
  ginput.faces
  ginput.faces.rest
  party_inp_init
  geometry/om6p01.fastbc
  geometry/om6p01.faux_input
  geometry/om6p01.fgrid

The om6p01 mesh has 5231 nodes and 28523 tets.

Setup
Create working directories, and copy geometry files, executables, and input files as needed.
  cd examples/adapt_examples
  mkdir no_flow
  cd no_flow
  cp ../geometry/* .
  ln -sf om6p01.faux_input faux_input
  cp ../ginput.faces .
  cp ../party_inp_init .
  ln -sf <your-path_to_executables>/party .
  ln -sf <your-path_to_executables>/adapt(_mpi) .
  cd ..

As of release 10.5.0, be sure to translate the ginput.faces file to the new namelist input using the ginput_translator utility in utils/Namelist_new prior to running FUN3D.

Case 1, no_flow
  cd no_flow
  ./party --no_renum < party_inp_init > party_out_init

Note that we are only creating 1 part file. This example can be run with or without mpi as it is. To test with more partitions, change the input to party to produce more partitions.

 ./adapt  --skip_qsave --adapt_cycles 1                \
          --adapt_coarsen 1.0 --adapt_feature_type 0   \
          --adapt_maxedge 1.0 --adapt_maxratio 10      \
          --output_error 0.0001 --adapt_freezebl 0.02  \
          --adapt_smooth_surface --adapt_feature_debug \
          --adapt_project om6p02

To run with mpi, use mpirun <options> adapt_mpi with the appropriate options for your system.

After the adaptation is complete, there should be many additional output files. The primary files to look at are

  om6p02_adapt_stats.txt
  om6p02_part.1
The first file is a text file that will contain the number of nodes and cells in the new mesh, and the adaptation parameters used. It should match the file of the same name in the no_flow_results directory. There might be a difference of a couple of nodes or cells, due to compiler differences. The new mesh size should be in the neighborhood of:
nodes:     8658
cells:     47948

Because no flow files are written out for this case (because it used a manufactured solution for adaptation), party cannot be used to generate a plot file to view the adapted mesh.

Case 2, flow
Repeat the setup steps for a directory named flow. Additionally, link the flow solver:
  ln -sf <your-path_to_executables>/nodet(_mpi) .
The preprocessing step is the same as Case 1.
  ./party < party_inp_init > party_out_init

Run the flow solver for a few steps. The convergence tolerance for the case is set to 1e-04, so the solver should stop quickly, after about 4 iterations. Again, use the appropriate mpirun options for a multiprocessor case.

 ./nodet  --skip_qsave 

The adaptation is run using the same options as Case 1, except without --adapt_feature_debug.

 ./adapt  --skip_qsave --adapt_cycles 1                \
          --adapt_coarsen 1.0 --adapt_feature_type 0   \
          --adapt_maxedge 1.0 --adapt_maxratio 10      \
          --output_error 0.0001 --adapt_freezebl 0.02  \
          --adapt_smooth_surface \
          --adapt_project om6p02
After the new mesh (om6p02) is generated, the flow solver should be run again. Note that the only differences in the ginput.faces file are that irest==1 and the project name is changed to om6p02
 cp ../ginput.faces.rest ginput.faces
 ./nodet  --skip_qsave 

As of release 10.5.0, be sure to translate the ginput.faces file to the new namelist input using the ginput_translator utility in utils/Namelist_new prior to running FUN3D. For this case, the primary files to look at are:

  om6p02_adapt_stats.txt
  om6p02_flow.1
  om6p02_part.1
The new mesh size should be in the neighborhood of:
 nodes:     8353
 cells:     46031

The results of the adaptation can be further checked by generating plot files for tecplot, and using the layout file, check_flow.lay. The files, om6p01_soln.lay and om6p02_soln.lay are generated with party, selecting option 20 to postprocess the files, and then choose the first tecplot option.

The tecplot view will show the symmetry plane and OM6 wing, with the adapted mesh (red) overlaid on the initial mesh (blue). The two meshes should be clearly different on the symmetry plane. Because the mesh was not adapted on the surface of the wing, the meshes should exactly overlay on the surface. The effect of freezing the boundary layer with the --adapt_freezebl 0.02 option is not clear for this example, because the mesh does not have a boundary layer, and the first points off of the body are further than the 0.02 distance specified.

Publications

See bibb_capsules for basic information

6.6. Error Estimation

To appear… for now, please see the publications and examples areas.