Rheolef  7.1
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
3 //
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 // uh = expr;
56 template<class T, class M>
57 template<class Expr>
58 inline
59 typename std::enable_if<
60  details::is_field_expr_affine_homogeneous<Expr>::value
61  && ! details::is_field_expr_v2_constant <Expr>::value
62  && ! details::is_field <Expr>::value
63  ,field_basic<T, M>&
64 >::type
66 {
68  check_macro (expr.have_homogeneous_space (Xh),
69  "field = expr; expr should have homogeneous space. HINT: use field = interpolate(Xh, expr)");
70  if (name() != Xh.name()) {
71  resize (Xh);
72  }
73  details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
74  return *this;
75 }
76 // field uh = expr;
77 template<class T, class M>
78 template<class Expr, class Sfinae>
79 inline
81  : _V (),
82  _u (),
83  _b (),
84  _dis_dof_indexes_requires_update(true),
85  _dis_dof_assembly_requires_update(false)
86 {
88 }
89 // -------------------------------------------
90 // 1.1.2. field_component
91 // -------------------------------------------
92 // uh [i_comp] = expr;
93 template<class T, class M>
94 template<class Expr, class Sfinae>
95 inline
98 {
100  check_macro (expr.have_homogeneous_space (Xh),
101  "field [idx] = expr; expr should have homogeneous space. HINT: use field [idx] = interpolate(Xh, expr)");
102  check_macro (name() == Xh.name(), "field [i_comp] = expr : incompatible spaces "
103  << name() << " and " << Xh.name());
104  details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
105  return *this;
106 }
107 // -------------------------------------------
108 // 1.1.2. field_indirect
109 // -------------------------------------------
110 // uh [domain] = expr;
111 template<class T, class M>
112 template<class Expr, class Sfinae>
113 inline
116  space_basic<T,M> Xh;
117  check_macro (expr.have_homogeneous_space (Xh),
118  "field [domain] = expr; expr should have homogeneous space. HINT: use field [domain] = interpolate(Xh, expr)");
119  check_macro (name() == Xh.name(), "field [domain] = field_expression : incompatible spaces "
120  << name() << " and " << Xh.name());
121  details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
122  return *this;
123 }
124 // ---------------------------------------------------------------------------
125 // 1.2. computed assignment
126 // ---------------------------------------------------------------------------
127 
128 // uh -+= expr
129 // uh [i_comp] -+= expr; // note: requires a move &&
130 // uh [domain] -+= expr;
131 #define _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
132 template<class T, class M, class Expr> \
133 inline \
134 typename std::enable_if< \
135  details::is_field_expr_affine_homogeneous<Expr>::value, \
136  field_basic<T,M>& \
137 >::type \
138 operator OP (field_basic<T,M>& uh, const Expr& expr) \
139 { \
140  space_basic<T,M> Xh; \
141  check_macro (expr.have_homogeneous_space (Xh), \
142  "field [domain] " << #OP << " expr; expr should have homogeneous space. " \
143  << "HINT: use field [domain] " << #OP << " interpolate(Xh, expr)"); \
144  check_macro (uh.name() == Xh.name(), "field " << #OP << " field_expression : incompatible spaces " \
145  << uh.name() << " and " << Xh.name()); \
146  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
147  return uh; \
148 }
149 
150 #define _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, NAME, IDX) \
151 template<class T, class M, class Expr> \
152 inline \
153 typename std::enable_if< \
154  details::is_field_expr_affine_homogeneous<Expr>::value, \
155  NAME<T,M>& \
156 >::type \
157 operator OP (NAME<T,M>&& uh, const Expr& expr) \
158 { \
159  space_basic<T,M> Xh; \
160  check_macro (expr.have_homogeneous_space (Xh), \
161  "field [" << #IDX << "] " << #OP << " expr; expr should have homogeneous space. " \
162  << "HINT: use field [" << #IDX << "] " << #OP << " interpolate(Xh, expr)"); \
163  check_macro (uh.name() == Xh.name(), "field [" << #IDX << "] " << #OP << " field_expression : incompatible spaces " \
164  << uh.name() << " and " << Xh.name()); \
165  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
166  return uh; \
167 }
168 
169 #define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR) \
170  _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
171  _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, field_component, "i_comp") \
172  _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, field_indirect, "domain")
173 
176 #undef _RHEOLEF_field_expr_v2_op_assign_field
177 #undef _RHEOLEF_field_expr_v2_op_assign_auxil
178 #undef _RHEOLEF_field_expr_v2_op_assign
179 
180 // uh -+*/= c
181 // uh [i_comp] -+*/= c; // requires a move &&
182 // uh [domain] -+*/= c; // TODO
183 #define _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
184 template<class T, class M, class Expr> \
185 inline \
186 typename std::enable_if< \
187  details::is_field_expr_v2_constant<Expr>::value \
188  ,field_basic<T,M>& \
189 >::type \
190 operator OP (field_basic<T,M>& uh, const Expr& expr) \
191 { \
192  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
193  return uh; \
194 }
195 
196 #define _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, NAME, IDX) \
197 template<class T, class M, class Expr> \
198 inline \
199 typename std::enable_if< \
200  details::is_field_expr_v2_constant<Expr>::value \
201  ,NAME<T,M>& \
202 >::type \
203 operator OP (NAME<T,M>&& uh, const Expr& expr) \
204 { \
205  details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
206  return uh; \
207 }
208 
209 #define _RHEOLEF_field_expr_v2_op_assign_constant(OP, FUNCTOR) \
210  _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
211  _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, field_component, "i_comp") \
212  _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, field_indirect, "domain")
213 
217 _RHEOLEF_field_expr_v2_op_assign_constant (/=, details::divides_assign)
218 #undef _RHEOLEF_field_expr_v2_op_assign_constant_field
219 #undef _RHEOLEF_field_expr_v2_op_assign_constant_auxil
220 #undef _RHEOLEF_field_expr_v2_op_assign_constant
221 
222 // ---------------------------------------------------------------------------
223 // 2. misc
224 // ---------------------------------------------------------------------------
225 // 2.1. duality product
226 // ---------------------------------------------------------------------------
227 // dual (uh,vh)
228 template <class Expr1, class Expr2>
229 inline
230 typename
231 std::enable_if<
234  typename promote<
235  typename Expr1::float_type,
236  typename Expr2::float_type>::type
237 >::type
238 dual (const Expr1& expr1, const Expr2& expr2)
239 {
240  typedef typename Expr1::float_type T;
241  typedef typename Expr1::memory_type M;
243  check_macro (expr1.have_homogeneous_space (Xh1),
244  "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)");
245  check_macro (expr2.have_homogeneous_space (Xh2),
246  "dual(expr1,expr2); expr2 should have homogeneous space. HINT: use dual(expr1,interpolate(Xh, expr2))");
247  check_macro (Xh1.name() == Xh2.name(),
248  "dual(expr1,expr2); incompatible \""<<Xh1.name()<<"\" and \""<<Xh2.name()<<" spaces for expr1 and expr2");
249  return dis_inner_product (expr1.begin_dof(), expr2.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M());
250 }
251 // dual (c,uh)
252 template <class Expr1, class Expr2>
253 inline
254 typename
255 std::enable_if<
256  details::is_field_expr_v2_constant <Expr1>::value &&
257  details::is_field_expr_affine_homogeneous<Expr2>::value
258  ,typename Expr2::float_type
259 >::type
260 dual (const Expr1& expr1, const Expr2& expr2)
261 {
262  typedef typename Expr2::float_type T;
263  typedef typename Expr2::memory_type M;
264  space_basic<T,M> Xh2;
265  check_macro (expr2.have_homogeneous_space (Xh2),
266  "dual(cte,expr2); expr2 should have homogeneous space. HINT: use dual(cte,interpolate(Xh, expr2))");
267  return expr1*dis_accumulate (expr2.begin_dof(), Xh2.ndof(), Xh2.ownership().comm(), M());
268 }
269 // dual (uh,c)
270 template <class Expr1, class Expr2>
271 inline
272 typename
273 std::enable_if<
274  details::is_field_expr_affine_homogeneous<Expr1>::value &&
275  details::is_field_expr_v2_constant <Expr2>::value
276  ,typename Expr1::float_type
277 >::type
278 dual (const Expr1& expr1, const Expr2& expr2)
279 {
280  typedef typename Expr1::float_type T;
281  typedef typename Expr1::memory_type M;
282  space_basic<T,M> Xh1;
283  check_macro (expr1.have_homogeneous_space (Xh1),
284  "dual(expr1,cte); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),cte)");
285  return dis_accumulate (expr1.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M())*expr2;
286 }
287 // ---------------------------------------------------------------------------
288 // 2.2. form d = diag (expr)
289 // ---------------------------------------------------------------------------
290 template<class Expr>
291 inline
292 typename
293 std::enable_if<
297 >::type
298 diag (const Expr& expr)
299 {
300  typedef typename Expr::value_type T;
301  typedef typename Expr::memory_type M;
302  return diag (field_basic<T,M>(expr));
303 }
304 // -------------------------------------------
305 // 2.3. output a linear expession
306 // -------------------------------------------
307 template <class Expr>
308 inline
309 typename
310 std::enable_if<
311  details::is_field_convertible<Expr>::value
312  && ! details::is_field<Expr>::value
313  ,odiststream&
315 operator<< (odiststream& ops, const Expr& expr) {
316  // distributed case: communications requires to store in memory
317  // and create a temporary
318  typedef typename Expr::value_type T;
319  typedef typename Expr::memory_type M;
321  return tmp.put (ops);
322 }
323 
324 } // namespace rheolef
325 #endif // _RHEOLEF_FIELD_EXPR_H
Xh1
space_basic< T, M > Xh1
Definition: field_expr.h:263
rheolef::begin_dof
const_iterator begin_dof() const
Definition: field_expr_recursive.h:569
M
Expr1::memory_type M
Definition: field_expr.h:262
mkgeo_ball.expr
expr
Definition: mkgeo_ball.sh:361
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::details::multiplies_assign
Definition: expr_utilities.h:127
rheolef::details::assign_with_operator
void assign_with_operator(ForwardIterator first, ForwardIterator last, InputIterator iter_rhs, OpAssign op_assign)
Definition: expr_utilities.h:137
rheolef::details::is_field_expr_affine_homogeneous
Definition: field.h:229
rheolef::diag
csr< T, M > diag(const vec< T, M > &d)
Definition: csr.cc:56
rheolef::dis_inner_product
promote< typename std::iterator_traits< InputIterator1 >::value_type, typename std::iterator_traits< InputIterator2 >::value_type >::type dis_inner_product(InputIterator1 first1, InputIterator2 first2, Size n, const distributor::communicator_type &comm, sequential)
Definition: dis_inner_product.h:72
rheolef::details::assign_op
Definition: expr_utilities.h:115
rheolef::_RHEOLEF_field_expr_v2_op_assign_constant
_RHEOLEF_field_expr_v2_op_assign_constant(+=, details::plus_assign) _RHEOLEF_field_expr_v2_op_assign_constant(-
rheolef::space_basic
the finite element space
Definition: space.h:352
rheolef::dual
rheolef::std enable_if ::type dual const Expr1 expr1, const Expr2 expr2 dual(const Expr1 &expr1, const Expr2 &expr2)
Definition: field_expr.h:260
rheolef::field_basic::field_basic
field_basic()
Definition: field.h:608
rheolef::field_indirect
Definition: field_indirect.h:39
rheolef::type
rheolef::std type
rheolef::field_basic
Definition: field.h:235
rheolef::field_component
Definition: field_component.h:61
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
rheolef::_RHEOLEF_field_expr_v2_op_assign
_RHEOLEF_field_expr_v2_op_assign(+=, details::plus_assign) _RHEOLEF_field_expr_v2_op_assign(-
rheolef::odiststream
odiststream: see the diststream page for the full documentation
Definition: diststream.h:126
rheolef::dis_accumulate
std::iterator_traits< InputIterator >::value_type dis_accumulate(InputIterator first, Size n, const distributor::communicator_type &comm, sequential)
Definition: dis_accumulate.h:61
rheolef::details::minus_assign
Definition: expr_utilities.h:123
rheolef::field_component::operator=
field_component< T, M > & operator=(const T &alpha)
Definition: field_component.h:322
rheolef::form_basic
Definition: form.h:144
rheolef::field_indirect::operator=
field_indirect< T, M > & operator=(const T &alpha)
Definition: field_indirect.h:131
Xh2
space_basic< T, M > Xh2
Definition: field_expr.h:263
rheolef::promote
Definition: promote.h:29
rheolef::Expr1
rheolef::std Expr1
dot(x,y): see the expression page for the full documentation
rheolef::field_basic::operator=
field_basic< T, M > & operator=(const field_basic< T, M > &)
Definition: field.h:619
mkgeo_ball.tmp
tmp
Definition: mkgeo_ball.sh:380
rheolef::operator<<
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition: catchmark.h:99
rheolef::details::plus_assign
Definition: expr_utilities.h:119
mkgeo_contraction.name
string name
Definition: mkgeo_contraction.sh:133
M
Expr1::memory_type M
Definition: vec_expr_v2.h:416
rheolef::details::is_field
Definition: field_expr_terminal.h:61
T
Expr1::float_type T
Definition: field_expr.h:261
rheolef::details::is_field_convertible
Definition: field_expr_terminal.h:65