Finite-Element Mesh#
The finite-element mesh specifies the geometry and topology of the discretization. It must be generated using external software before running PyLith. PyLith supports triangular and quadrilateral cells in 2D and tetrahedral and hexahedral cells in 3D. The vertex ordering must follow the convention shown in Fig. 7 and Fig. 8. The cells define the geometry of the domain; the basis order and quadrature order used to discretize the solution subfields are specified separately.
The mesh information specifies the vertex coordinates and the vertices composing each cell in the mesh. The mesh information must also define at least one set of vertices for which displacement (Dirichlet) boundary conditions will be provided. In most realistic problems, there will be several vertex groups, each with a unique identifying label. For example, one group might define a surface of the mesh where displacement (Dirichlet) boundary conditions will be applied, another might define a surface where traction (Neumann) boundary conditions will be applied, while a third might specify a surface that defines a fault. Similarly, the mesh information contains cell labels that define the material type for each cell in the mesh. For a mesh with a single material type, there will only be a single label for every cell in the mesh. See Materials and Boundary Conditions for more detailed discussions of setting the materials and boundary conditions.
Mesh Importer#
The default component for the PyLithApp mesher
facility is MeshImporter
, which provides the capabilities of reading the finite-element mesh from files.
The MeshImporter
includes a facility for reordering the mesh.
Reordering the mesh so that vertices and cells connected topologically reside close together in memory improves overall performance.
Pyre User Interface
PyLith supports reading meshes generated by CUBIT (Exodus II files) and Gmsh.
We have implemented our own readers for Exodus II files.
For Gmsh files we use the reader included in PETSc; PETSc also supports several other formats, but they have not been tested for use with PyLith.
Currently, PyLith requires that boundary conditions be specified by marking vertices and all materials are marked by the same label material-id
with different label values for each material.
The PyLith readers create the labels from the mesh input files.
Mesh generation with CUBIT and Gmsh#
CUBIT and Gmsh can generate quadrilateral or triangular meshes in 2D and hexahedral or tetrahedral meshes in 3D. In each case, you first create the geometry, specify the meshing algorithm and discretization size, and then generate the mesh. You can build up the geometry from points, curves, surfaces, and volumes or use the geometry engines to construct the domain using simple shapes.
CUBIT#
We have tended to construct CUBIT meshes using journal files and leverage the CUBIT APREPRO scripting language. CUBIT also provides a Python interface, but you must use the Python interpreter provided with CUBIT. The functionality of the two interfaces is quite similar, although one could argue that the Python interface leverages a more complete development experience through a commonly used programming language.
Gmsh#
We only recently started using Gmsh and have only used the Python interface. Gmsh also offers a simple scripting language, similar to CUBIT journal files. The Gmsh Python interface integrates well with the rest of Python; it can be installed so that it is compatible with the Python interpreter used by PyLith. This means one can leverage additional Python packages, such as geographic projection libraries. Gmsh includes its own geometry engine as well as an interface to the Open CASCADE engine.
Warning
Gmsh does not construct quadrilateral or hexahedral meshes directly; instead, it first constructs a triangular or tetrahedral mesh and then combines triangles or tetrahedra to form quadrilaterals or hexahedra.
Sometimes it will not be able to remove all triangular or hexahedral cells, resulting in meshes with multiple shapes, which PyLith does not support.
2D meshing#
Constructing surfaces from points and curves for 2D meshing with CUBIT and Gmsh is very similar. CUBIT provides more geometric operations than Gmsh, but many simple geometric operations in Gmsh can be implemented by the user when using the Python interface. Gmsh includes a simple yet powerful interface for specifying the discretization size. Generating unstructured quadrilateral meshes for complex geometry is often easier in CUBIT, whereas generating meshes with complex specification of discretization size is often easier with Gmsh.
3D meshing#
CUBIT provides an extensive suite of tools for constructing complex 3D geometry. This includes building surfaces and performing geometric operations on surfaces and volumes. The suite of tools in the Gmsh geometry engine is more limited; the Open CASCADE engine interface provides additional tools. With either CUBIT or Gmsh, you can use external CAD tools to generate the geometry. As in the case with 2D meshing, generating unstructure hexahedral meshes is often easier in CUBIT, whereas generating meshes with complex specification of discretization size is often eaiser in Gmsh.
ASCII Mesh Files - MeshIOAscii
#
The MeshIOAscii
object is intended for reading small, simple ASCII files containing a mesh constructed by hand.
We use this file format extensively in small tests.
PyLith Mesh ASCII File describes the format of the files.
MeshIOAscii entity |
|
|
---|---|---|
|
|
value |
Group name |
name |
1 (default) |
Pyre User Interface
CUBIT (Exodus II) Mesh Files - MeshIOCubit
#
The MeshIOCubit
object reads the NetCDF Exodus II files output from CUBIT.
Beginning with CUBIT 11.0, the names of the nodesets are included in the Exodus II files and PyLith can use these nodeset names or revert to using the nodeset ids.
CUBIT entity |
|
|
---|---|---|
Material block |
|
Block value |
Nodeset |
Nodeset name |
1 (default) |
Pyre User Interface
Warning
There are two versions of CUBIT: Sandia National Laboratory provides a version to U.S. government agencies, and Coreform provides another version to all other users. The two verisions used to be essentially the same, but the differences have started to grow. We strive to provide CUBIT Journal scripts that work with both versions without modification, but this is becoming more difficult.
Please be aware that we cannot guarantee that all CUBIT Journal files will work with all versions of CUBIT. You may need to make small adjustments (usually updating geometry ids) to get them to work with the version of CUBIT you are using.
Gmsh Files - MeshIOPetsc
#
The MeshIOPetsc
object supports reading a variety of mesh formats.
We have only thoroughly tested this interface using Gmsh files.
Gmsh entity |
|
|
---|---|---|
Material physical groups |
|
tag |
Boundary condition physical groups |
Physical group name |
tag |
Important
The Gmsh file must end in .msh
for the reader to recognize that it is a Gmsh file.
Tip
You can view the mesh quality in Gmsh using Tools
→Statistics
.
We prefer the condition number quality metric, which Gmsh provides as SICN (signed inverse of the condition number).
Click on 3D
next to SICN
to color the cells by mesh quality.
Click on Plot
to view the cumulative distribution of the metric over the cells.
Pyre User Interface
gmsh_utils
#
In Gmsh we use physical groups to associate cells with materials and mark entities for boundary conditions and faults.
The names of physical groups for materials must follow the syntax material-id:TAG
, where TAG is the tag of the physical group.
PyLith includes a Python module pylith.meshio.gmsh_utils
to make it easy to generate a PyLith compatible Gmsh file.
The function create_material()
generates physical groups following the required naming convention of material-id:TAG
given the tag and names of entities.
Similarly, the function create_group()
will construct physical groups for boundary conditions and faults compatible with PyLith.
The physical groups for boundary conditions and faults must include entities at the topological dimension of the boundary condition as well as all lower dimensions. For example, for a boundary condition on curves a physical group must include the entities on the curves as well as the vertices defining the curves. For a boundary condition on surfaces a physical group must include the entities on the surfaces as well as the curves and vertices defining the surfaces.
GenerateMesh
Application Template#
The gmsh_utils
module also includes a application template object (Python abstract base class) called GenerateMesh
for writing Python scripts that generate meshes using Gmsh.
The application template defines the steps for generating the mesh with a separate function (to be implemented by the user) for each step:
initialize()
: Initialize Gmsh;create_geometry()
: Create the geometry (implemented in user application);mark()
: Create physical groups for boundary conditions, faults, and materials (implemented in user application);generate_mesh()
: Generate the finite-element mesh (implemented in user application);write()
: Save the mesh to a file; andfinalize()
: Start the Gmsh graphical user interface, if requested, and then finalize Gmsh.
The command line arguments specify which step(s) to run, the output filename, and whether to invoke the Gmsh graphical user interface upon completing the steps:
--geometry
:Generate the geometry by calling
create_geometry()
.--mark
:Create physical groups by calling
mark()
.--generate
:Generate the mesh by calling
generate_mesh()
.--write
:Save the mesh by calling
write()
.--name
:Name of the mesh in Gmsh (default=”mesh”).
--filename=FILENAME
:Name of output mesh file (default=”mesh.msh”).
--ascii
:Write mesh to ASCII file (default is binary).
--cell=[tri,quad,tet,hex]
:Generate mesh with specified cell type.
--gui
:Start the Gmsh graphical user interface after running steps.
The application template always calls the initialize()
and finalize()
methods.
Additionally, the application will run any prerequisite steps.
For example, specifying --generate
will trigger creating the geometry and physical groups before generating the mesh.
The application is discussed in more detail in the examples.
MaterialGroup#
MaterialGroup
is a Python data class that holds information about a physical group associated with a material.
The data members include:
- tag (int):
Integer tag for the physical group.
- entities (list):
List (array) of entities for the material.
The MaterialGroup
data class include a method create_physical_group()
that will create a physical group from the information in the MaterialGroup
.
VertexGroup#
VertexGroup
is a Python data class that holds information about a physical group associated with a boundary or fault.
The data members include:
- name (str):
Name for the physical group.
- tag (int):
Integer tag for the physical group.
- dim (int):
Dimension of the entities (0=points, 1=curves, 2=surfaces)
- entities:
List (array) of entities for the boundary condition or fault.
The VertexGroup
data class include a method create_physical_group()
that will create a physical group from the information in the VertexGroup
.
Distribution among Processes - Distributor
#
The distributor uses a partitioner to compute which cells should be placed on each processor, computes the overlap among the processors, and then distributes the mesh among the processors. The type of partitioner is set via PETSc settings.
Note
METIS/ParMETIS are not included in the PyLith binaries due to licensing issues.
Pyre User Interface
Uniform Global Refinement - Refiner
#
The refiner is used to decrease node spacing by a power of two by recursively subdividing each cell by a factor of two. In a 2D triangular mesh a node is inserted at the midpoint of each edge, splitting each cell into four cells (see Fig. 9). In a 2D quadrilateral mesh a node is inserted at the midpoint of each edge and at the centroid of the cell, splitting each cell into four cells. In a 3D tetrahedral mesh a node is inserted at the midpoint of each edge, splitting each cell into eight cells. In a 3D hexahedral mesh a node is inserted at the midpoint of each edge, the centroid of each face, and at the centroid of the cell, splitting each cell into eight cells.
Refinement occurs after distribution of the mesh among processors. This allows one to run much larger simulations by (1) permitting the mesh generator to construct a mesh with a node spacing larger than that needed in the simulation and (2) operations performed in serial during the simulation setup phase, such as, adjusting the topology to insert cohesive cells and distribution of the mesh among processors uses this much smaller coarse mesh. For 2D problems the global mesh refinement increases the maximum problem size by a factor of \(4^{n}\), and for 3D problems it increases the maximum problem size by a factor of \(8^{n}\), where \(n\) is the number of recursive refinement levels. For a tetrahedral mesh, the element quality decreases with refinement so \(n\) should be limited to 1-2.