TRACE User Guide  TRACE Version 9.6.1
adAdjointTRACE

adAdjointTRACE is a discrete adjoint solver built by the aid of algorithmic differentiation.

A calculation with adAdjointTRACE consists of three steps:

  1. a forward (primal) run with a checkpoint written at the end
  2. a reverse (adjoint) run starting at the previously written checkpoint
  3. evaluation of gradients

Primal Calculation

The primal run is a nonlinear steady TRACE calculation, which must converge. A good rule of thumb is that the L1-Residual should at least fall below 1E-7 in double precision mode. For all AD-adjoint related runs, a special control file is needed.

Create a file called writeCheckpoint.prop, based on this example:

subsection settings
subsection write checkpoints
set start = 0
set end = 100000000
set interleave = -1
set offset = 0
end
set mesh sensitivity file name = ../output/TRACE_meshsensitivity.cgns
set calculate control vector length = 1
set base dir = ../output
set checkpoint dir = ../output/checkpoints_global
set global checkpoint dir =
set load checkpoint on start =
set stop file = ../ad/stop.file
set stop on signals =
set method = WriteCheckpoints
end

This says that a checkpoint should be written after the calculation has finished. A description of the parameters inside this file can be obtained by running

TRACEcxxprim --adhelp

The primal calculation can be started as follows

mpirun -np [#procs] TRACEcxxprim -cgns TRACE.cgns -adprop writeCheckpoint.prop [+ any additional trace arguments]

Selection of the functional to differentiate

adAdjointTRACE has a basic set of built-in evaluation functionals, which is printed when running

TRACEcxxcodi --adhelp

When one wants to differentiate other evaluation criteria, one may use adAdjointPOST. This allows to differentiate all criteria calculated by POSTs gta task. The selection of a quantity is achieved by a seeding file, which is a gta.ulst file, where all but one value are set to zero. By setting the quantities value to one, it is selected for differentiation. Such a file can be generated by running gta with the ad executable:

POSTcxxcodi -i ../output/cgns/TRACE.cgns -adb -rbc -avg -btm -gta -wgta -ulist ../output/post.ulst -ade

This produces the template for the seeding file ../output/GTAadjoint.ulst .

cp ../output/GTAadjoint.ulst adjointSeeding_TotalPressureRatio.ulst

Edit this file with your favorite editor and set the value of the entry you want to differentiate to 1.0 . This has to be done only once per testcase and functional. After each primal run, one can now differentiate the post-processing via

POSTcxxcodi -i ../output/cgns/TRACE.cgns -adb -rbc -avg -btm -gta -wgta -ulist ../output/post.ulst -ade -af adjointSeeding_TotalPressureRatio.ulst

Calculation

The next step is to start a process named reverse accumulation which calculates the gradient of one output property with respect to all mesh node coordinates ("mesh sensitivities"). Another property file called reverseAccumulation.prop is needed for that, which could look like this:

subsection settings
  subsection functional
    set use post                          = 1
    subsection post
      set com directory                   = ../output
    end
    subsection trace
      set value name                      = TotalPressureRatio
      set point                           = 
    end
  end
  subsection convergence criteria
    subsection adjoint res. L1 norm
      set enabled                         = 0
      set scaled                          = 1e-6
    end
    subsection adjoint res. L2 norm
      set enabled                         = 0
      set scaled                          = 1e-6
    end
    subsection control res. L1 norm
      set enabled                         = 0
      set scaled                          = 1e-6
    end
    subsection control res. L2 norm
      set enabled                         = 0
      set scaled                          = 1e-6
    end
  end
  subsection output
    set write per block convergence       = 0
    set output per variable residual      = 0
    set write text files                  = 0
    set write cgns files                  = 1
    set adjoint out interleave            = 1000
    set control out interleave            = 1000
  end
  subsection mesh metrics
    set use initialization                = 0
    set fixes for metric                  = 1
  end
  subsection reverse accumulation
    set start                             = -1
    set adjoint steps                     = 1000
    set always compute control derivative = 1
    set initial vector                    = 
    set read logic other                  = Mandatory
    set const impmatrix                   = 0
  end
   subsection optimization
    subsection preaccumulation
      set calcEulerFluxSides                      = 1
      set impmatrix                               = 1
      set phi                                     = 1
    end
    set passive implicit matrix           = 1
  end
  subsection switches
    set frozen gamma                      = 0
  end
  set mesh sensitivity file name          = ../output/TRACE_meshsensitivity_TotalPressureRatio.cgns
  set calculate control vector length     = 1
  set base dir                            = ../output/reverseAccumulation
  set checkpoint dir                      = ../output/checkpoints_intermediate
  set global checkpoint dir               = ../output/checkpoints_global
  set load checkpoint on start            = -1
  set stop file                           = ../ad/stop.file
  set stop on signals                     = 
  set method                              = ReverseAccumulation
end

Here the TotalPressureRatio will be differentiated w.r.t. each node of the computational mesh. If one wants to use TRACEs built in functionals instead, just change it as follows

    set use post = 0

And chose a functional by

    set value name = TotalPressureRatio

If adAdjointPOST is used, this line has no influence.

A description of these switches, other available options and other choices for the output quantity to differentiate for, can be obtained by the following command:

TRACEcxxcodi --adhelp

The adjoint solver can then be run by the following command:

mpirun -np [#procs] TRACEcxxcodi -cgns TRACE.cgns -adprop reverseAccumulation.prop [+ any additional trace arguments]

Evaluation of Gradients with respect to design variables

Typically mesh-sensitivities are only a by-product of the adjoint calculation. Most often one is interested in partial derivatives of output quantities w.r.t. design variables determining the shape of the turbomachinery parts. The dependency of design variables onto the CFD mesh is expressed in terms of deformed meshes in this process. These can be created by applying a small variation to each design variable and re-creating the CFD mesh. These deformed meshes are combined with the result from adjoint calculations by an inner product which can be evaluated as follows:

POSTcxxprim --evalSensitivities --adjointSolutions ../output/TRACE_meshsensitivity*.cgns --deformedMeshes ../deformed_meshes/TRACE_deformation*.cgns -out ../output/sensitivities.dat

If one wants to visualize the mesh sensitivities, you should add the results on all duplicate points (esp. block cuts) to avoid visualization artifacts.

PREP -cgns ../output/TRACE_meshsensitivity_TotalPressureRatio.cgns -ams