Mesh Generation#

Grid generation#

class polymesh.grid.Grid(*args, celltype=None, frame=None, eshape=None, **kwargs)[source]#

A class to generate meshes based on grid-like data. All input arguments are forwarded to grid(). The difference is that a PolyData instance is returned, insted of raw mesh data.

Examples

>>> from polymesh.grid import Grid
>>> size = 80, 60, 20
>>> shape = 8, 6, 2
>>> grid = Grid(size=size, shape=shape, eshape='H8')

See also

grid()

polymesh.grid.grid(size: Tuple[float] | None = None, shape: int | Tuple[int] | None = None, eshape: str | Tuple[int] | None = None, shift: Iterable | None = None, start: int = 0, bins: Iterable | None = None, centralize: bool = False, path: Iterable | None = None, **kwargs) Tuple[ndarray, ndarray][source]#

Crates a 1d, 2d or 3d grid for different patterns and returnes the raw data. If you want a more high level mesh object, consider using the Grid class, which calls this method to generate a PolyData instance.

Parameters:
  • size (Tuple[float], Optional) – A 2-tuple, containg side lengths of a rectangular domain. Should be provided alongside shape. Default is None.

  • shape (Union[int, Tuple[int]], Optional) – An integer or a tuple of integers, describing number of cells along coordinate directions. Should be provided alongside size. Default is None.

  • eshape (str or Tuple, Optional) –

    This specifies element shape. Supported strings are thw following:

    • ’Q4’ : 4-noded quadrilateral

    • ’Q9’ : 9-noded quadrilateral

    • ’H8’ : 8-noded hexagon

    • ’H27’ : 27-noded hexagon

  • shift (numpy.ndarray, Optional) – 1d float array, specifying a translation.

  • start (int, Optional) – Starting value for node numbering. Default is 0.

  • bins (numpy.ndarray, Optional) – Numpy array or an iterable of numy arrays.

  • centralize (bool, Optional) – If True, the returned coordinates are centralized.

  • path (Iterable, Optional) – A 1d iterable used to rewire the nodes of the resulting grid. If provided, the j-th node of the i-th cell becomes topo[i, path[j]]. Default is None.

Notes

1) The returned topology may not be compliant with vtk. If you want to use the results of this call to build a vtk model, you have to account for this (for instance through the ‘path’ parameter). Optionally, you can use the dedicated grid generation routines of this module. 2) If you’d rather get the result as a PolyData, use the Grid class.

Returns:

  • numpy.ndarray – A numpy float array of coordinates.

  • numpy.ndarray – A numpy integer array describing the topology.

Examples

Create a simple hexagonal mesh of 8 x 6 x 2 cells

>>> from polymesh import grid
>>> size = 80, 60, 20
>>> shape = 8, 6, 2
>>> mesh = (coords, topo) = grid(size=size, shape=shape, eshape='H8')

Create a mesh of 4-noded quadrilaterals

>>> gridparams = {
>>>     'size' : (1200, 600),
>>>     'shape' : (30, 15),
>>>     'eshape' : (2, 2),
>>>     'start' : 0
>>> }
>>> coordsQ4, topoQ4 = grid(**gridparams)

The same mesh with 6-noded quadrialterals, 2 in x direction, 3 in y direction

>>> gridparams['eshape'] = (2, 3)
>>> coordsQ4, topoQ4 = grid(**gridparams)
polymesh.grid.gridH27(*args, **kwargs) Tuple[ndarray, ndarray][source]#

Customized version of grid dedicated to H27 elements. It returns a topology with vtk-compliant node numbering.

In terms of parameters, this function have to be called the same way grid would be called, except the parameter eshape being obsolete.

polymesh.grid.gridH8(*args, **kwargs) Tuple[ndarray, ndarray][source]#

Customized version of grid dedicated to H8 elements. It returns a topology with vtk-compliant node numbering.

In terms of parameters, this function have to be called the same way grid would be called, except the parameter eshape being obsolete.

polymesh.grid.gridQ4(*args, **kwargs) Tuple[ndarray, ndarray][source]#

