26 mesh, reader, name2Id = create_mesh_from_CGNS(
28 os.path.dirname(__file__),
33 "Uniform32_Periodic.cgns",
37 inner_process_parts=4,
49 n2idmap = name2Id.n2id_map
50 id2nmap = {k: v
for v, k
in n2idmap.items()}
52 def name_is_wall(name: str):
53 name = name.capitalize()
56 if "bc-4".capitalize()
in name:
59 def id_is_wall(id: int):
61 if id
in id2nmap
and name_is_wall(id2nmap[id]):
65 wallDistOptions = Geom.UnstructuredMesh.WallDistOptions()
66 wallDistOptions.method = 1
67 wallDistOptions.subdivide_quad = 5
68 wallDistOptions.verbose = 10
69 wallDistOptions.wallDistExecution = 4
70 mesh.BuildNodeWallDist(id_is_wall, wallDistOptions)
72 meshBnd, readerBnd = create_bnd_mesh(mesh)
74 mesh_bytes = mesh.getArrayBytes()
75 mesh_nCell = mesh.NumCellGlobal()
78 print(f
"mesh num cell: {mesh_nCell}")
79 print(f
"mesh size total: {mesh_bytes / (1024 * 1024):.4g} MB")
82 mesh.coords.to_device(
"CUDA")
83 mesh.to_device(
"CUDA")
127 """Test multi-layer ghost cell creation with nGhostLayers=1,2,3.
130 1. Ghost cell/node/bnd counts increase monotonically with layer count.
131 2. For nLayers=2, every layer-1 ghost cell's cell2cell neighbors are
132 in the local+ghost set (the defining property of 2-layer ghosts).
133 3. The full pipeline (read + prepare) works for each layer count.
138 mesh_file = os.path.join(
139 os.path.dirname(__file__),
"..",
"..",
"data",
"mesh",
140 "Uniform32_Periodic.cgns",
145 for nLayers
in [1, 2, 3]:
146 mesh = Geom.UnstructuredMesh(mpi, 2)
147 reader = Geom.UnstructuredMeshSerialRW(mesh, 0)
148 reader.ReadFromCGNSSerial(mesh_file)
149 reader.Deduplicate1to1Periodic(1e-9)
150 reader.BuildCell2Cell()
151 reader.MeshPartitionCell2Cell({
157 reader.PartitionReorderToMeshCell2Cell()
159 mesh.RecoverNode2CellAndNode2Bnd()
160 mesh.RecoverCell2CellAndBnd2Cell()
161 mesh.BuildGhostPrimary(nLayers)
162 mesh.AdjGlobal2LocalPrimary()
163 mesh.AdjGlobal2LocalN2CB()
165 nCellOwned = mesh.NumCell()
166 nCellGhost = mesh.NumCellGhost()
167 nNodeGhost = mesh.NumNodeGhost()
168 nBndGhost = mesh.NumBndGhost()
170 ghost_counts[nLayers] = (nCellGhost, nNodeGhost, nBndGhost)
173 print(f
" nLayers={nLayers}: owned={nCellOwned}, "
174 f
"cellGhost={nCellGhost}, nodeGhost={nNodeGhost}, "
175 f
"bndGhost={nBndGhost}")
181 nCellProc = mesh.NumCellProc()
182 for iCell
in range(nCellOwned):
183 for iNeighbor
in mesh.cell2cell[iCell].tolist():
186 assert iNeighbor < nCellProc, (
187 f
"Layer-1 neighbor {iNeighbor} of owned cell {iCell} "
188 f
"is out of range [0, {nCellProc})")
190 for iNeighbor2
in mesh.cell2cell[iNeighbor].tolist():
193 assert iNeighbor2 < nCellProc, (
194 f
"Layer-2 neighbor {iNeighbor2} of cell {iNeighbor} "
195 f
"(neighbor of owned cell {iCell}) is out of range "
199 prepare_mesh(mesh, reader, build_serial_out=
False)
204 for key
in [
"cell",
"node",
"bnd"]:
205 idx = {
"cell": 0,
"node": 1,
"bnd": 2}[key]
206 counts = [ghost_counts[n][idx]
for n
in [1, 2, 3]]
207 for i
in range(len(counts) - 1):
208 assert counts[i + 1] >= counts[i], (
209 f
"{key} ghost count should be monotonically non-decreasing: "
210 f
"nLayers={i + 1}->{i + 2}: {counts[i]}->{counts[i + 1]}")
212 print(f
" {key} ghost counts: {counts}")
216 for key
in [
"cell",
"node"]:
217 idx = {
"cell": 0,
"node": 1}[key]
218 assert ghost_counts[2][idx] > ghost_counts[1][idx], (
219 f
"{key} ghost count should increase from 1 to 2 layers "
220 f
"with {mpi.size} ranks: "
221 f
"{ghost_counts[1][idx]} vs {ghost_counts[2][idx]}")