1#ifndef _RHEOLEF_FIELD_EXPR_H
2#define _RHEOLEF_FIELD_EXPR_H
44#include "rheolef/field_expr_recursive.h"
57template<
class T,
class M>
60typename std::enable_if<
61 details::is_field_expr_affine_homogeneous<Expr>::value
62 && ! details::is_field_expr_v2_constant <Expr>::value
63 && ! details::is_field <Expr>::value
70 "field = expr; expr should have homogeneous space. HINT: use field = interpolate(Xh, expr)");
71 if (get_space().
name() != Xh.name()) {
78template<
class T,
class M>
79template<
class Expr,
class Sfinae>
85 _dis_dof_indexes_requires_update(true),
86 _dis_dof_assembly_requires_update(false)
98#define _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
99template<class T, class M, class Expr> \
101typename std::enable_if< \
102 details::is_field_expr_affine_homogeneous<Expr>::value, \
105operator OP (field_basic<T,M>& uh, const Expr& expr) \
107 space_basic<T,M> Xh; \
108 check_macro (expr.have_homogeneous_space (Xh), \
109 "field [domain] " << #OP << " expr; expr should have homogeneous space. " \
110 << "HINT: use field [domain] " << #OP << " interpolate(Xh, expr)"); \
111 check_macro (uh.get_space().name() == Xh.name(), "field " << #OP << " field_expression : incompatible spaces " \
112 << uh.get_space().name() << " and " << Xh.name()); \
113 details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
117#define _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, NAME, IDX) \
118template<class FieldWdof, class FieldRdof> \
120typename std::enable_if< \
121 details::is_field_expr_affine_homogeneous<FieldRdof>::value, \
124operator OP (NAME<FieldWdof>&& uh, const FieldRdof& expr) \
126 using space_type = typename FieldWdof::space_type; \
128 check_macro (expr.have_homogeneous_space (Xh), \
129 "field [" << #IDX << "] " << #OP << " expr; expr should have homogeneous space. " \
130 << "HINT: use field [" << #IDX << "] " << #OP << " interpolate(Xh, expr)"); \
131 check_macro (uh.get_space().name() == Xh.name(), "field [" << #IDX << "] " << #OP << " field_expression : incompatible spaces " \
132 << uh.get_space().name() << " and " << Xh.name()); \
133 details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
137#define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR) \
138 _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
139 _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, details::field_wdof_sliced, "i_comp") \
140 _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, details::field_wdof_indirect, "domain")
144#undef _RHEOLEF_field_expr_v2_op_assign_field
145#undef _RHEOLEF_field_expr_v2_op_assign_auxil
146#undef _RHEOLEF_field_expr_v2_op_assign
151#define _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
152template<class T, class M, class Expr> \
154typename std::enable_if< \
155 details::is_field_expr_v2_constant<Expr>::value \
158operator OP (field_basic<T,M>& uh, const Expr& expr) \
160 details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
164#define _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, NAME, IDX) \
165template<class FieldWdof, class Expr> \
167typename std::enable_if< \
168 details::is_field_expr_v2_constant<Expr>::value \
171operator OP (NAME<FieldWdof>&& uh, const Expr& expr) \
173 details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
177#define _RHEOLEF_field_expr_v2_op_assign_constant(OP, FUNCTOR) \
178 _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
179 _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, details::field_wdof_sliced, "i_comp") \
180 _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, details::field_wdof_indirect, "domain")
186#undef _RHEOLEF_field_expr_v2_op_assign_constant_field
187#undef _RHEOLEF_field_expr_v2_op_assign_constant_auxil
188#undef _RHEOLEF_field_expr_v2_op_assign_constant_auxil_old
189#undef _RHEOLEF_field_expr_v2_op_assign_constant
197template <
class Expr1,
class Expr2>
204 typename Expr1::float_type,
205 typename Expr2::float_type>::type
207dual (
const Expr1& expr1,
const Expr2& expr2)
209 typedef typename Expr1::float_type
T;
210 typedef typename Expr1::memory_type
M;
213 "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)");
215 "dual(expr1,expr2); expr2 should have homogeneous space. HINT: use dual(expr1,interpolate(Xh, expr2))");
217 "dual(expr1,expr2); incompatible \""<<
Xh1.name()<<
"\" and \""<<
Xh2.name()<<
" spaces for expr1 and expr2");
221template <
class Expr1,
class Expr2>
225 details::is_field_expr_v2_constant <Expr1>::value &&
226 details::is_field_expr_affine_homogeneous<Expr2>::value
227 ,
typename Expr2::float_type
229dual (
const Expr1& expr1,
const Expr2& expr2)
231 typedef typename Expr2::float_type
T;
232 typedef typename Expr2::memory_type
M;
235 "dual(cte,expr2); expr2 should have homogeneous space. HINT: use dual(cte,interpolate(Xh, expr2))");
236 return expr1*dis_accumulate (expr2.begin_dof(),
Xh2.ndof(),
Xh2.ownership().comm(),
M());
239template <
class Expr1,
class Expr2>
243 details::is_field_expr_affine_homogeneous<Expr1>::value &&
244 details::is_field_expr_v2_constant <Expr2>::value
245 ,
typename Expr1::float_type
247dual (
const Expr1& expr1,
const Expr2& expr2)
249 typedef typename Expr1::float_type
T;
250 typedef typename Expr1::memory_type
M;
253 "dual(expr1,cte); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),cte)");
263 details::has_field_rdof_interface<Expr>::value
264 && ! details::is_field<Expr>::value
265 ,form_basic <typename Expr::value_type, typename Expr::memory_type>
269 typedef typename Expr::value_type
T;
270 typedef typename Expr::memory_type
M;
field_basic< T, M > & operator=(const field_basic< T, M > &)
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
#define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR)
return dis_inner_product(expr1.begin_dof(), expr2.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M())
#define _RHEOLEF_field_expr_v2_op_assign_constant(OP, FUNCTOR)
void assign_with_operator(ForwardIterator first, ForwardIterator last, InputIterator iter_rhs, OpAssign op_assign)
This file is part of Rheolef.
rheolef::std enable_if ::type dual const Expr1 expr1, const Expr2 expr2 dual(const Expr1 &expr1, const Expr2 &expr2)
const_iterator begin_dof() const
std::iterator_traits< InputIterator >::value_type dis_accumulate(InputIterator first, Size n, const distributor::communicator_type &comm, sequential)
csr< T, M > diag(const vec< T, M > &d)