under construction…

Cooking with tekigo - Intermediate level : the RECURSIVE adaptation

This is a short tutorial explaning how the tool Tekigo helps you to control the metric you will feed to your adaptation library. Note : this cannot be done with the compute_metric method.

Ingredients

To make a mesh adaptation you will need:

  • a virtual environment with Tekigo installed.
  • a mesh in h5 AVBP-Compatible format. Beware of starting from huge meshes, the adaptation will take a lot of time. You can fetch a light template mesh from our Gilgamesh repository.
  • a solution on the same mesh. It can be averaged or instantaneous.

The tekigoSolution object

Prepare your tekigo script using this baseline

import numpy as np
from tekigo import (TekigoSolution,
                    refine)


def custom_criteria(ts_):
    """Function to wrap the criterions"""
    criteria = dict()

    ... where the magic happen ...

    return criteria


def main():
    """Example of usage """
    tekigo_sol = TekigoSolution(mesh='default.mesh.h5',
                                solution='default_inst.sol.h5',
                                out_dir='./Results',
                                overwrite_dir= True,
                                only_sol_vars=['temperature'],
                                only_msh_vars=['volume','/Coordinates/x'])

    refine(
        tekigo_sol,
        custom_criteria,
        dry_run=True,
        iteration_max=1,
        nnode_max=120000,
        min_edge=0.7e-3,
        l2_crit=0.005,
        coarsen=False)

if __name__ == "__main__":
    main()

This is mixing together your mesh default.mesh.h5 and solution default_inst.sol.h5 into the object called tekigo_sol.

The twist

In the Beginner’s recipe, you have seen the raw_adapt function simply requiring your final metric. Here the function refine is no more taking a metric but a dynamic set of criteria called here custom_criteria. The signature of this set is

custom_criteria(ts_: TekigoSolutionObject) -> dict of numpy arrays of shape (nnode)

Therefore, the criteria computed by this function will change when the input mesh/or solution change. This what allows us to make a RECURSIVE adaptation.

beyond criterias, the Global constraints of refine

The other arguments to the refine function are global constraints.

  • nnode_max=120000 The target number of nodes for your adaptation. The number of nodes is ussually 4.5 times smaller than the number of cells.
  • min_edge=0.7e-3 The minimal edge used to limite the lower bound of the metric
  • iteration_max=1 The number of adaptation loops. Note : If the metric is very close to unity , ita est if L2_crit lower than the threshold.

We can add other elements:

  • dry_run=True Will interrupt Tekigo BEFORE the first adaptation. So you can check the metric but also the future edge.
  • coarsen=False will prevent Tekigo from coarsening.

Application to a real case

In the present case we define the following criterias.

def custom_criteria(tkg_sol):
    """Funtion to wrap the criterions


    This creteria will be called at each new adaptation mesh.
    Therefore the size of the array, and the mesh properties,
    will change acordingly.

    It is YOUR duty to make a criteria that converges (or not)

    Parameter :
    -----------
    tkg_sol : an instance of tekigo solution.

    Returns :
    ---------
        a flat dictionary of np_arrays of shape (nnode)
        each entry is a criterion
    """

    mesh = tkg_sol.load_current_mesh()
    x_coor = mesh['/Coordinates/x']
    # y_coor = mesh['/Coordinates/y']
    vol_node = mesh['/VertexData/volume']
    # curr_edge = approx_edge_from_vol_node(vol_node)

    sol = tkg_sol.load_current_solution()
    like = sol['LIKE']
    yplus = sol['wall_Yplus']

    criteria = dict()  # This dict store all the criterias to use
    # criterion on like.
    # max if like = 1e+3
    # min if like = 1e-1
    # log10 evolution
    crit = (np.log10(like) - (-1))/((3) - (-1))
    crit = np.clip(crit, 0, 1.)
    # nullify criterion on the last half of the domain
    # Mash in MILLIMETERS, you bet!
    crit = np.where(x_coor > -180., crit, 0.)
    criteria['like'] =  crit

    # max if yplus > 1
    # log10 evolution
    crit = (yplus - (0))/(1 - 0)
    crit = np.clip(crit, 0, 1.)
    # nullify criterion on the last half of the domain
    # Mash in MILLIMETERS, you bet!
    crit = np.where(x_coor > -180., crit, 0.)
    criteria['yplus'] =  crit

    return criteria

This gives, for the present setup, a 19M cells combustion chamber, a metric field negative where refinement is needed (blue), positive when coarsening is allowed (red). On this figure, one can see combination of the LIKE criteria, the Yplus criteria and unchanged last half:

The mesh, before (up) and after (down) will then look like this after 3 adaptation loops.

We therefore have the following improvements. :

. initial mesh final mesh
Min. edge 27 micrometers 59 micrometers
Tetrahedrons nb. 19.1M 15.2M

The mesh showz a larger smallest cell, and a reduced overall number of cells.

Like this post? Share on: TwitterFacebookEmail


Antoine Dauptain is a research scientist focused on computer science and engineering topics for HPC.

Keep Reading


Published

Category

Tutorials

Tags

Stay in Touch