Rheolef
7.2
an efficient C++ finite element environment
|
piecewise polynomial finite element function
This class represents a piecewise polynomial finite element function. Since this function spans onto a finite dimensional basis, it simply stores its coefficients on this basis: these coefficients are called the degrees of freedom (see space
).
For any function u
, its interpolation on the finite element space Xh
as a field uh in Xh
expresses simply via the interpolate
function:
Float u (const point& x) { return exp(x[0]*x[1]); } ... field uh = interpolate (Xh, u);
Linear algebra, such as uh+vh
, uh-vh
and lambda*uh + mu*vh
, where lambda
and mu
are of type Float
, are supported. The duality product between two fields lh
and uh
writes simply dual(lh,uh)
. As we consider finite dimensional spaces, this duality product coincides with the usual Euclidean dot product in IR^dim(Xh)
. The application of the a
bilinear form
writes a(uh,vh)
and is equivalent to dual(m*uh,vh)
.
For convenience, uh.max()
, uh.min()
and uh.max_abs()
returns respectively the maximum, minimum and maximum of the absolute value of the degrees of freedom.
Non-linear operations, such as sqrt(uh)
or 1/uh
are also available. Note that non-linear operations do not returns in general piecewise polynomials: the value returned by sqrt(uh)
may be filtered by interpolate
function:
field vh = interpolate (Xh, sqrt(uh));
Also, the multiplication uh*vh
and the division uh/vh
returns a result that is not in the same discrete finite element space: its result also may be filtered by interpolate
`:
field wh = interpolate(Xh, uh*vh);
All standard unary and binary math functions abs, cos, sin
... are extended to scalar fields. Also sqr(uh)
, the square of a field, and min(uh,vh)
, max(uh,vh)
are provided. Binary functions can be used also with a scalar, as in
field vh = interpolate (Xh, max (abs(uh), 0)); field wh = interpolate (Xh, pow (abs(uh), 1./3));
For applying a user-provided function to a field, please see the compose
function.
The restriction of a field to a geometric domain, says "boundary"
writes uh["boundary"]
: it represents the trace of the field on the boundary:
space Xh (omega, "P1"); uh["boundary"] = 0;
A possible alternative uses a geo
domain as index:
geo boundary = omega["boundary"]; uh[boundary] = 0;
A vector-valued field contains several components, as:
space Xh (omega, "P2", "vector"); field uh (Xh);
Conversely, for a tensor-valued field:
space Th (omega, "P1d", "tensor"); field sigma_h (Xh);
A general multi-component field writes:
space Th (omega, "P1d", "tensor"); space Vh (omega, "P2", "vector"); space Qh (omega, "P1"); space Xh = Th*Vh*Qh; field xh (Xh); field tau_h = xh[0]; // tensor-valued field uh = xh[1]; // vector-valued field qh = xh[2]; // scalar
Remark the hierarchical multi-component field structure: the first-component is tensor-valued and the second-one is vector-valued. There is no limitation upon the hierarchical number of levels in use: the hierarchy is not flattened.
The xh.size()
returns the number of field components. When the field is scalar, it returns zero by convention, and xh[0]
is undefined.
The field class provides a STL-like container interface for accessing the degrees-of-freedom (dofs) of a finite element field uh
. The number of dofs is uh.ndof()
and any dof can be accessed via uh.dof(idof)
. In a distributed memory environment, a non-local dof at the partition interface can be obtain via uh.dis_dof(dis_idof)
where dis_idof
is the (global) distributed index assoiated to the distribution uh.ownership()
. See distributor
.
For better performances, a STL-like iterator interface is available, with uh.begin_dof()
and uh.end_dof()
returns iterators to the dofs on the current processor.
The degrees of freedom (see space
) are splited between unknowns and blocked, i.e. uh=[uh.u,uh.b]
for any field uh in Xh
. Access to these vectors is allowed via some accessors: a read-only one, as uh.u()
and uh.b()
, and a read-and-write one, as uh.set_u()
and uh.set_b()
, see vec
.
Note that blocked and unknown degrees of freedom could also be elegantly set by using a domain name indexation (see geo
):
geo omega ("circle"); space Xh (omega, "P1"); Xh.block ("boundary"); field uh (Xh); uh ["boundary"] = 0;
This documentation has been generated from file main/lib/field.h
The field
class is simply an alias to the field_basic
class
The field_basic
class provides an interface to a vector data container: