Loading...
Searching...
No Matches
form_lazy_expr.h
Go to the documentation of this file.
# ifndef _RHEOLEF_FORM_LAZY_EXPR_H
# define _RHEOLEF_FORM_LAZY_EXPR_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// Rheolef is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Rheolef is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =========================================================================
// form_lazy_expr = result of a lazy integrate() that are combined in exprs
// AUTHOR: Pierre.Saramito@imag.fr
// DATE: 30 march 1920
namespace rheolef {
} // namespace rheolef
//
// SUMMARY: see also "form_lazy_terminal.h"
// 3. unary expressions
// 3.1. unary_minus & unary_plus
// 3.2. invert
// 3.3. transpose
// 4. binary expressions
// 4.1. plus & minus
// 4.2. multiply
// 5. form allocator
//
/*
Question:
What is the difference between
field_lazy_xxx and field_expr_xxx ?
form_lazy_xxx and form_expr_xxx ?
Response:
"lazy" means un-assembled matrix and vectors, here fields and forms.
The idea is to compute on the fly fields and forms during an iteration
on the element of the mesh.
exemple 1:
wh = uh + vh;
1) When both uh and vh are assembled (ie field)
the loop is unrolled at the "dof" level:
wh(i)= uh(i) + vh(i)
=> field_expr unroll at the "dof" level
2) Here, either uh or vh are un-assembled (ie field_lazy)
the loop is unrolled at the element level:
wh/K = uh/K + vh/K
=> field_lazy unrolls at the element level
exemple 2:
wh = a*uh + b*vh;
1) When both uh and vh are assembled (ie field)
the loop is unrolled at the "dof" level:
wh(i)= sum_j a_ij*uh(j) + sum_k b_ik*vh(k)
=> field_expr unroll at the dof level
2) Here, either uh or vh are un-assembled (ie field_lazy)
the loop is unrolled at the element level:
wh/K = a/K*uh/K + b/K*vh/K
assuming that we use discontiuous elements (eg "Pkd")
otherwise a and/or b are not diagonal versus K
=> field_lazy unrolls at the element level
exemple 3:
auto a = ...
auto b = ...
auto c = ...
form S = inv(a + b*inv(c)*trans(b));
The two imbricated inversions are possible here
based on an unassembled form_lazy a, b, c.
Otherwise, with a, b, c as forms, this is not possible.
Such an idom is typical in the HHO method, see dirichlet_hho.cc
IMPLEMENTATION NOTES:
* Expressions operates at the elementy level:
element matrix are: inverted, transposed, mult, etc.
Effective computations are delayed until the full
expr is converted to form_basic<T,M>
* A base class defines the common methods for all form_lazy_xxx
it uses the CRTP C++ idiom:
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
* Some computations are expensive :
- for field: O(n^p) with p > 1 where n is the typical element-vector size
- for forms: O(n^p) with p > 2 where n is the typical element-matrix size
Are converned:
- field: a*u, u=integrate(...), u=interpolate(...)
- forms: inv(a), a*b, a=integrate(...)
For these expensive computations, it is possible to share the result
of computations by speciying where is the common sub-expresion:
example:
auto a1 = inv(m)*b - b*inv(m); // inv(m) is computed 2 times
auto inv_m = inv(m); // the common sub-expr
auto a2 = inv_m*b - b*inv_m; // inv(m) computed once on the fly
requirements:
- The initialize() method should be "const" for the smart_pointer
to avoid generating a true copy when calling initialize()
- This also avoid the true-copy semantic of the imbedded eigen::matrix
that stores the shared result
*/
#include "rheolef/form_lazy_terminal.h"
namespace rheolef {
// -------------------------------------------------------------------
// 3. unary expressions
// -------------------------------------------------------------------
// 3.1. unary_minus & unary_plus
// -------------------------------------------------------------------
namespace details {
template<class Unop, class Expr>
class form_lazy_unop: public form_lazy_base<form_lazy_unop<Unop,Expr>> {
public :
// definitions:
using base = form_lazy_base<form_lazy_unop<Unop,Expr>>;
using size_type = geo_element::size_type;
using memory_type = typename Expr::memory_type;
using scalar_type = typename Expr::scalar_type;
using space_type = typename Expr::space_type;
using geo_type = typename Expr::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using matrix_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,Eigen::Dynamic>;
// allocator:
form_lazy_unop (const Unop& unop, const Expr& expr)
: base(),
_unop(unop),
_expr(expr)
{}
// accessors:
const geo_type& get_geo() const { return _expr.get_geo(); }
const space_type& get_trial_space() const { return _expr.get_trial_space(); }
const space_type& get_test_space() const { return _expr.get_test_space(); }
bool is_on_band() const { return false; }
band_type get_band() const { return band_type(); }
void initialize (const geo_type& omega_K) { _expr.initialize (omega_K); }
bool is_diagonal() const { return _expr.is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const;
// data:
protected:
Unop _unop;
Expr _expr;
};
// concept;
template<class Unop, class Expr>
struct is_form_lazy <form_lazy_unop<Unop,Expr> > : std::true_type {};
// inlined:
template<class Unop, class Expr>
void
form_lazy_unop<Unop,Expr>::evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& bk) const
{
matrix_element_type ak;
_expr.evaluate (omega_K, K, ak);
bk = ak.unaryExpr(_unop);
}
}// namespace details
#define _RHEOLEF_form_lazy_unop(OP,NAME) \
template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type> \
details::form_lazy_unop<NAME,Expr> \
operator OP (const Expr& a) \
{ \
return details::form_lazy_unop<NAME,Expr> (NAME(),a); \
}
_RHEOLEF_form_lazy_unop(+,details::unary_plus)
_RHEOLEF_form_lazy_unop(-,details::negate)
#undef _RHEOLEF_form_lazy_unop
// -------------------------------------------------------------------
// 3.2. invert
// -------------------------------------------------------------------
namespace details {
template<class Expr>
class form_lazy_invert_rep {
public :
// definitions:
using size_type = geo_element::size_type;
using memory_type = typename Expr::memory_type;
using scalar_type = typename Expr::scalar_type;
using space_type = typename Expr::space_type;
using geo_type = typename Expr::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using matrix_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,Eigen::Dynamic>;
// allocator:
form_lazy_invert_rep (const Expr& expr)
: _expr(expr),
_prev_omega_K(),
_prev_K_dis_ie(std::numeric_limits<size_type>::max()),
_prev_ak()
{}
// accessors:
const geo_type& get_geo() const { return _expr.get_geo(); }
const space_type& get_trial_space() const { return _expr.get_trial_space(); }
const space_type& get_test_space() const { return _expr.get_test_space(); }
bool is_on_band() const { return false; }
band_type get_band() const { return band_type(); }
void initialize (const geo_type& omega_K) const;
bool is_diagonal() const { return _expr.is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const;
// data:
protected:
mutable Expr _expr;
mutable geo_type _prev_omega_K;
mutable size_type _prev_K_dis_ie;
mutable matrix_element_type _prev_ak;
};
// inlined:
template<class Expr>
void
form_lazy_invert_rep<Expr>::initialize (const geo_type& omega_K) const
{
check_macro (get_trial_space() == get_test_space(),
"inv(form): spaces "
<< "\"" <<get_trial_space().name()<<"\" and \"" <<get_test_space().name()<<"\""
<< " should be equal");
check_macro (get_trial_space().get_constitution().have_compact_support_inside_element() &&
get_test_space().get_constitution().have_compact_support_inside_element(),
"inv(form): requires compact support inside elements (e.g. discontinuous or bubble)");
_expr.initialize (omega_K);
_prev_omega_K = omega_K;
_prev_K_dis_ie = std::numeric_limits<size_type>::max();
}
template<class Expr>
void
form_lazy_invert_rep<Expr>::evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const
{
if (_prev_omega_K == omega_K && _prev_K_dis_ie == K.dis_ie()) {
trace_macro("inv(K="<<K.name()<<K.dis_ie()<<",prev="<<_prev_K_dis_ie<<"): re-use");
ak = _prev_ak;
return;
}
trace_macro("inv(K="<<K.name()<<K.dis_ie()<<",prev="<<_prev_K_dis_ie<<"): compute");
_expr.evaluate (omega_K, K, ak);
#ifdef _RHEOLEF_PARANO
check_macro (ak.rows() == ak.cols(), "inv: matrix should be square");
#endif // _RHEOLEF_PARANO
details::local_invert (ak, _expr.is_diagonal());
_prev_ak = ak; // expensive to compute, so memorize it for common subexpressions
_prev_omega_K = omega_K;
_prev_K_dis_ie = K.dis_ie();
}
template<class Expr>
class form_lazy_invert: public smart_pointer_nocopy<form_lazy_invert_rep<Expr>>,
public form_lazy_base <form_lazy_invert<Expr>> {
public :
// definitions:
using rep = form_lazy_invert_rep<Expr>;
using base1 = smart_pointer_nocopy<rep>;
using base2 = form_lazy_base<form_lazy_invert<Expr>>;
using size_type = typename rep::size_type;
using memory_type = typename rep::memory_type;
using scalar_type = typename rep::scalar_type;
using space_type = typename rep::space_type;
using geo_type = typename rep::geo_type;
using band_type = typename rep::band_type;
using matrix_element_type = typename rep::matrix_element_type;
// allocator:
form_lazy_invert (const Expr& expr)
: base1(new_macro(rep(expr))),
base2()
{}
// accessors:
const geo_type& get_geo() const { return base1::data().get_geo(); }
const space_type& get_trial_space() const { return base1::data().get_trial_space(); }
const space_type& get_test_space() const { return base1::data().get_test_space(); }
bool is_on_band() const { return base1::data().is_on_band(); }
band_type get_band() const { return base1::data().get_band(); }
void initialize (const geo_type& omega_K) const { return base1::data().initialize (omega_K); }
bool is_diagonal() const { return base1::data().is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const
{ return base1::data().evaluate (omega_K, K, ak); }
};
// concept;
template<class Expr> struct is_form_lazy <form_lazy_invert<Expr> > : std::true_type {};
}// namespace details
template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
details::form_lazy_invert<Expr>
inv (const Expr& a)
{
return details::form_lazy_invert<Expr> (a);
}
// -------------------------------------------------------------------
// 3.3. transpose
// -------------------------------------------------------------------
namespace details {
template<class Expr>
class form_lazy_transpose: public form_lazy_base<form_lazy_transpose<Expr>> {
public :
// definitions:
using base = form_lazy_base<form_lazy_transpose<Expr>>;
using size_type = geo_element::size_type;
using memory_type = typename Expr::memory_type;
using scalar_type = typename Expr::scalar_type;
using space_type = typename Expr::space_type;
using geo_type = typename Expr::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using matrix_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,Eigen::Dynamic>;
// allocator:
form_lazy_transpose (const Expr& expr)
: base(),
_expr(expr)
{}
// accessors:
const geo_type& get_geo() const { return _expr.get_geo(); }
const space_type& get_trial_space() const { return _expr.get_test_space(); } // swapped!
const space_type& get_test_space() const { return _expr.get_trial_space(); } // swapped!
bool is_on_band() const { return false; }
band_type get_band() const { return band_type(); }
void initialize (const geo_type& omega_K) { _expr.initialize (omega_K); }
bool is_diagonal() const { return _expr.is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const;
// data:
protected:
Expr _expr;
};
// concept;
template<class Expr> struct is_form_lazy <form_lazy_transpose<Expr> > : std::true_type {};
// inlined:
template<class Expr>
void
form_lazy_transpose<Expr>::evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const
{
_expr.evaluate (omega_K, K, ak);
ak.transposeInPlace();
}
}// namespace details
template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
details::form_lazy_transpose<Expr>
trans (const Expr& a)
{
return details::form_lazy_transpose<Expr> (a);
}
// -------------------------------------------------------------------
// 4. binary expressions
// -------------------------------------------------------------------
// 4.1. add & minus
// -------------------------------------------------------------------
namespace details {
template<class Binop, class Expr1, class Expr2>
class form_lazy_add: public form_lazy_base<form_lazy_add<Binop,Expr1,Expr2>> {
public :
// definitions:
using base = form_lazy_base<form_lazy_add<Binop,Expr1,Expr2>>;
using size_type = geo_element::size_type;
using memory_type = typename Expr1::memory_type;
using scalar_type = typename Expr1::scalar_type;
using space_type = typename Expr1::space_type;
using geo_type = typename Expr1::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using matrix_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,Eigen::Dynamic>;
// allocator:
form_lazy_add (const Expr1& expr1, const Expr2& expr2)
: base(),
_binop(),
_expr1(expr1),
_expr2(expr2) {}
// accessors:
const geo_type& get_geo() const;
const space_type& get_trial_space() const { return _expr1.get_trial_space(); }
const space_type& get_test_space() const { return _expr1.get_test_space(); }
bool is_on_band() const { return false; }
band_type get_band() const { return band_type(); }
void initialize (const geo_type& omega_K);
bool is_diagonal() const { return _expr1.is_diagonal() &&
_expr2.is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const;
// data:
protected:
Binop _binop;
Expr1 _expr1;
Expr2 _expr2;
};
// concept;
template<class Binop, class Expr1, class Expr2>
struct is_form_lazy <form_lazy_add<Binop,Expr1,Expr2> > : std::true_type {};
// inlined:
template<class Binop, class Expr1, class Expr2>
void
form_lazy_add<Binop,Expr1,Expr2>::initialize (const geo_type& omega_K)
{
// TODO: subdomains e.g. robin
check_macro (_expr1.get_geo() == _expr2. get_geo(),
"lazy_add: different domain not yet supported");
check_macro (_expr1.get_trial_space() == _expr2.get_trial_space() &&
_expr1. get_test_space() == _expr2. get_test_space(),
"lazy_add: incompatible spaces "
<< "[\"" <<_expr1.get_trial_space().name()<<"\", \"" <<_expr1.get_test_space().name()<<"\"] and "
<< "[\"" <<_expr2.get_trial_space().name()<<"\", \"" <<_expr2.get_test_space().name()<<"\"]");
_expr1.initialize (omega_K);
_expr2.initialize (omega_K);
}
template<class Binop, class Expr1, class Expr2>
const typename form_lazy_add<Binop,Expr1,Expr2>::geo_type&
form_lazy_add<Binop,Expr1,Expr2>::get_geo() const
{
// TODO: subdomains e.g. robin
return _expr1.get_geo();
}
template<class Binop, class Expr1, class Expr2>
void
form_lazy_add<Binop,Expr1,Expr2>::evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ck) const
{
matrix_element_type ak, bk;
_expr1.evaluate (omega_K, K, ak);
_expr2.evaluate (omega_K, K, bk);
#ifdef _RHEOLEF_PARANO
check_macro (ak.rows() == bk.rows() && ak.cols() == bk.cols(), "a+b: invalid sizes");
#endif // _RHEOLEF_PARANO
ck = ak.binaryExpr (bk, _binop);
}
}// namespace details
#define _RHEOLEF_form_lazy_add(OP,NAME) \
template<class Expr1, class Expr2, \
class Sfinae1 = typename std::enable_if<details::is_form_lazy<Expr1>::value, Expr1>::type, \
class Sfinae2 = typename std::enable_if<details::is_form_lazy<Expr2>::value, Expr2>::type> \
details::form_lazy_add<details::NAME,Expr1,Expr2> \
operator OP (const Expr1& a, const Expr2& b) \
{ \
return details::form_lazy_add<details::NAME,Expr1,Expr2> (a,b); \
}
_RHEOLEF_form_lazy_add(+,plus)
_RHEOLEF_form_lazy_add(-,minus)
#undef _RHEOLEF_form_lazy_add
// -------------------------------------------------------------------
// 4.2. multiply
// -------------------------------------------------------------------
// TODO: shared on common subexpressions
namespace details {
template<class Expr1, class Expr2>
class form_lazy_multiply_rep {
public :
// definitions:
using size_type = geo_element::size_type;
using memory_type = typename Expr1::memory_type;
using scalar_type = typename Expr1::scalar_type;
using space_type = typename Expr1::space_type;
using geo_type = typename Expr1::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using matrix_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,Eigen::Dynamic>;
// allocator:
form_lazy_multiply_rep (const Expr1& expr1, const Expr2& expr2)
: _expr1(expr1),
_expr2(expr2),
_prev_omega_K(),
_prev_K_dis_ie(std::numeric_limits<size_type>::max()),
_prev_ck()
{}
// accessors:
const geo_type& get_geo() const;
const space_type& get_trial_space() const { return _expr2.get_trial_space(); }
const space_type& get_test_space() const { return _expr1.get_test_space(); }
bool is_on_band() const { return false; }
band_type get_band() const { return band_type(); }
void initialize (const geo_type& omega_K) const;
bool is_diagonal() const { return _expr1.is_diagonal() &&
_expr2.is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const;
// data:
protected:
mutable Expr1 _expr1;
mutable Expr2 _expr2;
mutable geo_type _prev_omega_K;
mutable size_type _prev_K_dis_ie;
mutable matrix_element_type _prev_ck;
};
// inlined:
template<class Expr1, class Expr2>
void
form_lazy_multiply_rep<Expr1,Expr2>::initialize (const geo_type& omega_K) const
{
// TODO: subdomains e.g. robin
check_macro (_expr1.get_geo() == _expr2. get_geo(),
"lazy_multiply: different domain not yet supported");
check_macro (_expr1.get_trial_space() == _expr2. get_test_space(),
"lazy_multiply: incompatible spaces \""
<<_expr1.get_trial_space().name()<<"\" and \""
<<_expr2. get_test_space().name()<<"\"");
if (! _expr1. get_test_space().get_constitution().have_compact_support_inside_element() ||
! _expr1.get_trial_space().get_constitution().have_compact_support_inside_element() ||
! _expr2.get_trial_space().get_constitution().have_compact_support_inside_element() ) {
warning_macro("lazy_multiply: requires compact support inside elements (e.g. discontinuous or bubble)");
warning_macro("lazy_multiply: space was "
<< "[\"" <<_expr1.get_trial_space().name()<<"\", \"" <<_expr1.get_test_space().name()<<"\"] and "
<< "[\"" <<_expr2.get_trial_space().name()<<"\", \"" <<_expr2.get_test_space().name()<<"\"]");
fatal_macro("lazy_multiply: HINT: convert to \"form\" before to do the product");
}
_expr1.initialize (omega_K);
_expr2.initialize (omega_K);
_prev_omega_K = omega_K;
_prev_K_dis_ie = std::numeric_limits<size_type>::max();
trace_macro("mult(omega_K="<<omega_K.name()<<"): init prev:="<<_prev_K_dis_ie<<" for this="<<(this));
}
template<class Expr1, class Expr2>
const typename form_lazy_multiply_rep<Expr1,Expr2>::geo_type&
form_lazy_multiply_rep<Expr1,Expr2>::get_geo() const
{
// TODO: subdomains e.g. robin
return _expr1.get_geo();
}
template<class Expr1, class Expr2>
void
form_lazy_multiply_rep<Expr1,Expr2>::evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ck) const
{
if (_prev_omega_K == omega_K && _prev_K_dis_ie == K.dis_ie()) {
trace_macro("mult(K="<<K.name()<<K.dis_ie()<<",prev="<<_prev_K_dis_ie<<"): re-use this="<<(this));
ck = _prev_ck;
return;
}
trace_macro("mult(K="<<K.name()<<K.dis_ie()<<",prev="<<_prev_K_dis_ie<<"): compute this="<<(this));
matrix_element_type ak, bk;
_expr1.evaluate (omega_K, K, ak);
_expr2.evaluate (omega_K, K, bk);
#ifdef _RHEOLEF_PARANO
check_macro (ak.cols() == bk.rows(), "a*b: invalid sizes");
#endif // _RHEOLEF_PARANO
ck = ak*bk;
_prev_ck = ck; // expensive to compute, so memorize it for common subexpressions
_prev_omega_K = omega_K;
_prev_K_dis_ie = K.dis_ie();
trace_macro("mult(K="<<K.name()<<K.dis_ie()<<"): prev:="<<_prev_K_dis_ie<<" for this="<<(this));
}
template<class Expr1, class Expr2>
class form_lazy_multiply: public smart_pointer_nocopy<form_lazy_multiply_rep<Expr1,Expr2>>,
public form_lazy_base <form_lazy_multiply<Expr1,Expr2>> {
public :
// definitions:
using rep = form_lazy_multiply_rep<Expr1,Expr2>;
using base1 = smart_pointer_nocopy<rep>;
using base2 = form_lazy_base<form_lazy_multiply<Expr1,Expr2>>;
using size_type = typename rep::size_type;
using memory_type = typename rep::memory_type;
using scalar_type = typename rep::scalar_type;
using space_type = typename rep::space_type;
using geo_type = typename rep::geo_type;
using band_type = typename rep::band_type;
using matrix_element_type = typename rep::matrix_element_type;
// allocator:
form_lazy_multiply (const Expr1& expr1, const Expr2& expr2)
: base1(new_macro(rep(expr1,expr2))),
base2()
{}
// accessors:
const geo_type& get_geo() const { return base1::data().get_geo(); }
const space_type& get_trial_space() const { return base1::data().get_trial_space(); }
const space_type& get_test_space() const { return base1::data().get_test_space(); }
bool is_on_band() const { return base1::data().is_on_band(); }
band_type get_band() const { return base1::data().get_band(); }
void initialize (const geo_type& omega_K) const { base1::data().initialize (omega_K); }
bool is_diagonal() const { return base1::data().is_diagonal(); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
matrix_element_type& ak) const
{ base1::data().evaluate (omega_K, K, ak); }
};
// concept;
template<class Expr1, class Expr2> struct is_form_lazy <form_lazy_multiply<Expr1,Expr2> > : std::true_type {};
}// namespace details
template<class Expr1, class Expr2,
class Sfinae1 = typename std::enable_if<details::is_form_lazy<Expr1>::value, Expr1>::type,
class Sfinae2 = typename std::enable_if<details::is_form_lazy<Expr2>::value, Expr2>::type>
details::form_lazy_multiply<Expr1,Expr2>
operator* (const Expr1& a, const Expr2& b)
{
return details::form_lazy_multiply<Expr1,Expr2> (a,b);
}
// -------------------------------------------------------
// 5. form allocator
// -------------------------------------------------------
template<class T, class M>
template<class Expr, class Sfinae>
inline
form_basic<T,M>&
form_basic<T,M>::operator= (const Expr& a)
{
// here is the main call to the effective computation
// of all sparse matrix asssembly from element matrix:
convert_from_form_lazy (a);
return *this;
}
template<class T, class M>
template<class Expr, class Sfinae>
inline
form_basic<T,M>::form_basic (const Expr& a)
: _X(), _Y(), _uu(), _ub(), _bu(), _bb()
{
operator= (a);
}
}// namespace rheolef
# endif /* _RHEOLEF_FORM_LAZY_EXPR_H */
rheolef::band_basic< float_type, memory_type >
rheolef::details::form_lazy_add
Definition form_lazy_expr.h:507
rheolef::details::form_lazy_add::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:575
rheolef::details::form_lazy_add::band_type
band_basic< float_type, memory_type > band_type
Definition form_lazy_expr.h:518
rheolef::details::form_lazy_add::size_type
geo_element::size_type size_type
Definition form_lazy_expr.h:512
rheolef::details::form_lazy_add::scalar_type
typename Expr1::scalar_type scalar_type
Definition form_lazy_expr.h:514
rheolef::details::form_lazy_add::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:582
rheolef::details::form_lazy_add::memory_type
typename Expr1::memory_type memory_type
Definition form_lazy_expr.h:513
rheolef::details::form_lazy_add::_expr1
Expr1 _expr1
Definition form_lazy_expr.h:548
rheolef::details::form_lazy_add::_expr2
Expr2 _expr2
Definition form_lazy_expr.h:549
rheolef::details::form_lazy_add::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:533
rheolef::details::form_lazy_add::form_lazy_add
form_lazy_add(const Expr1 &expr1, const Expr2 &expr2)
Definition form_lazy_expr.h:523
rheolef::details::form_lazy_add::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:538
rheolef::details::form_lazy_add::initialize
void initialize(const geo_type &omega_K)
Definition form_lazy_expr.h:558
rheolef::details::form_lazy_add::matrix_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, Eigen::Dynamic > matrix_element_type
Definition form_lazy_expr.h:519
rheolef::details::form_lazy_add::_binop
Binop _binop
Definition form_lazy_expr.h:547
rheolef::details::form_lazy_add::float_type
typename float_traits< scalar_type >::type float_type
Definition form_lazy_expr.h:517
rheolef::details::form_lazy_add::space_type
typename Expr1::space_type space_type
Definition form_lazy_expr.h:515
rheolef::details::form_lazy_add::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:532
rheolef::details::form_lazy_add::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:534
rheolef::details::form_lazy_add::get_band
band_type get_band() const
Definition form_lazy_expr.h:535
rheolef::details::form_lazy_add::geo_type
typename Expr1::geo_type geo_type
Definition form_lazy_expr.h:516
rheolef::details::form_lazy_base
Definition form_lazy_terminal.h:50
rheolef::details::form_lazy_invert_rep
Definition form_lazy_expr.h:292
rheolef::details::form_lazy_invert_rep::_prev_ak
matrix_element_type _prev_ak
Definition form_lazy_expr.h:334
rheolef::details::form_lazy_invert_rep::band_type
band_basic< float_type, memory_type > band_type
Definition form_lazy_expr.h:302
rheolef::details::form_lazy_invert_rep::size_type
geo_element::size_type size_type
Definition form_lazy_expr.h:296
rheolef::details::form_lazy_invert_rep::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:355
rheolef::details::form_lazy_invert_rep::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:318
rheolef::details::form_lazy_invert_rep::initialize
void initialize(const geo_type &omega_K) const
Definition form_lazy_expr.h:339
rheolef::details::form_lazy_invert_rep::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:323
rheolef::details::form_lazy_invert_rep::geo_type
typename Expr::geo_type geo_type
Definition form_lazy_expr.h:300
rheolef::details::form_lazy_invert_rep::scalar_type
typename Expr::scalar_type scalar_type
Definition form_lazy_expr.h:298
rheolef::details::form_lazy_invert_rep::memory_type
typename Expr::memory_type memory_type
Definition form_lazy_expr.h:297
rheolef::details::form_lazy_invert_rep::_prev_omega_K
geo_type _prev_omega_K
Definition form_lazy_expr.h:332
rheolef::details::form_lazy_invert_rep::_expr
Expr _expr
Definition form_lazy_expr.h:331
rheolef::details::form_lazy_invert_rep::form_lazy_invert_rep
form_lazy_invert_rep(const Expr &expr)
Definition form_lazy_expr.h:307
rheolef::details::form_lazy_invert_rep::matrix_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, Eigen::Dynamic > matrix_element_type
Definition form_lazy_expr.h:303
rheolef::details::form_lazy_invert_rep::_prev_K_dis_ie
size_type _prev_K_dis_ie
Definition form_lazy_expr.h:333
rheolef::details::form_lazy_invert_rep::float_type
typename float_traits< scalar_type >::type float_type
Definition form_lazy_expr.h:301
rheolef::details::form_lazy_invert_rep::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:317
rheolef::details::form_lazy_invert_rep::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:319
rheolef::details::form_lazy_invert_rep::get_band
band_type get_band() const
Definition form_lazy_expr.h:320
rheolef::details::form_lazy_invert_rep::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:316
rheolef::details::form_lazy_invert_rep::space_type
typename Expr::space_type space_type
Definition form_lazy_expr.h:299
rheolef::details::form_lazy_invert
Definition form_lazy_expr.h:378
rheolef::details::form_lazy_invert::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:411
rheolef::details::form_lazy_invert::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:404
rheolef::details::form_lazy_invert::memory_type
typename rep::memory_type memory_type
Definition form_lazy_expr.h:386
rheolef::details::form_lazy_invert::initialize
void initialize(const geo_type &omega_K) const
Definition form_lazy_expr.h:408
rheolef::details::form_lazy_invert::size_type
typename rep::size_type size_type
Definition form_lazy_expr.h:385
rheolef::details::form_lazy_invert::band_type
typename rep::band_type band_type
Definition form_lazy_expr.h:390
rheolef::details::form_lazy_invert::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:409
rheolef::details::form_lazy_invert::space_type
typename rep::space_type space_type
Definition form_lazy_expr.h:388
rheolef::details::form_lazy_invert::geo_type
typename rep::geo_type geo_type
Definition form_lazy_expr.h:389
rheolef::details::form_lazy_invert::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:403
rheolef::details::form_lazy_invert::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:405
rheolef::details::form_lazy_invert::get_band
band_type get_band() const
Definition form_lazy_expr.h:406
rheolef::details::form_lazy_invert::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:402
rheolef::details::form_lazy_invert::base1
smart_pointer_nocopy< rep > base1
Definition form_lazy_expr.h:383
rheolef::details::form_lazy_invert::form_lazy_invert
form_lazy_invert(const Expr &expr)
Definition form_lazy_expr.h:395
rheolef::details::form_lazy_invert::scalar_type
typename rep::scalar_type scalar_type
Definition form_lazy_expr.h:387
rheolef::details::form_lazy_invert::rep
form_lazy_invert_rep< Expr > rep
Definition form_lazy_expr.h:382
rheolef::details::form_lazy_invert::matrix_element_type
typename rep::matrix_element_type matrix_element_type
Definition form_lazy_expr.h:391
rheolef::details::form_lazy_multiply_rep
Definition form_lazy_expr.h:618
rheolef::details::form_lazy_multiply_rep::band_type
band_basic< float_type, memory_type > band_type
Definition form_lazy_expr.h:628
rheolef::details::form_lazy_multiply_rep::size_type
geo_element::size_type size_type
Definition form_lazy_expr.h:622
rheolef::details::form_lazy_multiply_rep::scalar_type
typename Expr1::scalar_type scalar_type
Definition form_lazy_expr.h:624
rheolef::details::form_lazy_multiply_rep::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:703
rheolef::details::form_lazy_multiply_rep::memory_type
typename Expr1::memory_type memory_type
Definition form_lazy_expr.h:623
rheolef::details::form_lazy_multiply_rep::_expr1
Expr1 _expr1
Definition form_lazy_expr.h:659
rheolef::details::form_lazy_multiply_rep::_expr2
Expr2 _expr2
Definition form_lazy_expr.h:660
rheolef::details::form_lazy_multiply_rep::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:645
rheolef::details::form_lazy_multiply_rep::initialize
void initialize(const geo_type &omega_K) const
Definition form_lazy_expr.h:668
rheolef::details::form_lazy_multiply_rep::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:696
rheolef::details::form_lazy_multiply_rep::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:650
rheolef::details::form_lazy_multiply_rep::form_lazy_multiply_rep
form_lazy_multiply_rep(const Expr1 &expr1, const Expr2 &expr2)
Definition form_lazy_expr.h:633
rheolef::details::form_lazy_multiply_rep::_prev_ck
matrix_element_type _prev_ck
Definition form_lazy_expr.h:663
rheolef::details::form_lazy_multiply_rep::_prev_omega_K
geo_type _prev_omega_K
Definition form_lazy_expr.h:661
rheolef::details::form_lazy_multiply_rep::matrix_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, Eigen::Dynamic > matrix_element_type
Definition form_lazy_expr.h:629
rheolef::details::form_lazy_multiply_rep::_prev_K_dis_ie
size_type _prev_K_dis_ie
Definition form_lazy_expr.h:662
rheolef::details::form_lazy_multiply_rep::float_type
typename float_traits< scalar_type >::type float_type
Definition form_lazy_expr.h:627
rheolef::details::form_lazy_multiply_rep::space_type
typename Expr1::space_type space_type
Definition form_lazy_expr.h:625
rheolef::details::form_lazy_multiply_rep::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:644
rheolef::details::form_lazy_multiply_rep::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:646
rheolef::details::form_lazy_multiply_rep::get_band
band_type get_band() const
Definition form_lazy_expr.h:647
rheolef::details::form_lazy_multiply_rep::geo_type
typename Expr1::geo_type geo_type
Definition form_lazy_expr.h:626
rheolef::details::form_lazy_multiply
Definition form_lazy_expr.h:728
rheolef::details::form_lazy_multiply::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:761
rheolef::details::form_lazy_multiply::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:754
rheolef::details::form_lazy_multiply::memory_type
typename rep::memory_type memory_type
Definition form_lazy_expr.h:736
rheolef::details::form_lazy_multiply::initialize
void initialize(const geo_type &omega_K) const
Definition form_lazy_expr.h:758
rheolef::details::form_lazy_multiply::size_type
typename rep::size_type size_type
Definition form_lazy_expr.h:735
rheolef::details::form_lazy_multiply::band_type
typename rep::band_type band_type
Definition form_lazy_expr.h:740
rheolef::details::form_lazy_multiply::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:759
rheolef::details::form_lazy_multiply::space_type
typename rep::space_type space_type
Definition form_lazy_expr.h:738
rheolef::details::form_lazy_multiply::geo_type
typename rep::geo_type geo_type
Definition form_lazy_expr.h:739
rheolef::details::form_lazy_multiply::rep
form_lazy_multiply_rep< Expr1, Expr2 > rep
Definition form_lazy_expr.h:732
rheolef::details::form_lazy_multiply::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:753
rheolef::details::form_lazy_multiply::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:755
rheolef::details::form_lazy_multiply::get_band
band_type get_band() const
Definition form_lazy_expr.h:756
rheolef::details::form_lazy_multiply::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:752
rheolef::details::form_lazy_multiply::base1
smart_pointer_nocopy< rep > base1
Definition form_lazy_expr.h:733
rheolef::details::form_lazy_multiply::scalar_type
typename rep::scalar_type scalar_type
Definition form_lazy_expr.h:737
rheolef::details::form_lazy_multiply::form_lazy_multiply
form_lazy_multiply(const Expr1 &expr1, const Expr2 &expr2)
Definition form_lazy_expr.h:745
rheolef::details::form_lazy_multiply::matrix_element_type
typename rep::matrix_element_type matrix_element_type
Definition form_lazy_expr.h:741
rheolef::details::form_lazy_transpose
Definition form_lazy_expr.h:435
rheolef::details::form_lazy_transpose::band_type
band_basic< float_type, memory_type > band_type
Definition form_lazy_expr.h:446
rheolef::details::form_lazy_transpose::size_type
geo_element::size_type size_type
Definition form_lazy_expr.h:440
rheolef::details::form_lazy_transpose::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:481
rheolef::details::form_lazy_transpose::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:460
rheolef::details::form_lazy_transpose::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:465
rheolef::details::form_lazy_transpose::initialize
void initialize(const geo_type &omega_K)
Definition form_lazy_expr.h:464
rheolef::details::form_lazy_transpose::geo_type
typename Expr::geo_type geo_type
Definition form_lazy_expr.h:444
rheolef::details::form_lazy_transpose::scalar_type
typename Expr::scalar_type scalar_type
Definition form_lazy_expr.h:442
rheolef::details::form_lazy_transpose::memory_type
typename Expr::memory_type memory_type
Definition form_lazy_expr.h:441
rheolef::details::form_lazy_transpose::_expr
Expr _expr
Definition form_lazy_expr.h:473
rheolef::details::form_lazy_transpose::form_lazy_transpose
form_lazy_transpose(const Expr &expr)
Definition form_lazy_expr.h:451
rheolef::details::form_lazy_transpose::matrix_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, Eigen::Dynamic > matrix_element_type
Definition form_lazy_expr.h:447
rheolef::details::form_lazy_transpose::float_type
typename float_traits< scalar_type >::type float_type
Definition form_lazy_expr.h:445
rheolef::details::form_lazy_transpose::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:459
rheolef::details::form_lazy_transpose::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:461
rheolef::details::form_lazy_transpose::get_band
band_type get_band() const
Definition form_lazy_expr.h:462
rheolef::details::form_lazy_transpose::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:458
rheolef::details::form_lazy_transpose::space_type
typename Expr::space_type space_type
Definition form_lazy_expr.h:443
rheolef::details::form_lazy_unop
Definition form_lazy_expr.h:214
rheolef::details::form_lazy_unop::band_type
band_basic< float_type, memory_type > band_type
Definition form_lazy_expr.h:225
rheolef::details::form_lazy_unop::size_type
geo_element::size_type size_type
Definition form_lazy_expr.h:219
rheolef::details::form_lazy_unop::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, matrix_element_type &ak) const
Definition form_lazy_expr.h:263
rheolef::details::form_lazy_unop::get_test_space
const space_type & get_test_space() const
Definition form_lazy_expr.h:240
rheolef::details::form_lazy_unop::_unop
Unop _unop
Definition form_lazy_expr.h:253
rheolef::details::form_lazy_unop::is_diagonal
bool is_diagonal() const
Definition form_lazy_expr.h:245
rheolef::details::form_lazy_unop::initialize
void initialize(const geo_type &omega_K)
Definition form_lazy_expr.h:244
rheolef::details::form_lazy_unop::geo_type
typename Expr::geo_type geo_type
Definition form_lazy_expr.h:223
rheolef::details::form_lazy_unop::scalar_type
typename Expr::scalar_type scalar_type
Definition form_lazy_expr.h:221
rheolef::details::form_lazy_unop::memory_type
typename Expr::memory_type memory_type
Definition form_lazy_expr.h:220
rheolef::details::form_lazy_unop::_expr
Expr _expr
Definition form_lazy_expr.h:254
rheolef::details::form_lazy_unop::matrix_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, Eigen::Dynamic > matrix_element_type
Definition form_lazy_expr.h:226
rheolef::details::form_lazy_unop::form_lazy_unop
form_lazy_unop(const Unop &unop, const Expr &expr)
Definition form_lazy_expr.h:230
rheolef::details::form_lazy_unop::float_type
typename float_traits< scalar_type >::type float_type
Definition form_lazy_expr.h:224
rheolef::details::form_lazy_unop::get_trial_space
const space_type & get_trial_space() const
Definition form_lazy_expr.h:239
rheolef::details::form_lazy_unop::is_on_band
bool is_on_band() const
Definition form_lazy_expr.h:241
rheolef::details::form_lazy_unop::get_band
band_type get_band() const
Definition form_lazy_expr.h:242
rheolef::details::form_lazy_unop::get_geo
const geo_type & get_geo() const
Definition form_lazy_expr.h:238
rheolef::details::form_lazy_unop::space_type
typename Expr::space_type space_type
Definition form_lazy_expr.h:222
rheolef::form_basic::form_basic
form_basic()
Definition form.h:316
rheolef::form_basic::operator=
form_basic< T, M > & operator=(const form_basic< T, M > &)
Definition form.h:329
rheolef::geo_element
see the geo_element page for the full documentation
Definition geo_element.h:102
rheolef::geo_element::size_type
reference_element::size_type size_type
Definition geo_element.h:125
rheolef::geo_element::dis_ie
size_type dis_ie() const
Definition geo_element.h:163
rheolef::geo_element::name
char name() const
Definition geo_element.h:169
rheolef::smart_pointer_nocopy
Definition smart_pointer.h:389
trace_macro
#define trace_macro(message)
Definition dis_macros.h:111
fatal_macro
#define fatal_macro(message)
Definition dis_macros.h:33
warning_macro
#define warning_macro(message)
Definition dis_macros.h:53
get_geo
void get_geo(istream &in, my_geo &omega)
Definition field2gmsh_pos.cc:126
check_macro
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
_RHEOLEF_form_lazy_unop
#define _RHEOLEF_form_lazy_unop(OP, NAME)
-a, +a: see the form page for the full documentation
Definition form_lazy_expr.h:276
_RHEOLEF_form_lazy_add
#define _RHEOLEF_form_lazy_add(OP, NAME)
a+b, a-b: see the form page for the full documentation
Definition form_lazy_expr.h:599
rheolef::details::local_invert
void local_invert(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &m, bool is_diag)
Definition form_vf_assembly.cc:77
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::inv
tensor_basic< T > inv(const tensor_basic< T > &a, size_t d)
Definition tensor.cc:219
rheolef::trans
csr< T, sequential > trans(const csr< T, sequential > &a)
trans(a): see the form page for the full documentation
Definition csr.h:455
rheolef::operator*
csr< T, sequential > operator*(const T &lambda, const csr< T, sequential > &a)
Definition csr.h:437
std
STL namespace.
rheolef::details::is_form_lazy
Definition form.h:137
rheolef::details::negate
Definition expression.h:231
rheolef::details::unary_plus
Definition expression.h:209
rheolef::float_traits::type
T type
Definition Float.h:94