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 is nelems(). The plexitude (the number of points in an element) of a Mesh is found from nplex(). Each point has ndim=3 coordinates. While in a Formex all these points are stored in an array with shape (nelems, nplex, 3), the Mesh 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 the Mesh.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 the coords 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 the elems Connectivity. See below.

A Mesh object can be initialized in many different ways, depending on the values passed for the coords and elems arguments.

  • Coords, Connectivity: This is the most obvious case: coords is a 2-dim Coords object holding the coordinates of all the nodes in the Mesh, and elems is a Connectivity object describing the geometric elements by indices into the coords.

  • 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 a toMesh method and elems is not provided, the result of the toMesh method will be used to initialize both coords and elems.

  • None: If neither coords nor elems are specified, but eltype is, a unit sized single element Mesh of the specified ElementType 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 the eltype parameter. In case you pass a simple array or list in the elems 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 the ElementType 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 range 0 <= 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:

Attributes

fields

The Fields defined on the Mesh. See geometry.Geometry.fields.

Type:

dict

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(full=True))
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(full=True))
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.]]
property eltype

Return the element type of the Mesh.

Returns:

elements.ElementType – The eltype attribute of the elems attribute.

Examples

>>> M = Mesh(eltype='tri3')
>>> M.eltype
Tri3
>>> M.eltype = 'line3'
>>> M.eltype
Line3
>>> print(M)
Mesh: nnodes: 3, nelems: 1, nplex: 3, level: 1, eltype: line3
BBox: [0.  0.  0.], [1.  1.  0.]
Size: [1.  1.  0.]
Length: 1.0

One cannot set an element type with nonmatching plexitude:

>>> M.eltype = 'quad4'
Traceback (most recent call last):
...
p...InvalidElementType: Data plexitude (3) != eltype plexitude (4)
setEltype(eltype=None)[source]

Set the eltype of the Mesh.

elType()[source]

Return the element type of the Mesh.

elName()[source]

Return the element name of the Mesh.

Returns:

str – The name of the ElementType of the Mesh.

See also

elType

returns the ElementType instance

Examples

>>> Formex('4:0123').toMesh().elName()
'quad4'
setNormals(normals=None)[source]

Set/Remove the normals of the mesh.

Parameters:

normals (float array_like) – A float array of shape (ncoords,3) or (nelems,nplex,3). If provided, this will set these normals for use in rendering, overriding the automatically computed ones. If None, this will clear any previously set user normals.

__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. Then M[i][j] will return the coordinates of node j of element i.

level()[source]

Return the level of the elements in the Mesh.

Returns:

int – The dimensionality of the elements: 0 (point), 1(line), 2 (surface), 3 (volume).

nelems()[source]

Return the number of elements in the Mesh.

Returns:

int – The first dimension of the elems array.

nplex()[source]

Return the plexitude of the elements in the Mesh.

Returns:

int – The second dimension of the elems array.

ncoords()[source]

Return the number of nodes in the Mesh.

Returns:

int – The first dimension of the coords array.

nnodes()

Return the number of nodes in the Mesh.

Returns:

int – The first dimension of the coords array.

npoints()

Return the number of nodes in the Mesh.

Returns:

int – The first dimension of the coords array.

shape()[source]

Returns the shape of the elems array.

info()[source]

Return short info about the Mesh.

Returns:

str – A string with info about the shape of the coords and elems attributes.

report(full=False, **kargs)[source]

Create a report on the Mesh shape and size.

Parameters:
  • full (bool) – If False (default), the report only contains the number of points, the number of elements, the plexitude, the dimensionality, and the element type (None in most cases). If True, it also contains the coordinates array.

  • **kargs – Numpy print options to be used in the formatting of the coords array.

Returns:

str

shallowCopy(prop=None)[source]

Return a shallow copy.

Parameters:

prop (int array_like, optional) – 1-dim int array with non-negative element property numbers.

Returns:

  • A shallow copy of the Mesh, using the same data arrays

  • for coords and elems. If prop was provided,

  • the new Mesh can have other property numbers.

  • This is a convenient method to use the same Mesh

  • with different property attributes.

toFormex()[source]

Convert a Mesh to a Formex.

Returns:

Formex – A Formex equivalent with the calling Mesh. The Formex inherits the element property numbers and eltype from the Mesh. Drawing attributes and Fields are not transfered though.

Examples

>>> M = Mesh([[0,0,0],[1,0,0]],[[0,1],[1,0]],eltype='line2')
>>> M.toFormex()
Formex([[[0.,  0.,  0.],
         [1.,  0.,  0.]],

        [[1.,  0.,  0.],
         [0.,  0.,  0.]]])
toMesh()[source]

Convert to a Mesh.

Returns:

Mesh – The Mesh itself. This is provided as a convenience for use in functions that need to work on different Geometry types.

toSurface()[source]

Convert a Mesh to a TriSurface.

Only Meshes of level 2 (surface) and 3 (volume) can be converted to a TriSurface. For a level 3 Mesh, the border Mesh is taken first. A level 2 Mesh is converted to element type ‘tri3’ and then to a TriSurface.

Returns:

TriSurface – A TriSurface corresponding with the input Mesh. If that has eltype ‘tri3’, the resulting TriSurface is fully equivalent. Otherwise, a triangular approximation is returned.

Raises:

ValueError – If the Mesh can not be converted to a TriSurface.

toLines()[source]

Convert a Mesh to a line2 mesh.

All Meshes of level 1 or higher can be converted to a line2 Mesh. For level 2 and 3 Meshes, first the edgeMesh() is taken. The level 1 Mesh is then converted to ‘line2’ elements.

Returns:

Mesh – A Mesh of eltype ‘line2’ containing all the linearized edges of the input Mesh.

Raises:

ValueError – If the input Mesh has level < 1..

toCurve(connect=False)[source]

Convert a Mesh to a Curve.

If the element type is one of ‘line*’ types, the Mesh is converted to a Curve. The type of the returned Curve is dependent on the element type of the Mesh:

  • ‘line2’: PolyLine,

  • ‘line3’: BezierSpline (degree 2),

  • ‘line4’: BezierSpline (degree 3)

If connect is False, this is equivalent to

self.toFormex().toCurve()

Any other type will raise an exception.

centroids()[source]

Return the centroids of all elements of the Mesh.

The centroid of an element is the point with coordinates equal to the average of those of all nodes of the element.

Returns:

Coords – A Coords object with shape (nelems(), 3), holding the centroids of all the elements in the Mesh.

Examples

>>> rectangle(L=3,W=2,nl=3,nw=2).centroids()
Coords([[0.5,  0.5,  0. ],
        [1.5,  0.5,  0. ],
        [2.5,  0.5,  0. ],
        [0.5,  1.5,  0. ],
        [1.5,  1.5,  0. ],
        [2.5,  1.5,  0. ]])
bboxes()[source]

Returns the bboxes of all elements in the Mesh.

Returns:

float array (nelems,2,3). – An array with the minimal and maximal values of the coordinates of the nodes of each element, stored along the 1-axis.

getLowerEntities(level=-1)[source]

Get the entities of a lower dimensionality.

Parameters:

level (int) – The level of the entities to return. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level. Thus, for a Mesh with a 3D element type, getLowerEntities(-1) returns the faces, while for a 2D element type, it returns the edges. For both meshes however, getLowerEntities(+1) returns the edges.

Returns:

Connectivity – A Connectivity defining the lower entities of the specified level in terms of the nodes of the Mesh.

The return value may be an empty table, if the element type does not have the requested entities (e.g. ‘quad4’ Mesh does not have entities of level 3).

If the targeted entity level is outside the range 0..3, the return value is None.

Notes

This returns all entities for all elements and entities shared by multiple elements will appear multiple times. If you only want the unique lower entities, apply removeDuplicate() on the result, or use:

sel = self.eltype.getEntities(level)
lower = self.elems.insertLevel(sel)[1]

See also

level

return the dimensionality of the Mesh

connectivity.Connectivity.insertLevel()

returns two tables: elems vs. lower entities, lower enitites vs. nodes.

Examples

Mesh with one ‘quad4’ element and 4 nodes.

>>> M = Mesh(eltype='quad4')

The element defined in function of the nodes.

>>> print(M.elems)
[[0 1 2 3]]

The edges of the element defined in function of the nodes.

>>> print(M.getLowerEntities(-1))
[[0 1]
 [1 2]
 [2 3]
 [3 0]]

And finally, the nodes themselves: not very useful, but works.

