# Initialization Phases `MeshReader` : Read a finite-element mesh from a file. `MeshWriter` : Write a finite-element mesh to a file. `MeshReordering` : Reorder the cells and vertices of a finite-element mesh. `MeshDistributor` : Distribute a finite-element mesh among processes. `MeshInsertInterfaces` : Insert cohesive cells for faults. `MeshRefine` : Refine a finite-element mesh. ## `MeshReader` and `MeshWriter` PyLith supports reading meshes generated by Cubit (Exodus II files) and Gmsh, as well as mesh files converted to HDF5 files in the PETSc mesh format. We have implemented our own readers for Exodus II files. For Gmsh and HDF5 files we use the reader included in PETSc; PETSc also supports several other formats, but they have not been tested for use with PyLith. Mesh vertices or faces can be associated with boundary conditions, fault interfaces, or output by creating groups of vertices or faces. 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. Refer to {ref}`sec-user-meshing` for information about generating finite-element meshes using Cubit and Gmsh and converting Exodus II files from Cubit and Gmsh files to HDF5 files in the PETSc format. :::{important} Marking faces (edges in 2D), which is a new capability in version 5.0, is preferred. Marking vertices is deprecated and will be removed in version 6.0. ::: :::{admonition} Pyre User Interface :class: seealso [`MeshReader` Component](../../components/initializers/MeshReader.md) [`MeshWriter` Component](../../components/initializers/MeshWriter.md) ::: ### 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 in small tests. {ref}`sec-user-file-formats-meshio-ascii` describes the format of the files. ```{table} Translation of ASCII mesh 'tags' to PyLith mesh 'label' and 'label_value'. :name: tab:mesh:tags:translation:ascii | MeshIOAscii entity | `label` | `label_value` | | :----------------- | :------------------------ | :-----------: | | `material-ids` | `material-id` (hardwired) | value | | Group name | name | 1 (default) | ``` :::{admonition} Pyre User Interface :class: seealso [`MeshIOAscii` Component](../../components/meshio/MeshIOAscii.md) ::: (sec-user-run-pylith-meshiocubit)= ### 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. ```{table} Translation of Cubit mesh 'tags' to PyLith mesh 'label' and 'label_value'. :name: tab:mesh:tags:translation:cubit | Cubit entity | `label` | `label_value` | | :------------- | :------------------------ | :-----------: | | Material block | `material-id` (hardwired) | Block value | | Nodeset | Nodeset name | 1 (default) | | Sideset | Sideset name | 1 (default) | ``` :::{admonition} Pyre User Interface :class: seealso [`MeshIOCubit` Component](../../components/meshio/MeshIOCubit.md) ::: :::{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 versions 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. Cubit is no longer supported on macos, so we are phasing out use of Cubit in PyLith examples. ::: (sec-user-run-pylith-meshiopetsc)= ### Gmsh and HDF5 Files - `MeshIOPetsc` The `MeshIOPetsc` object supports reading a variety of mesh formats. We have only thoroughly tested this interface using Gmsh files and HDF5 files in the PETSc mesh format. Refer to {ref}`sec-user-run-pylith-convertmesh` for how to convert an Exodus II file from Cubit or a Gmsh file to an HDF5 file in the PETSc mesh format. ```{table} Translation of Gmsh mesh 'tags' to PyLith mesh 'label' and 'label_value'. :name: tab:mesh:tags:translation:gmsh | Gmsh entity | `label` | `label_value` | | :--------------------------------- | :------------------------ | :-----------: | | Material physical groups | `material-id` (hardwired) | tag | | Boundary condition physical groups | Physical group name | tag | ``` :::{important} A Gmsh file must end in `.msh` for the reader to recognize that it is a Gmsh file. The HDF5 file must end in `.h5` for the reader to recognize that it is an HDF5 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. ::: :::{admonition} Pyre User Interface :class: seealso [`MeshIOPetsc` Component](../../components/meshio/MeshIOPetsc.md) ::: ## `MeshReordering` Reordering the mesh so that vertices and cells connected topologically reside close together in memory improves overall performance. We use the revere Cuthill-McKee algorithm, which is available in PETSc, for reordering. ## `MeshDistributor` The distributor uses a partitioner to compute which cells should be placed on each process, computes the overlap among the processes, and then distributes the mesh among the processes. The default partitioner is METIS/ParMETIS. :::{admonition} Pyre User Interface :class: seealso [`Distributor` Component](../../components/topology/Distributor.md) ::: ## `MeshInsertInterfaces` Insert fault interfaces into the mesh by creating cohesive cells. Refer to {ref}`sec-user-physics-faults` for more information. ## `MeshRefine` Refining the mesh adjusts the discretization size for a specific simulation. The typical use case is uniformly refining a mesh to decrease the discretization size by the same amount over the entire domain. ### `RefineUniform` This 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 {numref}`fig:uniform:refinement:2x`). 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. :::{figure-md} fig:uniform:refinement:2x Global refinement Global uniform mesh refinement of 2D and 3D linear cells. The blue lines and orange circles identify the edges and vertices in the original cells. The purple lines and green circles identify the new edges and vertices added to the original cells to refine the mesh by a factor of two. ::: Refinement occurs after distribution of the mesh among processes. 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.