Skip to content

Commit 556d52a

Browse files
committed
feat(网格优化): 重构边折叠算法并优化节点索引管理
重构边折叠算法,改进拓扑重建逻辑,确保正确重连相邻单元。优化Adfront2中的节点索引管理,避免重复坐标节点残留无效索引。更新测试用例以反映网格生成结果的变更。 边折叠算法现在能正确处理边界节点和内部短边,并保持网格拓扑一致性。Adfront2类新增节点哈希映射,确保节点索引正确性。测试用例调整了预期网格尺寸和输出文件路径。
1 parent 44080a2 commit 556d52a

5 files changed

Lines changed: 283 additions & 164 deletions

File tree

adfront2/adfront2.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def __init__(
8181
self.unstr_grid = None # Unstructured_Grid网格对象
8282

8383
self.node_hash_list = None # 节点hash列表,用于判断是否重复
84+
self.node_elem_by_hash = None # 节点hash到NodeElement对象的映射
8485
self.cell_hash_list = None # 单元hash列表,用于判断是否重复
8586

8687
self.initialize()
@@ -93,6 +94,7 @@ def initialize(self):
9394

9495
self.boundary_nodes = set()
9596
self.node_hash_list = set()
97+
self.node_elem_by_hash = {}
9698
self.cell_hash_list = set()
9799
self.cell_container = []
98100
self.front_node_list = []
@@ -110,8 +112,27 @@ def initialize(self):
110112
if node_elem.hash not in self.node_hash_list:
111113
self.node_hash_list.add(node_elem.hash)
112114
self.boundary_nodes.add(node_elem) # 添加边界节点
113-
if not flag_given_node: # 如果未给定节点坐标,则添加节点坐标
115+
if not flag_given_node: # 如果未给定节点坐标,则添加节点坐标并重建索引
116+
node_elem.idx = len(self.node_coords)
114117
self.node_coords.append(node_elem.coords)
118+
elif (
119+
not isinstance(node_elem.idx, int)
120+
or node_elem.idx < 0
121+
or node_elem.idx >= len(self.node_coords)
122+
):
123+
# 外部提供了节点坐标,但当前front节点索引无效时,补齐索引并扩展坐标表
124+
node_elem.idx = len(self.node_coords)
125+
self.node_coords.append(node_elem.coords)
126+
self.node_elem_by_hash[node_elem.hash] = node_elem
127+
else:
128+
# 复用已登记节点索引,避免重复坐标节点残留idx=-1
129+
existing_node = self.node_elem_by_hash.get(node_elem.hash)
130+
if existing_node is not None and (
131+
not isinstance(node_elem.idx, int) or node_elem.idx < 0
132+
):
133+
node_elem.idx = existing_node.idx
134+
135+
front.node_ids = [node_elem.idx for node_elem in front.node_elems]
115136

116137
self.front_node_list = list(self.boundary_nodes)
117138
self.num_nodes = len(self.node_coords)
@@ -724,24 +745,31 @@ def add_new_point(self, spacing):
724745
def update_nodes(self):
725746
"""更新节点"""
726747
# 应对pselected可能为NodeElement,也可能为多个NodeElement的情况,统一转换为list
727-
# 注意不能直接将self.pselected转换为list,应该后面update_fronts时还需要使用self.pselected
728-
pselected = (
729-
[self.pselected]
730-
if is_node_element(self.pselected)
731-
else self.pselected
732-
)
748+
is_single_selected = is_node_element(self.pselected)
749+
pselected = [self.pselected] if is_single_selected else list(self.pselected)
733750

734751
for i, node in enumerate(pselected):
735752
node_hash = node.hash
736753
if node_hash not in self.node_hash_list:
737754
self.node_hash_list.add(node_hash)
738755
self.node_coords.append(node.coords)
739756
pselected[i].idx = self.num_nodes
757+
self.node_elem_by_hash[node_hash] = pselected[i]
758+
self.front_node_list.append(pselected[i])
740759
self.add_elems_to_space_index(
741760
[node], self.space_index_node, self.node_dict
742761
)
743762

744763
self.num_nodes += 1
764+
else:
765+
# 对重复节点仅回填合法idx,不替换节点对象,避免改变原有推进行为
766+
existing_node = self.node_elem_by_hash.get(node_hash)
767+
if existing_node is not None and (
768+
not isinstance(pselected[i].idx, int) or pselected[i].idx < 0
769+
):
770+
pselected[i].idx = existing_node.idx
771+
772+
self.pselected = pselected[0] if is_single_selected else pselected
745773

746774
def update_fronts(self, new_fronts):
747775
"""更新阵面"""

adfront2/adfront2_hybrid.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -507,17 +507,22 @@ def add_new_points_for_quad(self, spacing):
507507
def reconstruct_node2front(self):
508508
"""重构node2front列表,按照先左侧阵面,后右侧阵面的顺序存储"""
509509
num_neighbors = 2
510-
for front in self.front_list:
511-
for node_elem in front.node_elems:
512-
if len(node_elem.node2front) == 0:
513-
node_elem.node2front = [None] * num_neighbors # 预分配2个位置
510+
node_front_slots = {}
514511

512+
for front in self.front_list:
515513
# node_elem在front中是起点,则front是在后面
516514
for i, node_elem in enumerate(front.node_elems):
517-
node_elem.node2front[(i + 1) % num_neighbors] = front
515+
slots = node_front_slots.setdefault(
516+
node_elem.idx,
517+
[None] * num_neighbors,
518+
)
519+
slots[(i + 1) % num_neighbors] = front
518520

519521
# 检查每个节点的邻阵面数量是否为2
520522
for front in self.front_list:
521523
for node_elem in front.node_elems:
522-
if not all(node_elem.node2front):
524+
node_elem.node2front = list(
525+
node_front_slots.get(node_elem.idx, [None] * num_neighbors)
526+
)
527+
if node_elem.idx < 0 or not all(node_elem.node2front):
523528
raise ValueError(f"节点 {node_elem.idx} 的邻阵面数量不足2")

0 commit comments

Comments
 (0)