>>> print(M.getLowerEntities(-2))
[[0]
 [1]
 [2]
 [3]]
getNodes()[source]

Return the set of unique node numbers in the Mesh.

Returns:

int array – The sorted node numbers that are actually used in the connectivity table. For a compacted Mesh, it is equal to np.arange(self.nelems).

getPoints()[source]

Return the nodal coordinates of the Mesh.

Returns:

Coords – The coordinates of the nodes that are actually used in the connectivity table. For a compacted Mesh, it is equal to the coords attribute.

property edges

Return the unique edges of all the elements in the Mesh.

Returns:

Elems – A connectivity table defining the unique element edges in function of the nodes.

Notes

This is like self.elems.insertLevel(1)[1] but the result is memoized in the Mesh object to avoid recomputation on a next call.

Examples

>>> Mesh(eltype='quad4').subdivide(2,1).edges
Elems([[0, 1],
       [3, 0],
       [1, 2],
       [1, 4],
       [2, 5],
       [4, 3],
       [5, 4]], eltype=Line2)
property elem_edges

Defines the elements in function of its edges.

Returns:

Connectivity – A connectivity table with the elements defined in function of the edges.

Notes

As a side effect, this also stores the definition of the edges and the returned element to edge connectivity in the attributes edges, resp. elem_edges.

See also

edges

Return the definition of the edges

Examples

>>> Mesh(eltype='quad4').subdivide(2,1).elem_edges
Connectivity([[0, 3, 5, 1],
              [2, 4, 6, 3]])
property faces

Return the unique faces of all the elements in the Mesh.

Returns:

Elems – A connectivity table defining all the element faces in function of the nodes.

Notes

This is like self.elems.insertLevel(2)[1] but the result is memoized in the Mesh object to avoid recomputation on a next call.

Examples

>>> Mesh(eltype='hex8').subdivide(2,1,1).faces
Elems([[ 0,  3,  4,  1],
       [ 0,  1,  7,  6],
       [ 0,  6,  9,  3],
       [ 1,  4,  5,  2],
       [ 1,  2,  8,  7],
       [ 1,  4, 10,  7],
       [ 2,  5, 11,  8],
       [ 3,  9, 10,  4],
       [ 4, 10, 11,  5],
       [ 6,  7, 10,  9],
       [ 7,  8, 11, 10]], eltype=Quad4)
property elem_faces

Defines the elements in function of its faces.

Returns:

Elems – A connectivity table with the elements defined in function of the faces.

Notes

As a side effect, this also stores the definition of the faces and the returned element to face connectivity in the attributes faces, resp. elem_faces.

See also

faces

Return the definition of the faces

Examples

>>> Mesh(eltype='hex8').subdivide(2,1,1).elem_faces
Connectivity([[ 2,  5,  1,  7,  0,  9],
              [ 5,  6,  4,  8,  3, 10]])
property cells

Return the 3D cells in the Mesh.

For a level 3 Mesh, this is equivalent to self.elems. For other Meshes, an empty connectivity is returned.

edgeMesh()[source]

Return a Mesh with the unique edges of the elements.

This can only be used with a Mesh of level >= 1.

faceMesh()[source]

Return a Mesh with the unique faces of the elements.

This can only be used with a Mesh of level >= 2.

getFreeEntities(level=-1, return_indices=False)[source]

Return the free entities of the specified level.

Parameters:
  • level (int) – The level of the entities to return. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level.

  • return_indices (bool) – If True, also returns an index array (nentities,2) for inverse lookup of the higher entity (column 0) and its local lower entity number (column 1).

Returns:

Elems – A connectivity table with the free entities of the specified level of the Mesh. Free entities are entities that are only connected to a single element.

See also

getFreeEntitiesMesh

return the free entities as a Mesh

getBorder

return the free entities of the first lower level

Examples

>>> M = Formex('3:.12.34').toMesh()
>>> print(M.report(full=True))
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.]
           [0.  1.  0.]
           [1.  1.  0.]]
  Elems: [[0 1 3]
          [3 2 0]]
>>> M.getFreeEntities(1)
Elems([[0, 1],
       [2, 0],
       [1, 3],
       [3, 2]], eltype=Line2)
>>> M.getFreeEntities(1,True)[1]
array([[0, 0],
       [1, 1],
       [0, 1],
       [1, 0]])
getFreeEntitiesMesh(level=-1, compact=True)[source]

Return a Mesh with lower entities.

Parameters:
  • level (int) – The level of the entities to return. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level.

  • compact (bool) – If True (default), the returned Mesh will be compacted. If False, the returned Mesh will contain all the nodes present in the input Mesh.

Returns:

Mesh – A Mesh containing the lower entities of the specified level. If the Mesh has property numbers, the lower entities inherit the property of the element to which they belong.

See also

getFreeEdgesMesh

return a Mesh with the free entities of the level 1

getBorderMesh

return the free entities Mesh of the first lower level

getFreeEdgesMesh(compact=True)[source]

Return a Mesh with the free edges.

Parameters:

compact (bool) – If True (default), the returned Mesh will be compacted. If False, the returned Mesh will contain all the nodes present in the input Mesh.

Returns:

Mesh – A Mesh containing the free edges of the input Mesh. If the input Mesh has property numbers, the edge elements inherit the property of the element to which they belong.

See also

getFreeEntitiesMesh

return the free entities Mesh of any lower level

getBorderMesh

return the free entities Mesh of level -1

border(return_indices=False)[source]

Return the border of the Mesh.

Border entities are the free entities of the first lower level.

Parameters:

return_indices (bool) – If True, also returns an index array (nentities,2) for inverse lookup of the higher entity (column 0) and its local lower entity number (column 1).

Returns:

Elems – A connectivity table with the border entities of the specified level of the Mesh. Free entities are entities that are only connected to a single element.

See also

getFreeEntities

return the free entities of any lower level

getBorderMesh

return the border as a Mesh

Notes

This is a convenient shorthand for

self.getFreeEntities(level=-1,return_indices=return_indices)
borderMesh(compact=True)[source]

Return a Mesh representing the border.

Parameters:

compact (bool) – If True (default), the returned Mesh will be compacted. If False, the returned Mesh will contain all the nodes present in the input Mesh.

Returns:

Mesh – A Mesh containing the border of the input Mesh. The level of the Mesh is one less than that of the input Mesh. If the input Mesh has property numbers, the border elements inherit the property of the element to which they belong.

Notes

This is a convenient shorthand for

self.getFreeEntitiesMesh(level=-1,compact=compact)
borderElems()[source]

Find the elements that are touching the border of the Mesh.

Returns:

int array – A list of the numbers of the elements that fully contain at least one of the elements of the border Mesh. Thus, in a volume Mesh, elements only touching the border by a vertex or an edge are not considered border elements.

borderNodes()[source]

Find the nodes that are on the border of the Mesh.

Returns:

int array – A list of the numbers of the nodes that are on the border of the Mesh.

innerNodes()[source]

Find the nodes that are not on the border of the Mesh.

Returns:

int array – A list of the numbers of the nodes that are not on the border of the Mesh.

getBorder(return_indices=False)

Return the border of the Mesh.

Border entities are the free entities of the first lower level.

Parameters:

return_indices (bool) – If True, also returns an index array (nentities,2) for inverse lookup of the higher entity (column 0) and its local lower entity number (column 1).

Returns:

Elems – A connectivity table with the border entities of the specified level of the Mesh. Free entities are entities that are only connected to a single element.

See also

getFreeEntities

return the free entities of any lower level

getBorderMesh

return the border as a Mesh

Notes

This is a convenient shorthand for

self.getFreeEntities(level=-1,return_indices=return_indices)
getBorderMesh(compact=True)

Return a Mesh representing the border.

Parameters:

compact (bool) – If True (default), the returned Mesh will be compacted. If False, the returned Mesh will contain all the nodes present in the input Mesh.

Returns:

Mesh – A Mesh containing the border of the input Mesh. The level of the Mesh is one less than that of the input Mesh. If the input Mesh has property numbers, the border elements inherit the property of the element to which they belong.

Notes

This is a convenient shorthand for

self.getFreeEntitiesMesh(level=-1,compact=compact)
getBorderElems()

Find the elements that are touching the border of the Mesh.

Returns:

int array – A list of the numbers of the elements that fully contain at least one of the elements of the border Mesh. Thus, in a volume Mesh, elements only touching the border by a vertex or an edge are not considered border elements.

getBorderNodes()

Find the nodes that are on the border of the Mesh.

