1# ifndef _RHEOLEF_FORM_LAZY_EXPR_H
2# define _RHEOLEF_FORM_LAZY_EXPR_H
202#include "rheolef/form_lazy_terminal.h"
213template<
class Unop,
class Expr>
257template<
class Unop,
class Expr>
261template<
class Unop,
class Expr>
270 bk = ak.unaryExpr(_unop);
276#define _RHEOLEF_form_lazy_unop(OP,NAME) \
277template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type> \
278details::form_lazy_unop<NAME,Expr> \
279operator OP (const Expr& a) \
281 return details::form_lazy_unop<NAME,Expr> (NAME(),a); \
285#undef _RHEOLEF_form_lazy_unop
341 check_macro (get_trial_space() == get_test_space(),
343 <<
"\"" <<get_trial_space().name()<<
"\" and \"" <<get_test_space().name()<<
"\""
344 <<
" should be equal");
346 check_macro (get_trial_space().get_constitution().have_compact_support_inside_element() &&
347 get_test_space().get_constitution().have_compact_support_inside_element(),
348 "inv(form): requires compact support inside elements (e.g. discontinuous or bubble)");
349 _expr.initialize (omega_K);
350 _prev_omega_K = omega_K;
351 _prev_K_dis_ie = std::numeric_limits<size_type>::max();
360 if (_prev_omega_K == omega_K && _prev_K_dis_ie == K.
dis_ie()) {
366 _expr.evaluate (omega_K, K, ak);
367#ifdef _RHEOLEF_PARANO
368 check_macro (ak.rows() == ak.cols(),
"inv: matrix should be square");
372 _prev_omega_K = omega_K;
373 _prev_K_dis_ie = K.
dis_ie();
405 bool is_on_band()
const {
return base1::data().is_on_band(); }
415 {
return base1::data().evaluate (omega_K, K, ak); }
423template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
487 ak.transposeInPlace();
493template<class Expr, class Sfinae = typename std::enable_if<details::is_form_lazy<Expr>::value, Expr>::type>
506template<
class Binop,
class Expr1,
class Expr2>
552template<
class Binop,
class Expr1,
class Expr2>
556template<
class Binop,
class Expr1,
class Expr2>
562 "lazy_add: different domain not yet supported");
564 check_macro (_expr1.get_trial_space() == _expr2.get_trial_space() &&
565 _expr1. get_test_space() == _expr2. get_test_space(),
566 "lazy_add: incompatible spaces "
567 <<
"[\"" <<_expr1.get_trial_space().name()<<
"\", \"" <<_expr1.get_test_space().name()<<
"\"] and "
568 <<
"[\"" <<_expr2.get_trial_space().name()<<
"\", \"" <<_expr2.get_test_space().name()<<
"\"]");
570 _expr1.initialize (omega_K);
571 _expr2.initialize (omega_K);
573template<
class Binop,
class Expr1,
class Expr2>
578 return _expr1.get_geo();
580template<
class Binop,
class Expr1,
class Expr2>
588 _expr1.evaluate (omega_K, K, ak);
589 _expr2.evaluate (omega_K, K, bk);
590#ifdef _RHEOLEF_PARANO
591 check_macro (ak.rows() == bk.rows() && ak.cols() == bk.cols(),
"a+b: invalid sizes");
593 ck = ak.binaryExpr (bk, _binop);
599#define _RHEOLEF_form_lazy_add(OP,NAME) \
600template<class Expr1, class Expr2, \
601 class Sfinae1 = typename std::enable_if<details::is_form_lazy<Expr1>::value, Expr1>::type, \
602 class Sfinae2 = typename std::enable_if<details::is_form_lazy<Expr2>::value, Expr2>::type> \
603details::form_lazy_add<details::NAME,Expr1,Expr2> \
604operator OP (const Expr1& a, const Expr2& b) \
606 return details::form_lazy_add<details::NAME,Expr1,Expr2> (a,b); \
610#undef _RHEOLEF_form_lazy_add
617template<
class Expr1,
class Expr2>
666template<
class Expr1,
class Expr2>
672 "lazy_multiply: different domain not yet supported");
674 check_macro (_expr1.get_trial_space() == _expr2. get_test_space(),
675 "lazy_multiply: incompatible spaces \""
676 <<_expr1.get_trial_space().name()<<
"\" and \""
677 <<_expr2. get_test_space().name()<<
"\"");
679 if (! _expr1. get_test_space().get_constitution().have_compact_support_inside_element() ||
680 ! _expr1.get_trial_space().get_constitution().have_compact_support_inside_element() ||
681 ! _expr2.get_trial_space().get_constitution().have_compact_support_inside_element() ) {
682 warning_macro(
"lazy_multiply: requires compact support inside elements (e.g. discontinuous or bubble)");
684 <<
"[\"" <<_expr1.get_trial_space().name()<<
"\", \"" <<_expr1.get_test_space().name()<<
"\"] and "
685 <<
"[\"" <<_expr2.get_trial_space().name()<<
"\", \"" <<_expr2.get_test_space().name()<<
"\"]");
686 fatal_macro(
"lazy_multiply: HINT: convert to \"form\" before to do the product");
688 _expr1.initialize (omega_K);
689 _expr2.initialize (omega_K);
690 _prev_omega_K = omega_K;
691 _prev_K_dis_ie = std::numeric_limits<size_type>::max();
692 trace_macro(
"mult(omega_K="<<omega_K.name()<<
"): init prev:="<<_prev_K_dis_ie<<
" for this="<<(
this));
694template<
class Expr1,
class Expr2>
699 return _expr1.get_geo();
701template<
class Expr1,
class Expr2>
708 if (_prev_omega_K == omega_K && _prev_K_dis_ie == K.
dis_ie()) {
715 _expr1.evaluate (omega_K, K, ak);
716 _expr2.evaluate (omega_K, K, bk);
717#ifdef _RHEOLEF_PARANO
718 check_macro (ak.cols() == bk.rows(),
"a*b: invalid sizes");
722 _prev_omega_K = omega_K;
723 _prev_K_dis_ie = K.
dis_ie();
726template<
class Expr1,
class Expr2>
746 :
base1(new_macro(
rep(expr1,expr2))),
755 bool is_on_band()
const {
return base1::data().is_on_band(); }
765 { base1::data().evaluate (omega_K, K, ak); }
774template<
class Expr1,
class Expr2,
775 class Sfinae1 =
typename std::enable_if<details::is_form_lazy<Expr1>::value, Expr1>::type,
776 class Sfinae2 =
typename std::enable_if<details::is_form_lazy<Expr2>::value, Expr2>::type>
785template<
class T,
class M>
786template<
class Expr,
class Sfinae>
793 convert_from_form_lazy (a);
796template<
class T,
class M>
797template<
class Expr,
class Sfinae>
800: _X(), _Y(), _uu(), _ub(), _bu(), _bb()
see the geo_element page for the full documentation
reference_element::size_type size_type
#define trace_macro(message)
#define fatal_macro(message)
#define warning_macro(message)
void get_geo(istream &in, my_geo &omega)
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
void local_invert(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &m, bool is_diag)
This file is part of Rheolef.
tensor_basic< T > inv(const tensor_basic< T > &a, size_t d)
csr< T, sequential > trans(const csr< T, sequential > &a)
trans(a): see the form page for the full documentation
csr< T, sequential > operator*(const T &lambda, const csr< T, sequential > &a)