Post.IBM: immersed boundary method specific post-processing

Specific post-processing for immersed boundaries (IB).

These functions work with a solution tree “t”, a geometry tree “tb”, and/or a connectivity tree “tc”.

All of these functions can be executed in both sequential and parallel contexts.

List of functions

– Extract additional IBM information in the connectivity tree

Post.IBM.extractPressureGradients

Extracts the pressure gradients at the image points.

Post.IBM.extractPressureHighOrder

Extrapolates the wall pressure (1st or 2nd order) at the immersed boundaries.

Post.IBM.extractYplusAtImagePoints

Extracts the yplus values at the image points.

– IBM post-processing

Post.IBM.prepareSkinReconstruction

Prepares the flow solution extraction at immersed boundaries.

Post.IBM.computeSkinVariables

Computes the surface flow solution at the wall.

Post.IBM.computeAerodynamicLoads

Computes the aerodynamic loads at the wall.

Post.IBM.computeAerodynamicCoefficients

Normalizes aerodynamic coefficients and places integration information in the wind frame.

Contents

Post.IBM.extractPressureGradients(t, tc, secondOrder=False)

Computes and extracts the pressure gradients from the solution tree (t) to the image points. The pressure gradients are computed within the fluid domain using a second order technique. The pressure gradients are finally obtained at the image points with the same interpolation technique as for the immersed boundary treatment used during the simulation. The updated information is stored in the connectivity tree (tc) within the IBCD* sub-regions. The solution tree (t) remains unchanged.

Also available as in-place (_extractPressureGradients).

Parameters:
  • t ([zone, list of zones, base, tree]) – solution tree

  • tc ([zone, list of zones, base, tree]) – connectivity tree

  • secondOrder (boolean) – if True, also computes second order pressure gradients

Returns:

same as input with updated pressure gradient solution in each IBCD zone

Example of use:

# - extractPressureGradients (pyTree) -
import Converter.PyTree as C
import Geom.PyTree as D
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

ac = P_IBM.extractPressureGradients(a, ac, secondOrder=True)

C.convertPyTree2File(ac,'out.cgns')

Post.IBM.extractPressureHighOrder(tc, order=1)

Extrapolates the wall pressure (1st or 2nd order) at the immersed boundaries and stores the solution in the connectivity tree. This function requires the pressure gradient information stored in the IBCD* sub-regions in the x, y, and z directions (see Post.IBM.extractPressureGradients).

Also available as in-place (_extractPressureHighOrder).

Parameters:
  • tc ([zone, list of zones, base, tree]) – connectivity tree

  • order (1 or 2) – int

Returns:

same as input with updated pressure solution in each IBCD zone

Example of use:

# - extractPressureGradients (pyTree) -
import Converter.PyTree as C
import Geom.PyTree as D
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

ac = P_IBM.extractPressureGradients(a, ac, secondOrder=True)

ac = P_IBM.extractPressureHighOrder(ac, order=2)

C.convertPyTree2File(ac,'out.cgns')

Post.IBM.extractYplusAtImagePoints(tc)

Extracts the yplus values at the image points and stores the solution in the connectivity tree. This function uses the yplus information located in the IBCD* subregions corresponding to the yplus values calculated at the target points during the simulation.

Also available as in-place (_extractYplusAtImagePoints).

Parameters:

tc ([zone, list of zones, base, tree]) – connectivity tree

Returns:

same as input with updated yplus solution (yplusIP) in each IBCD zone

Example of use:

# - computePressureGradients (pyTree) -
import Converter.Internal as Internal
import Converter.PyTree as C
import Generator.PyTree as G
import Geom.PyTree as D
import KCore.test as test
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM
import copy
import numpy

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

ac = P_IBM.extractYplusAtImagePoints(ac)

C.convertPyTree2File(ac, 'out.cgns')

Post.IBM.prepareSkinReconstruction(tb, tc, dimPb=3, ibctypes=[])