Returns:

int array – A list of the numbers of the nodes that are on the border of the Mesh.

getInnerNodes()

Find the nodes that are not on the border of the Mesh.

Returns:

int array – A list of the numbers of the nodes that are not on the border of the Mesh.

peel(nodal=False)[source]

Remove the border elements from a Mesh.

Parameters:

nodal (bool) – If True, all elements connected to a border node are removed. The default will only remove the elements returned by getBorderElems().

Returns:

Mesh – A Mesh with the border elements removed.

connectedTo(entities, level=0)[source]

Find the elements connected to specific lower entities.

Parameters:
  • entities (int or int array_like) – The indices of the lower entities to which connection should exist.

  • level (int) – The level of the entities to which connection should exist. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level. Default is 0 (nodes).

Returns:

int array – A list of the numbers of the elements that contain at least one of the specified lower entities.

adjacentTo(elements, level=0)[source]

Find the elements adjacent to the specified elements.

Adjacent elements are elements that share some lower entity.

Parameters:
  • elements (int or int array_like) – Element numbers to find the adjacent elements for.

  • level (int) – The level of the entities used to define adjacency. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level. Default is 0 (nodes).

Returns:

int array – A list of the numbers of all the elements in the Mesh that are adjacent to any of the specified elements.

reachableFrom(elements, level=0)[source]

Select the elements reachable from the specified elements.

Elements are reachable if one can travel from one of the origin elements to the target, by only following the specified level of connections.

Parameters:
  • elements (int or int array_like) – Element number(s) from where to start the walk.

  • level (int) – The level of the entities used to define connections. If negative, it is a value relative to the level of the caller. If non-negative, it specifies the absolute level. Default is 0 (nodes).

Returns:

int array – A list of the numbers of all the elements in the Mesh reachable from any of the specified elements by walking over entities of the specified level. The list will include the original set of elements.

adjacency(level=0, diflevel=-1, kind='e')[source]

Create an element adjacency table.

This creates an element adjacenty table (kind=’e’) or a node adjacency table (kind=’n’). Two elements are said to be adjacent if they share a lower entity of the specified level. Two nodes are said to be adjacent if they share a higher entity of the specified level.

Parameters:
  • level (int) – Hierarchic level of the geometric items connecting two elements: 0 = node, 1 = edge, 2 = face. Only values of a lower hierarchy than the level of the Mesh itself make sense. Default is to consider nodes as the connection between elements.

  • diflevel (int, optional) – Only used with kind=’e’. If >= level, and smaller than the level of the Mesh itself, elements that have a connection of this level are removed. Thus, in a Mesh with volume elements, self.adjacency(0,1) gives the adjacency of elements by a node but not by an edge.

  • kind ('e' or 'n') – Select element (‘e’) or node (n’) adjacency table. Default is element adjacency.

Returns:

adj (Adjacency) – An Adjacency table specifying for each element or node its neighbours connected by the specified geometrical subitems.

frontWalk(level=0, startat=0, frontinc=1, partinc=1, maxval=-1)[source]

Visit all elements using a frontal walk.

In a frontal walk a forward step is executed simultanuously from all the elements in the current front. The elements thus reached become the new front. An element can be reached from the current element if both are connected by a lower entity of the specified level. Default level is ‘point’.

Parameters:
  • level (int) – Hierarchy of the geometric items connecting two elements: 0 = node, 1 = edge, 2 = face. Only values of a lower hierarchy than the elements of the Mesh itself make sense. There are no connections on the upper level.

  • startat (int or list of ints) – Initial element number(s) in the front.

  • frontinc (int) – Increment for the front number on each frontal step.

  • partinc (int) – Increment for the front number when the front gets empty and a new part is started.

  • maxval (int) – Maximum frontal value. If negative (default) the walk will continue until all elements have been reached. If non-negative, walking will stop as soon as the frontal value reaches this maximum.

Returns:

int array – An array of ints specifying for each element in which step the element was reached by the walker. Unwalked elements have a value -1.

Examples

>>> M = Mesh(eltype='quad4').subdivide(5,2)
>>> print(M.frontWalk())
[0 1 2 3 4 1 1 2 3 4]
>>> print(M.frontWalk(maxval=2))
[ 0  1  2 -1 -1  1  1  2 -1 -1]
maskedEdgeFrontWalk(mask=None, startat=0, frontinc=1, partinc=1, maxval=-1)[source]

Perform a front walk over masked edge connections.

This is like frontWalk(level=1), but has an extra parameter mask to select the edges that are used as connectors between elements. The remainder of the parameters are like in frontWalk().

Parameters:

mask (array_like, bool or int) – A boolean array or index flagging the nodes which are to be considered as connectors between elements. If None, all nodes are connections.

See also

frontWalk()

partitionByConnection(level=0, startat=0, sort='number', nparts=-1)[source]

Detect the connected parts of a Mesh.

The Mesh is partitioned in parts in which all elements are connected. Two elements are connected if it is possible to draw a continuous line from a point in one element to a point in the other element without leaving the Mesh.

Parameters:
  • sort (str, optional) – One of ‘number’ (default), ‘length’, ‘area’, ‘volume’. Defines the weights to be used in sorting the parts. Specifying another string will leave the parts unsorted.

  • level (int, optional) – Hierarchy of the geometric items connecting two elements: 0 = node, 1 = edge, 2 = face. Only values of a lower hierarchy than the elements of the Mesh itself make sense. There are no connections on the upper level.

  • startat (int or list of ints, optional) – Initial element number(s) in the front. Beware: if you specify unconnected elements, their parts will be returned as a single part.

  • nparts (int, optional) – Maximum number of parts to detect. If negative, the procedure continues until all elements have been attributed to some part.

Returns:

int array – An int array specifying for each element the part number to which it belongs. By default the parts are sorted in decreasing order of the number of elements.

splitByConnection(level=0, startat=0, sort='number', nparts=-1)[source]

Split a Mesh into connected parts.

This is like partitionByConnection() but returns a list of partial Meshes. The parameters are like in partitionByConnection()

Returns:

list of Mesh – A list of Meshes that each form a connected part. By default the parts are sorted in decreasing order of the number of elements.

largestByConnection(level=0)[source]

Return the largest connected part of the Mesh.

Notes

This is equivalent with, but more efficient than

self.splitByConnection(level)[0]
growSelection(sel, mode='node', nsteps=1)[source]

Grow a selection of a Mesh by frontal steps.

Parameters:
  • sel (int or list of ints) – Initial element number(s) in the selection.

  • mode (str) –

    Specifies how a single frontal step is done:

    • ’node’ : add all elements that have a node in common,

    • ’edge’ : add all elements that have an edge in common.

  • nsteps (int) – Number of frontal steps to undertake.

Returns:

int array – The list of element numbers obtained by growing the front nsteps times.

partitionByCurve(edges, sort='number')[source]

Partition a level-2 Mesh by closed curve(s) along the edges.

Parameters:
  • edges (bool or int array_like | level-1 Mesh) –

    If a bool type array, it flags for every edge with a True value whether the edge is part of the partitioning curve(s). The ordering of the edges is that as obtained from edges.

    If an int type array, it is a list of edge nummers that constitute the curve(s). Numbers refer to the edges order of edges. The order in which the edge numbers are given is irrelevant though.

    If a level-1 Mesh, it is a Mesh containing the edges that constitute the partitioning curve(s). In this case the edge numbers will be determined by matching the edges centroids on the level-2 Mesh.

  • sort (str) –

    Defines how the resulting parts are sorted (by assigning them increasing part numbers). The following sort criteria are currently defined (any other value will return the parts unsorted):

    • ’number’: sort in decreasing order of the number of triangles in the part. This is the default.

    • ’area’: sort according to decreasing surface area of the part.

Returns:

int array – An int array specifying for each triangle to which part it belongs. Values are in the range 0..nparts.

Notes

In order for the operation to be non-trivial, the specified edges, possibly together with (parts of) the border, should form one or more closed loops.

partitionByAngle(**kargs)[source]

Partition a level-2 Mesh by the angle between adjacent elements.

The Mesh is partitioned in parts bounded by the sharp edges in the surface. The arguments and return value are the same as in trisurface.TriSurface.partitionByAngle().

For eltypes other than ‘tri3’, a conversion to ‘tri3’ is done before computing the partitions.

nodeConnections()[source]

Find and store the elems connected to nodes.

Examples