Customized version of grid() dedicated to Q4 elements. It returns a topology with vtk-compliant node numbering.

In terms of parameters, this function have to be called the same way grid would be called, except the parameter eshape being obsolete.

Example

Creating a mesh of 4-noded quadrilaterals

>>> from polymesh.grid import gridQ4
>>> gridparams = {
>>>     'size' : (1200, 600),
>>>     'shape' : (30, 15),
>>>     'origo' : (0, 0),
>>>     'start' : 0
>>> }
>>> coordsQ4, topoQ4 = gridQ4(**gridparams)
polymesh.grid.gridQ9(*args, **kwargs) Tuple[ndarray, ndarray][source]#

Customized version of grid dedicated to Q9 elements. It returns a topology with vtk-compliant node numbering.

In terms of parameters, this function have to be called the same way grid would be called, except the parameter eshape being obsolete.

polymesh.grid.knngridL2(*args, max_distance: float | None = None, k: int = 3, X: ndarray | None = None, **kwargs) Tuple[ndarray, ndarray][source]#

Returns a KNN grid of L2 lines. First a grid of points is created using :func:grid, then points are connected based on a KNN-tree.

Parameters:
  • *args (tuple, Optional) – Positional arguments forwarded to :func:grid.

  • max_distance (float, Optional) – Maximum distance allowed. Default is None.

  • k (int, Optional) – Number of neighbours for a given point.

  • X (numpy.ndarray, Optional) – Coordinates of a pointcloud. If provided, args and kwargs are ignored. Default is None.

  • **kwargs (dict, Optional) – Keyword arguments forwarded to :func:grid.

See also

k_nearest_neighbours(), knn_to_lines()

Recipes#

polymesh.recipes.circular_disk(nangles: int, nradii: int, rmin: float, rmax: float, frame=None) TriMesh[source]#

Returns the triangulation of a circular disk.

Parameters:
  • nangles (int) – Number of subdivisions in radial direction.

  • nradii (int) – Number of subdivisions in circumferential direction.

  • rmin (float) – Inner radius. Can be zero.

  • rmax (float) – Outer radius.

Return type:

TriMesh

Examples

>>> from polymesh.recipes import circular_disk
>>> mesh = circular_disk(120, 60, 5, 25)
polymesh.recipes.circular_helix(a=None, b=None, *args, slope=None, pitch=None)[source]#

Returns the function \(f(t) = [a \cdot cos(t), a \cdot sin(t), b \cdot t]\), which describes a circular helix of radius a and slope a/b (or pitch 2πb).

polymesh.recipes.cylinder(shape, size: tuple | float | int | None = None, *args, regular: bool = True, voxelize: bool = False, celltype=None, frame: CartesianFrame | None = None, **kwargs) PolyData[source]#

Returns the coordinates and the topology of cylinder as numpy arrays.

Parameters:
  • shape (tuple or int, Optional) – A 2-tuple or a float, describing the shape of the cylinder.

  • size (Union[tuple, float, int], Optional) –

    Parameter controlling the density of the mesh. Default is None.

    If voxelize is False, size must be a tuple of three integers, describing the number of angular, radial, and vertical divions in this order.

    If voxelize is True and size is a float, the parameter controls the size of the individual voxels.

    If voxelize is True and size is an int, the parameter controls the size of the individual voxels according to \(edge \, length = (r_{ext} - r_{int})/shape\).

  • regular (bool, Optional) – If True and voxelize is False, the mesh us a result of an extrusion applied to a trianglarion, and as a consequence it returns a more or less regular mesh. Otherwise the cylinder is created from a surface trangulation using the tetgen package. Default is True.

  • voxelize (bool, Optional) – If True, the cylinder gets voxelized to a collection of H8 cells. In this case the size of a voxel can be controlled by specifying a flaot or an integer as the second parameter size. Default is False.

  • celltype – Specifies the celltype to be used.

Return type:

PolyData

polymesh.recipes.perforated_cube(lx: float, ly: float, lz: float, radius: float, *, nangles: int | None = None, lmax: float | None = None, order: int = 1, prismatic: bool = True) PolyData[source]#

