Quantum
Quantum is a mesh deformation module based on inverse distance weighting interpolation. To preserve the orthogonality of the mesh in the boundary layers when large displacements occur, the surfaces displacements are splitted in a rotation and a translation terms. These terms are then interpolated in the volume mesh. The Inverse distance weighting interpolation is speed up by a Fast Multipole like Algorithm.
CGNS parser
Data used in mesh deformation module can either be set in the CGNS File or using set up class methods. The figure below show the data structure that mesh deformation module can handle. All mesh deformation parameters are located in the BC_t nodes. The mesh deformation boundary condition is set inside the .Solver#BC Nodes using Data_t node type named mesh_def_type.
Possible values for this field are :
“imposed” or “prescribed”: displacements are imposed on this boundary conditions meaning that Quantum will search a .BCDisplacement#i node containing mesh displacement fields : DisplacementX, DisplacementY, DisplacementZ.
“free” : displacements are free on this boundary.
“null” or “zero” : displacements are null on this boundary.
Warning
be aware that this data structure is not fixed. it might change in the next Quantum version
Class methods
|
Initialize the mesh deformation module. |
Run Fast Multipole method to solve interpolation problem. |
|
Returns Final Tree. |
|
Returns Source Tree. |
|
|
Build the Fast Multipole problem : |
|
Print the Final Tree. |
|
Print the IDW data Tree. |
|
Displacement field <-> pyTree boundary Association. |
|
set Deformation Amplitude. |
-
class
Ael.Quantum.
KeDefGrid
(pyTREE, **kwargs)[source] Initialize the mesh deformation module.
Note
The inititalization will build a deformation tree by splitting surfaces points and uinterior points.
- Parameters
pyTREE (python_CGNS) – Cassiopee PyTree containing the CFD geometry. Surface mesh displacements may be attached.
Approach (string) –
Choose the interpolation methods. Both are taking into account rotations.
- Possible values :
””Matrix”” : interpolation using rotation matrices. Default value
”Quaternions” : interpolation of the quaternions.
”Vector” : interpolation no rotation.
ComputeVelocity (bool) –
Compute the grid velocity through the interpolation using rotation matrices. Only for Matrix approach
- Possible values :
””False””: not taken into account. Default value
””True””
Mode (string) –
If set to True perform the adjoint mesh deformation.
- Possible values :
””Direct”” : perform Mesh deformation. Default value
””Adjoint””: perform Adjoint Mesh computation.
OneOrTwoSideFMM (string) –
Set interpolation speed up approach.
- Possible values :
Two : two sides FMM. Default value
One : one side FMM.
Epsilon (float) –
Error for FMM method.
- Recommended values :
0.5 : for two sides multipole expansion. Default value
0.8 : for one side multipole expansion.
Ndivision (int) – number of implicit step in the Ndivision process.
OmpAllInOne (bool) – If set to True group all the blocks on a processor. Default value : True
isIntegrale (bool) – If set to False surface area are not taken into account in the weighting functions. Default value : True
Leafsize (int) – Minimum number of point in the surfaces and volumes ADT Trees leaves. In 3D 9 is the minimum. Default value : 8
NullDisplacements (string) –
if set to 1 null displacements are weighting the IDWs else damping function is used.
- Possible values :
Weighted : IDW. Default value
Damped : Damping function is used.
Smoothing (bool) –
if set to True, Smoothing is applied. False is the Default value
Warning
not very stable
MpiComm (MPI_communicator) – Set to Comm_World bu default, can be set to local MPI communicator values. Global MPI communicator is the Default value
DEBUG (bool) – set verbosity and checking to maximum.
-
computeMeshDisplacement
()[source] Run Fast Multipole method to solve interpolation problem.
CGNS Tree is filled with the volume displacements
Note
If more than one surface Tree is moving post processing will include smoothing iteration.
-
getFinalTree
()[source] Returns Final Tree.
- Return type
CGNS/Python
-
getSurfTree
()[source] Returns Source Tree.
- Return type
CGNS/Python
-
makeSources
(shape=1)[source] Build the Fast Multipole problem :
Compute displacement of sliding surfaces.
Build surfaces and volume ADT-Trees.
. Note:: If MPI is set to True aggregate surfaces points on all processors.
- Parameters
shape – surface shape number that user want to use for mesh deformation
-
printFinalTree
(Name)[source] Print the Final Tree.
- Parameters
Name – FileName.
-
printSurfTree
(Name)[source] Print the IDW data Tree. Surfaces and displacements and interior points.
- Parameters
Name – FileName.
-
setBndSurfTo
(Name, typeOfBnd, FileName=None, Modenumber=0, path='h*')[source] Displacement field <-> pyTree boundary Association. it Will fill the Deformation PyTree
- Parameters
FileName – Path to the CGNS boundary. must be given as: “ZoneName#BoundaryName”.
typeOfBnd –
Set the mesh deformation boundary type.
- Possible values :
”imposed” : in this case FileName must be filled.
”null” :
”slidingonsurface” :
FileName – Displacements Filename or list of numpy array.
Modenumber – If more than one displacement field is in the file, set the Field number to take into account.
path – Path to displacement variable Names (use wildcard).
-
set_Amplitude
(Amplitude)[source] set Deformation Amplitude.
- Parameters
Name – FileName.
Examples
Pure openMP set up
First set the number of Thread you want to use.
export OMP_NUM_THREADS=4
Warning
when the number of threads is superior to 6 lower performances are observed.
Then run normaly your python script. Here is an example of a python script
import numpy as num
import sys
import Converter.PyTree as C
import Converter.Internal as I
import Ael.Quantum as KDG
import Generator.PyTree as G
#
#Read Cgns File and return CGNS/Python Tree
#
Tree=C.convertFile2PyTree("aileM6_all.cgns")
#
#Parametres de la deformation de maillage
#
DeformationArgs={"Approach" : "Quaternions",
"Epsilon" : 0.5,
"Leafsize" : 8,
"Ndivision" : 250,
"OneOrTwoSideFMM" : "Two",
"NullDisplacements" : "Weighted",
"Smoothing" : False}
#
#Declare mesh deformation object deftree
#
defTree = KDG.KeDefGrid(Tree,**DeformationArgs)
#
#Set amplitude deformation
#
defTree.set_Amplitude(5000.)
#
#Impose some Boundary conditions ( by default boundarys are set to null displacement)
#
defTree.setBndSurfTo("Zone1#BCWall.4","imposed","mode0001_fm.tp",Modenumber=2)
defTree.setBndSurfTo("Zone5#BCWall","imposed","mode0002_fm.tp",Modenumber=2)
defTree.setBndSurfTo("Zone5#BCFarfield.63","slidingonsurface")
#
#Eventually print the deformation TREE
#
defTree.printSurfTree("windows.cgns")
#
#Build FMM problem
#
defTree.makeSources()
#
#Run mesh displacement
#
defTree.computeMeshDisplacement()
I.__FlowSolutionNodes__ = 'Displacement#0'
Tree=C.initVars(Tree, '{CoordinateX} = {CoordinateX}+{DisplacementX}')
Tree=C.initVars(Tree, '{CoordinateY} = {CoordinateY}+{DisplacementY}')
Tree=C.initVars(Tree, '{CoordinateZ} = {CoordinateZ}+{DisplacementZ}')
Tree = G.getVolumeMap(Tree)
vol=I.getNodesFromName(Tree,"vol")
concatenated=[]
for v in vol:
concatenated+=set(v[1].flatten())
print " Sort :: volmin=",num.amin(num.array(concatenated))
I.__FlowSolutionNodes__ = 'FlowSolution'
#
#Tree has been chaged inplace it just has to be write in file.
#
C.convertPyTree2File(Tree,"zones")
MPI/openMP set up
Again set the number of Thread you want to use, then run the case using mpirun :
export OMP_NUM_THREADS=4
mpirun -np nb_procs python Yourcase.py
Parallel mpi mesh deformaton implementation use Converter.mpi. Few more lines are needed to run the previous case in parallel :
import numpy as num
import sys
import Converter.PyTree as C
import Converter.Internal as I
import Ael.Quantum as KDG
#
# Need for mpi
#
import Converter.Mpi as Cmpi
import Distributor2.PyTree as Distributor2
import Generator.PyTree as G
#
#Read Cgns File but leave numpy arrays on all procs
#
skeletonTree= Cmpi.convertFile2SkeletonTree('aileM6_all.cgns')
#
# Distribute over processors
#
#print distribute on N procs
(skeletonTree, dic) = Distributor2.distribute(skeletonTree, NProc=Cmpi.size, algorithm='fast')
#
# load numpy arrays on procs
#
skeletonTree = Cmpi.readZones(skeletonTree, 'aileM6_all.cgns',format="bin_hdf", rank=Cmpi.rank)
#
# remove empty zones
#
skeletonTree = Cmpi.convert2PartialTree(skeletonTree)
#
#Parametres de la deformation de maillage
#
DeformationArgs={"Approach" : "Quaternions",
"Epsilon" : 0.5,
"Leafsize" : 8,
"Ndivision" : 250,
"OneOrTwoSideFMM" : "Two",
"NullDisplacements" : "Weighted",
"Smoothing" : False}
#
#Declare mesh deformation object deftree (MPI=True)
#
defTree = KDG.KeDefGrid(skeletonTree,**DeformationArgs)
#
#Set amplitude deformation
#
defTree.set_Amplitude(5000.)
#
#Impose some Boundary conditions ( by default boundarys are set to null displacement)
#
defTree.setBndSurfTo("Zone1#BCWall.4","imposed","mode0001_fm.tp",Modenumber=2)
defTree.setBndSurfTo("Zone5#BCWall","imposed","mode0002_fm.tp",Modenumber=2)
defTree.setBndSurfTo("Zone5#BCFarfield.63","slidingonsurface")
#
#Build FMM problem
#
defTree.makeSources()
#
#Run mesh displacement
#
defTree.computeMeshDisplacement()
I.__FlowSolutionNodes__ = 'Displacement#0'
skeletonTree=C.initVars(skeletonTree, '{CoordinateX} = {CoordinateX}+{DisplacementX}')
skeletonTree=C.initVars(skeletonTree, '{CoordinateY} = {CoordinateY}+{DisplacementY}')
skeletonTree=C.initVars(skeletonTree, '{CoordinateZ} = {CoordinateZ}+{DisplacementZ}')
skeletonTree = G.getVolumeMap(skeletonTree)
vol=I.getNodesFromName(skeletonTree,"vol")
concatenated=[]
for v in vol:
concatenated+=set(v[1].flatten())
print " Sort :: volmin=",num.amin(num.array(concatenated))
I.__FlowSolutionNodes__ = 'FlowSolution'
#
#gather all zones
#
d = Cmpi.allgather(skeletonTree)
skeletonTree = I.merge(d)
#Cmpi.convertPyTree2File(skeletonTree, 'out.cgns')
#
#Write tree on proc 0
#
if Cmpi.rank==0:
C.convertPyTree2File(skeletonTree,"zones")
Gallery
Initial mesh |
Final mesh |
Final mesh |
Zoom |
Inital |
Final |
Final |