mimetic2d#
Most of the module is in the process of getting refactored into others.
Previously, code was written with element objects, which were used to
hold element relations. These are now all handled by
mfv2d.element.ElementCollection
.
Incidence Functions#
While these are not used internally, when it comes to testing these functions play a very important role. They are not fast nor are they efficient, their main purpose is to be used in tests to validate that operations done in C are correct. If they were to be rewritten to allow different polynomial order in each dimension, it would allow the code to deal with mixed-order elements.
Generating Matrices#
These directly generate the incidence matrices.
- mfv2d.mimetic2d.incidence_10(order: int) npt.NDArray[np.float64] [source]#
Incidence matrix from 0.forms to 1-forms.
This applies the exterior derivative operation to primal 0-forms and maps them into 1-forms. The negative transpose is the equivalent operation for the dual 1-forms, the derivatives of which are consequently dual 2-forms.
This is done by mapping degrees of freedom of the original primal 0-form or dual 1-form into those of the derivative primal 1-forms or dual 2-forms respectively.
\[\vec{\mathcal{N}}^{(1)}(f) = \mathbb{E}^{(1,0)} \vec{\mathcal{N}}^{(0)}(f)\]\[\tilde{\mathcal{N}}^{(2)}(f) = -\left(\mathbb{E}^{(1,0)}\right)^{T} \tilde{\mathcal{N}}^{(1)}(f)\]- Returns:
Incidence matrix \(\mathbb{E}^{(1,0)}\).
- Return type:
array
- mfv2d.mimetic2d.incidence_21(order: int) npt.NDArray[np.float64] [source]#
Incidence matrix from 1-forms to 2-forms.
This applies the exterior derivative operation to primal 1-forms and maps them into 2-forms. The negative transpose is the equivalent operation for the dual 0-forms, the derivatives of which are consequently dual 1-forms.
This is done by mapping degrees of freedom of the original primal 1-form or dual 0-form into those of the derivative primal 2-forms or dual 1-forms respectively.
\[\vec{\mathcal{N}}^{(2)}(f) = \mathbb{E}^{(2,1)} \vec{\mathcal{N}}^{(1)}(f)\]\[\tilde{\mathcal{N}}^{(1)}(f) = -\left(\mathbb{E}^{(2,1)}\right)^{T} \tilde{\mathcal{N}}^{(0)}(f)\]- Returns:
Incidence matrix \(\mathbb{E}^{(2,1)}\).
- Return type:
array
Applying Matrices#
Since C code does not explicitly compute incidnece matrices unless necessary, these are a lot more commonly used. Here they are written very explicitly, so that they can be translated into C almost line by line.
- mfv2d.mimetic2d.apply_e10(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the E10 matrix to the given input.
Calling this function is equivalent to left multiplying by E10.
- mfv2d.mimetic2d.apply_e10_t(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the E10 transpose matrix to the given input.
Calling this function is equivalent to left multiplying by E10 transposed.
- mfv2d.mimetic2d.apply_e10_r(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the right E10 matrix to the given input.
Calling this function is equivalent to right multiplying by E10.
- mfv2d.mimetic2d.apply_e10_rt(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the right transposed E10 matrix to the given input.
Calling this function is equivalent to right multiplying by E10 transposed.
- mfv2d.mimetic2d.apply_e21(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the E21 matrix to the given input.
Calling this function is equivalent to left multiplying by E21.
- mfv2d.mimetic2d.apply_e21_t(order: int, other: npt.NDArray[np.float64]) npt.NDArray[np.float64] [source]#
Apply the E21 transposed matrix to the given input.
Calling this function is equivalent to left multiplying by E21 transposed.
Mesh Geometry#
Mesh geometry is handled by the Mesh2D
type. This uses
mfv2d._mfv2d.Manifold2D
to store its topology and its dual topology,
but also contains geometry. It is also equiped with helper methods for
obtaining elements and plotting with pyvista
.
- class mfv2d.mimetic2d.Mesh2D(order: int | Sequence[int] | npt.ArrayLike, positions: Sequence[tuple[float, float, float]] | Sequence[Sequence[float]] | Sequence[npt.ArrayLike] | npt.ArrayLike, lines: Sequence[tuple[int, int]] | Sequence[npt.ArrayLike] | Sequence[Sequence[int]] | npt.ArrayLike, surfaces: Sequence[tuple[int, ...]] | Sequence[Sequence[int]] | Sequence[npt.ArrayLike] | npt.ArrayLike)[source]#
Two dimensional manifold with associated geometry.
Mesh holds the primal manifold, which describes the topology of surfaces and lines that make it up. It also contains the dual mesh, which contains duals of all primal geometrical objects. The dual is useful when connectivity is needed.
- Parameters:
order (int or Sequence of int or array-like) – Orders of elements. If a single value is specified, then the same order is used for all elements. If a sequence is specified, then each element is given that order.
positions ((N, 2) array-like) – Positions of the nodes.
lines ((N, 2) array-like) – Lines of the mesh specified as pairs of nodes connected. These use 1-based indexing.
surfaces ((N, 4) array-like) – Surfaces of the mesh specified in their positive orientation as 1-based indices of lines that make up the surface, with negative sign indicating reverse direction.
- boundary_indices: ndarray[tuple[Any, ...], dtype[int32]]#
Indices of lines that make up the boundary of the mesh. These can be useful when prescribing boundary conditions.
- dual: Manifold2D#
Dual topology of the mesh.
- primal: Manifold2D#
Primal topology of the mesh.
- surface_to_element(idx: int, /) ElementLeaf2D [source]#
Create a 2D element from a surface with the given index.
- Parameters:
idx (int) – Index of the surface.
- Returns:
Leaf element with the geometry of the specified surface.
- Return type:
Elements#
Surfaces of the mesh can be converted into computational elements. These
can either be leaf elements, with the type ElementLeaf2D
, or
nodes, which contain other nodes or leaves, with the type
ElementNode2D
. Both are subtypes of Element2D
, which
only contains the information about the parent.
- class mfv2d.mimetic2d.ElementLeaf2D(parent: ElementNode2D | None, order: int, bottom_left: tuple[float, float], bottom_right: tuple[float, float], top_right: tuple[float, float], top_left: tuple[float, float])[source]#
Two dimensional square element.
This type facilitates operations related to calculations which need to be carried out on the reference element itself, such as calculation of the mass and incidence matrices, as well as the reconstruction of the solution.
- Parameters:
order_h (int) – Order of the basis functions used for the nodal basis in the first dimension.
order_v (int) – Order of the basis functions used for the nodal basis in the second dimension.
bottom_left ((float, float)) – Coordinates of the bottom left corner.
bottom_right ((float, float)) – Coordinates of the bottom right corner.
top_right ((float, float)) – Coordinates of the top right corner.
top_left ((float, float)) – Coordinates of the top left corner.
- divide(order_bl: int, order_br: int, order_tl: int, order_tr: int) tuple[ElementNode2D, tuple[tuple[ElementLeaf2D, ElementLeaf2D], tuple[ElementLeaf2D, ElementLeaf2D]]] [source]#
Divide the element into four child elements of the specified order.
- Parameters:
- Returns:
ElementNode2D – Parent element which contains the nodes.
(2, 2) tuple of ElementLeaf2D – Child elements of the same order as the element itself. Indexing the tuple will give bottom/top for the first axis and left/right for the second.
- parent: ElementNode2D | None#
- class mfv2d.mimetic2d.ElementNode2D(parent: ElementNode2D | None, child_bl: Element2D, child_br: Element2D, child_tl: Element2D, child_tr: Element2D)[source]#
Two dimensional element that contains children.
- children() tuple[Element2D, Element2D, Element2D, Element2D] [source]#
Return children of the element ordered.
- parent: ElementNode2D | None#
- class mfv2d.mimetic2d.Element2D(parent: ElementNode2D | None)[source]#
General 2D element.
- parent: ElementNode2D | None#
Element Sides#
Many functions have to perform operations on boundaries of the elements. To
make this easier to type check, the type ElementSide
is introduced.
This is an enum.IntEnum
subtype with only four values and is used
everywhere when a side of an element is an input of any function.
- class mfv2d.mimetic2d.ElementSide(*values)[source]#
Enum specifying the side of an element.
- SIDE_BOTTOM = 1#
- SIDE_RIGHT = 2#
- SIDE_TOP = 3#
- SIDE_LEFT = 4#
- property next: ElementSide#
Next side.
- property prev: ElementSide#
Previous side.
To help identify what side a Line
with a specific index
of a Surface
is from, the function
find_surface_boundary_id_line()
is given.
- mfv2d.mimetic2d.find_surface_boundary_id_line(s: Surface, i: int) ElementSide [source]#
Find what boundary the line with a given index is in the surface.
Caching Basis#
Since only a handful of basis and integration orders are ever used in the solve
and creating mfv2d._mfv2d.Basis1D
and
mfv2d._mfv2d.IntegrationRule1D
both is not extremely cheap, the
FemCache
is introduced to deal with caching them. It does not
deal with caching mfv2d._mfv2d.Basis2D
objects, since they are
just containers for two objects and so are not a significant cost to newly
construct each time.
- class mfv2d.mimetic2d.FemCache(order_difference: int)[source]#
Cache for integration rules and basis functions.
This type allows for caching 1D integration rules and 1D basis. The 2D basis are not cached, since the
Basis2D
is just a container for two 1D Basis objects, so it is probably just as cheap to create a new one as it would be to cache it.- Parameters:
order_difference (int) – Difference of orders between the integration rule and the basis in the case that it is not specified.
- get_basis1d(order: int, int_order: int | None = None) Basis1D [source]#
Get requested one-dimensional basis.
- get_basis2d(order1: int, order2: int, int_order1: int | None = None, int_order2: int | None = None) Basis2D [source]#
Get two-dimensional basis.
These are not cached, since there is zero calculations involved in their computations.
- Parameters:
order1 (int) – Order of basis in the first dimension.
order2 (int) – Order of basis in the second dimension.
int_order1 (int, optional) – Order of the integration rule in the first direction. If unspecified, it defaults to
order1 + self.order_diff
.int_order2 (int, optional) – Order of the integration rule in the second direction. If unspecified, it defaults to
order2 + self.order_diff
.
- Returns:
Requested two-dimensional basis.
- Return type:
- get_integration_rule(order: int) IntegrationRule1D [source]#
Return integration rule.
- Parameters:
order (int) – Order of integration rule to use.
- Returns:
Integration rule that was obtained from cache or created and cached if it was previously not there.
- Return type:
- get_mass_inverse_1d_edge(order: int) npt.NDArray[np.float64] [source]#
Get the 1D edge mass matrix inverse.