>>> M = Mesh(eltype='quad4').subdivide(2,2)
>>> M.nodeConnections()
Varray([[0], [0, 1], [1], [0, 2], [0, 1, 2, 3], [1, 3], [2], [2, 3], [3]])
nNodeConnected()[source]

Find the number of elems connected to nodes.

Examples

>>> M = Mesh(eltype='quad4').subdivide(2,2)
>>> M.nNodeConnected()
array([1, 2, 1, 2, 4, 2, 1, 2, 1])
edgeConnections()[source]

Find and store the elems connected to edges.

Examples

>>> Mesh(eltype='quad4').subdivide(2,1).edgeConnections()
array([[-1,  0],
       [-1,  0],
       [-1,  1],
       [ 0,  1],
       [-1,  1],
       [-1,  0],
       [-1,  1]])
nEdgeConnected()[source]

Find the number of elems connected to edges.

Examples

>>> Mesh(eltype='quad4').subdivide(2,1).nEdgeConnected()
array([1, 1, 1, 2, 1, 1, 1])
nodeAdjacency()[source]

Find the elems adjacent to each elem via one or more nodes.

nNodeAdjacent()[source]

Find the number of elems which are adjacent by node to each elem.

edgeAdjacency()[source]

Find the elems adjacent to elems via an edge.

Examples

>>> Mesh(eltype='quad4').subdivide(2,1).edgeAdjacency()
Adjacency([[1],
           [0]])
nEdgeAdjacent()[source]

Find the number of adjacent elems.

nonManifoldNodes()[source]

Return the non-manifold nodes of a Mesh.

Non-manifold nodes are nodes where subparts of a mesh of level >= 2 are connected by a node but not by an edge.

Returns an integer array with a sorted list of non-manifold node numbers. Possibly empty (always if the dimensionality of the Mesh is lower than 2).

nonManifoldEdges()[source]

Return the non-manifold edges of a Mesh.

Non-manifold edges are edges where subparts of a mesh of level 3 are connected by an edge but not by a face.

Returns an integer array with a sorted list of non-manifold edge numbers. Possibly empty (always if the dimensionality of the Mesh is lower than 3).

As a side effect, this constructs the list of edges in the object. The definition of the nonManifold edges in terms of the nodes can thus be got from

self.edges[self.nonManifoldEdges()]
nonManifoldEdgeNodes()[source]

Return the non-manifold edge nodes of a Mesh.

Non-manifold edges are edges where subparts of a mesh of level 3 are connected by an edge but not by an face.

Returns an integer array with a sorted list of numbers of nodes on the non-manifold edges. Possibly empty (always if the dimensionality of the Mesh is lower than 3).

fuse(parts=None, nodes=None, **kargs)[source]

Fuse the nodes of a Meshes.

Nodes that are within the tolerance limits of each other are merged into a single node.

Parameters:
  • parts (int array_like, optional) – If provided, it is an int array with length equal to the number of elements that will be used to split the Mesh into parts (see splitProp()) and the fuse operation will be executed per part. Elements for which the value of nparts is negative will not be involved in the fuse operations.

  • nodes (int array_like, optional) – A list of node numbers. If provided, only these nodes will be involved in the fuse operation. This option can not be used together with the parts option.

  • **kargs – Extra arguments for tuning the fuse operation are passed to the coords.Coords:fuse() method.

matchCoords(coords, **kargs)[source]

Match nodes of coords with nodes of self.

coords can be a Coords or a Mesh object This is a convenience function equivalent to

self.coords.match(mesh.coords,**kargs)

or

self.coords.match(coords,**kargs)

See also coords.Coords.match()

matchCentroids(mesh, **kargs)[source]

Match elems of Mesh with elems of self.

self and Mesh are same eltype meshes and are both without duplicates.

Elems are matched by their centroids.

compact(return_index=False)[source]

Remove unconnected nodes and renumber the mesh.

Returns a mesh where all nodes that are not used in any element have been removed, and the nodes are renumbered to a compacter scheme.

If return_index is True, also returns an index specifying the index of the new nodes in the old node scheme.

Examples

>>> x = Coords([[i] for i in np.arange(5)])
>>> M = Mesh(x,[[0,2],[1,4],[4,2]])
>>> M,ind = M.compact(True)
>>> print(M.coords)
[[0. 0. 0.]
 [1. 0. 0.]
 [2. 0. 0.]
 [4. 0. 0.]]
>>> print(M.elems)
[[0 2]
 [1 3]
 [3 2]]
>>> M = Mesh(x,[[0,2],[1,3],[3,2]])
>>> M = M.compact()
>>> print(M.coords)
[[0. 0. 0.]
 [1. 0. 0.]
 [2. 0. 0.]
 [3. 0. 0.]]
>>> print(M.elems)
[[0 2]
 [1 3]
 [3 2]]
>>> print(ind)
[0 1 2 4]
>>> M = M.cselect([0,1,2])
>>> M.coords.shape, M.elems.shape
((4, 3), (0, 2))
>>> M = M.compact()
>>> M.coords.shape, M.elems.shape
((0, 3), (0, 2))
selectNodes(nodsel, eltype=None)[source]

Return a Mesh with subsets of the original nodes.

Parameters:
  • nodsel (1-dim or 2-dim int array_like) – An object that can be converted to a 1-dim or 2-dim array. Each row of nodsel holds a list of local node numbers that should be retained in the new connectivity table. See also connectivity.Connectivity.selectNodes().

  • eltype (ElementType or str, optional) – The element type or name for the new Mesh. It should be specified if the default for the plexitude would not be correct.

Returns:

Mesh – A Mesh with the same node set as the input but other element connectivity and eltype

Examples

From a Mesh of triangles, create a Mesh with the edges.

>>> M = Formex('3:.12.34').toMesh()
>>> M.elems
Elems([[0, 1, 3],
       [3, 2, 0]], eltype=Tri3)
>>> M1 = M.selectNodes([(0,1), (1,2), (2,0)])
>>> M1.elems
Elems([[0, 1],
       [1, 3],
       [3, 0],
       [3, 2],
       [2, 0],
       [0, 3]], eltype=Line2)
hits(entities, level=0)[source]

Count the lower entities from a list connected to the elements.

entities: a single number or a list/array of entities

splitRandom(n, compact=True)[source]

Split a Mesh in n parts, distributing the elements randomly.

Returns a list of n Mesh objects, constituting together the same Mesh as the original. The elements are randomly distributed over the subMeshes.

By default, the Meshes are compacted. Compaction may be switched off for efficiency reasons.

reverse(sel=None, inplace=False)[source]

Reverse some or all elements of a Mesh.

Reversing an element has the following meaning:

  • for 1D elements: reverse the traversal direction,

  • for 2D elements: reverse the direction of the positive normal,

  • for 3D elements: reverse inside and outside directions of the element’s border surface. This also changes the sign of the element’s volume.

Parameters:

sel (int or boolean array_like, optional) – The selected elements to be reversed. Default is to reverse all elements.

Returns:

Mesh – A Mesh like the input but with the specified elements reversed.

Notes

The reflect() method by default calls this method to undo the element reversal caused by the reflection operation.

reflect(dir=0, pos=0.0, reverse=True, **kargs)[source]

Reflect the coordinates in one of the coordinate directions.

This applies the reflect() transformation on the coords of the Mesh, and then by default does a reversal of the elements.

Parameters:
  • dir (int (0,1,2)) – Global axis direction of the reflection (default 0 or x-axis).

  • pos (float) – Offset of the mirror plane from origin (default 0.0)

  • reverse (bool,optional) – If True (default), the reverse() method is called after the reflection to undo the element reversal caused by the reflection of its coordinates. This has in most cases the desired effect. If not, the user can set this to False to skip the element reversal.

pointsAt(rst)[source]

Compute points at parametric values.

Parameters:

rst (array_like) – A float array with shape (ndim, npts) specifying the parameter values for the point to be computed.

Returns:

coords (Coords) – A Coords array of shape (nelems, npts, 3) with npts points at parametric values rst for each element.

addNodes(newcoords, eltype=None)[source]

Add new nodes to elements.

Parameters:
  • newcoords (coords_like) – A Coords array with shape (nelems,nnod,3) or`(nelems*nnod,3)`. Each element gets exactly nnod extra nodes from this array.

  • eltype (str, optional) – An optional element type for the returned Mesh. If not provided, or if the plexitude of the specified element does not match the constructed plexitude, a temporary ‘plex..’ element type is set. The user then has to set the correct element type afterwards.

Returns:

