Rheolef  7.2
an efficient C++ finite element environment
field_expr.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FIELD_EXPR_H
2 #define _RHEOLEF_FIELD_EXPR_H
23 //
24 // field assignement from expresions, e.g.
25 //
26 // field xh = expr;
27 //
28 // author: Pierre.Saramito@imag.fr
29 //
30 // date: 13 september 2015
31 //
32 // Notes:
33 // check at compile time that the expression is affine
34 // check at run time that it is also homogneous in terms of approximation space
35 //
36 // 1. field assignments
37 // 1.1. field assignment members
38 // 1.2. computed assignment
39 // 2. misc
40 // 2.1. duality product
41 // 2.2. form d = diag (expr)
42 // 2.3. output a linear expession
43 
44 #include "rheolef/field_expr_recursive.h"
45 
46 namespace rheolef {
47 
48 // -------------------------------------------
49 // 1. field assignments
50 // -------------------------------------------
51 // 1.1. field assignment members
52 // -------------------------------------------
53 // 1.1.1 field
54 // -------------------------------------------
55 #ifdef TO_CLEAN
56 // uh = expr;
57 template<class T, class M>
58 template<class Expr>
59 inline
60 typename 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
64  ,field_basic<T, M>&
65 >::type
67 {
68  space_basic<T,M> Xh;
69  check_macro (expr.have_homogeneous_space (Xh),
70  "field = expr; expr should have homogeneous space. HINT: use field = interpolate(Xh, expr)");
71  if (get_space().name() != Xh.name()) {
72  resize (Xh);
73  }
74  details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
75  return *this;
76 }
77 // field uh = expr;
78 template<class T, class M>
79 template<class Expr, class Sfinae>
80 inline
82  : _V (),
83  _u (),
84  _b (),
85  _dis_dof_indexes_requires_update(true),
86  _dis_dof_assembly_requires_update(false)
87 {
88  operator= (expr);
89 }
90 #endif // TO_CLEAN
91 // ---------------------------------------------------------------------------
92 // 1.2. computed assignment
93 // ---------------------------------------------------------------------------
94 
95 // uh -+= expr
96 // uh [i_comp] -+= expr; // note: requires a move &&
97 // uh [domain] -+= expr;
98 #define _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
99 template<class T, class M, class Expr> \
100 inline \
101 typename std::enable_if< \
102  details::is_field_expr_affine_homogeneous<Expr>::value, \
103  field_basic<T,M>& \
104 >::type \
105 operator OP (field_basic<T,M>& uh, const Expr& expr) \
106 { \
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()); \
114  return uh; \
115 }
116 
117 #define _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, NAME, IDX) \
118 template<class FieldWdof, class FieldRdof> \
119 inline \
120 typename std::enable_if< \
121  details::is_field_expr_affine_homogeneous<FieldRdof>::value, \
122  NAME<FieldWdof>& \
123 >::type \
124 operator OP (NAME<FieldWdof>&& uh, const FieldRdof& expr) \
125 { \
126  using space_type = typename FieldWdof::space_type; \
127  space_type Xh; \
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()); \
134  return uh; \
135 }
136 
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")
141 
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
147 
148 // uh -+*/= c
149 // uh [i_comp] -+*/= c; // requires a move &&
150 // uh [domain] -+*/= c; // TODO
151 #define _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
152 template<class T, class M, class Expr> \
153 inline \
154 typename std::enable_if< \
155  details::is_field_expr_v2_constant<Expr>::value \
156  ,field_basic<T,M>& \
157 >::type \
158 operator OP (field_basic<T,M>& uh, const Expr& expr) \
159 { \
160  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
161  return uh; \
162 }
163 
164 #define _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, NAME, IDX) \
165 template<class FieldWdof, class Expr> \
166 inline \
167 typename std::enable_if< \
168  details::is_field_expr_v2_constant<Expr>::value \
169  ,NAME<FieldWdof>& \
170 >::type \
171 operator OP (NAME<FieldWdof>&& uh, const Expr& expr) \
172 { \
173  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
174  return uh; \
175 }
176 
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")
181 
185 _RHEOLEF_field_expr_v2_op_assign_constant (/=, details::divides_assign)
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
190 
191 // ---------------------------------------------------------------------------
192 // 2. misc
193 // ---------------------------------------------------------------------------
194 // 2.1. duality product
195 // ---------------------------------------------------------------------------
196 // dual (uh,vh)
197 template <class Expr1, class Expr2>
198 inline
199 typename
200 std::enable_if<
203  typename promote<
204  typename Expr1::float_type,
205  typename Expr2::float_type>::type
206 >::type
207 dual (const Expr1& expr1, const Expr2& expr2)
208 {
209  typedef typename Expr1::float_type T;
210  typedef typename Expr1::memory_type M;
212  check_macro (expr1.have_homogeneous_space (Xh1),
213  "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)");
214  check_macro (expr2.have_homogeneous_space (Xh2),
215  "dual(expr1,expr2); expr2 should have homogeneous space. HINT: use dual(expr1,interpolate(Xh, expr2))");
216  check_macro (Xh1.name() == Xh2.name(),
217  "dual(expr1,expr2); incompatible \""<<Xh1.name()<<"\" and \""<<Xh2.name()<<" spaces for expr1 and expr2");
218  return dis_inner_product (expr1.begin_dof(), expr2.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M());
219 }
220 // dual (c,uh)
221 template <class Expr1, class Expr2>
222 inline
223 typename
224 std::enable_if<
225  details::is_field_expr_v2_constant <Expr1>::value &&
226  details::is_field_expr_affine_homogeneous<Expr2>::value
227  ,typename Expr2::float_type
228 >::type
229 dual (const Expr1& expr1, const Expr2& expr2)
230 {
231  typedef typename Expr2::float_type T;
232  typedef typename Expr2::memory_type M;
233  space_basic<T,M> Xh2;
234  check_macro (expr2.have_homogeneous_space (Xh2),
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());
237 }
238 // dual (uh,c)
239 template <class Expr1, class Expr2>
240 inline
241 typename
242 std::enable_if<
243  details::is_field_expr_affine_homogeneous<Expr1>::value &&
244  details::is_field_expr_v2_constant <Expr2>::value
245  ,typename Expr1::float_type
246 >::type
247 dual (const Expr1& expr1, const Expr2& expr2)
248 {
249  typedef typename Expr1::float_type T;
250  typedef typename Expr1::memory_type M;
251  space_basic<T,M> Xh1;
252  check_macro (expr1.have_homogeneous_space (Xh1),
253  "dual(expr1,cte); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),cte)");
254  return dis_accumulate (expr1.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M())*expr2;
255 }
256 // ---------------------------------------------------------------------------
257 // 2.2. form d = diag (expr)
258 // ---------------------------------------------------------------------------
259 template<class Expr>
260 inline
261 typename
262 std::enable_if<
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>
266 >::type
267 diag (const Expr& expr)
268 {
269  typedef typename Expr::value_type T;
270  typedef typename Expr::memory_type M;
271  return diag (field_basic<T,M>(expr));
272 }
273 
274 } // namespace rheolef
275 #endif // _RHEOLEF_FIELD_EXPR_H
field_basic< T, M > & operator=(const field_basic< T, M > &)
Definition: field.h:894
rheolef::std type
Expr1::float_type T
Definition: field_expr.h:230
space_basic< T, M > Xh1
Definition: field_expr.h:232
Expr1::memory_type M
Definition: field_expr.h:231
#define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR)
Definition: field_expr.h:137
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
space_basic< T, M > Xh2
Definition: field_expr.h:232
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)
Definition: field_expr.h:177
void assign_with_operator(ForwardIterator first, ForwardIterator last, InputIterator iter_rhs, OpAssign op_assign)
This file is part of Rheolef.
std::enable_if< details::has_field_rdof_interface< Expr >::value &&! details::is_field< Expr >::value,form_basic< typename Expr::value_type, typename Expr::memory_type >>::type diag(const Expr &expr)
Definition: field_expr.h:267
std::iterator_traits< InputIterator >::value_type dis_accumulate(InputIterator first, Size n, const distributor::communicator_type &comm, sequential)
rheolef::std enable_if ::type dual const Expr1 expr1, const Expr2 expr2 dual(const Expr1 &expr1, const Expr2 &expr2)
Definition: field_expr.h:229
const_iterator begin_dof() const
Expr1::memory_type M
Definition: vec_expr_v2.h:416