DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
OversetCartManager.py
Go to the documentation of this file.
1from DNDSR import DNDS, Geom
2import mpi4py as pyMPI
3import scipy.spatial
4from OversetCart import OversetBG2D, OversetPart2D, DistMap
5from GeomUtils import get_mpi4py_comm_from_MPIInfo
6import numpy as np
7import sys, os
8import time, itertools
9
10
12 def __init__(self, mpi: DNDS.MPIInfo):
13 self._mpi = mpi
14 self._MPI = get_mpi4py_comm_from_MPIInfo(mpi)
15
17 self,
18 mesh_names: list[str],
19 initial_transforms=list[tuple[np.ndarray, np.ndarray]],
20 ):
21 mpi = self._mpi
22 assert len(mesh_names) == len(initial_transforms)
23 self.parts = parts = [
24 OversetPart2D(mpi, transform=initial_transforms[i])
25 for i in range(len(initial_transforms))
26 ]
27 for i, osPart in enumerate(parts):
28 osPart.read_mesh(mesh_names[i])
29 osPart.obtain_dist_node()
30 self.osBG = OversetBG2D(mpi)
31
32 @property
33 def nPart(self):
34 return len(self.parts)
35
36 def process_overset(self, h: float):
37 mpi = self._mpi
38 parts = self.parts
39 osBG = self.osBG
40 osBG.set_bg(parts, h)
41 assert osBG.procMap[osBG.rank_to_ax_rank()] == mpi.rank
42 self.dist_maps = dist_maps = osBG.obtain_dist_map(parts)
43 # self.print_proc_dist_maps()
44 self.cell_type_arrs, self.other_dists_nodes = osBG.decide_cell_types(
45 parts, dist_maps
46 )
47
48 # print(
49 # osBG.query_dist_from_points(
50 # dist_maps[0], points=np.array([[0.25, 0, 0 - 0.025], [0.5, 0.25, 0.5]])
51 # )
52 # )
54 for iPart, part in enumerate(parts):
55 iFacesSourceLoc, coords_mid = part.get_holed_faces_midpt(
56 self.cell_type_arrs[iPart]
57 )
58 iPartTemp, iCellTemp = osBG.decide_point_templates(
59 parts, dist_maps, coords_mid
60 )
61 self.part_bnd_templates.append((iPartTemp, iCellTemp, iFacesSourceLoc))
62
63 def cache_templates(self):
64 pass
65
67 self.osBG.print_proc_dist_maps(self.dist_maps)
68
69 def print_full_mesh_type(self, out_name="", together=False):
70 highlight_iCells_list = []
71 for iPart, part in enumerate(self.parts):
72 highlight_iCells = set()
73 for iPartTemp, iCellTemp, iFacesSourceLoc in self.part_bnd_templates:
74 highlight_iCells.update(set(iCellTemp[iPartTemp == iPart]))
75 highlight_iCells_list.append(highlight_iCells)
76
77 if not together:
78 for iPart, part in enumerate(self.parts):
79 part.print_full_mesh_type(
80 iPart,
81 self.cell_type_arrs[iPart],
82 highlight_iCells=highlight_iCells_list[iPart],
83 )
84 else:
85 import matplotlib.pyplot as plt
86
87 fig = plt.figure(figsize=(8, 6), dpi=400)
88
89 for iPart, part in enumerate(self.parts):
90 part.print_full_mesh_type(
91 iPart,
92 self.cell_type_arrs[iPart],
93 no_hole=True,
94 ax=plt.gca(),
95 highlight_iCells=highlight_iCells_list[iPart],
96 )
97 plt.axis("equal")
98 plt.gca().autoscale()
99 if len(out_name):
100 out_name += "_"
101 plt.savefig(out_name + "parts_all.png")
102 plt.close(fig)
103
104
105def AnimateMotion(mpi: DNDS.MPIInfo):
106 mpiGlob = mpi
107 translates = [[0, 0, 0], [1.5, 0, 0]]
108 translates_end = [[0, 0, 0], [0.5, 0, 0]]
109 rot = np.array([0.0, 0])
110 rot_end = np.array([0.0, 90])
111 translates = np.array(translates)
112 translates_end = np.array(translates_end)
113 Nstep = 41
114
115 transforms = [
116 (np.eye(3, 3), np.array(translates[i])) for i in range(len(translates))
117 ]
118 # translates = [[0, 0, 0]]
119
120 mesh_names = [
121 os.path.join(
122 os.path.dirname(__file__),
123 "..",
124 "..",
125 "..",
126 "data",
127 "mesh",
128 "CylinderNoFar.cgns",
129 )
130 ] * len(transforms)
131
132 osMan = OversetBG2DManager(mpiGlob)
133
134 osMan.read_meshes_and_init(mesh_names, transforms)
135
136 # for iter in range(100000):
137 # osMan.process_overset(1.0 / 10) #todo: test forged leak here
138
139 inter = np.linspace(0, 1, Nstep)
140 for i in range(0, Nstep):
141 translate_now = inter[i] * translates_end + (1 - inter[i]) * translates
142 rot_now = inter[i] * rot_end + (1 - inter[i]) * rot
143 import scipy.linalg
144 from scipy.spatial.transform import Rotation as R
145
146 transforms = [
147 (
148 R.from_euler("xyz", [0, 0, rot_now[i]], degrees=True).as_matrix(),
149 np.array(translate_now[i]),
150 )
151 for i in range(len(translate_now))
152 ]
153 for iPart, part in enumerate(osMan.parts):
154 part.transform = transforms[iPart]
155
156 t0 = time.perf_counter()
157 osMan.process_overset(1.0 / 10)
158 if mpiGlob.rank == 0:
159 print(
160 f"[{i+1}/{Nstep}] process done. 🥺 time: [{time.perf_counter() - t0}]"
161 )
162
163 osMan.print_full_mesh_type(together=True, out_name=f"os_type_1_{i:04}")
164
165
166if __name__ == "__main__":
167 mpiGlob = DNDS.MPIInfo()
168 mpiGlob.setWorld()
169
170 AnimateMotion(mpiGlob)
print_full_mesh_type(self, out_name="", together=False)
read_meshes_and_init(self, list[str] mesh_names, initial_transforms=list[tuple[np.ndarray, np.ndarray]])
set(LIBNAME cfv) set(LINKS) set(LINKS_SHARED geom_shared dnds_shared $
Definition CMakeLists.txt:5
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
Definition MPI.hpp:215