Mesh – A Mesh where the coords are the concatenation of self.coords and newcoords, and the connectivity table defining the new elements has a plexitude self.nplex() + nnod.

Notes

This is mainly intended for use in convert().

addNewNodes(rst, eltype)[source]

Add new nodes to elements at given parametric values.

Parameters:
  • rst (array_like) – A float array with shape (ndim, npts) specifying the parameter values for the new nodes.

  • eltype (eltype_like) – The element type for the enlarged element. It should have plexitude self.nplex+npts.

Returns:

Mesh – A Mesh of plexitude nplex+npts and the specified eltype.

See also

addMeanNodes

add nodes at average positions of existing nodes.

convert

convert a Mesh to another eltype

Notes

The use of the Mesh.convert method is the prefered way to convert the element type.

addMeanNodes(nodsel, eltype)[source]

Add new nodes to elements by averaging existing ones.

Parameters:
  • nodsel (array_like) – A local node selector as in selectNodes().

  • eltype (str, optional) – An optional element type for the returned Connecitivity.

Returns:

Mesh – A Mesh of plexitude nplex+npts and the specified eltype.

See also

addNewNodes

add nodes at parametric positions

Notes

The use of the Mesh.convert method is the prefered way to convert the element type.

convert(totype, fuse=None, verbose=False)[source]

Convert a Mesh to another element type.

Converting a Mesh from one element type to another can only be done if both element types are of the same dimensionality. Thus, 3D elements can only be converted to 3D elements.

Parameters:
  • totype (str or ElementType) – The name or type of the target element to which to convert. A generic type ‘linear’ may be specified to convert to the linear element type of the same family.

  • fuse (bool, optional) – If True, the resulting Mesh will be run through fuse() before returning. If False, no fuse will be done. The default (None) is a smart mode: a fuse will be applied if new nodes were added during the conversion.

  • verbose (bool, optional) – If True, intermediate steps during the conversion will be reported.

Returns:

Mesh – A Mesh of the requested element type, representing the same geometry (possibly approximatively) as the original Mesh.

Raises:

ValueError – If the Mesh can not be transformed to the specified eltype.

Notes

The conversion uses two basic methods for converting the element type: split the elements in smaller parts and add new nodes to the elements. Adding new nodes may produce duplicate nodes at the common border of elements. Not using a final fuse operation will then likely produce unwanted results.

In many cases a conversion is done over one (or more) intermediary element types. The fuse operation is only done once, after all transformation steps have occurred.

If the user wants/needs to apply multiple conversions in sequence, he may opt to switch off the fusing for all but the last conversion.

Not all conversions between elements of the same dimensionality are possible. The possible conversion strategies are implemented in a table in elements. New strategies may be added however.

Examples

>>> M = Mesh(eltype='quad4').convert('tri3')
>>> M.coords
Coords([[0.,  0.,  0.],
        [1.,  0.,  0.],
        [1.,  1.,  0.],
        [0.,  1.,  0.]])
>>> M.elems
Elems([[0, 1, 2],
       [2, 3, 0]], eltype=Tri3)
convertRandom(choices)[source]

Convert choosing randomly between choices

Returns a Mesh obtained by converting the current Mesh by a randomly selected method from the available conversion type for the current element type.

subdivide(*ndiv, fuse=None)[source]

Subdivide the elements of a Mesh.

Parameters:
  • *ndiv (sequence) –

    A sequence of divisor specifications for the parametric directions of the element. There can not be more divisor specifications than the number of parametric directions (self.eltype.ndim). If there are less specifications, the last one is repeated up to the elements ndim. Each divisor specification should be either

    • an int, specifying the number of equidistant partitions of the parameter space along that direction, or

    • an ordered list of float values specifying the partitioning points in the parametric range (normally 0..1). In order to completely fill the element, the first and last values in the list should be the start and end of the parameter range.

  • fuse (bool, optional) – If True (default), the resulting Mesh is completely fused. If False, the Mesh is only fused over each individual element of the original Mesh.

Returns:

Mesh – A Mesh where each element is replaced by a number of smaller elements of the same type.

Notes

Some element types can not be subdivided: the non-dimensional Point and the complex structures Octa and Icosa.

Examples

>>> M = Mesh(eltype='quad4').subdivide(3,2)
>>> print(M)
Mesh: nnodes: 12, nelems: 6, nplex: 4, level: 2, eltype: quad4
  BBox: [0.  0.  0.], [1.  1.  0.]
  Size: [1.  1.  0.]
  Length: 4.0  Area: 1.0
>>> M = Mesh(eltype='quad4').subdivide(3,2)
>>> print(M.coords)
[[0.     0.     0.    ]
 [0.3333 0.     0.    ]
 [0.6667 0.     0.    ]
 [1.     0.     0.    ]
 [0.     0.5    0.    ]
 [0.3333 0.5    0.    ]
 [0.6667 0.5    0.    ]
 [1.     0.5    0.    ]
 [0.     1.     0.    ]
 [0.3333 1.     0.    ]
 [0.6667 1.     0.    ]
 [1.     1.     0.    ]]
>>> print(M.elems)
[[ 0  1  5  4]
 [ 1  2  6  5]
 [ 2  3  7  6]
 [ 4  5  9  8]
 [ 5  6 10  9]
 [ 6  7 11 10]]
>>> M = Mesh(eltype='hex8').subdivide(2,1,1)
>>> print(M)
Mesh: nnodes: 12, nelems: 2, nplex: 8, level: 3, eltype: hex8
  BBox: [0. 0. 0.], [1. 1. 1.]
  Size: [1. 1. 1.]
  Area: 6.0  Volume: 1.0
>>> print(M.coords)
[[0.  0.  0. ]
 [0.5 0.  0. ]
 [1.  0.  0. ]
 [0.  1.  0. ]
 [0.5 1.  0. ]
 [1.  1.  0. ]
 [0.  0.  1. ]
 [0.5 0.  1. ]
 [1.  0.  1. ]
 [0.  1.  1. ]
 [0.5 1.  1. ]
 [1.  1.  1. ]]
>>> print(M.elems)
[[ 0  1  4  3  6  7 10  9]
 [ 1  2  5  4  7  8 11 10]]
splitDegenerate(reduce=True, return_indices=False)[source]

Split a Mesh in non-degenerate and degenerate elements.

Splits a Mesh in non-degenerate elements and degenerate elements, and tries to reduce degenerate elements to lower plexitude elements.

Parameters:
  • reduce (bool or ElementType name) – If True, the degenerate elements will be tested against known degeneration patterns, and the matching elements will be transformed to non-degenerate elements of a lower plexitude. If a string, it is an element name and only transforms to this element type will be considered. If False, no reduction of the degenerate elements will be attempted.

  • return_indices (bool, optional) – If True, also returns the element indices in the original Mesh for all of the elements in the derived Meshes.

Returns:

ML (list of Mesh objects) – The list of Meshes resulting from the split operation. The first holds the non-degenerate elements of the original Mesh. The last holds the remaining degenerate elements. The intermediate Meshes, if any, hold elements of a lower plexitude than the original.

Warning

The Meshes that hold reduced elements may still contain degenerate elements for the new element type

Examples

>>> M = Mesh(np.zeros((4,3)),
...     [[0,0,0,0],
...      [0,0,0,1],
...      [0,0,1,2],
...      [0,1,2,3],
...      [1,2,3,3],
...      [2,3,3,3],
...     ],eltype='quad4')
>>> M.elems.listDegenerate()
array([0, 1, 2, 4, 5])
>>> for Mi in M.splitDegenerate(): print(Mi)
Mesh: nnodes: 4, nelems: 1, nplex: 4, level: 2, eltype: quad4
  BBox: [0.  0.  0.], [0.  0.  0.]
  Size: [0.  0.  0.]
  Length: 0.0  Area: 0.0
Mesh: nnodes: 4, nelems: 5, nplex: 3, level: 2, eltype: tri3
  BBox: [0.  0.  0.], [0.  0.  0.]
  Size: [0.  0.  0.]
  Length: 0.0  Area: 0.0
>>> conn,ind = M.splitDegenerate(return_indices=True)
>>> print(ind[0],ind[1])
[3] [0 1 2 5 4]
>>> print(conn[1].elems)
[[0 0 0]
 [0 0 1]
 [0 1 2]
 [2 3 3]
 [1 2 3]]
removeDegenerate()[source]

Remove the degenerate elements from a Mesh.

Returns:

Mesh – A Mesh with all degenerate elements removed.

removeDuplicate(permutations='all')[source]

