Creating a mesh

We start with setting the Feel++ environment and loading the Feel++ library.

Set the Feel++ environment with local repository
import feelpp
import sys
app = feelpp.Environment(["myapp"],config=feelpp.localRepository(""))
Results

1. Load a mesh from a geo or msh file

feelpp.mesh(dim=2, geo=1, realdim=2, worldComm=None) : create a mesh. The mesh is of topological dimension dim, in real dimension realdim with geometric order geo. The mesh is configured with a WorldComm which provides the parallel process layout.

Keyword arguments:

  • dim : the topological dimension (default: 2)

  • geo : the geometrical order (default: 1)

  • realdim : the real dimension (default: 2)

  • worldComm : the parallel communicator for the mesh (default: Environment::worldCommPtr())

feelpp.load(m, path, size) → feelpp._mesh.Mesh_S1DG1R1 : load a mesh from a file

  • m declared with the function mesh above

  • path (string) path to the geometry (with geo or msh format)

  • size (float) size of the meshed geometry (if it is not meshed yet)

Example
geo=feelpp.download( "github:{repo:feelpp,path:feelpp/quickstart/laplacian/cases/feelpp2d/feelpp2d.geo}", worldComm=app.worldCommPtr() )[0]
print("geo file: {}".format(geo))
mesh = feelpp.load(feelpp.mesh(dim=2,realdim=2), geo, 0.1)
Results
geo file: /nvme0/prudhomm/github-actions/actions-runner-2/_work/book.feelpp.org/book.feelpp.org/feelppdb/downloads/feelpp2d.geo

2. Usage

The mesh provides the Feel++ data structures in Python: The following methods are to use on the mesh object (mesh in the previous example) :

2.1. Mesh information :

  • dimension(self) → int : get topological dimension

  • hAverage(self) → float : get the average edge length of the mesh

  • hMax(self) → float : get the maximum edge length of the mesh

  • hMin(self) → float : get the minimum edge length of the mesh

  • measure(self, parallel: bool = True) → float : get the measure of the mesh (which is equal to \(\int_\Omega 1\))

  • measureBoundary(self) → float : get the measure of the boundary of the mesh (which is equal to \(???\))

  • numGlobalEdges(self) → int : get the number of edges over the whole mesh, requires communication if the mesh is parallel

  • numGlobalElements(self) → int : get the number of elements over the whole mesh, requires communication if the mesh is parallel

  • numGlobalFaces(self) → int : get the number of faces over the whole mesh, requires communication if the mesh is parallel

  • numGlobalPoints(self) → int : get the number of points over the whole mesh, requires communication if the mesh is parallel

  • realDimension(self) → int : get real dimension

  • updateMeasures(self) → None : update the measures of the mesh

Here is an example of how to use the mesh information:

Query the mesh information
print(f"dimention: {mesh.dimension()}")
print(f"number of elements: {mesh.numGlobalElements()}")
print(f"number of faces: {mesh.numGlobalFaces()}")
print(f"hmin: {mesh.hMin()}")
print(f"havg: {mesh.hAverage()}")
print(f"hmax: {mesh.hMax()}")
print(f"measure: {mesh.measure()}")
print(f"measure of boundary: {mesh.measureBoundary()}")
Results
dimention: 2
number of elements: 5134
number of faces: 8006
hmin: 0.0763352613189128
havg: 0.10274873094289755
hmax: 0.13695416558140516
measure: 20.79999999999997
measure of boundary: 1497.0959239128888

2.2. Test relation between meshes :

  • isParentMeshOf(self: feelpp._mesh.Mesh_S3DG1R3, arg0: feelpp._mesh.Mesh_S3DG1R3) → bool : is the mesh the parent mesh of another mesh

  • isRelatedTo(self: feelpp._mesh.Mesh_S3DG1R3, arg0: feelpp._mesh.Mesh_S3DG1R3) → bool : is the mesh related to another mesh

  • isSiblingOf(self: feelpp._mesh.Mesh_S3DG1R3, arg0: feelpp._mesh.Mesh_S3DG1R3) → bool: is the mesh a sibling of another mesh

  • isSubMeshFrom(self: feelpp._mesh.Mesh_S3DG1R3, arg0: feelpp._mesh.Mesh_S3DG1R3) → bool : is the mesh a sub mesh of another mesh

2.3. Export and load mesh on HDF5 format

  • saveHDF5(self, name: str) → None : save mesh to H5 file

  • loadHDF5(self, name: str) → None : load mesh from H5 file

3. Ranges

elements

feelpp.elements(mesh) : get iterator over the elements of the mesh

markedelements
  1. feelpp.markedelements(mesh, tag: str) : get iterator over the marked elements of the mesh

  2. feelpp.markedelements(mesh, marker: str) : return the range of elements of the mesh with marker

  3. feelpp.markedelements(mesh, markers: List[str]) : return the range of elements of the mesh with markers

faces

feelpp.faces(mesh) : get iterator over the faces of the mesh

markedfaces
  1. feelpp.markedfaces(mesh, marker: str) : return the range of facets of the mesh with marker

  2. markedfaces(mesh, markers: List[str]) : return the range of facets of the mesh with marker

boundaryfaces

feelpp.boundaryfaces(mesh): get iterator over the boundary faces of the mesh

A first example with ranges:

r = feelpp.elements(mesh)
print("mesh elts:", feelpp.nelements(r))
r = feelpp.boundaryfaces(mesh)
print("mesh boundary faces:", feelpp.nelements(r))
Results
mesh elts: 5134
mesh boundary faces: 610

A second more interesting example with ranges uses integrate to compute integrals of expressions over the mesh:

Example : compute integrals
from feelpp.integrate  import integrate

i1 = integrate(range=feelpp.elements(mesh),expr="sin(x+y):x:y")
i2 = integrate(range=feelpp.boundaryfaces(mesh),expr="x*nx+y*ny+z*nz:x:y:z:nx:ny:nz")
i3 = integrate(range=feelpp.markedelements(mesh, "marker"), expr="1")

print(f"i1 = {i1}, i2 = {i2}, i3 = {i3}")
Results
i1 = [3.24282386], i2 = [41.6], i3 = [0.]