`field`

piecewise polynomial finite element function

# Description

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`).

# Interpolation

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

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)`.

# Common accessors

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 algebra

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.

# Access by domain

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;

# Multi-valued fields

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);

# General space product interface

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.

# Direct access to degrees-of-freedom

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.

# Representation

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;

# Implementation

This documentation has been generated from file main/lib/field.h

The `field` class is simply an alias to the `field_basic` class

typedef field_basic<Float> field;

The `field_basic` class provides an interface to a vector data container:

template <class T, class M = rheo_default_memory_model>
class field_basic {
public :
// typedefs:
using size_type = std::size_t;
using memory_type = M;
using value_type = T; // TODO: run-time dependent
using result_type = T; // TODO: run-time dependent
// using value_type = undeterminated_basic<T>; // TODO
using scalar_type = T;
using float_type = typename float_traits<T>::type;
using valued_type = space_constant::valued_type;
using geo_type = geo_basic <float_type,M>;
using space_type = space_basic<float_type,M>;
using dis_reference = typename vec<T,M>::dis_reference;
class iterator;
class const_iterator;
// allocator/deallocator:
field_basic();
explicit field_basic (
const space_type& V,
const T& init_value = std::numeric_limits<T>::max());
void resize (
const space_type& V,
const T& init_value = std::numeric_limits<T>::max());
// expressions:
template <class Expr, class Sfinae =
typename std::enable_if<
details::is_field_expr_affine_homogeneous<Expr>::value
&& ! details::is_field<Expr>::value>::type>
field_basic (const Expr& expr);
// initializer list (c++ 2011):
field_basic (const std::initializer_list<details::field_concat_value<T,M> >& init_list);
// assignments:
field_basic<T,M>& operator= (const field_basic<T,M>&);
template <class Value>
typename std::enable_if<
details::is_rheolef_arithmetic<Value>::value
,field_basic<T,M>&
>::type
operator= (const Value& value);
template <class Expr>
typename std::enable_if<
details::is_field_expr_affine_homogeneous<Expr>::value
&& ! details::is_field_expr_v2_constant <Expr>::value
&& ! details::is_field <Expr>::value
,field_basic<T, M>&>::type
operator= (const Expr&);
// initializer list (c++ 2011):
field_basic<T,M>& operator= (const std::initializer_list<details::field_concat_value<T,M> >& init_list);
// accessors:
const space_type& get_space() const { return _V; }
const geo_type& get_geo() const { return _V.get_geo(); }
std::string name() const { return _V.name(); }
std::string get_approx() const { return _V.get_approx(); }
valued_type valued_tag() const { return _V.valued_tag(); }
const std::string& valued() const { return _V.valued(); }
bool have_homogeneous_space (space_basic<T,M>& Xh) const { Xh = get_space(); return true; }
// accessors & modifiers to unknown & blocked parts:
const vec<T,M>& u() const { return _u; }
const vec<T,M>& b() const { return _b; }
vec<T,M>& set_u() { dis_dof_indexes_requires_update(); return _u; }
vec<T,M>& set_b() { dis_dof_indexes_requires_update(); return _b; }
// accessors to extremas:
T min() const;
T max() const;
T max_abs() const;
T min_abs() const;
// accessors by domains:
field_indirect<T,M> operator[] (const geo_basic<T,M>& dom);
field_indirect_const<T,M> operator[] (const geo_basic<T,M>& dom) const;
field_indirect<T,M> operator[] (std::string dom_name);
field_indirect_const<T,M> operator[] (std::string dom_name) const;
// accessors by components:
size_type size() const { return _V.size(); }
field_component<T,M> operator[] (size_type i_comp);
field_component_const<T,M> operator[] (size_type i_comp) const;
field_component<T,M> operator() (size_type i_comp, size_type j_comp);
field_component_const<T,M> operator() (size_type i_comp, size_type j_comp) const;
// accessors by degrees-of-freedom (dof):
const distributor& ownership() const { return get_space().ownership(); }
const communicator& comm() const { return ownership().comm(); }
size_type ndof() const { return ownership().size(); }
size_type dis_ndof() const { return ownership().dis_size(); }
T& dof (size_type idof);
const T& dof (size_type idof) const;
const T& dis_dof (size_type dis_idof) const;
// write access to non-local dis_idof changes to others procs
dis_reference dis_dof_entry (size_type dis_idof);
iterator begin_dof();
iterator end_dof();
const_iterator begin_dof() const;
const_iterator end_dof() const;
// input/output:
idiststream& get (idiststream& ips);
odiststream& put (odiststream& ops) const;
odiststream& put_field (odiststream& ops) const;
// evaluate uh(x) where x is given locally as hat_x in K:
T dis_evaluate (const point_basic<T>& x, size_type i_comp = 0) const;
T operator() (const point_basic<T>& x) const { return dis_evaluate (x,0); }
point_basic<T> dis_vector_evaluate (const point_basic<T>& x) const;
};
rheolef::field_basic::get_space
const space_type & get_space() const
Definition: field.h:300
rheolef::field_basic::get_approx
std::string get_approx() const
Definition: field.h:303
rheolef::field_basic::ownership
const distributor & ownership() const
Definition: field.h:339
mkgeo_ball.expr
expr
Definition: mkgeo_ball.sh:361
rheolef::field_basic::dis_vector_evaluate
point_basic< T > dis_vector_evaluate(const point_basic< T > &x) const
Definition: field.cc:490
rheolef::field_basic::comm
const communicator & comm() const
Definition: field.h:340
rheolef::distributor::comm
const communicator_type & comm() const
Definition: distributor.h:145
rheolef::field
field_basic< Float > field
see the field page for the full documentation
Definition: field.h:419
rheolef::value
rheolef::std value
rheolef::field_basic::float_type
typename float_traits< T >::type float_type
Definition: field.h:245
rheolef::field_basic::ndof
size_type ndof() const
Definition: field.h:341
rheolef::field_basic::name
std::string name() const
Definition: field.h:302
rheolef::field_basic::min_abs
T min_abs() const
Definition: field.h:715
rheolef::space_constant::valued_type
valued_type
Definition: space_constant.h:135
rheolef::space_numbering::dis_idof
void dis_idof(const basis_basic< T > &b, const geo_size &gs, const geo_element &K, typename std::vector< size_type >::iterator dis_idof_tab)
Definition: space_numbering.cc:187
rheolef::field_basic::result_type
T result_type
Definition: field.h:242
rheolef::field_basic::dis_dof
const T & dis_dof(size_type dis_idof) const
Definition: field.cc:376
rheolef::field_basic::u
const vec< T, M > & u() const
Definition: field.h:310
rheolef::field_basic::valued_type
space_constant::valued_type valued_type
Definition: field.h:246
rheolef::field_basic::field_basic
field_basic()
Definition: field.h:608
rheolef::field_basic::dis_dof_entry
dis_reference dis_dof_entry(size_type dis_idof)
Definition: field.cc:397
rheolef::field_basic::value_type
T value_type
Definition: field.h:241
rheolef::field_basic::get_geo
const geo_type & get_geo() const
Definition: field.h:301
rheolef::field_basic::resize
void resize(const space_type &V, const T &init_value=std::numeric_limits< T >::max())
Definition: field.cc:48
rheolef::field_basic::_V
space_type _V
Definition: field.h:403
rheolef::field_basic::set_u
vec< T, M > & set_u()
Definition: field.h:312
rheolef::field_basic::set_b
vec< T, M > & set_b()
Definition: field.h:313
rheolef::field_basic::valued_tag
valued_type valued_tag() const
Definition: field.h:304
rheolef::field_basic::min
T min() const
Definition: field.h:683
rheolef::type
rheolef::std type
rheolef::field_basic::max
T max() const
Definition: field.h:699
rheolef::field_basic::dof
T & dof(size_type idof)
Definition: field.h:658
rheolef::field_basic::end_dof
iterator end_dof()
Definition: field.h:509
rheolef::field_basic::_b
vec< T, M > _b
Definition: field.h:405
rheolef::field_basic::scalar_type
T scalar_type
Definition: field.h:244
rheolef::field_basic::begin_dof
iterator begin_dof()
Definition: field.h:501
rheolef::float_traits::type
T type
Definition: Float.h:94
rheolef::distributor::dis_size
size_type dis_size() const
global and local sizes
Definition: distributor.h:207
rheolef::field_basic::put_field
odiststream & put_field(odiststream &ops) const
Definition: field.cc:302
rheolef::field_basic::space_type
space_basic< float_type, M > space_type
Definition: field.h:248
rheolef::field_basic::dis_ndof
size_type dis_ndof() const
Definition: field.h:342
rheolef::point_basic< T >
point_basic< T >
Definition: piola_fem.h:135
rheolef::field_basic::valued
const std::string & valued() const
Definition: field.h:305
rheolef::field_basic::_u
vec< T, M > _u
Definition: field.h:404
rheolef::field_basic::have_homogeneous_space
bool have_homogeneous_space(space_basic< T, M > &Xh) const
Definition: field.h:306
rheolef::field_basic::b
const vec< T, M > & b() const
Definition: field.h:311
size_type
field::size_type size_type
Definition: branch.cc:425
rheolef::field_basic::operator()
field_component< T, M > operator()(size_type i_comp, size_type j_comp)
Definition: field.cc:508
rheolef::field_basic::operator[]
field_indirect< T, M > operator[](const geo_basic< T, M > &dom)
Definition: field_indirect.h:158
rheolef::field_basic::memory_type
M memory_type
Definition: field.h:240
rheolef::field_basic::dis_evaluate
T dis_evaluate(const point_basic< T > &x, size_type i_comp=0) const
Definition: field.cc:460
rheolef::field_basic::dis_dof_indexes_requires_update
void dis_dof_indexes_requires_update() const
Definition: field.h:630
rheolef::field_basic::operator=
field_basic< T, M > & operator=(const field_basic< T, M > &)
Definition: field.h:619
rheolef::field_basic::size
size_type size() const
Definition: field.h:331
rheolef::field_basic::put
odiststream & put(odiststream &ops) const
Definition: field.cc:366
rheolef::field_basic::geo_type
geo_basic< float_type, M > geo_type
Definition: field.h:247
rheolef::field_basic::max_abs
T max_abs() const
Definition: field.h:731
rheolef::field_basic::get
idiststream & get(idiststream &ips)
Definition: field.cc:121
M
Expr1::memory_type M
Definition: vec_expr_v2.h:385
rheolef::distributor::size
size_type size(size_type iproc) const
Definition: distributor.h:163
rheolef::field_basic::dis_reference
typename vec< T, M >::dis_reference dis_reference
Definition: field.h:249
T
Expr1::float_type T
Definition: field_expr.h:218