Remove the duplicate elements from a Mesh.

Duplicate elements are elements that consist of the same nodes.

Parameters:
  • permutations (str) – Defines which permutations of the nodes are allowed while still considering the elements duplicates. Possible values are:

  • 'none' (-) – must have the same value at every position in order to be considered duplicates;

  • 'roll' (-) – each other by rolling are considered equal;

  • 'all' (-) – a duplicate element. This is the default.

Returns:

Mesh – A Mesh with all duplicate elements removed.

renumber(order='elems')[source]

Renumber the nodes of a Mesh in the specified order.

Parameters:

order (int array_like or str) –

If an array, it is an index with length equal to the number of nodes. It should be a permutation of np.arange(self.nnodes()). The index specifies the node number that should come at this position. Thus, the order values are the old node numbers on the new node number positions.

order can also be a predefined string that will generate the node index automatically:

  • ’elems’: the nodes are number in order of their appearance in the Mesh connectivity.

  • ’random’: the nodes are numbered randomly.

  • ’front’: the nodes are numbered in order of their frontwalk.

Returns:

Mesh – A Mesh equivalent with the input, but with the nodes numbered differently.

reorder(order='nodes')[source]

Reorder the elements of a Mesh.

Parameters:

order (array_like or str) –

If an array, it is a permutation of the numbers in np.arange(self.nelems()), specifying the requested order of the elements.

order can also be one of the following predefined strings:

  • ’nodes’: order the elements in increasing node number order.

  • ’random’: number the elements in a random order.

  • ’reverse’: number the elements in reverse order.

Returns:

Mesh – A Mesh equivalent with self but with the elements ordered as specified.

connectedElements(startat, mask, level=0)[source]

Return the elements reachable from startat.

Finds the elements which can be reached from startat by walking along a mask (a subset of elements). Walking is possible over nodes, edges or faces, as specified in level.

Parameters:
  • startat (int or array_like, int.) – The starting element number(s).

  • level (int) – Specifies how elements can be reached: via node (0), edge (1) or face (2).

  • mask (array_like, bool or int) – Flags the elements that are considered walkable. It is an int array with the walkable element numbers, or a bool array flagging these elements with a value True. If none of the start elements is in mask, the result will obviously be nil.

Returns:

array – List of element indices that can be reached from any of the start elements by walking only over elements in mask.

connect(coordslist, div=1, degree=1, loop=False, eltype=None)[source]

Connect a sequence of topologically congruent Meshes into a hypermesh.

Parameters:
  • coordslist (list of Coords | list of Mesh | Mesh) –

    If Mesh objects are given, they should (all) have the same element type as self. Their connectivity tables will not be used. They will only serve to construct a list of Coords objects by taking the coords attribute of each of the Meshes. If only a single Mesh was specified, self.coords will be added as the first Coords object in the list.

    All Coords objects in the coordslist (either specified or constructed from the Mesh objects), should have the exact same shape as self.coords. The number of Coords items in the list should be a multiple of degree, plus 1.

    Each of the Coords in the final coordslist is combined with the connectivity table, element type and property numbers of self to produce a list of toplogically congruent Meshes. The return value is the hypermesh obtained by connecting each consecutive slice of (degree+1) of these Meshes.

    Note that unless a single Mesh was specified as coordslist parameter, the coords of self are not used. In many cases however self or self.coords will be one of the items in the specified coordslist.

  • degree (int) –

    The degree of the connection. Currently only degree 1 and 2 are supported:

    • If degree is 1, every Coords from the coordslist is connected with hyperelements of a linear degree in the connection direction.

    • If degree is 2, quadratic hyperelements are created from one Coords item and the next two in the list. Note that all Coords items should contain the same number of nodes, even for higher order elements where the intermediate planes contain less nodes.

      Currently, degree=2 is not allowed when coordslist is specified as a single Mesh.

  • loop (bool, optional) – If True, the connections with loop around the list and connect back to the first. This is accomplished by adding the first Coords item back at the end of the list.

  • div (seed) –

    This parameter can only be used for degree==1.

    With this parameter the generated connections can be further subdivided along the connection direction. div can be any of the values accepted by smartSeed(), or a list thereof. In the latter case, the length of the list should be one less than the length of the coordslist. Each pair of consecutive items from the coordinate list will be connected using the seeds generated by the corresponding value from div, passed to smartSeed().

    If seed values are specified directly as a list of floats, the list should start with a value 0.0 and end with 1.0.

  • eltype (str or ElementType, optional) – The element type of the constructed hypermesh. Normally, this is set automatically from the base element type and the connection degree. If a different element type is specified, a final conversion to the requested element type is attempted (using convert()).

Returns:

Mesh – The hypermesh obtained by connecting each consecutive slice of (degree+1) of the Meshes created as explained above under the parameters. The hypermesh has a dimensionality that is one higher than the original Mesh (i.e. points become lines, lines become surfaces, surfaces become volumes). The resulting elements are of the given degree in the direction of the connection.

extrude(div, dir=0, length=1.0, degree=1, eltype=None)[source]

Extrude a Mesh along a straight line.

The Mesh is extruded over a given length in the given direction.

Parameters:
  • div (smartseed) – Specifies how the extruded direction will be subdivided in elements. It can be anything that is acceptable as input for smartSeed().

  • dir (int (0,1,2) or float array_like (3,)) – The direction of the extrusion: either a global axis number or a direction vector.

  • length (float) – The length of the extrusion, measured along the direction dir.

Returns:

Mesh – A Mesh obtained by extruding the input Mesh over the given length in direction dir, subdividing this length according to the seeds generated by smartSeed(div).

See also

sweep

extrusion along a general path

Examples

>>> M = Mesh(Formex([0])).extrude(3,0,3)
>>> print(M)
Mesh: nnodes: 4, nelems: 3, nplex: 2, level: 1, eltype: line2
  BBox: [0.  0.  0.], [3.  0.  0.]
  Size: [3.  0.  0.]
  Length: 3.0
revolve(n, axis=0, angle=360.0, around=None, loop=False, eltype=None)[source]

Revolve a Mesh around an axis.

Revolving a Mesh extrudes the Mesh along a circular path.

Parameters:
  • n (int) – Number of circumferential steps

  • axis (int (0,1,2) or float array_like (3,)) – The direction of the rotation axis: either one of 0,1,2 for a global axis, or a vector with 3 components for a general direction.

  • angle (float) – The total angle (in degrees) of the revolve operation.

  • around (float array_like (3,)) – If provided, it specifies a point on the rotation axis. If not, the rotation axis goes through the origin of the global axes.

  • loop (bool) – If True, the end of the revolution will be connected back to the start.

  • eltype (str of ElementType, optional.) – The final element type. If specified, and it does not match the natural extruded element type, a final conversion to this target type will be attempted.

Returns:

Mesh – A Mesh obtained by revolving the given Mesh over an angle around an axis in n steps, while extruding the mesh from one step to the next. This extrudes points into lines, lines into surfaces and surfaces into volumes.

See also

sweep

extrusion along a general path

sweep(path, eltype=None, **kargs)[source]

Sweep a mesh along a path, creating an extrusion.

Parameters:
  • path (but the) –

  • eltype (-) – returned Meshes.

  • **kargs (-) – curve.Curve.sweep2(), with the same meaning. Usually, you will need to at least set the normal parameter.

  • path. (Returns a Mesh obtained by sweeping the given Mesh over a) –

  • original. (The returned Mesh has double plexitude of the) –

  • first. (If path is a closed Curve connect back to the) –

  • method (This operation is similar to the extrude()) –

  • path

  • curve. (can be any 3D) –

See also

extrude

extrusion along a straight path

revolve

extrusion along a circular path

connect

general connection of Meshes into a hypermesh

classmethod concatenate(meshes, fuse=True, **kargs)[source]

Concatenate a list of meshes of the same plexitude and eltype.

Parameters:
  • meshes (list of Mesh) – A list of Meshes all having the same plexitude. Meshes without plexitude are silently ignored: this allows empty Meshes to be appear in the list.

  • fuse (bool) – If True, the resulting concatenation will be fused.

  • *kargs – Optional extra parameters for the fuse() operation.

Notes

If any of the meshes has property numbers, the resulting mesh will inherit the properties. In that case, any meshes without properties will be assigned property 0. If all meshes are without properties, so will be the result.

This is a class method, and should be invoked as follows:

Mesh.concatenate([mesh0,mesh1,mesh2])

Examples

