discretize.TreeMesh.refine_surface#
- TreeMesh.refine_surface(xyz, level=-1, padding_cells_by_level=None, pad_up=False, pad_down=True, finalize=True, diagonal_balance=None, extrapolate_surface=None)[source]#
Refine along a surface triangulated from xyz to the prescribed level.
This function refines the mesh based on a triangulated surface from the input points. Every cell that intersects the surface will be refined to the given level.
It also optionally pads the surface at each level based on the number of padding cells at each dimension. Vertically, the surface is shifted down (and/or up) by the padding amount. Horizontally, the padding is done in one of two ways, set by
extrapolate_surface. IfFalse(the current default), the bounding box of the surface is stretched in each dimension. IfTrue, points are added outward from every node along the boundary of the triangulation, along the outward bisector of the adjacent boundary edges (equivalent to a nearest neighbor extrapolation of the surface), seeextend_surface_boundary().- Parameters:
- xyz(
N,dim) array_like ortuple The points defining the surface. Will be triangulated along the horizontal dimensions. You are able to supply your own triangulation in 3D by passing a tuple of (xyz, triangle_indices).
- level
int,optional The level of the tree mesh to refine to. Negative values index tree levels backwards, (e.g. -1 is max_level).
- padding_cells_by_level
None,int, (n_level) array_likeor(n_level,dim) array_like,optional The number of cells to pad the bounding box at each level of refinement. If a single number, each level below
levelwill be padded with those number of cells. If array_like, n_level`s below ``level` will be padded, where if a 1D array, each dimension will be padded with the same number of cells, or 2D array supports variable padding along each dimension. None implies no padding.- pad_upbool,
optional Whether to pad above the surface.
- pad_downbool,
optional Whether to pad below the surface.
- finalizebool,
optional Whether to finalize the mesh after the call.
- diagonal_balance
Noneor bool,optional Whether to balance cells diagonally in the refinement, None implies using the same setting used to instantiate the TreeMesh`.
- extrapolate_surface
Noneor bool,optional Whether to pad horizontally by extrapolating the surface outward from the nodes on its boundary, instead of stretching its bounding box. None implies False, but issues a warning if horizontal padding is requested, as the default will change to True in discretize v1.0. This has no effect if there is no horizontal padding.
- xyz(
See also
Notes
When
extrapolate_surface=Trueand the surface has a non-convex boundary, the outward bisectors of different boundary nodes can intersect if the horizontal padding is large compared to the size of local features of the boundary (e.g. notches or concavities). In that case the padded region can fold over itself and the result may be unreliable. Keep the padding small relative to such features, or use a convex boundary.Examples
In 2D we define the surface as a line segment, which we would like to refine along.
>>> import discretize >>> import matplotlib.pyplot as plt >>> import matplotlib.patches as patches >>> mesh = discretize.TreeMesh([32, 32])
This surface is a simple sine curve, which we would like to pad with at least 2 cells vertically below at the maximum level, and 3 cells below that at the second highest level.
>>> x = np.linspace(0.2, 0.8, 51) >>> z = 0.25*np.sin(2*np.pi*x)+0.5 >>> xz = np.c_[x, z] >>> mesh.refine_surface(xz, -1, [[0, 2], [0, 3]])
>>> ax = mesh.plot_grid() >>> ax.plot(x, z, color='C1') >>> plt.show()
(
Source code,png,pdf)
In 3D we define a grid of surface locations with there corresponding elevations. In this example we pad 2 cells at the finest level below the surface, and 3 cells down at the next level.
>>> mesh = discretize.TreeMesh([32, 32, 32]) >>> x, y = np.mgrid[0.2:0.8:21j, 0.2:0.8:21j] >>> z = 0.125*np.sin(2*np.pi*x) + 0.5 + 0.125 * np.cos(2 * np.pi * y) >>> points = np.stack([x, y, z], axis=-1).reshape(-1, 3) >>> mesh.refine_surface(points, -1, [[0, 0, 2], [0, 0, 3]])
>>> v = mesh.cell_levels_by_index(np.arange(mesh.n_cells)) >>> fig, axs = plt.subplots(1, 3, figsize=(12,4)) >>> mesh.plot_slice(v, ax=axs[0], normal='x', grid=True, clim=[2, 5]) >>> mesh.plot_slice(v, ax=axs[1], normal='y', grid=True, clim=[2, 5]) >>> mesh.plot_slice(v, ax=axs[2], normal='z', grid=True, clim=[2, 5]) >>> plt.show()