Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
46namespace 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;
57template<class T, class M>
58template<class Expr>
59inline
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
64 ,field_basic<T, M>&
65>::type
66field_basic<T,M>::operator= (const Expr& expr)
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;
78template<class T, class M>
79template<class Expr, class Sfinae>
80inline
81field_basic<T,M>::field_basic (const Expr& expr)
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) \
99template<class T, class M, class Expr> \
100inline \
101typename std::enable_if< \
102 details::is_field_expr_affine_homogeneous<Expr>::value, \
103 field_basic<T,M>& \
104>::type \
105operator 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) \
118template<class FieldWdof, class FieldRdof> \
119inline \
120typename std::enable_if< \
121 details::is_field_expr_affine_homogeneous<FieldRdof>::value, \
122 NAME<FieldWdof>& \
123>::type \
124operator 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) \
152template<class T, class M, class Expr> \
153inline \
154typename std::enable_if< \
155 details::is_field_expr_v2_constant<Expr>::value \
156 ,field_basic<T,M>& \
157>::type \
158operator 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) \
165template<class FieldWdof, class Expr> \
166inline \
167typename std::enable_if< \
168 details::is_field_expr_v2_constant<Expr>::value \
169 ,NAME<FieldWdof>& \
170>::type \
171operator 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)
197template <class Expr1, class Expr2>
198inline
199typename
200std::enable_if<
203 typename promote<
204 typename Expr1::float_type,
205 typename Expr2::float_type>::type
206>::type
207dual (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)
221template <class Expr1, class Expr2>
222inline
223typename
224std::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
229dual (const Expr1& expr1, const Expr2& expr2)
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());
238// dual (uh,c)
239template <class Expr1, class Expr2>
240inline
241typename
242std::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
247dual (const Expr1& expr1, const Expr2& expr2)
248{
249 typedef typename Expr1::float_type T;
250 typedef typename Expr1::memory_type M;
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// ---------------------------------------------------------------------------
259template<class Expr>
260inline
261typename
262std::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
267diag (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
the finite element space
Definition space.h:382
Expr1::float_type T
Definition field_expr.h:230
space_basic< T, M > Xh1
Definition field_expr.h:232
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
Expr1::memory_type M
Definition field_expr.h:231
#define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR)
Definition field_expr.h:137
return dis_inner_product(expr1.begin_dof(), expr2.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M())
space_basic< T, M > Xh2
Definition field_expr.h:232
#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.
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
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)
Definition csr.cc:56
Expr1::memory_type M