>>> M0 = Mesh(eltype='quad4')
>>> M1 = M0.trl(0,1.)
>>> M = Mesh.concatenate([M0,M1])
>>> print(M.coords)
[[0.  0.  0.]
 [0.  1.  0.]
 [1.  0.  0.]
 [1.  1.  0.]
 [2.  0.  0.]
 [2.  1.  0.]]
>>> print(M.elems)
[[0 2 3 1]
 [2 4 5 3]]

Concatenate Meshes using the same Coords block

>>> M0 = Mesh(M.coords, M.elems[:1])
>>> M1 = Mesh(M.coords, M.elems[1:])
>>> M2 = Mesh.concatenate([M0,M1])
>>> id(M.coords) == id(M2.coords)
False
>>> M2 = Mesh.concatenate([M0,M1], fuse=False)
>>> id(M.coords) == id(M2.coords)
True
test(nodes='all', dir=0, min=None, max=None, atol=0.0)[source]

Flag elements having nodal coordinates between min and max.

This is comparable with coords.Coords.test() but operates at the Mesh element level. It tests the position of one or more nodes of the elements of the Mesh with respect to one or two parallel planes. This is very useful in clipping a mesh in a specified direction. In most cases the clipping direction is one of the global coordinate axes, but a general direction may be used as well.

Testing along global axis directions is highly efficient. It tests whether the corresponding coordinate is above or equal to the min value and/or below or equal to the max value. Testing in a general direction tests whether the distance to the min plane is positive or zero and/or the distance to the max plane is negative or zero.

Parameters:
  • nodes (int, list of ints or string) –

    Specifies which points of the elements are taken into account in the tests. It should be one of the following:

    • a single node index (smaller than self.nplex()),

    • a list of node indices (all smaller than self.nplex()),

    • one of the special strings: ‘all’, ‘any’, ‘none’.

    The default (‘all’) will flag the elements that have all their nodes between the planes x=min and x=max, i.e. the elements that fall completely between these planes.

  • dir (a single int or a float array_like (3,)) – The direction in which to measure distances. If an int, it is one of the global axes (0,1,2). Else it is a vector with 3 components. The default direction is the global x-axis.

  • min (float or point-like, optional) – Position of the minimal clipping plane. If dir is an int, this is a single float giving the coordinate along the specified global axis. If dir is a vector, this must be a point and the minimal clipping plane is defined by this point and the normal vector dir. If not provided, there is no clipping at the minimal side.

  • max (float or point-like.) – Position of the maximal clipping plane. If dir is an int, this is a single float giving the coordinate along the specified global axis. If dir is a vector, this must be a point and the maximal clipping plane is defined by this point and the normal vector dir. If not provided, there is no clipping at the maximal side.

  • atol (float) – Tolerance value added to the tests to account for accuracy and rounding errors. A min test will be ok if the point’s distance from the min clipping plane is > -atol and/or the distance from the max clipping plane is < atol. Thus a positive atol widens the clipping planes.

Returns:

1-dim bool array – Array with length self.nelems() flagging the elements that pass the test(s). The return value can directly be used as an index in select() or cselect to obtain a Mesh with the elements satisfying the test or not. Or you can use np.where(result)[0] to get the indices of the elements passing the test.

Raises:

ValueError – At least one of min or max have to be specified: If neither min nor max are provided.

See also

coords.Coords.test()

testing individual points

select

return only the selected elements

cselect

return all but the selected elements

Examples

>>> M = Mesh(eltype='tri3').subdivide(2)
>>> M.coords
Coords([[0. ,  0. ,  0. ],
        [0.5,  0. ,  0. ],
        [1. ,  0. ,  0. ],
        [0. ,  0.5,  0. ],
        [0.5,  0.5,  0. ],
        [0. ,  1. ,  0. ]])
>>> M.elems
Elems([[0, 1, 3],
       [1, 2, 4],
       [3, 4, 5],
       [1, 4, 3]], eltype=Tri3)
>>> M.test(min=0.0,max=0.5)
array([ True, False,  True,  True])
>>> M.test(nodes=[0],min=0.0,max=0.2)
array([ True, False,  True, False])
>>> M.test(dir=(-1.,1.,0.), min=(0.,0.,0.))
array([False, False,  True, False])
>>> M.test(dir=(-1.,1.,0.), min=(0.,0.,0.), nodes='any')
array([ True,  True,  True,  True])
>>> M.test(dir=(-1.,1.,0.), min=(0.,0.,0.), nodes='any', atol=-1.e-5)
array([ True, False,  True,  True])
clipAtPlane(p, n, nodes='any', side='+')[source]

Return the Mesh clipped at plane (p,n).

This is a convenience function returning the part of the Mesh at one side of the plane (p,n)

intersectionWithLines(approximated=True, **kargs)[source]

Return the intersections of a surface Mesh with lines.

The Mesh is intersected with lines. The arguments and return values are the same as in trisurface.TriSurface.intersectionWithLines(), except for the approximated.

For a Mesh with eltype ‘tri3’, the intersections are exact. For other eltypes, if approximated is True a conversion to ‘tri3’ is done before computing the intersections. This may produce an exact result, an approximate result or no result (if the conversion fails). Of course the user can create his own approximation to a ‘tri3’ surface first, before calling this method.

levelVolumes()[source]

Return the level volumes of all elements in a Mesh.

The level volume of an element is defined as:

  • the length of the element if the Mesh is of level 1,

  • the area of the element if the Mesh is of level 2,

  • the (signed) volume of the element if the Mesh is of level 3.

The level volumes can be computed directly for Meshes of eltypes ‘line2’, ‘tri3’ and ‘tet4’ and will produce accurate results. All other Mesh types are converted to one of these before computing the level volumes. Conversion may result in approximation of the results. If conversion can not be performed, None is returned.

If successful, returns an (nelems,) float array with the level volumes of the elements. Returns None if the Mesh level is 0, or the conversion to the level’s base element was unsuccessful.

Note that for level-3 Meshes, negative volumes will be returned for elements having a reversed node ordering.

lengths()[source]

Return element or perimeter lengths for a Mesh of level 1 or 2.

Returns:

array | None – For a level 1 Mesh, the length of the elements. For a level 2 Mesh, the length of the elements’ perimeter. If the elements or its edges are of eltype ‘line2’, the lengths are exact. For other eltypes, a conversion to ‘line2’ is done before computing the lengths. This can produce an exact result, an approximate result or no result (if the conversion fails). If successful, returns an (nelems,) float array with the lengths.

Returns None if the Mesh level is not 1 or 2, or the conversion to ‘line2’ does not succeed.

Examples

>>> nx = 4
>>> M = Mesh(eltype='line2').subdivide(nx)
>>> a = M.lengths()
>>> print(a)        # each equals 1. / nx
[0.25 0.25 0.25 0.25]
>>> print(a.sum())  # equals 1.
1.0
>>> nx, ny = 3, 2
>>> M = Mesh(eltype='quad4').subdivide(nx, ny)
>>> a = M.lengths()
>>> print(a)        # each equals (nx + ny) * 2 / (nx * ny)
[1.6667 1.6667 1.6667 1.6667 1.6667 1.6667]
>>> print(a.sum())  # equals (nx + ny) * 2
10.0...
areas()[source]

Return the areas of all elements in a Mesh of level 2 or 3.

Returns:

array | None – For a level 2 Mesh, the area of the elements. For a level 3 Mesh, the area of the elements’ surface. If the elements or its faces are of eltype ‘tri3’, the areas are exact. For other eltypes, a conversion to ‘tri3’ is done before computing the areas. This can produce an exact result, an approximate result or no result (if the conversion fails). If successful, returns an (nelems,) float array with the areas.

Returns None if the Mesh level is < 2, or the conversion to ‘tri3’ does not succeed.

Examples

