Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
<tt>form_lazy_expr</tt>

form expressions: concept and class hierarchy

Description

This page explains the design of the class hierarchy used for the representation of form expressions and how they fit together. Casual users probably need not concern themselves with these details, but it may be useful for both advanced users and Rheolef's developers.

Expression features

Expressions involving forms are computed in a lazy way: nothing is done until a conversion to the form class is explicitly required. Recall that form are represented by distributed sparse matrix. This approach allows many memory and computing time optimizations. Moreover, it enable new features, such as matrix inversion on the fly during assembly process when matrix are block diagonal at the element level. Such a feature is heavily used by hybrid discontinuous Galerkin and HHO methods. In these cases, complex expressions are evaluated in only one loop instead of several ones with temporary variables. Note that matrix-matrix products cannot be assembled efficiently in a lazy way, since the sparsity pattern is expected to change: in these cases, temporaries are used.

The efficient lazy implementation is obtained by using the expression template technique in C++. In consequence, if a is a form, then, for instance, -a and lambda*a, where lambda is a scalar, are no longer a form but a form expression. It leads to represent at compile time an expression tree by a hierarchy of classes. Each class represent a node of the expression tree while leaves, also called terminals, are the field themselves.

Any class representing an expression node tree derives from the form_lazy_base and is called here a form_lazy: it is represented by a C++ concept. Since concepts in C++ would be available only with the forthcoming 2020 standard, these concepts are actually represented by traits in Rheolef.

Detailed specifications

The form_lazy concept is defined by:

   form_lazy:
        form
      | integrate (opt_domain form_test opts)
      | +- form_lazy
      | constant * form_lazy
      | form_lazy / constant
      | form_lazy +- form_lazy
      | form_lazy * form_lazy
      | trans (form_lazy)
      | inv (form_lazy)
      | lump (form_lazy)

The opt_domain stands for an optional domain specification and opts for an optional integrate_option variable. Finally, the form_test concept involved by the integrate call is defined by:

    form_test:
        field_test * field_trial
        field_trial * field_test

where field_test has been defined by field_lazy and field_trial is obtained by replacing test by trial in the field expression.


Implementation

The implementation is similar to those of the field_lazy class hierarchy.