1# ifndef _RHEOLEF_FIELD_LAZY_FORM_MULT_H
2# define _RHEOLEF_FIELD_LAZY_FORM_MULT_H
31#include "rheolef/field_lazy_node.h"
32#include "rheolef/form.h"
41template<
class FormExpr,
class FieldExpr>
82template<
class FormExpr,
class FieldExpr>
84 const FormExpr& a_expr,
85 const FieldExpr& u_expr)
93template<
class FormExpr,
class FieldExpr>
98 check_macro (_a_expr.get_trial_space().get_geo() == _u_expr.get_geo(),
99 "lazy_multiply: different domain not yet supported");
101 check_macro (_a_expr.get_trial_space() == _u_expr.get_space(),
102 "lazy_multiply: incompatible spaces \""
103 <<_a_expr.get_trial_space().name()<<
"\" and \""
104 <<_u_expr.get_space().name()<<
"\"");
106 if (! _a_expr. get_test_space().get_constitution().have_compact_support_inside_element() ||
107 ! _a_expr.get_trial_space().get_constitution().have_compact_support_inside_element()) {
108 warning_macro(
"lazy_multiply: requires compact support inside elements (e.g. discontinuous or bubble)");
110 <<
"[\"" <<_a_expr.get_trial_space().name()<<
"\", \"" <<_a_expr.get_test_space().name()<<
"\"]");
111 fatal_macro(
"lazy_multiply: HINT: convert to \"form\" before to do the product");
113 _a_expr.initialize (omega_K);
114 _u_expr.initialize (omega_K);
115 _prev_omega_K = omega_K;
116 _prev_K_dis_ie = std::numeric_limits<size_type>::max();
118template<
class FormExpr,
class FieldExpr>
125 if (_prev_omega_K == omega_K && _prev_K_dis_ie == K.
dis_ie()) {
133 _a_expr.evaluate (omega_K, K, ak);
134 _u_expr.evaluate (omega_K, K, uk);
135#ifdef _RHEOLEF_PARANO
136 check_macro (ak.cols() == uk.size(),
"a*u: invalid sizes");
139 _prev_omega_K = omega_K;
141 _prev_K_dis_ie = K.
dis_ie();
143template<
class FormExpr,
class FieldExpr>
163 :
base1(new_macro(
rep(a_expr,u_expr))),
171 bool is_on_band()
const {
return base1::data().is_on_band(); }
180 { base1::data().evaluate (omega_K, K, uk); }
183template<
class FormExpr,
class FieldExpr>
189template<
class FormExpr,
class FieldExpr,
190 class Sfinae1 =
typename std::enable_if<details:: is_form_lazy<FormExpr> ::value, FormExpr>::type,
191 class Sfinae2 =
typename std::enable_if<details::is_field_lazy<FieldExpr>::value, FieldExpr>::type>
200 ,
class Sfinae =
typename std::enable_if<details::is_form_lazy<FormExpr>::value, FormExpr>::type
202details::field_lazy_mult_form<
204 ,details::field_lazy_terminal_field<
205 typename FormExpr::scalar_type
206 ,
typename FormExpr::memory_type
215 typename FormExpr::scalar_type
216 ,
typename FormExpr::memory_type>;
224template<
class FormExpr,
class FieldExpr>
265template<
class FormExpr,
class FieldExpr>
267 const FormExpr& a_expr,
268 const FieldExpr& u_expr)
276template<
class FormExpr,
class FieldExpr>
281 check_macro (_a_expr.get_test_space().get_geo() == _u_expr.get_geo(),
282 "lazy_trans_mult: different domain not yet supported");
284 check_macro (_a_expr.get_test_space() == _u_expr.get_space(),
285 "lazy_trans_mult: incompatible spaces \""
286 <<_a_expr.get_test_space().name()<<
"\" and \""
287 <<_u_expr.get_space().name()<<
"\"");
289 if (! _a_expr. get_test_space().get_constitution().have_compact_support_inside_element() ||
290 ! _a_expr.get_trial_space().get_constitution().have_compact_support_inside_element()) {
291 warning_macro(
"lazy_trans_mult: requires compact support inside elements (e.g. discontinuous or bubble)");
293 <<
"[\"" <<_a_expr.get_trial_space().name()<<
"\", \"" <<_a_expr.get_test_space().name()<<
"\"]");
294 fatal_macro(
"lazy_trans_mult: HINT: convert to \"form\" before to do the product");
296 _a_expr.initialize (omega_K);
297 _u_expr.initialize (omega_K);
298 _prev_omega_K = omega_K;
299 _prev_K_dis_ie = std::numeric_limits<size_type>::max();
301template<
class FormExpr,
class FieldExpr>
308 if (_prev_K_dis_ie == K.
dis_ie()) {
316 _a_expr.evaluate (omega_K, K, ak);
317 _u_expr.evaluate (omega_K, K, uk);
318#ifdef _RHEOLEF_PARANO
319 check_macro (ak.rows() == uk.size(),
"a*u: invalid sizes");
321 vk = uk.transpose()*ak;
323 _prev_omega_K = omega_K;
324 _prev_K_dis_ie = K.
dis_ie();
326template<
class FormExpr,
class FieldExpr>
328 public field_lazy_base <field_lazy_trans_mult_form <FormExpr,FieldExpr>> {
346 :
base1(new_macro(
rep(a_expr,u_expr))),
354 bool is_on_band()
const {
return base1::data().is_on_band(); }
363 { base1::data().evaluate (omega_K, K, uk); }
366template<
class FormExpr,
class FieldExpr>
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)
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.
csr< T, sequential > operator*(const T &lambda, const csr< T, sequential > &a)