>>> nx, ny = 3, 2
>>> M = Mesh(eltype='quad4').subdivide(nx, ny)
>>> a = M.areas()
>>> print(a)        # each equals 1. / (nx * ny)
[0.1667 0.1667 0.1667 0.1667 0.1667 0.1667]
>>> print(a.sum())  # equals 1.
1.0
>>> nx, ny, nz = 4, 3, 2
>>> M = Mesh(eltype='hex8').subdivide(nx, ny, nz)
>>> a = M.areas()
>>> print(a)        # each equals (nx + ny + nz) * 2 / (nx * ny * nz)
[0.75 0.75 ...
>>> print(a.sum())  # equals (nx + ny + nz) * 2
18.0...
volumes()[source]

Return the signed volume of the elements in Mesh of level 3.

Returns:

array | None – For a level 3 Mesh, the signed volume of the elements. If the elements are of eltype ‘tet4’, the volumes are exact. For other eltypes, a conversion to ‘tet4’ is done before computing the volumes. This can produce an exact result, an approximate result or no result (if the conversion fails). If successful, returns an (nelems,) float array with the volumes.

Returns None if the Mesh level is < 3, or the conversion to ‘tri3’ does not succeed.

Examples

>>> nx, ny, nz = 2, 2, 1
>>> M = Mesh(eltype='hex8').subdivide(nx, ny, nz)
>>> a = M.volumes()
>>> print(a)        # each equals 1. / (nx * ny * nz)
[0.25 0.25 0.25 0.25]
>>> print(a.sum())  # equals 1.
1.0
length()[source]

Return the total length of a Mesh.

Returns:

float – For a level 1 Mesh, the sum of all element lengths(); for a level 2 Mesh, the length of the borderMesh(); 0.0 if lengths() returned None.

Examples

>>> Mesh(eltype='line2').subdivide(4).length()
1.0

For a level 2 Mesh, note the difference between these three: the length of the border, the length of all edges (includes non-border edges), the sum of all element perimeters (includes edges multiple times).

>>> M = Mesh(eltype='quad4').subdivide(2,1)
>>> M.length(), M.edgeMesh().length(), M.lengths().sum()
(4.0, 5.0, 6.0)
area()[source]

Return the total area of a Mesh.

Returns:

float – For a level 2 Mesh, the sum of all element areas(); for a level 3 Mesh, the area of the borderMesh(); 0.0 if lengths() returned None.

Examples

>>> Mesh(eltype='quad4').subdivide(3,2).area()
1.0

For a level 3 Mesh, note the difference between these three: the area of the border, the area of all faces (includes non-border faces), the sum of all element face areas (includes faces multiple times).

>>> M = Mesh(eltype='hex8').subdivide(4,3,2)
>>> M.area(), M.faceMesh().area(), M.areas().sum()
(6.0..., 12.0..., 18.0...)
volume()[source]

Return the total volume of a Mesh.

Returns:

float – For a level 3 Mesh, the total volume of all elements (see Notes). For a Mesh of level < 3, returns 0.

Notes

The total volume of the Mesh is computed by taking its border surface (see toSurface()) and computing the volume inside that surface. It is equivalent with:

self.toSurface().volume()

This is far more efficient than:

self.volumes().sum().

Examples

>>> nx, ny, nz = 4, 3, 2
>>> M = Mesh(eltype='hex8').subdivide(nx, ny, nz)
>>> print(M.volume(), M.volumes().sum())
1.0... 1.0...
fixVolumes()[source]

Reverse the elements with negative volume.

Elements with negative volume may result from incorrect local node numbering. This method will reverse all elements in a Mesh of dimensionality 3, provided the volumes of these elements can be computed.

scaledJacobian(scaled=True, blksize=100000)[source]

Compute a quality measure for volume meshes.

Parameters:
  • scaled (bool) – If False returns the Jacobian at the corners of each element. If True, returns a quality metrics, being the minimum value of the scaled Jacobian in each element (at one corner, the Jacobian divided by the volume of a perfect brick).

  • blksize (int) – If > 0 and the number of elements is larger than blksize, the Mesh is split in blocks with this number of elements, to reduce the memory required in handling large meshes. If <= 0, all elements are handled at once.

Returns:

todo – @DEVS: This needs to be filled in.

Notes

If scaled is True each tet or hex element gets a value between -1 and 1. Acceptable elements have a positive scaled Jacobian. However, good quality requires a minimum of 0.2. Quadratic meshes are first converted to linear. If the mesh contain mainly negative Jacobians, it probably has negative volumes and can be fixed with the correctNegativeVolumes.

smooth(niter=1, lamb=0.5, *, mu=None, border='sep', level=1, exclude=[], weight='uniform', data=None, **kargs)[source]

Smooth the geometry of a Mesh or data defined over a Mesh.

Uses Taubin lambda/mu method to smooth the node positions or any other float data defined on the nodes of the Mesh. This is a two-step iteration method. In the first (smoothing) step, the new nodal values are set to a weighted interpolation of the old values and the weighted mean values at the neighboring nodes. The relaxation factor lambda determines how far the value moves towards the local centroid. As this smoothing causes shrinkage of the model, it is followed by a compensating scaling (expansion) step, governed by the value mu. The more iterations the smoother the result will be, possibly at the cost of increased shrinkage. Options are available to tune the weights, exclude nodes from smoothing, or separately smooth border and inner nodes.

Parameters:
  • niter (int) – The number of smoothing iterations to be performed.

  • lamb (float) – Relaxation factor (0 <= lamb <= 1) for the smoothing step. A value 0 keeps the old values, while a value 1 replaces them with the (weighted) mean values at the neighbors.

  • mu (float) – Relaxation factor for the expansion step (mu < -lambda). The value should be negative to undo the shrinkage of the first step. If not provided, the default value used is -lamb / (1.0 - 0.1*lamb). The higher the absolute value of mu, the more the shrinkage is reduced, and the model may even start to expand. If a value of 0.0 is specified, no second step is done.

  • border ('sep' | 'fix' | 'incl') – Specifies how border nodes are handled. With ‘sep’ (default), border nodes are smoothed independently from internal nodes. Internal nodes still remain dependent on border nodes though. With ‘fix’, border nodes remain in place and do not take part in the smoothing. With ‘incl’, border nodes are included in the smoothing process just like other nodes. For a borderless mesh (like a closed surface), ‘sep’ and ‘incl’ are obviously the same.

  • level (int) – The level of connections between the nodes that will define the neighbors in the smoothing process. If an int, nodes are only considered neighbors if the belong to the same lower level entities: 1 for edges, 2 for faces, 3 for 3D-cells. The default uses neigbors by edge. A value 0 will use the highest (element) level. For simplex meshes (line2, tri3, tet4) the value makes no difference, as all nodes in an element are connected by an edge. Using a value different from 1 tends to produce more shrinkage. Therefore the default is set to 1 even for non-simplex meshes.

  • exclude (list of int) – A list of nodes that should retain their position throughout the smoothing process. When using border='fix', the border nodes are automatically added to this list.

  • weight ('uniform' | 'inverse' | 'distance') – Specifies how the relative weight of the neighboring points is calculated. With ‘uniform’ all neighbor points have the same weight. With ‘distance’, neighbor points have a weight proportional to their distance to the point to be moved. With ‘inverse’, the weight is proportional to the inverse of the distances. Prepending ‘sq’ to ‘inverse’ or ‘distance’ will make the weights proportional to the square (inverse) distances.

  • data (array_like) – An array of floating point data defined at the nodes. The first dimension of the array should be equal to the number of nodes. If data is provided, returns the smoothed data instead of a Mesh with smoothed geometry.

Returns:

Mesh | array – If no data was provided, returns a smoothed Mesh with otherwise same characteristics. If data was provided, returns an array of the same shape containing the smoothed data.

Notes

For the smoothing algorithm, see Taubin, Curve and Surface Smoothing without Shrinkage, ICCV 1995.

The default border='sep' works well in most cases. For models with a border, shrinkage is prominent near the border and the setting helps in reducing it. For models without a border, there is no difference between ‘sep’ and ‘incl’.

The weights are currently only computed once before starting the smoothing iterations. As a result, there is a difference between using a single smooth with niter iterations and using niter successive smooths with a single iteration. This behavior may be changed in future.

pzf_dict()[source]

Construct common part of all Geometry pzf dicts

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:
  • L (float) – The length of the rectangle.

  • W (float) – The width of the rectangle.

  • nl (seed) – The element seed along the length.

  • nw (seed) – The element seed along the width.

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:
  • x (Coords(4,3)) – The four corners of the mesh, in anti-clockwise order.

  • n1 (int) – The number of elements along the sides x0-x1 and x2-x3.

  • n2 (int) – The number of elements along the sides x1-x2 and x3-x4.

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 a Line ([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:
  • n1 (int) – Number of elements along the edges 01 and 23

  • n2 (int) – Number of elements along the edges 12 and 30

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_checkNormals(self)[source]

Find out which elements have reversed surface orientation

mesh.quad4_fixNormals(self, ids)[source]

Fixes orientation of some quad4 surface elements

mesh.quad4_fixSurface(self)[source]

Do all fixes inplace

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.