Prepares the flow solution extraction at immersed boundaries. This function extracts the IBM wall points originally stored in the connectivity tree to create a cloud of points that can be projected onto the surface. This function then pre-calculates and stores the intepolation data for the MLS projection (Moving Least Square, 3rd order), which can be particularly useful when more than one on-the-fly force extraction is requested during the simulation.

When run in parallel, this function also automatically splits the case tree into NP parts (where NP is the number of MPI processes) and dispatches them between procs.

If ibctypes is not empty, only the information associated with some immersed boundary conditions is calculated.

Parameters:
  • tb ([zone, list of zones, base, tree]) – surface mesh (TRI-type) with density, pressure, utau, and velocity variables

  • tc ([zone, list of zones, base, tree]) – connectivity tree

  • dimPb (list of integers) – problem dimension

  • ibctypes – list of IBC conditions

Returns:

Communication graph for IBM post-processing (for parallel use) and surface tree with interpolation data stored in each zone

Example of use:

# - extractSkinReconstruction (pyTree) -
import Converter.Internal as Internal
import Converter.PyTree as C
import Generator.PyTree as G
import Geom.PyTree as D
import KCore.test as test
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM
import copy
import numpy

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

graphIBCDPost, ts = P_IBM.prepareSkinReconstruction(tb, ac, dimPb=2, ibctypes=[3]) #3: Musker

C.convertPyTree2File(ts, 'out.cgns')

Post.IBM.computeSkinVariables(ts, tc, graphIBCDPost, dimPb=3, ibctypes=[])

Computes the surface flow solution at the wall using the IBM information updated and stored in the connectivity tree at each iteration of the flow simulation. This function operates in conjunction with Post.IBM.prepareSkinReconstruction, which must be called beforehand.

Density, pressure and velocity vector (VelocityX, VelocityY, VelocityZ) information is updated in each zone of the surface tree. Depending on the immersed boundary condition, additional variables may also be updated, such as utau and yplus when using wall models.

Also available as in-place (_computeSkinVariables).

Parameters:
  • ts ([zone, list of zones, base, tree]) – surface mesh (TRI-type) with interpolation data stored in each zone

  • tc ([zone, list of zones, base, tree]) – connectivity tree

  • graphIBCDPost (python dictionary) – communication graph for IBM post-processing

  • dimPb (list of integers) – problem dimension

  • ibctypes – list of IBC conditions

Returns:

surface tree with updated flow information

Example of use:

# - computeSkinVariables (pyTree) -
import Converter.Internal as Internal
import Converter.PyTree as C
import Generator.PyTree as G
import Geom.PyTree as D
import KCore.test as test
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM
import copy
import numpy

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

graphIBCDPost, ts = P_IBM.prepareSkinReconstruction(tb, ac, dimPb=2, ibctypes=[3]) #3: Musker
P_IBM._computeSkinVariables(ts, ac, graphIBCDPost, dimPb=2, ibctypes=[3])

C.convertPyTree2File(ts, 'out.cgns')

Post.IBM.computeAerodynamicLoads(ts, ts2=None, dimPb=3, famZones=[], Pref=None, center=(0., 0., 0.), verbose=0)

Computes the aerodynamic loads acting on the immersed boundaries (forces and moments). This function computes the pressure and friction contributions separately. If an additional surface tree solution (ts2) is specified, the pressure solution is extracted from ts2 to ts, since ts2 is usually used to extract the pressure solution further away from the wall. A list of family names can also be specified to integrate only some parts of the geometry.

This function returns a list of four lists containing the integration information in the body frame (aeroLoads = [forcePressure, forceFriction, momentPressure, momentFriction]).

If Pref is omitted, its value is extracted from the reference state stored in ts.

Warning: the pressure and friction coefficients, as well as the aerodynamic loads are still dimensionalized.

