3. mesh
— Finite element meshes in pyFormex.¶
This module defines the Mesh class, which can be used to describe discrete geometrical models like those used in Finite Element models. It also contains some useful functions to create such models.
3.1. Classes defined in module mesh¶
-
class
mesh.
Mesh
(coords=None, elems=None, prop=None, eltype=None)[source]¶ A Mesh is a discrete geometrical model defined by nodes and elements.
The Mesh class is one of the two basic geometrical models in pyFormex, the other one being the
Formex
. Both classes have a lot in common: they represent a collection of geometrical entities of the same type (e.g., lines, or triangles, …). The geometrical entities are also called ‘elements’, and the number of elements in the Mesh isnelems()
. The plexitude (the number of points in an element) of a Mesh is found fromnplex()
. Each point hasndim=3
coordinates. While in aFormex
all these points are stored in an array with shape (nelems, nplex, 3), theMesh
stores the information in two arrays: the coordinates of all the points are gathered in a single twodimensional array with shape (ncoords,3). The individual geometrical elements are then described by indices into that array: we call that the connectivity, with shape (nelems, nplex).This model has some advantages over the
Formex
data model:a more compact storage, because coordinates of coinciding points require only be stored once (and we usually call the points node s);
the single storage of coinciding points represents the notion of connections between elements (a
Formex
to the contrary is always a loose collection of elements);connectivity related algorithms are generally faster;
the connectivity info also allows easy identification of geometric subentities (entities of a lower level, like the border lines of a surface).
The downside is that geometry generating and replicating algorithms are often far more complex and possibly slower.
In pyFormex we therefore mostly use the Formex data model when creating, copying and replicating geometry, but when we come to the point of needing connectivity related algorithms or exporting the geometry to file (and to other programs), a Mesh data model usually becomes more appropriate. A
Formex can be converted into a Mesh with the :meth:`Formex.toMesh
method, while theMesh.toFormex()
method performs the inverse conversion.- Parameters
coords (
Coords
or other object.) – Usually, a 2-dim Coords object holding the coordinates of all the nodes used in the Mesh geometry. See details below for different initialization methods.elems (
Connectivity
(nelems,nplex)) – A Connectivity object, defining the elements of the geometry by indices into thecoords
Coords array. All values in elems should be in the range 0 <= value < ncoords.prop (int array_like, optional) – 1-dim int array with non-negative element property numbers. If provided,
setProp()
will be called to assign the specified properties.eltype (str or
ElementType
, optional) – The element type of the geometric entities (elements). This is only needed if the element type has not yet been set in theelems
Connectivity. See below.
A Mesh object can be initialized in many different ways, depending on the values passed for the
coords
andelems
arguments.Coords, Connectivity: This is the most obvious case:
coords
is a 2-dimCoords
object holding the coordinates of all the nodes in the Mesh, andelems
is aConnectivity
object describing the geometric elements by indices into thecoords
.Coords, : If A Coords is passed as first argument, but no
elems
, the result is a Mesh of points, with plexitude 1. The Connectivity will be constructed automatically.object with
toMesh
, : As a convenience, if another object is provided that has atoMesh
method andelems
is not provided, the result of thetoMesh
method will be used to initialize bothcoords
andelems
.None: If neither
coords
norelems
are specified, buteltype
is, a unit sized single element Mesh of the specifiedElementType
is created.Specifying no parameters at all creates an empty Mesh, without any data.
Setting the element type can also be done in different ways. If
elems
is a Connectivity, it will normally already have a element type. If not, it can be done by passing it in theeltype
parameter. In case you pass a simple array or list in theelems
parameter, an element type is required. Finally, the user can specify an eltype to override the one in the Connectivity. It should however match the plexitude of the connectivity data.eltype
should be one of theElementType
instances or the name of such an instance. If required but not provided, the pyFormex default is used, which is based on the plexitude: 1 = point, 2 = line segment, 3 = triangle, 4 or more is a polygon.A properly initialized Mesh has the following attributes:
-
coords
¶ A 2-dim Coords object holding the coordinates of all the nodes used to describe the Mesh geometry.
- Type
Coords
(ncoords,3)
-
elems
¶ A Connectivity object, defining the elements of the geometry by indices into the
coords
Coords array. All values in elems should be in the range0 <= value < ncoords
.The Connectivity also stores the element type of the Mesh.
- Type
Connectivity
(nelems,nplex)
-
prop
¶ Element property numbers. See
geometry.Geometry.prop
.- Type
int array, optional
-
attrib
¶ An Attributes object. See
geometry.Geometry.attrib
.- Type
Note
The coords` attribute of a Mesh can hold points that are not used or needed to describe the Geometry. They do not influence the result of Mesh operations, but use more memory than needed. If their number becomes large, you may want to free that memory by calling the
compact()
method. Also, before exporting a Mesh (e.g. to a numerical simulation program), you may want to compact the Mesh first.Examples
Create a Mesh with four points and two triangle elements of type ‘tri3’.
>>> coords = Coords('0123') >>> elems = [[0,1,2], [0,2,3]] >>> M = Mesh(coords,elems,eltype='tri3') >>> print(M.report()) Mesh: nnodes: 4, nelems: 2, nplex: 3, level: 2, eltype: tri3 BBox: [0. 0. 0.], [1. 1. 0.] Size: [1. 1. 0.] Length: 4.0 Area: 1.0 Coords: [[0. 0. 0.] [1. 0. 0.] [1. 1. 0.] [0. 1. 0.]] Elems: [[0 1 2] [0 2 3]] >>> M.nelems(), M.ncoords(), M.nplex(), M.level(), M.elName() (2, 4, 3, 2, 'tri3')
And here is a line Mesh converted from a Formex:
>>> M1 = Formex('l:112').toMesh() >>> print(M1.report()) Mesh: nnodes: 4, nelems: 3, nplex: 2, level: 1, eltype: line2 BBox: [0. 0. 0.], [2. 1. 0.] Size: [2. 1. 0.] Length: 3.0 Coords: [[0. 0. 0.] [1. 0. 0.] [2. 0. 0.] [2. 1. 0.]] Elems: [[0 1] [1 2] [2 3]]
Indexing returns the full coordinate set of the specified element(s). See
__getitem__()
.>>> M1[1:] Coords([[[1., 0., 0.], [2., 0., 0.]], [[2., 0., 0.], [2., 1., 0.]]])
The Mesh class inherits from
Geometry
and therefore has all the coordinate transform methods defined there readily available:>>> M2 = M1.rotate(90) >>> print(M2.coords) [[ 0. 0. 0.] [ 0. 1. 0.] [ 0. 2. 0.] [-1. 2. 0.]]
-
__getitem__
(i)[source]¶ Return element i of the Mesh.
This allows addressing element i of Mesh M as M[i].
- Parameters
i (index) – The index of the element(s) to return. This can be a single element number, a slice, or an array with a list of numbers.
- Returns
Coords – A Coords with a shape (nplex, 3), or if multiple elements are requested, a shape (nelements, nplex, 3), holding the coordinates of all points of the requested elements.
Notes
This is normally used in an expression as
M[i]
, which will return the element i. ThenM[i][j]
will return the coordinates of node j of element i.
3.2. Functions defined in module mesh¶
-
mesh.
mergeNodes
(nodes, fuse=True, **kargs)[source]¶ Merge a list of Coords into a single one.
Merging the Coords creates a single Coords object containing all points, and the indices to find the points of the original Coords in the merged set.
- Parameters
nodes (list of Coords) – A list of Coords objects, all having the same shape, except possibly for their first dimension.
fuse (bool, optional) – If True (default), coincident (or very close) points are fused into a single point. If False, a simple concatenation will result.
**kargs – Keyword arguments that are passed to the fuse operation.
- Returns
coords (Coords) – A single Coords with the coordinates of all (unique) points.
index (list of int arrays) – A list of indices giving for each Coords in the input list the position of its nodes in the merged output Coords.
Examples
>>> M1 = Mesh(eltype='quad4') >>> M1.coords Coords([[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.]]) >>> M2 = Mesh(eltype='tri3').rot(90) >>> M2.coords Coords([[ 0., 0., 0.], [ 0., 1., 0.], [-1., 0., 0.]]) >>> coords, index = mergeNodes([M1.coords, M2.coords]) >>> print(coords) [[-1. 0. 0.] [ 0. 0. 0.] [ 0. 1. 0.] [ 1. 0. 0.] [ 1. 1. 0.]] >>> print(index) [array([1, 3, 4, 2]), array([1, 2, 0])]
-
mesh.
mergeMeshes
(meshes, fuse=True, **kargs)[source]¶ Merge a list of Meshes to a single list of nodes.
- Parameters
meshes (list of Mesh instances) – The Meshes to be merged.
fuse (bool) – If True (default), coinciding nodes will be fused to single nodes. If set False, all original nodes are retained, only renumbered.
**kargs (other parameters to pass to the
mergeNodes()
method.) –
- Returns
coords (Coords) – The single list of nodal coordinates obtained from merging the Meshes.
elems (list of Elems) – A list of Elems instances corresponding to those of the input Meshes, but with numbers referring to the new (single) coords array.
Notes
This method cleverly detects if the input Meshes use the same coords block, and will not concatenate and fuse these. The fuse parameter still might change the single coords. If you want to make sure that the coords remains unaltered, either fuse the Meshes in advance, or use the fuse=False argument. See Examples in
Mesh.concatenate()
.
-
mesh.
quadgrid
(seed0, seed1, roll=0)[source]¶ Create a quadrilateral mesh of unit size with the specified seeds.
- Parameters
seed0 (seed) – Seed for the elements along the parametric direction 0.
seed1 (seed) – Seed for the elements along the parametric direction 1.
roll (int, optional) – If provided, the set of axis direction are rolled this number of positions, allowing the quadgrid to be created in the (x,y), (y,z) or (z,x) plane.
- Returns
Mesh – A Mesh of Quad4 elements filling a unit square between the values 0 and 1 in the two parametric directions (default x,y). The node and element numbers vary first in the direction0, then in the direction 1.
-
mesh.
rectangle
(L=1.0, W=1.0, nl=1, nw=1)[source]¶ Create a plane rectangular mesh of quad4 elements.
- Parameters
- Returns
Mesh – A Mesh of eltype Quad4 representing a rectangular domain.
Notes
This is syntactical sugar for:
quadgrid(nl, nw).resized([L, W, 1.0])
-
mesh.
rectangleWithHole
(L, W, r, nr, nl, nw=None)[source]¶ Create a Mesh of quarter of a rectangle with a central circular hole.
- Parameters
L (float) – Length of the (quarter) rectangle.
W (float) – Width of the (quarter) rectangle.
r (float) – Radius of the hole.
nr (seed) – The element seed in radial direction.
nl (seed) – The element seed in tangential direction along L.
nw (seed, optional) – The element seed in tangential direction along W. If not provided, it is set equal to nl.
- Returns
Mesh – A Mesh of eltype Quad4 representing a quarter of a rectangular domain with a central hole.
-
mesh.
quadrilateral
(x, n1, n2)[source]¶ Create a quadrilateral mesh.
- Parameters
- Returns
Mesh – A Mesh of quads filling the quadrilateral defined by the four points x.
-
mesh.
continuousCurves
(c0, c1)[source]¶ Make two curves continuous.
Ensures that the end point of curve c0 and the start point of curve c1 are coincident.
- Parameters
c0 (
Curve
) – First Curve.c1 (
Curve
) – Second Curve.
Note
This is done by replacing these two points with their mean value. If the points are originally far apart, the curves may change shape considerably.
The curves are changed inplace! There is no return value.
-
mesh.
triangleQuadMesh
(P0, C0, n, P0wgt=0.0)[source]¶ Create a quad Mesh over a (quasi-)triangular domain.
The domain is described by a point and a curve. The point is connected with straight lines to the curve end points. The result is a quasi-triangular domain with possibly one non-straight edge. For example, a circular sector is defined by a circular arc and the center of the circle.
- Parameters
P0 (coords_like (3,)) – The coordinates of the point connecting two straight edges.
C0 (
Curve
) – A Curve defining the edge of the domain opposite to the point P0. Use aLine
([P1, P2]) to create a triangular domain (P0, P1,P2).n (tuple of 3 ints) – Specifies the number of elements along the subdomain edges. Near the point is a quad kernel with n0*n1 elements (n0 along the straight line to the startpoint of the curve, n1 along the straight line to the endpoint of the curve. The boundary zone near the curve has n0+n1 elements along the curve, and n2 elements perpendicular to the curve.
-
mesh.
quarterCircle
(n1, n2)[source]¶ Create a mesh of quadrilaterals filling a quarter circle.
- Parameters
- Returns
Mesh – A ‘quad4’ Mesh filling a quarter circle with radius 1 and center at the origin, in the first quadrant of the axes.
Notes
The quarter circle mesh has a kernel of n1*n1 cells, and two border meshes of n1*n2 cells. The resulting mesh has n1+n2 cells in radial direction and 2*n1 cells in tangential direction (in the border mesh).
-
mesh.
quad4_checkFolded
(self)[source]¶ Check which quads are folded. Returns two sets for different unfold.
-
mesh.
quad4_unFold
(self, ids, jds)[source]¶ Unfold quad elements: ids switch node 1,2; jds switch node 2,3
-
mesh.
wedge6_roll
(elems)[source]¶ Roll wedge6 elems to make the lowest node of bottom plane the first
This is a helper function for the
wedge6_tet4()
conversion.
-
mesh.
wedge6_tet4
(M)[source]¶ Convert a Mesh from wedge6 to tet4
Converts a ‘wedge6’ Mesh to ‘tet4’, by replacing each wedge element with three tets. The conversion ensures that the subdivisions of the wedge elements are compatible in the common quad faces of any two wedge elements.
Note
This is a helper function for the
convert()
method. It is better to use Mesh.convert(‘tet4’) instead of calling this function directly.- Parameters
M (Mesh) – A Mesh of eltype ‘wedge6’.
- Returns
Mesh – A Mesh of eltype ‘tet4’ representing the same domain as the input Mesh. The nodes are the same as those of the input Mesh. The number of elements is three times that of the input Mesh. The order of numbering of the elements is dependent on the conversion algorithm.