Fields

In physics, a field is a physical quantity, represented by a scalar, vector or tensor, that has a value for each point in space and time ([1]).

In the context of finite elements, a field is a scalar defined at each point inside (every or a selection of elements of) a discrete domain \(\Omega_h\). The discrete domain \(\Omega_h\) is, in fact, a finite element mesh (see Mesh).

The number of parameters (degrees of freedom or dofs) used to define the finite element field depends on the underlying interpolation functions (also called approximation space). These interpolation functions enable us to define the scalar at every point (not only the nodes) inside the domain.

Two types of operations (over fields) are often required to prepare, compute, and post-process a finite element problem:
  • Operations on the fields heavily related to the mesh: Creation, extraction…

  • Linear algebra operations over the arrays holding the values for each dof.

This means we have to keep track of the relationship between the mesh and the values for every shape function. This is done using the FEField class.

FEField

To fully define a FEField, it is necessary to fill all the following properties:

  • name, the name of the finite element field;

  • mesh, the mesh where the finite element field is defined;

  • space, the space of approximation used for describing the finite element field (see Lagrange Interpolation);

  • numbering, the numbering of the degrees of freedom (mapping from mesh to vector);

  • data, the field data (only scalar field).

Finite Element Field Class

Fig. 8 ULM Representation of a FEField, Example for a simple Lagrange P1 field.

Note

In Muscat, the fields are always scalar. The user can put two or more FEFields in a vector and use numpy for array/vector operations.

Name

The name of the field is an arbitrary user string (and can be different from the name of the Python variable holding the instance). It is worth noticing that operations on fields will generate new fields without names, and it is up to the user to name these new fields.

from Muscat.FE.Fields.FieldTools import CreateFieldFromDescription
myField = CreateFieldFromDescription(myMesh, (ElementFilter(), 125000))
myField.name = "E"
myNewField = myField**2
myNewField = "E^2"
In this example, we:
  • Create a FEField with the function CreateFieldFromDescription()

  • Name it to “E”

  • Compute a new FEField with the values of myField squared.

  • Name it to “E^2”

Mesh

The mesh to define the domain \(\Omega_h\).

Note

A reference to the mesh is kept, so any modification to the mesh after the definition of the FEField will invalidate the numbering and the data. Be careful to define your domain (nodes and elements insertions/deletions). Tags can be added/removed later to the mesh.

Space

The space used for the interpolation of the values inside the elements. The available spaces are:

  • LagrangeSpaceGeo - isoparametric Lagrange space (if the mesh is quadratic, the field is P2).

  • ConstantSpaceGlobal - global constant space. Used to integrate expression over a domain into a scalar.

  • LagrangeSpaceP0 - Degree 0 Lagrange space. This space is constant per element (one value per element).

  • LagrangeSpaceP1 - Degree 1 Lagrange space. This space implements linear interpolation functions.

  • LagrangeSpaceP2 - Degree 2 Lagrange space. This space implements quadratic interpolation functions.

  • LagrangeSpaceP2_incomplete - Incomplete (serendipity) degree 2 Lagrange space.

The user is free to choose any approximation space for the field. So a LagrangeSpaceP0 field can be used over a quadratic mesh to represent material properties, for example. Or a LagrangeSpaceP1 field can be used over a mixed Quadratic/linear mesh to represent a linear solution.

The shape functions are defined in the subpackage Muscat.FE.Spaces. In this package, different approximation spaces are defined for each type of element.

Numbering

The numbering is the mapping to find data (values for the dofs) from the geometrical entities. It stores the values indices for each element on the mesh (-1 if the element does not have values associated with its dofs). Because the number of dofs depends on the type of element, a dictionary-like structure is used.

The figure (ULM Representation of a FEField, Example for a simple Lagrange P1 field.) shows an example of a Lagrange P1 FEField (one value per node) over the full mesh. The numbering for the first quadrant is [0, 2, 11, 3]. This means the values for the 4 degrees of freedom of this element are stored in the positions 0, 2, 11, 3 of the vector data.

In Muscat, the computation of the numbering is done using DofNumbering.

The computation of the numbering requires:
  • Mesh: to define the domain to work on

  • FESpace: to recover the number of shape function (dofs) for every type of element

  • ElementFilter: (Optional) to define FEField to some restricted area of the mesh

Data

The attribute data stores the values of all the dofs for the field. It is always a 1D array of size the number of dofs of the field.

Muscat offers functions to allocate, fill, and extract information from/to this vector data.

Usage

This an example to initialize a FEField on a Muscat mesh Muscat.Containers.Mesh properly, firstly for an isoparametric field:

# By default, FEField uses LagrangeSpaceGeo isoparametric elements and compute the numbering vector for the field using the same numbering as the mesh

# The initialization of the FEField reads
myFEField = FEField(name='myFEField', mesh=myMesh)

It is also possible to define a FEField with a different space of approximation:

# Import the FESpace for P2 elements
from Muscat.FE.Spaces.FESpaces import LagrangeSpaceP2
# Compute the numbering vector for the field. Independent from the mesh numbering.
mynumbering = ComputeDofNumbering(mymesh, space=LagrangeSpaceP2)

# Initialization of the FEField
myFEField = FEField(name='myFEField', mesh=mymesh, space=myspace, numbering=mynumbering)

Then it is possible to allocate a value to the FEField, which consists of applying the value at each DOF:

myFEField.Allocate(value)

Users can manually set the data from a vector homogeneous to the mesh using the following method:

# Filling the FEField with userdata and complete - if datas are incomplete - other DOFs with fillvalue
myFEField.SetDataFromPointRepresentation(userdata, fillvalue)

Finally, it is possible to get the representation of the field on the mesh, especially at the nodes. This step is not necessary when using an isoparametric FEField with the numbering computed along the connectivity of the mesh.

# Filling the FEField with userdata and complete - if datas are incomplete - other DOFs with fillvalue
ValuesAtNodes = myFEField.GetPointRepresentation(fillvalue)

See more in Muscat.FE.Fields.FEField module.

A complete example is available in the Examples section.

IPField

When using a variational formulation to define a finite element problem, it is common to compute integrals over elements of the mesh. These integrals are computed using numerical integration (quadrature), which consists of a weighted sum of the field evaluation at the integration points. Sometimes, the quantity of interest is only available at these integration points, e.g. state variables (plasticity) in a classical mechanical problem.

The IPField class is an object that keeps information at integration points. In Muscat, there is a major difference between FEField and IPField objects. The FEField represents a finite element field over a mesh (evaluable everywhere), whereas the IPField is a collection of values at integration points. Thus, the FEField represents a real finite element field, whereas the IPField is just a point cloud.

To fully define a IPField, it is necessary to fill all the following properties:

  • Muscat.FE.Fields.IPField.IPField.name, the name of the finite element field;

  • Muscat.FE.Fields.IPField.IPField.mesh, the mesh where the finite element is defined;

  • Muscat.FE.Fields.IPField.IPField.ruleName, the name of the integration rule used for this field;

  • Muscat.FE.Fields.IPField.IPField.data, the field data at integration points (only scalar field).

FieldTools

The Muscat.FE.Fields.FieldTools module module contains functions for the manipulation of FEField or IPField and operations between fields. Users may read the associated documentation for more information.

Footnotes