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:
This indicates that we are marking a boundary with the integer attribute 11.
This signifies that we are marking a boundary with the string name attribute "Bnd1".
This means that we are marking a volume with the integer attribute 101.
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:
Similarly, the following code achieves the same result for the boundaries with the string name attributes "Bnd1" and "Bnd2":
In the same manner, we can create markers that refer to several volumes at once:
or
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 Everywhere.
For example, in the case of the above mesh file, the marker
is equivalent to:
Similarly, for volumes, we can use:
which is equivalent to:
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:
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:
is equivalent to:
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:
The final marker will include all attributes 11, 12, and 13, which is equivalent to the following definition:
Example¶
import mufem
sim = mufem.Simulation.New(
name="My Case", mesh_path="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)