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
Extracts the pressure gradients at the image points. |
|
Extrapolates the wall pressure (1st or 2nd order) at the immersed boundaries. |
|
Extracts the yplus values at the image points. |
– IBM post-processing
Prepares the flow solution extraction at immersed boundaries. |
|
Computes the surface flow solution at the wall. |
|
Computes the aerodynamic loads at the wall. |
|
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')