Markers
Introduction
In μfem, as in other FEM codes, it is essential to have a method for identifying specific parts of the mesh. This capability allows us to define the regions of the computational domain where a given model operates, specify the boundaries to which boundary conditions will be applied, and assign specific materials to designated bodies. To facilitate this, we utilize “markers”.
Each marker is an instance of the mufem.Marker
class, which contains information about the mesh attributes associated with the entity we wish to mark. Typically, meshes are stored in files of a specific format that describe the connectivity between different elements. These files include attributes that provide information about groups of mesh elements, which can represent a particular body or boundary.
For example, the following block shows the beginning of a mesh file created by the Gmsh mesh generator:
$MeshFormat
2.2 0 8
$EndMeshFormat
$PhysicalNames
5
2 11 "Bnd1"
2 12 "Bnd2"
2 13 "Bnd3"
3 101 "Vol1"
3 102 "Vol2"
$EndPhysicalNames
$Nodes
945
1 6.798155367234455e-33 6.123233995736766e-17 1
2 1.110223024625157e-16 1 0
3 1 0 0
4 1.359631073446891e-32 1.224646799147353e-16 2
5 2.220446049250313e-16 2 0
...
In the header, between $PhysicalNames and $EndPhysicalNames, we see a block containing the mesh attributes. The number 5 indicates that there are a total of five records, which follow immediately after. The records are organized into three columns: the first column corresponds to the dimension of the entity to which each attribute relates (2 for two-dimensional entities, such as planes or boundaries, and 3 for three-dimensional bodies). The second column provides an integer attribute for a given entity, while the last column contains an optional string name. For example, in the above mesh, there is a boundary with the integer attribute 11 and the name “Bnd1,” as well as a volume with the integer attribute 101 and the name “Vol1”.
Defining Markers
In μfem we can mark a specific mesh entity in one of the following ways:
marker = 11 @ Bnd
This indicates that we are marking a boundary with the integer attribute 11.
marker = "Bnd1" @ Bnd
This signifies that we are marking a boundary with the string name attribute “Bnd1”.
marker = 101 @ Vol
This means that we are marking a volume with the integer attribute 101.
marker = "Vol1" @ Vol
This indicates that we are marking a volume with the string name attribute “Vol1”.
We can also mark multiple entities at once. For example, the following code creates a marker that marks two boundaries with the integer attributes 11 and 12:
marker = [11, 12] @ Bnd
Similarly, the following code achieves the same result for the boundaries with the string name attributes “Bnd1” and “Bnd2”:
marker = ["Bnd1", "Bnd2"] @ Bnd
In the same manner, we can create markers that refer to several volumes at once:
marker = [101, 102] @ Vol
or
marker = ["Vol1", "Vol2"] @ Vol
Using the “Everywhere” Keyword
In situations where we want to mark the entire computational domain or all the mesh boundaries, we can use a special keyword, mufem.Everywhere
.
For example, in the case of the above mesh file, the marker
marker = Everywhere @ Bnd
is equivalent to:
marker = [11, 12, 13] @ Bnd # or marker = ["Bnd1", "Bnd2", "Bnd3"] @ Bnd
Similarly, for volumes, we can use:
marker = Everywhere @ Vol
which is equivalent to:
marker = [101, 102] @ Vol # or marker = ["Vol1", "Vol2"] @ Vol
Using Regular Expressions
When a mesh has numerous attributes and we prefer not to list them all individually, we can define a marker using a regular expression (regex) pattern. For example, if we have a set of attributes with string names such as “Coil::Vol1”, “Coil::Vol2”, “Coil::Vol3”, and so on, we can create a marker that encompasses all these volumes as follows:
marker = Vol("Coil::.*")
In this case, the “.*” in the pattern “Coil::.*” acts as a placeholder, indicating that any string name starting with “Coil::” will be marked.
As another example, the following marker:
marker = Vol(".*")
is equivalent to:
marker = Everywhere @ Vol
Any valid regex patterns for attribute string names can be used to define markers. This approach offers greater flexibility and efficiency when managing a large number of mesh attributes.
Combining Markers
Markers can be combined to create a new marker that encompasses the attributes of both terms. For example, in the following code:
marker1 = 11 @ Bnd
marker2 = [12, 13] @ Bnd
marker = marker1 + marker2
The final marker will include all attributes 11, 12, and 13, which is equivalent to the following definition:
marker = [11, 12, 13] @ Bnd
Example
import mufem
sim = mufem.Simulation.New("My Case", f"data/geometry.mesh", print_only_warnings=True)
volume_marker = "MyVolume" @ mufem.Vol
boundary_marker = ["MyVolume::1::Boundary", "MyVolume::2::Boundary", "MyVolume::3::Boundary"] @ mufem.Bnd
print(volume_marker)
print(boundary_marker)
[1 (MyVolume )] @Vol
[1, 2, 3, 4, 5 (MyVolume::3::Boundary MyVolume::2::Boundary MyVolume::1::Boundary )] @Bnd