Returns a cube of side lengths ‘lx’, ‘ly’ and ‘lz’, with a circular hole along the ‘z’ axis.

Return type:

PolyData

polymesh.recipes.ribbed_plate(lx: float, ly: float, t: float, *, wx: float | None = None, wy: float | None = None, hx: float | None = None, hy: float | None = None, ex: float | None = None, ey: float | None = None, lmax: float | None = None, order: int = 1, tetrahedralize: bool = False) PolyData[source]#

Creates a ribbed plate.

Parameters:
  • lx (float) – The length of the plate along the X axis.

  • ly (float) – The length of the plate along the Y axis.

  • t (float) – The thickness of a plate.

  • wx (float, Optional) – The width of the ribs running in X direction. Must be defined alongside hx. Default is None.

  • hx (float, Optional) – The height of the ribs running in X direction. Must be defined alongside wx. Default is None.

  • ex (float, Optional) – The eccentricity of the ribs running in X direction.

  • wy (float, Optional) – The width of the ribs running in Y direction. Must be defined alongside hy. Default is None.

  • hy (float, Optional) – The height of the ribs running in Y direction. Must be defined alongside wy. Default is None.

  • ey (float, Optional) – The eccentricity of the ribs running in Y direction.

  • lmax (float, Optional) – Maximum edge length of the cells in the resulting mesh. Default is None.

  • order (int, Optional) – Determines the order of the cells used. Allowed values are 1 and 2. If order is 1, either H8 hexahedra or TET4 tetrahedra are returned. If order is 2, H27 hexahedra or TET10 tetrahedra are returned.

  • tetrahedralize (bool, Optional) – If True, a mesh of 4-noded tetrahedra is returned. Default is False.

Example

>>> from polymesh.recipes import ribbed_plate
>>> mesh = ribbed_plate(lx=5.0, ly=5.0, t=1.0,
>>>                     wx=1.0, hx=2.0, ex=0.05,
>>>                     wy=1.0, hy=2.0, ey=-0.05)
Return type:

PolyData

Downloadable examples#

polymesh.examples.delete_downloads()[source]#

Delete all downloaded examples to free space or update the files.

Returns:

Returns True if the operation was succesful, False otherwise.

Return type:

bool

Examples

Delete all local downloads.

>>> from polymesh.examples import delete_downloads
>>> delete_downloads()  
True
polymesh.examples.download_bunny(tetra: bool = False, read: bool = False) str | PolyData[source]#

Downloads and optionally reads the bunny example as a vtk file.

Parameters:
  • tetra (bool, Optional) – If True, the returned mesh is a tetrahedral one, otherwise it is a surface triangulation. Default is False.

  • read (bool, Optional) – If False, the path of the mesh file is returned instead of a PolyData object. Default is False.

Example

>>> from polymesh.examples import download_bunny
>>> mesh = download_bunny(tetra=True, read=True)
polymesh.examples.download_bunny_coarse(tetra: bool = False, read: bool = False) str | PolyData[source]#

Downloads and optionally reads the bunny example as a vtk file.

Parameters:
  • tetra (bool, Optional) – If True, the returned mesh is a tetrahedral one, otherwise it is a surface triangulation. Default is False.

  • read (bool, Optional) – If False, the path of the mesh file is returned instead of a PolyData object. Default is False.

Example

>>> from polymesh.examples import download_bunny_coarse
>>> mesh = download_bunny_coarse(tetra=True, read=True)
polymesh.examples.download_gt40(read: bool = False) str | PolyData[source]#

Downloads and optionally reads the Gt40 example as a vtk file.

Parameters:

read (bool, Optional) – If False, the path of the mesh file is returned instead of a PolyData object. Default is False.

Example

>>> from polymesh.examples import download_gt40
>>> mesh = download_gt40(read=True)
polymesh.examples.download_stand(read: bool = False) str | PolyData[source]#

Downloads and optionally reads the stand example as a vtk file.

Parameters:

read (bool, Optional) – If False, the path of the mesh file is returned instead of a PolyData object. Default is False.

Example

>>> from polymesh.examples import download_stand
>>> mesh = download_stand(read=True)