586 lines
16 KiB
Markdown
586 lines
16 KiB
Markdown
# 曲线网格基础
|
|
|
|
本教程介绍如何使用 `meshkernel` 库生成曲线网格。
|
|
|
|
[返回示例目录](index.md)
|
|
|
|
以下保留原笔记本的代码和已保存输出;转换过程中未重新执行代码。
|
|
|
|
首先导入所需的库。
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
from meshkernel import (
|
|
CurvilinearParameters,
|
|
MakeGridParameters,
|
|
GeometryList,
|
|
MeshKernel,
|
|
SplinesToCurvilinearParameters,
|
|
OrthogonalizationParameters,
|
|
)
|
|
```
|
|
|
|
定义一个函数,使用 `curvilinear_compute_transfinite_from_splines` 生成曲线网格,并创建包含该网格的 `MeshKernel` 实例:
|
|
|
|
- 首先创建用于生成曲线网格的样条曲线,各条样条曲线用 `-999.0` 分隔。
|
|
- 在新的 `CurvilinearParameters` 实例中设置 m、n 方向的划分数。
|
|
- 创建一个新的 `MeshKernel` 实例。
|
|
- 使用超限插值算法生成曲线网格。
|
|
|
|
```python
|
|
def create_mk_instance_with_curvilinear_grid_from_transfinite_method():
|
|
r"""创建包含曲线网格的 MeshKernel 实例。"""
|
|
mk = MeshKernel()
|
|
|
|
separator = -999.0
|
|
splines_x = np.array(
|
|
[
|
|
2.0,
|
|
4.0,
|
|
7.0,
|
|
separator,
|
|
-1.0,
|
|
1.0,
|
|
5.0,
|
|
separator,
|
|
3.0,
|
|
-2.0,
|
|
separator,
|
|
7.0,
|
|
4.0,
|
|
],
|
|
dtype=np.double,
|
|
)
|
|
splines_y = np.array(
|
|
[
|
|
1.0,
|
|
3.0,
|
|
4.0,
|
|
separator,
|
|
4.0,
|
|
6.0,
|
|
7.0,
|
|
separator,
|
|
1.0,
|
|
6.0,
|
|
separator,
|
|
3.0,
|
|
8.0,
|
|
],
|
|
dtype=np.double,
|
|
)
|
|
splines = GeometryList(splines_x, splines_y)
|
|
|
|
curvilinear_parameters = CurvilinearParameters()
|
|
curvilinear_parameters.n_refinement = 10
|
|
curvilinear_parameters.m_refinement = 10
|
|
|
|
mk.curvilinear_compute_transfinite_from_splines(splines, curvilinear_parameters)
|
|
|
|
return mk
|
|
```
|
|
|
|
定义一个用于创建矩形曲线网格的函数。
|
|
|
|
```python
|
|
def create_mk_instance_with_a_rectangular_curvilinear_grid(num_columns=3, num_rows=3):
|
|
r"""创建包含矩形曲线网格的 MeshKernel 实例的局部函数。"""
|
|
mk = MeshKernel()
|
|
|
|
# 创建 MakeGridParameters 实例并设置参数值
|
|
make_grid_parameters = MakeGridParameters()
|
|
make_grid_parameters.num_columns = num_columns
|
|
make_grid_parameters.num_rows = num_rows
|
|
make_grid_parameters.angle = 0.0
|
|
make_grid_parameters.origin_x = 0.0
|
|
make_grid_parameters.origin_y = 0.0
|
|
make_grid_parameters.block_size_x = 10.0
|
|
make_grid_parameters.block_size_y = 10.0
|
|
|
|
mk.curvilinear_compute_rectangular_grid(make_grid_parameters)
|
|
|
|
return mk
|
|
```
|
|
|
|
## 使用超限插值法生成曲线网格
|
|
|
|
```python
|
|
curvilinear_grid_transfinite = (
|
|
create_mk_instance_with_curvilinear_grid_from_transfinite_method().curvilineargrid_get()
|
|
)
|
|
```
|
|
|
|
绘制结果。
|
|
|
|
```python
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid_transfinite.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 使用推进前沿法生成曲线网格
|
|
|
|
定义生成曲线网格的过程,使用 `curvilinear_compute_orthogonal_from_splines` 方法创建包含网格的 `MeshKernel` 实例:
|
|
|
|
- 首先创建用于生成曲线网格的样条曲线,各条样条曲线用 `-999.0` 分隔。
|
|
- 在新的 `CurvilinearParameters` 实例中设置 m、n 方向的划分数。
|
|
- 该算法还需要设置从样条曲线生成曲线网格所需的附加参数。
|
|
- 然后使用推进前沿算法生成曲线网格。
|
|
|
|
```python
|
|
mk = MeshKernel()
|
|
|
|
separator = -999.0
|
|
splines_x = np.array([-1.0, 2.0, 6.0, separator, 3.0, -2.0, separator], dtype=np.double)
|
|
splines_y = np.array([2.0, 5.0, 6.0, separator, 1.0, 6.0, separator], dtype=np.double)
|
|
|
|
splines_values = np.zeros_like(splines_x)
|
|
splines = GeometryList(splines_x, splines_y, splines_values)
|
|
|
|
curvilinearParameters = CurvilinearParameters()
|
|
curvilinearParameters.n_refinement = 10
|
|
curvilinearParameters.m_refinement = 10
|
|
|
|
splinesToCurvilinearParameters = SplinesToCurvilinearParameters()
|
|
splinesToCurvilinearParameters.aspect_ratio = 1.0
|
|
splinesToCurvilinearParameters.aspect_ratio_grow_factor = 1.0
|
|
splinesToCurvilinearParameters.average_width = 0.2
|
|
splinesToCurvilinearParameters.nodes_on_top_of_each_other_tolerance = 1e-4
|
|
splinesToCurvilinearParameters.min_cosine_crossing_angles = 0.95
|
|
splinesToCurvilinearParameters.check_front_collisions = 0
|
|
splinesToCurvilinearParameters.curvature_adapted_grid_spacing = 1
|
|
splinesToCurvilinearParameters.remove_skinny_triangles = 1
|
|
|
|
mk.curvilinear_compute_orthogonal_from_splines(
|
|
splines, curvilinearParameters, splinesToCurvilinearParameters
|
|
)
|
|
|
|
curvilinear_grid_orthogonal = mk.curvilineargrid_get()
|
|
```
|
|
|
|
绘制结果。
|
|
|
|
```python
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid_orthogonal.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格加密与粗化
|
|
|
|
加密前的网格。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_curvilinear_grid_from_transfinite_method()
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
在两个选定点之间,为每一行添加两条水平网格线进行加密,并绘制结果。
|
|
|
|
```python
|
|
mk.curvilinear_refine(2.299, 4.612, 3.074, 3.684, 2)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
删除相同行中的网格线,进行粗化。
|
|
|
|
```python
|
|
mk.curvilinear_refine(2.299, 4.612, 3.074, 3.684, -2)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 创建矩形网格
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid()
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
也可以根据多边形生成矩形网格。多边形必须闭合。
|
|
|
|
```python
|
|
node_x = np.array([2.5, 5.5, 3.5, 0.5, 2.5], dtype=np.double)
|
|
node_y = np.array([0.5, 3.0, 5.0, 2.5, 0.5], dtype=np.double)
|
|
geometry_list = GeometryList(node_x, node_y)
|
|
```
|
|
|
|
```python
|
|
make_grid_parameters = MakeGridParameters()
|
|
make_grid_parameters.num_columns = 10
|
|
make_grid_parameters.num_rows = 10
|
|
make_grid_parameters.angle = 0.0
|
|
make_grid_parameters.origin_x = 0.0
|
|
make_grid_parameters.origin_y = 0.0
|
|
make_grid_parameters.block_size_x = 0.2
|
|
make_grid_parameters.block_size_y = 0.2
|
|
```
|
|
|
|
```python
|
|
mk.curvilinear_compute_rectangular_grid_from_polygon(
|
|
make_grid_parameters, geometry_list
|
|
)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 利用多边形边界上的节点生成曲线网格
|
|
|
|
定义多边形并生成曲线网格。
|
|
|
|
```python
|
|
node_x = np.array([2, 4, 6, 7, 8, 8, 8, 8, 7, 5, 3, 2, 2, 2, 2], dtype=np.double)
|
|
node_y = np.array([1, 1, 1, 1, 1, 1.2, 4, 6, 6, 6, 6, 6, 5, 3, 1], dtype=np.double)
|
|
geometry_list = GeometryList(node_x, node_y)
|
|
mk = MeshKernel()
|
|
mk.curvilinear_compute_transfinite_from_polygon(geometry_list, 0, 4, 7, False)
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格正交化
|
|
|
|
移动一个节点,使网格不再正交,并绘制结果。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid()
|
|
mk.curvilinear_move_node(10.0, 20.0, 18.0, 12.0)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
执行正交化。
|
|
|
|
```python
|
|
# 在正交化前检查节点位置
|
|
orthogonalization_parameters = OrthogonalizationParameters()
|
|
orthogonalization_parameters.outer_iterations = 1
|
|
orthogonalization_parameters.boundary_iterations = 25
|
|
orthogonalization_parameters.inner_iterations = 25
|
|
orthogonalization_parameters.orthogonalization_to_smoothing_factor = 0.95
|
|
|
|
# 初始化曲线网格正交化算法
|
|
# 设置要正交化的网格块(本例指定网格的左下角和右上角)
|
|
mk.curvilinear_orthogonalize(orthogonalization_parameters, 0.0, 0.0, 30.0, 30.0)
|
|
```
|
|
|
|
绘制正交化后的结果。
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 固定一条网格线进行曲线网格正交化
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid()
|
|
mk.curvilinear_move_node(10.0, 20.0, 18.0, 12.0)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
执行正交化,同时固定被移动节点所在的垂直网格线。
|
|
|
|
```python
|
|
# 在正交化前检查节点位置
|
|
orthogonalization_parameters = OrthogonalizationParameters()
|
|
orthogonalization_parameters.outer_iterations = 1
|
|
orthogonalization_parameters.boundary_iterations = 25
|
|
orthogonalization_parameters.inner_iterations = 25
|
|
orthogonalization_parameters.orthogonalization_to_smoothing_factor = 0.95
|
|
|
|
# 固定被移动节点所在的垂直网格线
|
|
mk.curvilinear_frozen_line_add(10.0, 0.0, 10.0, 30.0)
|
|
|
|
# 执行正交化
|
|
# 初始化曲线网格正交化算法
|
|
# 设置要正交化的网格块(本例指定网格的左下角和右上角)
|
|
mk.curvilinear_orthogonalize(orthogonalization_parameters, 0.0, 0.0, 30.0, 30.0)
|
|
```
|
|
|
|
绘制正交化后的结果。
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格平滑
|
|
|
|
移动一个节点,使网格不再平滑,并绘制结果。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid()
|
|
mk.curvilinear_move_node(10.0, 20.0, 18.0, 12.0)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
执行平滑。
|
|
|
|
```python
|
|
mk.curvilinear_smoothing(10, 0.0, 0.0, 30.0, 30.0)
|
|
```
|
|
|
|
绘制平滑后的结果。
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格定向平滑
|
|
|
|
移动一个节点,使网格不再平滑,并绘制结果。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid()
|
|
mk.curvilinear_move_node(10.0, 20.0, 18.0, 12.0)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
执行定向平滑。
|
|
|
|
```python
|
|
mk.curvilinear_smoothing_directional(
|
|
10, # 平滑迭代次数
|
|
10.0,
|
|
0.0,
|
|
10.0,
|
|
30.0, # 用于定义平滑方向的网格线坐标
|
|
0.0,
|
|
0.0,
|
|
30.0,
|
|
30.0,
|
|
) # 要平滑的网格块角点
|
|
```
|
|
|
|
绘制定向平滑后的结果。
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格线平移
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
初始化网格线平移操作,并设置要移动的网格线。
|
|
|
|
```python
|
|
mk.curvilinear_initialize_line_shift()
|
|
mk.curvilinear_set_line_line_shift(0.0, 0.0, 0.0, 50.0)
|
|
```
|
|
|
|
设置用于分配网格线位移的网格块。
|
|
|
|
```python
|
|
mk.curvilinear_set_block_line_shift(0.0, 0.0, 20.0, 50.0)
|
|
```
|
|
|
|
将曲线网格左侧的所有节点向左移动。
|
|
|
|
```python
|
|
mk.curvilinear_move_node_line_shift(0.0, 0.0, -50.0, 0.0)
|
|
mk.curvilinear_move_node_line_shift(0.0, 10.0, -50.0, 10.0)
|
|
mk.curvilinear_move_node_line_shift(0.0, 20.0, -50.0, 20.0)
|
|
mk.curvilinear_move_node_line_shift(0.0, 30.0, -50.0, 30.0)
|
|
mk.curvilinear_move_node_line_shift(0.0, 40.0, -50.0, 40.0)
|
|
mk.curvilinear_move_node_line_shift(0.0, 50.0, -50.0, 50.0)
|
|
```
|
|
|
|
执行网格线平移。前面指定网格块以外的节点不会移动。
|
|
|
|
```python
|
|
mk.curvilinear_line_shift()
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 在曲线网格中插入网格面
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
插入两个网格面。
|
|
|
|
```python
|
|
mk.curvilinear_insert_face(-10.0, 5.0)
|
|
mk.curvilinear_insert_face(-5.0, 10.0)
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 删除曲线网格节点
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
删除角点节点。
|
|
|
|
```python
|
|
mk.curvilinear_delete_node(0.0, 0.0)
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格线吸引与排斥
|
|
|
|
将网格块内的节点向指定网格线吸引。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
mk.curvilinear_line_attraction_repulsion(
|
|
1.0, # 正值表示排斥网格线,此处为列宽的 1 倍
|
|
30.0,
|
|
0.0,
|
|
30.0,
|
|
50.0, # 网格线坐标
|
|
10.0,
|
|
0.0,
|
|
50.0,
|
|
50.0,
|
|
) # 受影响的网格块
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
mk.curvilinear_line_attraction_repulsion(
|
|
-1.0, # 负值表示吸引网格线,此处为列宽的 0.5 倍
|
|
30.0,
|
|
0.0,
|
|
30.0,
|
|
50.0, # 网格线坐标
|
|
10.0,
|
|
0.0,
|
|
50.0,
|
|
50.0,
|
|
) # 受影响的网格块
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|
|
|
|
## 曲线网格线镜像扩展
|
|
|
|
以两倍列宽对左侧网格线进行镜像扩展。
|
|
|
|
```python
|
|
mk = create_mk_instance_with_a_rectangular_curvilinear_grid(5, 5)
|
|
# 镜像系数、要镜像的网格线数量以及目标网格线
|
|
mk.curvilinear_line_mirror(2.0, 1, 0.0, 0.0, 0.0, 50.0)
|
|
```
|
|
|
|
```python
|
|
curvilinear_grid = mk.curvilineargrid_get()
|
|
fig, ax = plt.subplots()
|
|
curvilinear_grid.plot_edges(ax)
|
|
```
|
|
|
|

|