Man pages sections > man2 > form

# form - representation of a finite element bilinear form

 form(2rheolef) rheolef-6.7 form(2rheolef)

## NAME

form - representation of a finite element bilinear form

## DESCRIPTION

The form class groups four sparse matrix, associated to a bilinear form on two finite element spaces:

```       a: U*V   ----> IR
(u,v)  |---> a(u,v)

```
The operator A associated to the bilinear form is defined by:

```       A: U  ----> V'
u  |---> A(u)

```
where u and v are fields (see field(2)), and A(u) is such that a(u,v)=<A(u),v> for all u in U and v in V and where <.,.> denotes the duality product between V and V'. Since V is a finite dimensional spaces, the duality product is the euclidian product in IR^dim(V).
Since both U and V are finite dimensional spaces, the linear operator can be represented by a matrix. The form class is represented by four sparse matrix in csr format (see csr(2)), associated to unknown and blocked degrees of freedom of origin and destination spaces (see space(2)).

## EXAMPLE

The operator A associated to a bilinear form a(.,.) by the relation (Au,v) = a(u,v) could be applied by using a sample matrix notation A*u, as shown by the following code:

```      geo omega("square");
space V (omega,"P1");
field uh = interpolate (fct, V);
field vh = a*uh;
cout << v;

```
The form-field vh=a*uh operation is equivalent to the following matrix-vector operations:

```     vh.set_u() = a.uu()*uh.u() + a.ub()*uh.b();
vh.set_b() = a.bu()*uh.u() + a.bb()*uh.b();

```

## ALGEBRA

Forms, as matrices (see csr(2)), support linear algebra: Adding or substracting two forms writes a+b and a-b, respectively, and multiplying a form by a field uh writes a*uh. Thus, any linear combination of forms is available.

## WEIGHTED FORM

A weighted form is a form with an extra weight function w(x), e.g.:

```                   /
|
|
/ Omega

```
In the present implementation, w can be any field, function or class-function or any nonlinear field expression (see field(2)). As the integration cannot be performed exactly in general, a quadrature formula can be supplied. This feature is extensively used when solving nonlinear problems.

## IMPLEMENTATION

```template<class T, class M>
class form_basic {
public :
// typedefs:

typedef typename csr<T,M>::size_type    size_type;
typedef T                               value_type;
typedef typename scalar_traits<T>::type float_type;
typedef geo_basic<float_type,M>         geo_type;
typedef space_basic<float_type,M>       space_type;

// allocator/deallocator:

form_basic ();
form_basic (const form_basic<T,M>&);
form_basic<T,M>& operator= (const form_basic<T,M>&);

// allocators from initializer list (c++ 2011):

#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
form_basic (const std::initializer_list<form_concat_value<T,M> >& init_list);
form_basic (const std::initializer_list<form_concat_line <T,M> >& init_list);
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST

// accessors:

const space_type& get_first_space() const;
const space_type& get_second_space() const;
const geo_type&   get_geo() const;

const communicator& comm() const;

// linear algebra:

form_basic<T,M>  operator+  (const form_basic<T,M>& b) const;
form_basic<T,M>  operator-  (const form_basic<T,M>& b) const;
form_basic<T,M>  operator*  (const form_basic<T,M>& b) const;
form_basic<T,M>& operator*= (const T& lambda);
field_basic<T,M> operator*  (const field_basic<T,M>& xh) const;
field_basic<T,M> trans_mult (const field_basic<T,M>& yh) const;
float_type operator () (const field_basic<T,M>& uh, const field_basic<T,M>& vh) const;

// io:

odiststream& put (odiststream& ops, bool show_partition = true) const;
void dump (std::string name) const;

// accessors & modifiers to unknown & blocked parts:

const csr<T,M>&     uu() const { return _uu; }
const csr<T,M>&     ub() const { return _ub; }
const csr<T,M>&     bu() const { return _bu; }
const csr<T,M>&     bb() const { return _bb; }
csr<T,M>& set_uu()       { return _uu; }
csr<T,M>& set_ub()       { return _ub; }
csr<T,M>& set_bu()       { return _bu; }
csr<T,M>& set_bb()       { return _bb; }

// data
protected:
space_type  _X;
space_type  _Y;
csr<T,M>    _uu;
csr<T,M>    _ub;
csr<T,M>    _bu;
csr<T,M>    _bb;

// internals:
public:
// with vf expression arg
template <class Expr>
void assembly_internal (
const geo_basic<T,M>&         dom,
const geo_basic<T,M>&         band,
const band_basic<T,M>&        gh,
const Expr&                   expr,
const form_option_type&       fopt,
bool                          is_on_band);
template <class Expr>
void assembly (
const geo_basic<T,M>&         domain,
const Expr&                   expr,
const form_option_type&       fopt);
template <class Expr>
void assembly (
const band_basic<T,M>&        gh,
const Expr&                   expr,
const form_option_type&       fopt);

// backward compat: named forms
form_basic (const space_type& X, const space_type& Y,
const std::string& name = "",

form_basic (const space_type& X, const space_type& Y,
const std::string& name,
const field_basic<T,M>& weight,

template<class Function>
form_basic (const space_type& X, const space_type& Y,
const std::string& name,
Function weight,

form_basic (const space_type& X, const space_type& Y,
const std::string& name,
const geo_basic<T,M>& gamma,

form_basic (const space_type& X, const space_type& Y,
const std::string& name,
const geo_basic<T,M>& gamma,
const field_basic<T,M>& weight,

template<class Function>
form_basic (
const space_type& X,
const space_type& Y,
const std::string& name,
const geo_basic<T,M>& gamma,
Function weight,
protected:
// backward compat: named forms (cont.)
template<class WeightFunction>
void form_init (
const std::string&      name,
bool                    has_weight,
WeightFunction          weight,
template<class WeightFunction>
void form_init_on_domain (
const std::string&      name,
const geo_basic<T,M>&   gamma,
bool                    has_weight,
WeightFunction          weight,
const geo_basic<T,M>&   w_omega, // the domain where the fct weight is defined