-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathcore.py
More file actions
281 lines (241 loc) · 11 KB
/
core.py
File metadata and controls
281 lines (241 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
import sys
from pathlib import Path
# 获取项目根目录
project_root = str(Path(__file__).parent)
# 将项目根目录添加到sys.path - DO THIS FIRST before any imports
sys.path.insert(0, project_root) # Add project root first
# Now import modules using proper package structure
from meshsize import QuadtreeSizing
from adfront2.adlayers2 import Adlayers2
from data_structure.parameters import Parameters
from optimize.optimize import edge_swap, edge_collapse, laplacian_smooth
from utils.timer import TimeSpan
from utils.message import info, gui_log, gui_progress
from optimize.optimize import optimize_hybrid_grid
from utils.core_helpers import (
is_mixed_mesh,
use_triangle_pipeline_for_qmorph,
create_interior_generator,
log_parameters_debug_summary,
log_mesh_debug_summary,
)
from utils.core_io import (
create_visualization,
resolve_input_grid_and_front,
merge_generated_grids,
output_and_finalize,
)
from delaunay.bw_utils import generate_delaunay_triangular_grid
from utils.mesh_utils import deduplicate_grid_cells
def _has_boundary_layer(parameters):
"""Return True when any part enables prism-layer growth."""
for part_obj in parameters.part_params:
mesh_param = getattr(part_obj, "part_params", None)
if getattr(mesh_param, "PRISM_SWITCH", "off") != "off":
return True
return False
def _generate_boundary_layer_grid(parameters, front_heap, sizing_system, visual_obj, gui_instance):
"""Generate the boundary-layer grid when enabled."""
has_boundary_layer = _has_boundary_layer(parameters)
if not has_boundary_layer:
if parameters.mesh_type == 4:
info("Bowyer-Watson 模式:无边界层配置,跳过边界层生成")
gui_log(gui_instance, "无边界层配置")
return None, front_heap, False
gui_log(gui_instance, "开始生成边界层网格...")
gui_progress(gui_instance, 4)
adlayers = Adlayers2(
boundary_front=front_heap,
sizing_system=sizing_system,
param_obj=parameters,
visual_obj=visual_obj,
)
boundary_grid, updated_front_heap = adlayers.generate_elements()
log_mesh_debug_summary(boundary_grid, "边界层网格")
gui_log(gui_instance, "边界层网格生成完成")
return boundary_grid, updated_front_heap, True
def _generate_advancing_front_grid(
parameters,
front_heap,
sizing_system,
boundary_grid,
visual_obj,
gui_instance,
):
"""Generate the non-Delaunay interior grid path."""
if use_triangle_pipeline_for_qmorph(parameters):
info("q-morph模式:先生成纯三角形网格,再进行q-morph四边形合并")
adfront2 = create_interior_generator(
parameters=parameters,
front_heap=front_heap,
sizing_system=sizing_system,
boundary_grid=boundary_grid,
visual_obj=visual_obj,
)
triangular_grid = adfront2.generate_elements()
gui_log(gui_instance, "网格生成完成")
return triangular_grid
def generate_mesh(parameters, mesh_data=None, parts=None, gui_instance=None):
"""核心网格生成流程(统一入口)。
支持三类输入来源(优先级从高到低):
1) `parts`:直接使用外部构造好的front_list;
2) `mesh_data`:直接使用外部网格对象;
3) `parameters.input_file`:从算例文件读取。
网格类型与流程分支:
- 三角网格(mesh_type == 1 或 2):
边界层 -> 三角推进 -> edge swap -> laplacian -> 合并输出。
- Bowyer-Watson 三角网格(mesh_type == 4):
边界层 -> Bowyer-Watson Delaunay 三角剖分 -> edge swap -> laplacian -> 合并输出。
- 混合网格(mesh_type == 3, 非q_morph):
边界层 -> 混合推进(Adfront2Hybrid) -> edge swap -> 三角转四边形 -> 混合优化 -> 合并输出。
- 混合网格(mesh_type == 3, q_morph):
边界层 -> 纯三角推进(Adfront2) -> edge swap -> laplacian(预平滑) -> q_morph合并 -> 混合优化 -> 合并输出。
"""
# ------------------------------------------------------------------
# 0) 运行上下文初始化(GUI消息路由、计时器、可视化对象)
# ------------------------------------------------------------------
# 设置GUI实例到消息系统,确保所有info/error/warning消息都能输出到GUI
if gui_instance:
from utils.message import set_gui_instance
set_gui_instance(gui_instance)
# 开始计时
global_timer = TimeSpan("PyMeshGen开始运行...")
visual_obj = create_visualization(parameters, gui_instance)
# 输出信息到GUI
if gui_instance:
mesh_type_str = (
"三角形/四边形混合网格"
if is_mixed_mesh(parameters.mesh_type)
else "三角形网格"
)
gui_log(gui_instance, f"开始生成{mesh_type_str}...")
gui_progress(gui_instance, 0) # 初始化参数
# ------------------------------------------------------------------
# 1) 输入解析与初始阵面构造(由utils.core_io统一处理)
# ------------------------------------------------------------------
input_grid, front_heap = resolve_input_grid_and_front(
parameters=parameters,
mesh_data=mesh_data,
parts=parts,
gui_instance=gui_instance,
visual_obj=visual_obj,
)
log_parameters_debug_summary(parameters)
# ------------------------------------------------------------------
# 2) 构建尺寸场(QuadtreeSizing)
# ------------------------------------------------------------------
gui_log(gui_instance, "开始计算网格尺寸场...")
gui_progress(gui_instance, 3) # 开始计算网格尺寸场
sizing_system = QuadtreeSizing(
initial_front=front_heap,
max_size=4,
resolution=0.1,
decay=getattr(parameters, 'sizing_decay', 1.2),
visual_obj=visual_obj
)
# sizing_system.draw_bgmesh()
gui_log(gui_instance, "网格尺寸场计算完成")
# ------------------------------------------------------------------
# 3) 生成边界层网格(Adlayers2)
# - Bowyer-Watson 模式(mesh_type == 4)也支持边界层
# ------------------------------------------------------------------
unstr_grid_list = []
boundary_grid, front_heap, has_boundary_layer = _generate_boundary_layer_grid(
parameters=parameters,
front_heap=front_heap,
sizing_system=sizing_system,
visual_obj=visual_obj,
gui_instance=gui_instance,
)
if boundary_grid is not None:
unstr_grid_list.append(boundary_grid)
# ------------------------------------------------------------------
# 4) 生成内层网格
# - Bowyer-Watson:mesh_type == 4
# - 普通混合:Adfront2Hybrid
# - q_morph混合:Adfront2(先纯三角)
# - 三角网格:Adfront2
# ------------------------------------------------------------------
gui_log(gui_instance, "开始推进生成网格...")
gui_progress(gui_instance, 5) # 开始推进生成网格
# Bowyer-Watson Delaunay 网格生成分支
if parameters.mesh_type == 4:
triangular_grid, delaunay_backend = generate_delaunay_triangular_grid(
parameters=parameters,
sizing_system=sizing_system,
front_heap=front_heap,
has_boundary_layer=has_boundary_layer,
info_logger=info,
)
gui_log(gui_instance, "Bowyer-Watson 网格生成完成")
else:
triangular_grid = _generate_advancing_front_grid(
parameters=parameters,
front_heap=front_heap,
sizing_system=sizing_system,
boundary_grid=boundary_grid,
visual_obj=visual_obj,
gui_instance=gui_instance,
)
# ------------------------------------------------------------------
# 5) 网格质量优化与单元类型后处理
# - Bowyer-Watson:默认跳过后续优化(已经是 Delaunay 最优网格)
# - Triangle 后端(mesh_type == 4):允许轻量 laplacian 平滑
# - 公共:edge_swap
# - q_morph混合:先laplacian预平滑,再q_morph合并
# - 非q_morph混合:直接按配置方法合并(默认greedy)
# - 三角网格:laplacian
# ------------------------------------------------------------------
gui_log(gui_instance, "开始优化网格质量...")
gui_progress(gui_instance, 6) # 开始优化网格质量
if parameters.mesh_type != 4:
triangular_grid = edge_swap(triangular_grid)
removed_duplicates = deduplicate_grid_cells(triangular_grid)
if removed_duplicates > 0:
info(f"优化后去重: 删除了 {removed_duplicates} 个重复单元")
triangular_grid = edge_collapse(triangular_grid)
# triangular_grid.save_to_vtkfile("./out/debug.vtk")
if parameters.mesh_type == 4 and delaunay_backend == "triangle":
triangular_grid = laplacian_smooth(triangular_grid, 3)
info("Triangle 后端:已执行 3 轮 laplacian 平滑")
# Q-morph算法执行前先确保三角形网格质量
if use_triangle_pipeline_for_qmorph(parameters):
triangular_grid = laplacian_smooth(triangular_grid, 3)
if is_mixed_mesh(parameters.mesh_type): # 三角形/四边形混合网格
# 合并三角形生成混合网格
hybrid_grid = triangular_grid.merge_elements(
method=parameters.triangle_to_quad_method
)
# 优化混合网格
hybrid_grid = optimize_hybrid_grid(
hybrid_grid,
use_angle_based=True, # 设置为 True 启用角度优化
angle_iterations=3
)
unstr_grid_list.append(hybrid_grid)
else: # 三角形网格
if parameters.mesh_type != 4:
triangular_grid = laplacian_smooth(triangular_grid, 3)
removed_duplicates = deduplicate_grid_cells(triangular_grid)
if removed_duplicates > 0:
info(f"平滑后去重: 删除了 {removed_duplicates} 个重复单元")
unstr_grid_list.append(triangular_grid)
gui_log(gui_instance, "网格质量优化完成")
# ------------------------------------------------------------------
# 6) 合并边界层与内层网格
# ------------------------------------------------------------------
gui_log(gui_instance, "开始合并网格...")
gui_progress(gui_instance, 7) # 开始合并网格
global_unstr_grid = merge_generated_grids(unstr_grid_list, input_grid)
log_mesh_debug_summary(global_unstr_grid, "最终网格")
gui_log(gui_instance, "网格合并完成")
# ------------------------------------------------------------------
# 7) 输出与收尾(可视化、保存、GUI状态回填、计时结束)
# ------------------------------------------------------------------
return output_and_finalize(
global_unstr_grid=global_unstr_grid,
parameters=parameters,
gui_instance=gui_instance,
visual_obj=visual_obj,
global_timer=global_timer,
)