# 曲线网格基础 本教程介绍如何使用 `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) ``` ![单元格 10 的绘图输出](images/04_curvilineargrid_basics_10_0.png) ## 使用推进前沿法生成曲线网格 定义生成曲线网格的过程,使用 `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) ``` ![单元格 15 的绘图输出](images/04_curvilineargrid_basics_15_0.png) ## 曲线网格加密与粗化 加密前的网格。 ```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) ``` ![单元格 18 的绘图输出](images/04_curvilineargrid_basics_18_0.png) 在两个选定点之间,为每一行添加两条水平网格线进行加密,并绘制结果。 ```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) ``` ![单元格 20 的绘图输出](images/04_curvilineargrid_basics_20_0.png) 删除相同行中的网格线,进行粗化。 ```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) ``` ![单元格 22 的绘图输出](images/04_curvilineargrid_basics_22_0.png) ## 创建矩形网格 ```python mk = create_mk_instance_with_a_rectangular_curvilinear_grid() curvilinear_grid = mk.curvilineargrid_get() fig, ax = plt.subplots() curvilinear_grid.plot_edges(ax) ``` ![单元格 24 的绘图输出](images/04_curvilineargrid_basics_24_0.png) 也可以根据多边形生成矩形网格。多边形必须闭合。 ```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) ``` ![单元格 28 的绘图输出](images/04_curvilineargrid_basics_28_0.png) ## 利用多边形边界上的节点生成曲线网格 定义多边形并生成曲线网格。 ```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) ``` ![单元格 32 的绘图输出](images/04_curvilineargrid_basics_32_0.png) ## 曲线网格正交化 移动一个节点,使网格不再正交,并绘制结果。 ```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) ``` ![单元格 35 的绘图输出](images/04_curvilineargrid_basics_35_0.png) 执行正交化。 ```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) ``` ![单元格 39 的绘图输出](images/04_curvilineargrid_basics_39_0.png) ## 固定一条网格线进行曲线网格正交化 ```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) ``` ![单元格 41 的绘图输出](images/04_curvilineargrid_basics_41_0.png) 执行正交化,同时固定被移动节点所在的垂直网格线。 ```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) ``` ![单元格 45 的绘图输出](images/04_curvilineargrid_basics_45_0.png) ## 曲线网格平滑 移动一个节点,使网格不再平滑,并绘制结果。 ```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) ``` ![单元格 48 的绘图输出](images/04_curvilineargrid_basics_48_0.png) 执行平滑。 ```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) ``` ![单元格 52 的绘图输出](images/04_curvilineargrid_basics_52_0.png) ## 曲线网格定向平滑 移动一个节点,使网格不再平滑,并绘制结果。 ```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) ``` ![单元格 55 的绘图输出](images/04_curvilineargrid_basics_55_0.png) 执行定向平滑。 ```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) ``` ![单元格 59 的绘图输出](images/04_curvilineargrid_basics_59_0.png) ## 曲线网格线平移 ```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) ``` ![单元格 61 的绘图输出](images/04_curvilineargrid_basics_61_0.png) 初始化网格线平移操作,并设置要移动的网格线。 ```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) ``` ![单元格 70 的绘图输出](images/04_curvilineargrid_basics_70_0.png) ## 在曲线网格中插入网格面 ```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) ``` ![单元格 72 的绘图输出](images/04_curvilineargrid_basics_72_0.png) 插入两个网格面。 ```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) ``` ![单元格 75 的绘图输出](images/04_curvilineargrid_basics_75_0.png) ## 删除曲线网格节点 ```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) ``` ![单元格 77 的绘图输出](images/04_curvilineargrid_basics_77_0.png) 删除角点节点。 ```python mk.curvilinear_delete_node(0.0, 0.0) ``` ```python curvilinear_grid = mk.curvilineargrid_get() fig, ax = plt.subplots() curvilinear_grid.plot_edges(ax) ``` ![单元格 80 的绘图输出](images/04_curvilineargrid_basics_80_0.png) ## 曲线网格线吸引与排斥 将网格块内的节点向指定网格线吸引。 ```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) ``` ![单元格 84 的绘图输出](images/04_curvilineargrid_basics_84_0.png) ```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) ``` ![单元格 86 的绘图输出](images/04_curvilineargrid_basics_86_0.png) ## 曲线网格线镜像扩展 以两倍列宽对左侧网格线进行镜像扩展。 ```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) ``` ![单元格 90 的绘图输出](images/04_curvilineargrid_basics_90_0.png)