Filters
Filters (by nodes, elements and operators) are objects used to select nodes/elements of a mesh based on filter parameters. In Muscat, we have two categories:
Filter objects (:py:class`~Muscat.Containers.Filters.FilterObjects.ElementFilter`,
Muscat.Containers.Filters.FilterObjects.NodeFilter
) for selecting nodes or elements.Filter operators (
FilterOperators
) for constructing complex expressions (unions, intersections, etc.).
Node Filter
The class Muscat.Containers.Filters.FilterObjects.NodeFilter
implements the nodal filter.
To create a basic NodeFilter that selects all the nodes, you can use the following code:
nf = NodeFilter()
nIndices = nf.GetNodesIndices(myMesh)
The function GetNodesIndices returns a list of all the node indices selected by the filter on the mesh (myMesh). In this case, all the nodes are selected.
Here’s a more complex case: Selecting all the nodes with the nodal tag “Dirichlet”, the nodes of the surface elements with the tag “Forces”, and with a negative X coordinate.
nf = NodeFilter(nTag="Dirichlet", eTag="Forces", zone= lambda x: x[:,0] < 0 )
nIndices = nf.GetNodesIndices(myMesh)
Note
The function provided (zone argument) must accept a 2D numpy array containing the coordinates to be tested, and it must return a 1D boolean array.
Element Filter
The class Muscat.Containers.Filters.FilterObjects.ElementFilter
implements the element filter.
To create a basic ElementFilter that selects all the elements, you can use the following code:
ef = ElementFilter()
for selection in ef(myMesh):
currentElementType = selection.elementType
currenIndices = selection.indices
...
Due to the complexity of element storage, performing operations on the selection requires a bit more work.
The ‘for’ loop is necessary to iterate for each element type, and the selection (instance of ElementsSelection
) stores all the necessary information to extract the index slices and some extra data for the current element type.
Here’s a more complex example: Selecting the 2D elements connected to the node tag “Dirichlet” by all the nodes.
ef = ElementFilter(dimensionality=2, nTag="Dirichlet", nTagsTreatment="ALL_NODES")
counter = 0
for selection in ef(myMesh):
counter += selection.Size()
print(f"{counter} 2D elements on the mesh fully connected to nodes 'Dirichlet' ")
The element filter implements the NodeFilter interface. In this case, the filter returns all the nodes used by the selected elements.
ef = ElementFilter(dimensionality=2, nTag="Dirichlet", nTagsTreatment="AT_LEAST_ONE")
counter = 0
for selection in ef(myMesh):
counter += selection.Size()
print(f"{counter} 2D elements on the mesh connected by at least one node to the 'Dirichlet' node tag")
nodeUsedByTheSelection = ef.GetNodesIndices(myMesh)
print(f"{len(nodeUsedByTheSelection)} nodes used by the elements in the selection. Some of these nodes are not present in the 'Dirichlet' tag")
Filter Operators
Filter operators perform operations on one or more filters. The main operators are:
UnionFilter
: for the union of node or element filters.
IntersectionFilter
: for the intersection of node or element filters.
DifferenceFilter
: for the difference of node or element filters
ComplementaryFilter
: to compute the complementary part of a node or element filter
FrozenFilter
: to evaluate the filter once and store the selection in an internal cache for later use.
FilterWithMesh
: to lock an initial mesh for a filter and ignore later meshes.
PartialFilter
: to create a partial selection of a filter.
These operators behave like a NodeFilter or ElementFilter and can be used in any function operation on filters.
Here’s an example of a filter that selects only the bars and the triangles.
f1 = ElementFilter(elementType=ED.Bar_2)
f2 = ElementFilter(elementType=ED.Triangle_3)
uf1 = UnionFilter(filters=[f1, f2])
Note
Do not mix a NodeFilter with an ElementFilter in an operator if you intend to use the ElementFilter interface. The NodeFilter does not implement the iterator over the elements.