form - finite element bilinear form (rheolef-7.2)
Contents
Algebra
Forms, as matrix, support standard algebra. Adding or subtracting two forms writes a+b and a-b,
respectively, while multiplying by a scalar lambda writes lambda*a and multiplying two forms writes a*b.
Also, multiplying a form by a field uh writes a*uh. The form inversion is not as direct as e.g. as
inv(a), since forms are very large matrix in practice: form inversion can be obtained via the solver(4)
class. A notable exception is the case of block-diagonal forms at the element level: in that case, a
direct inversion is possible during the assembly process, see integrate_option(3).
Copyright
Copyright (C) 2000-2018 Pierre Saramito <Pierre.Saramito@imag.fr> GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and
redistribute it. There is NO WARRANTY, to the extent permitted by law.
rheolef Version 7.2 form(2rheolef)
Description
The form class groups four sparse matrix, associated to a bilinear form defined on two finite element
spaces:
a: Uh*Vh ----> IR
(uh,vh) +---> a(uh,vh)
The A operator associated to the bilinear form is defined by:
A: Uh ----> Vh
uh +---> A*uh
where uh is a field(2), and vh=A*uh in Vh is such that a(uh,vh)=dual(A*uh,vh) for all vh in Vh and where
dual(.,.) denotes the duality product between Vh and its dual. Since Vh is a finite dimensional space,
its dual is identified to Vh itself and the duality product is the euclidean product in IR^dim(Vh). Also,
the linear operator can be represented by a matrix.
In practice, bilinear forms are created by using the integrate(3) function.
Implementation
This documentation has been generated from file main/lib/form.h
The form class is simply an alias to the form_basicclass
typedef form_basic<Float,rheo_default_memory_model> form;
The form_basicclassprovidesaninterfacetofoursparsematrix:
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>&);
template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
form_basic (const Expr&);
template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
form_basic<T,M>& operator= (const Expr&);
// allocators from initializer list (c++ 2011):
form_basic (const std::initializer_list<details::form_concat_value<T,M> >& init_list);
form_basic (const std::initializer_list<details::form_concat_line <T,M> >& init_list);
// accessors:
const space_type& get_first_space() const;
const space_type& get_second_space() const;
const geo_type& get_geo() const;
bool is_symmetric() const;
void set_symmetry (bool is_symm = true) const;
bool is_definite_positive() const;
void set_definite_positive (bool is_dp = true) const;
bool is_symmetric_definite_positive() const;
void set_symmetric_definite_positive() 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; }
};
template<class T, class M> form_basic<T,M> trans (const form_basic<T,M>& a);
template<class T, class M> field_basic<T,M> diag (const form_basic<T,M>& a);
template<class T, class M> form_basic<T,M> diag (const field_basic<T,M>& dh);
Name
form - finite element bilinear form (rheolef-7.2)
Representation
The degrees of freedom (see space(2)) are splited between unknownsandblocked, i.e. uh=[uh.u,uh.b] for
any field uh in Uh. Conversely, vh=[vh.u,vh.b] for any field vh in Vh. Then, the form-field vh=a*uh
operation is formally equivalent to the following matrix-vector block operations:
[ vh.u ] [ a.uu a.ub ] [ uh.u ]
[ ] = [ ] [ ]
[ vh.b ] [ a.bu a.bb ] [ uh.n ]
or, after expansion:
vh.u = a.uu*uh.u + a.ub*vh.b
vh.b = a.bu*uh.b + a.bb*vh.b
i.e. the A matrix also admits a 2x2 block structure. Then, the form class is represented by four sparse
matrix and the csr(4) compressed format is used. Note that the previous formal relations for vh=a*uh
writes equivalently within the Rheolef library as:
vh.set_u() = a.uu()*uh.u() + a.ub()*uh.b();
vh.set_b() = a.bu()*uh.u() + a.bb()*uh.b();
