|
DNDSR 0.2.1
Distributed Numeric Data Structure for CFV
|
This document describes how to use the DNDSR Python Geom module for reading and manipulating computational meshes.
The DNDSR.Geom module provides Python bindings to the C++ geometry library, enabling:
Import the module and initialize MPI:
MPI is initialized automatically when DNDSR.DNDS is imported (via MPI.Init_thread). If you need to control MPI initialization yourself (e.g., to set the thread level), import and initialize mpi4py before importing DNDSR.DNDS.
The main mesh container class.
Key Methods:
| Method | Description |
|---|---|
NumCell() | Number of local cells |
NumCellGlobal() | Global cell count (collective) |
NumNode() | Number of local nodes |
NumNodeGlobal() | Global node count (collective) |
NumFace() | Number of local faces |
NumFaceGlobal() | Global face count (collective) |
NumBnd() | Number of local boundary faces |
NumBndGlobal() | Global boundary face count (collective) |
NumCellGhost() | Number of ghost cells |
NumNodeGhost() | Number of ghost nodes |
NumFaceGhost() | Number of ghost faces |
NumBndGhost() | Number of ghost boundary faces |
getDim() | Mesh dimension (2 or 3) |
getMPI() | Return the MPIInfo object |
RecoverNode2CellAndNode2Bnd() | Build node connectivity |
RecoverCell2CellAndBnd2Cell() | Build cell/boundary connectivity |
BuildGhostPrimary() | Build ghost cell communication |
AdjGlobal2LocalPrimary() | Convert global indices to local |
AdjLocal2GlobalPrimary() | Convert local indices to global |
AdjGlobal2LocalPrimaryForBnd() | Global→local for boundary mesh |
AdjLocal2GlobalPrimaryForBnd() | Local→global for boundary mesh |
AdjGlobal2LocalN2CB() | Global→local for node-to-cell/bnd |
AdjLocal2GlobalN2CB() | Local→global for node-to-cell/bnd |
BuildGhostN2CB() | Build ghost node-to-cell/bnd comm |
InterpolateFace() | Build face interpolation data |
AssertOnFaces() | Validate face data |
BuildVTKConnectivity() | Prepare for VTK output |
RecreatePeriodicNodes() | Reconstruct periodic node mapping |
ConstructBndMesh(bndMesh) | Extract (dim-1) boundary mesh |
ReorderLocalCells(nParts, nPartsInner) | Reorder cells for cache locality |
BuildO2FromO1Elevation(meshO1) | Elevate O1→O2 in-place |
BuildBisectO1FormO2(meshO2) | Bisect O2→O1 sub-mesh in-place |
BuildNodeWallDist(fBndIsWall, options) | Compute wall distance field |
to_device(backend) | Offload arrays to device ("CUDA") |
to_host() | Pull arrays back to host |
getArrayBytes() | Total memory used by arrays |
Key Read-Only Members:
| Member | Type | Description |
|---|---|---|
coords | coordinate pair | Node coordinates |
cell2node | adjacency pair | Cell-to-node connectivity |
bnd2node | adjacency pair | Boundary-to-node connectivity |
bnd2cell | adjacency pair | Boundary-to-cell connectivity |
cell2cell | adjacency pair | Cell-to-cell connectivity |
cellElemInfo | ElemInfo pair | Per-cell element type and zone |
bndElemInfo | ElemInfo pair | Per-bnd element type and zone |
cell2face | adjacency pair | Cell-to-face (after InterpolateFace) |
face2cell | adjacency pair | Face-to-cell (after InterpolateFace) |
face2node | adjacency pair | Face-to-node (after InterpolateFace) |
faceElemInfo | ElemInfo pair | Per-face element type and zone |
Note:
GetCellElement(),GetBndElement(),IsO1(), andIsO2()are C++ methods that are not exposed in the Python bindings. To query element types from Python, usemesh.cellElemInfo[iCell][0].getElemType()which returns aGeom.Elem.ElemTypeenum value.
Per-element metadata, accessible via mesh.cellElemInfo and mesh.bndElemInfo.
Serial mesh reader/writer for CGNS files.
Key Methods:
| Method | Description |
|---|---|
ReadFromCGNSSerial(path) | Read CGNS file; returns AutoAppendName2ID |
Deduplicate1to1Periodic(tol) | Merge periodic 1-to-1 connections |
BuildCell2Cell() | Build serial cell-to-cell adjacency |
MeshPartitionCell2Cell(options) | Partition with Metis |
PartitionReorderToMeshCell2Cell() | Reorder to match partition |
BuildSerialOut() | Prepare serial output data |
Key Members:
| Member | Access | Description |
|---|---|---|
mesh | read/write | The UnstructuredMesh object |
dataIsSerialOut | read-only | Whether serial output is built |
dataIsSerialIn | read-only | Whether serial input is ready |
Returned by ReadFromCGNSSerial. Maps boundary/zone names to integer IDs.
Available as Geom.Elem.ElemType:
| Value | Description |
|---|---|
UnknownElem | Unknown / uninitialized |
Line2, Line3 | 1D line elements |
Tri3, Tri6 | Triangle elements |
Quad4, Quad9 | Quadrilateral elements |
Tet4, Tet10 | Tetrahedron elements |
Hex8, Hex27 | Hexahedron elements |
Prism6, Prism18 | Prism elements |
Pyramid5, Pyramid14 | Pyramid elements |
Note: The C++
Elem::Elementstruct (with methodsGetDim(),GetOrder(),GetNumNodes(),IsO1(),GetParamSpace(), etc.) is not exposed in the Python bindings. Only theElemTypeenum is available.
Nested class UnstructuredMesh.WallDistOptions for configuring wall distance computation:
The recommended API uses read_mesh + prepare_mesh from DNDSR.Geom.utils:
read_mesh returns a MeshReadResult dataclass with mesh, reader, and name_to_id fields. prepare_mesh mutates the mesh in-place (cell reorder, face interpolation, ghost N2CB, serial output, periodic nodes, VTK connectivity).
The legacy create_mesh_from_CGNS function is still available as a backward-compatible wrapper:
**read_mesh parameter list:**
| Parameter | Type | Default | Description |
|---|---|---|---|
mesh_file | str | required | Path to CGNS or H5 mesh file |
mpi | MPIInfo | required | MPI context |
dim | int | 2 | Mesh dimension (2 or 3) |
periodic_geometry | dict | see below | Periodic transform parameters |
periodic_tolerance | float | 1e-9 | Tolerance for periodic dedup |
read_mode | str | auto | "cgns" or "h5" (auto-detected from extension) |
partition_options | dict | Metis defaults | Metis/ParMetis partitioning options |
elevation | str | "" | "" or "O2" for quadratic elevation |
bisect | int | 0 | Number of bisection levels (0-4) |
serializer_factory | SerializerFactory | H5 factory | For H5 read modes |
**prepare_mesh parameter list:**
| Parameter | Type | Default | Description |
|---|---|---|---|
mesh | UnstructuredMesh | required | Mesh to prepare (mutated in-place) |
reader | UnstructuredMeshSerialRW | required | Reader from read_mesh |
reorder_parts | int | 1 | Cell reordering partitions |
reorder_inner_parts | int | 1 | Second-level reordering partitions |
build_serial_out | bool | True | Build serial output data |
wall_dist_predicate | callable | None | f(bnd_id) -> bool for wall distance |
wall_dist_options | WallDistOptions | None | Wall distance settings |
coord_scale | float | None | Scale coordinates |
coord_rot_z_deg | float | None | Rotate coordinates around Z axis |
rectify_near_plane | str | None | Rectify near-plane coords ("x", "y", "z") |
rectify_threshold | float | 1e-10 | Threshold for rectification |
Periodic geometry default:
These are passed directly to mesh.SetPeriodicGeometry(), which accepts up to three periodic direction triples (translation, rotationCenter, eulerAngle).
read_mesh auto-detects the mode from the file extension (.cgns -> CGNS serial read, .h5 -> H5 distributed read). Override with the read_mode parameter:
| Mode | Extension | Description |
|---|---|---|
"cgns" | .cgns | Read CGNS on rank 0, partition with Metis, distribute. Returns name_to_id. |
"h5" | .h5 | Read H5 with even-split + ParMetis repartition. Works with any MPI rank count. |
Warning: In H5 mode,
name_to_id(boundary name mapping) is not read from the serializer and will beNone. Only CGNS mode returns a validAutoAppendName2ID.
read_mesh + prepare_mesh run the complete mesh pipeline so you do not need to call these steps manually. For reference, the CGNS-mode pipeline is:
**read_mesh (CGNS mode):**
reader.ReadFromCGNSSerial(meshFile) — read CGNS on rank 0reader.Deduplicate1to1Periodic(tolerance) — merge periodic connectionsreader.BuildCell2Cell() — build serial cell adjacencyreader.MeshPartitionCell2Cell({...}) — partition with Metisreader.PartitionReorderToMeshCell2Cell() — reorder to match partitionelevation == "O2") Build O2 mesh and swapbisect > 0) Elevate→bisect loop**prepare_mesh:**
mesh.ReorderLocalCells(nParts, nPartsInner) — cell reorderingmesh.InterpolateFace() — build face datamesh.AssertOnFaces() — validate facesAdjLocal2GlobalN2CB() / BuildGhostN2CB() / AdjGlobal2LocalN2CB()build_serial_out) Build serial outputmesh.RecreatePeriodicNodes() — reconstruct periodic mappingmesh.BuildVTKConnectivity() — prepare VTK outputwall_dist_predicate) Compute wall distancesIf you need fine-grained control, you can run the pipeline manually:
Elevation converts linear elements to quadratic elements:
Node count increase for UniformSquare_10 (10×10 Quad4):
Bisection splits O2 elements into O1 sub-elements:
| O2 Element | Sub-elements | O1 Type |
|---|---|---|
| Quad9 | 4 | Quad4 |
| Tri6 | 4 | Tri3 |
| Hex27 | 8 | Hex8 |
| Tet10 | 8 | Tet4 |
| Prism18 | 8 | Prism6 |
| Pyramid14 | 12 | Pyramid5 |
Cell count progression for UniformSquare_10:
For meshes with periodic boundaries:
SetPeriodicGeometry accepts up to three periodic direction triples: translation1/rotationCenter1/eulerAngles1 through translation3/rotationCenter3/eulerAngles3.
VTK connectivity is built automatically by create_mesh_from_CGNS. For manual control:
Note: The C++ methods
IsO1()andIsO2(), as well as theMeshElevationStateenum (Elevation_Untouched,Elevation_O1O2), are not exposed in the Python bindings. To check whether a mesh uses O2 elements, inspect the element types viacellElemInfo[i][0].getElemType().
Note: The
MeshAdjStateenum is exposed in Python asGeom.MeshAdjStatewith valuesUnknown,PointToGlobal, andPointToLocal. Each adjacency member (e.g.mesh.cell2node) is anAdjPairTrackedobject whoseidxmember exposes read-only state query methods:state(),isLocal(),isGlobal(),isBuilt(),isWired(). The group state variables (e.g.adjPrimaryState) are still accessible as integers for backward compatibility.
test/Geom/test_basic_geom.py for Python usage examplespython/DNDSR/Geom/utils.py for the Python API implementationsrc/Geom/Mesh/Mesh_bind.hpp for the complete list of Python-exposed methodssrc/Geom/Elements_bind.hpp for the ElemType enum bindingsdocs/architecture/Paradigm.md for overall design philosophy