ENH: update of the adjoint library and introduction of topology optimisation
Summary
Overhaul and generalization of the adjoint library and introduction of topology optimisation capabilities.
Details
Shape optimisation
 An overhaul of the adjoint library to ease extension to flow physics other than incompressible flows (see 9a89fcc0 for details)
 Corrections/improvements to shape optimisation, like (see 9a89fcc0 for details)
 Improved consistency between the ESI and FI formulations for computing sensitivity derivatives for shape optimisation. An example of the code behavior before and after the changes is given below, obtained from the tutorial under $FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/shapeOptimisation/naca0012/laminar/moment/primalAdjoint
NACA0012 C_M sensitivities, v2306 
NACA0012 C_M sensitivities, v2312 

 Consistent point/face sensitivity maps
Drivaer drag sensitivity map computed on boundary faces, v2306  Drivaer drag sensitivity map computed on boundary faces, v2312 

By comparing the drag sensitivity maps computed with v2306 and v2312, it can be observed that: a) the new pointtoface interpolation produces smoother results, even for the raw (i.e. nonsmoothed) sensitivities and b) artifacts close to the symmetry plane of the car have disappeared.
 A new adjoint solver (null) and objective function (geometric) type, for defining geometric constraints without unnecessarily allocating new adjoint fields
 Three new update methods (ISQP, nullSpace, MMA) for tackling optimisation problems with inequality constraints
 Introduction of bounds for the design variables; for volumetric BSplines this can help better preserve the quality of the mesh throughout the optimisation
 Introduction of convergence criteria for the optimisation loop.
Features 3 to 6 are showcased in the new tutorial $FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/shapeOptimisation/naca0012/laminar/multipleConstraints
Topology optimisation
New topology optimisation capabilities, using either a porositybased or a levelset approach. Both include the capability of exporting the designed geometry as an STL, for production and/or reevaluation with a bodyfitted grid.
The porositybased approach relies on a field of design variables (artificial porosities, \alpha
) that block the counterproductive parts of the computational domain by solidifying them. To increase the smoothness of the obtained solutions, a regularisation equation is solved computing the intermediate field \widetilde{\alpha}
, followed by a sharpening/projection step to compute the almost binary field \beta
. The latter is then used to introduce sources terms to the flow equations that drive the flow solution to zero in the solidified areas (i.e., areas with \beta \approx 1
). The steps of the abovementioned process are showcased below
\alpha 
\widetilde{\alpha} 
\beta 

The following table shows the results of topology optimisation for three different variants of the same case, namely the minimization of total pressure losses (J_{pt}
) (left), minimization of J_{pt}
with a constraint on equally distributing the volume flow rate between the bottom and right outlets (J_{m}
) (center) and maximization of the flow uniformity (J_{un}
), under the J_{pt} \lt J_{pt}^{target}
constraint (right).
The cases can be found under
$FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/topologyOptimisation/monoFluidAero/turbulent/1_Inlet_2_Outlet/porosityBased/BP
min. losses  min. losses flowrate constr. 
max. uniformity, losses constr. 

The next table showcases the outcome of topology optimisation for a 3D manifold, with similar objective and constraint functions. The first row depicts the progression of the boundary between the fluid and solid parts of the computational domain during the optimisation cycles and the last row illustrates the STL files of the three optimised geometries. The process of generating the latter is automatic and executed at the end of each optimisation cycle. These STL files can then be used for performing bodyfitted simulations with proper boundary condition or subsequent shape optimisations or even for manufacturing.
The cases can be found under
$FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/topologyOptimisation/monoFluidAero/laminar/3DBox
min. losses  min. losses flowrate constr. 
max. uniformity, losses constr., flowrate constr. 

More tutorials can be found under
$FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/topologyOptimisation
Risks
The entries of optimisationDict.optimisation have slightly changed, arguably towards something more intuitive. The changes can be observed by comparing, for instance, the optimisationDict of $FOAM_TUTORIALS/incompressible/adjointOptimisationFoam/shapeOptimisation/motorbike with its previous variant
Successfully compiles with

Gcc9.3 int32 DP 
clang 15 int32 DP 
clang 15 int32 SPDP