Parameters:
  • ts ([zone, list of zones, base, tree]) – surface mesh (TRI-type) with updated flow solution

  • ts2 ([zone, list of zones, base, tree]) – optional second surface mesh (TRI-type) with updated pressure solution

  • dimPb (2 or 3) – problem dimension

  • famZones (list of strings) – list of family names

  • Pref (float) – reference pressure for the pressure coefficient

  • center (tuple of three floats) – reference center for the integration of the aerodynamic moments

  • verbose (0 or 1) – if verbose > 0, print integration information

Returns:

surface tree with updated flow information (Cp, Cf, etc.) and aeroLoads

Example of use:

# - computeAerodynamicLoads (pyTree) -
import Converter.Internal as Internal
import Converter.PyTree as C
import Generator.PyTree as G
import Geom.PyTree as D
import KCore.test as test
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM
import copy
import numpy

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

graphIBCDPost, ts = P_IBM.prepareSkinReconstruction(tb, ac, dimPb=2, ibctypes=[3]) #3: Musker
P_IBM._computeSkinVariables(ts, ac, graphIBCDPost, dimPb=2, ibctypes=[3])

wall, aeroLoads = P_IBM.computeAerodynamicLoads(ts, ts2=None, dimPb=2, famZones=[], Pref=None, center=(0.,0.,0.), verbose=1)

C.convertPyTree2File(wall, 'out.cgns')

Post.IBM.computeAerodynamicCoefficients(ts, aeroLoads, dimPb=3, Sref=None, Lref=None, Qref=None, alpha=0., beta=0., verbose=0)

Normalizes aerodynamic coefficients and places integration information in the wind frame. This function uses the a priori information obtained with Post.IBM.computeAerodynamicLoads.

If Qref is omitted, its value is extracted from the reference state stored in ts.

If Sref is omitted, its value is calculated as the area of the geometry surface.

If Lref is omitted, it is set to Lref = 1 by default.

Parameters:
  • ts ([zone, list of zones, base, tree]) – surface mesh (TRI-type) with extra information (dimensionalized pressure and friction coefficients)

  • dimPb (2 or 3) – problem dimension

  • Sref (float) – reference surface

  • Lref (float) – reference length

  • Qref (float) – reference dynamic pressure

  • alpha (float) – angle of attack (x-z plane)

  • beta (float) – angle of sideslip (x-y plane)

  • verbose (0 or 1) – if verbose > 0, print integration information

Returns:

Surface tree with normalized Cp & Cf and updated aeroLoads with adimensionalized integration information placed in the wind frame.

Example of use:

# - computeAerodynamicCoefficients (pyTree) -
import Converter.Internal as Internal
import Converter.PyTree as C
import Generator.PyTree as G
import Geom.PyTree as D
import KCore.test as test
import Post.IBM as P_IBM
import Geom.IBM as D_IBM
import Connector.IBM as X_IBM
import copy
import numpy

tb = D.circle((0.,0.,0.), 1., N=100)
tb = C.newPyTree(['Base', tb])
D_IBM._setSnear(tb, 0.05)
D_IBM._setDfar(tb, 10.)
D_IBM._setIBCType(tb, 'Musker')
C._addState(tb, adim='adim1', MInf=0.2, alphaZ=0., alphaY=0., ReInf=5.e6, EquationDimension=2, GoverningEquations='NSTurbulent')

a, ac = X_IBM.prepareIBMData(tb, t_out=None, tc_out=None, vmin=21, frontType=1, check=False)

graphIBCDPost, ts = P_IBM.prepareSkinReconstruction(tb, ac, dimPb=2, ibctypes=[3]) #3: Musker
P_IBM._computeSkinVariables(ts, ac, graphIBCDPost, dimPb=2, ibctypes=[3])

wall, aeroLoads = P_IBM.computeAerodynamicLoads(ts, ts2=None, dimPb=2, famZones=[], Pref=None, center=(0.,0.,0.), verbose=1)
wall, aeroLoads = P_IBM.computeAerodynamicCoefficients(wall, aeroLoads, dimPb=2, Sref=1, Lref=None, Qref=None, alpha=0., beta=0., verbose=1)

C.convertPyTree2File(wall, 'out.cgns')