Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
field_lazy_node.h
Go to the documentation of this file.
1# ifndef _RHEOLEF_FIELD_LAZY_NODE_H
2# define _RHEOLEF_FIELD_LAZY_NODE_H
3//
4// This file is part of Rheolef.
5//
6// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
7//
8// Rheolef is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 2 of the License, or
11// (at your option) any later version.
12//
13// Rheolef is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with Rheolef; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// =========================================================================
23// field_lazy = un-assembled field
24// as returned by lazy_integrate, lazy_interpolate or encapsulated field_basic
25// here, they are combined with +- operators
26// AUTHOR: Pierre.Saramito@imag.fr
27// DATE: 6 april 1920
28
29// SUMMARY: see also "field_lazy_terminal.h"
30// 3. unary expressions
31// 3.1. unary_minus & unary_plus
32// 4. binary expressions
33// 4.1. add & minus
34//
35#include "rheolef/field_lazy_terminal.h"
36
37namespace rheolef {
38
39// -------------------------------------------------------------------
40// 3. unary expressions
41// -------------------------------------------------------------------
42// 3.1. unary_minus & unary_plus
43// -------------------------------------------------------------------
44namespace details {
45
46template<class Unop, class Expr>
47class field_lazy_unop: public field_lazy_base<field_lazy_unop<Unop,Expr>> {
48public :
49// definitions:
50
53 using memory_type = typename Expr::memory_type;
54 using scalar_type = typename Expr::scalar_type;
55 using space_type = typename Expr::space_type;
56 using geo_type = typename Expr::geo_type;
59 using vector_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,1>;
60
61// allocator:
62
63 field_lazy_unop (const Unop& unop, const Expr& expr)
64 : base(),
65 _unop(unop),
66 _expr(expr)
67 {}
68
69// accessors:
70
71 const geo_type& get_geo() const { return _expr.get_geo(); }
72 const space_type& get_space() const { return _expr.get_space(); }
73 bool is_on_band() const { return _expr.is_on_band(); }
74 band_type get_band() const { return _expr.get_band(); }
75
76 void initialize (const geo_type& omega_K) { _expr.initialize (omega_K); }
77
78 void evaluate (
79 const geo_type& omega_K,
80 const geo_element& K,
81 vector_element_type& uk) const;
82// data:
83protected:
84 Unop _unop;
85 Expr _expr;
86};
87// concept;
88template<class Unop, class Expr>
89struct is_field_lazy <field_lazy_unop<Unop,Expr> > : std::true_type {};
90
91// inlined:
92template<class Unop, class Expr>
93void
95 const geo_type& omega_K,
96 const geo_element& K,
97 vector_element_type& uk) const
98{
99 _expr.evaluate (omega_K, K, uk);
100 uk = uk.unaryExpr(_unop);
101}
102
103}// namespace details
104
106#define _RHEOLEF_field_lazy_unop(OP,NAME) \
107template<class Expr, class Sfinae = typename std::enable_if<details::is_field_lazy<Expr>::value, Expr>::type> \
108details::field_lazy_unop<NAME,Expr> \
109operator OP (const Expr& u) \
110{ \
111 return details::field_lazy_unop<NAME,Expr> (NAME(),u); \
112}
115#undef _RHEOLEF_field_lazy_unop
116// -------------------------------------------------------------------
117// 4. binary expressions
118// -------------------------------------------------------------------
119// 4.1. add & minus
120// -------------------------------------------------------------------
121namespace details {
122
123template<class Binop, class Expr1, class Expr2>
124class field_lazy_add: public field_lazy_base<field_lazy_add<Binop,Expr1,Expr2>> {
125public :
126// definitions:
127
130 using memory_type = typename Expr1::memory_type;
131 using scalar_type = typename Expr1::scalar_type;
132 using space_type = typename Expr1::space_type;
133 using geo_type = typename Expr1::geo_type;
136 using vector_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,1>;
137
138// allocator:
139
140 field_lazy_add (const Expr1& expr1, const Expr2& expr2)
141 : base(),
142 _binop(),
143 _expr1(expr1),
144 _expr2(expr2) {}
145
146// accessors:
147
148 const geo_type& get_geo() const;
149 const space_type& get_space() const { return _expr1.get_space(); }
150 bool is_on_band() const { return _expr1.is_on_band(); }
151 band_type get_band() const { return _expr1.get_band(); }
152
153 void initialize (const geo_type& omega_K);
154
155 void evaluate (
156 const geo_type& omega_K,
157 const geo_element& K,
158 vector_element_type& uk) const;
159// data:
160protected:
161 Binop _binop;
162 Expr1 _expr1;
163 Expr2 _expr2;
164};
165// concept;
166template<class Binop, class Expr1, class Expr2>
167struct is_field_lazy <field_lazy_add<Binop,Expr1,Expr2> > : std::true_type {};
168
169// inlined:
170template<class Binop, class Expr1, class Expr2>
173{
174 // TODO: improve the automatic determination of the domain
175 // by an union that operates recursively
176 const geo_type& dom1 = _expr1.get_geo();
177 const geo_type& dom2 = _expr2.get_geo();
178 if (dom1 == dom2 || dom1 == dom2.get_background_geo() || dom1.is_broken()) {
179 trace_macro("lazy_add: union("<<dom1.name()<<","<<dom2.name()<<")="<<dom1.name());
180 return dom1;
181 } else if (dom2 == dom1.get_background_geo() || dom2.is_broken()) {
182 trace_macro("lazy_add: union("<<dom1.name()<<","<<dom2.name()<<")="<<dom2.name());
183 return dom2;
184 } else {
185 error_macro("lazy_add: incompatible domains \""<<dom1.name()
186 << "\" and \"" << dom2.name() << "\"");
187 return dom2;
188 }
189 check_macro (_expr1.is_on_band() == _expr2.is_on_band(),
190 "lazy_add: invalid combination of banded and non-banded geoetry");
191}
192template<class Binop, class Expr1, class Expr2>
193void
195{
196 check_macro (_expr1.get_space() == _expr2.get_space(),
197 "lazy_add: incompatible spaces "
198 << "\"" <<_expr1.get_space().name()<<"\" and \"" <<_expr2.get_space().name()<<"\"");
199
200 _expr1.initialize (omega_K);
201 _expr2.initialize (omega_K);
202}
203template<class Binop, class Expr1, class Expr2>
204void
206 const geo_type& omega_K,
207 const geo_element& K,
208 vector_element_type& wk) const
209{
210 vector_element_type uk, vk;
211 _expr1.evaluate (omega_K, K, uk);
212 _expr2.evaluate (omega_K, K, vk);
213#ifdef _RHEOLEF_PARANO
214 check_macro (uk.size() == vk.size(), "u+v: invalid sizes");
215#endif // _RHEOLEF_PARANO
216 wk = uk.binaryExpr (vk, _binop);
217}
218
219}// namespace details
220
222#define _RHEOLEF_field_lazy_add(OP,NAME) \
223template<class Expr1, class Expr2, \
224 class Sfinae1 = typename std::enable_if<details::is_field_lazy<Expr1>::value, Expr1>::type, \
225 class Sfinae2 = typename std::enable_if<details::is_field_lazy<Expr2>::value, Expr2>::type> \
226details::field_lazy_add<details::NAME,Expr1,Expr2> \
227operator OP (const Expr1& u, const Expr2& v) \
228{ \
229 return details::field_lazy_add<details::NAME,Expr1,Expr2> (u,v); \
230} \
231template<class Expr1, \
232 class Sfinae1 = typename std::enable_if<details::is_field_lazy<Expr1>::value, Expr1>::type> \
233details::field_lazy_add< \
234 details::NAME \
235 ,Expr1 \
236 ,details::field_lazy_terminal_field<typename Expr1::scalar_type,typename Expr1::memory_type> \
237> \
238operator OP (const Expr1& u, const field_basic<typename Expr1::scalar_type,typename Expr1::memory_type>& v) \
239{ \
240 using Expr2 = details::field_lazy_terminal_field<typename Expr1::scalar_type,typename Expr1::memory_type>; \
241 return details::field_lazy_add<details::NAME,Expr1,Expr2> (u,Expr2(v)); \
242} \
243template<class Expr2, \
244 class Sfinae2 = typename std::enable_if<details::is_field_lazy<Expr2>::value, Expr2>::type> \
245details::field_lazy_add< \
246 details::NAME \
247 ,details::field_lazy_terminal_field<typename Expr2::scalar_type,typename Expr2::memory_type> \
248 ,Expr2 \
249> \
250operator OP (const field_basic<typename Expr2::scalar_type,typename Expr2::memory_type>& u, const Expr2& v) \
251{ \
252 using Expr1 = details::field_lazy_terminal_field<typename Expr2::scalar_type,typename Expr2::memory_type>; \
253 return details::field_lazy_add<details::NAME,Expr1,Expr2> (Expr1(u),v); \
254}
257#undef _RHEOLEF_field_lazy_add
258
259}// namespace rheolef
260# endif /* _RHEOLEF_FIELD_LAZY_NODE_H */
geo_element::size_type size_type
typename Expr1::scalar_type scalar_type
typename Expr1::memory_type memory_type
void evaluate(const geo_type &omega_K, const geo_element &K, vector_element_type &uk) const
void initialize(const geo_type &omega_K)
const geo_type & get_geo() const
Eigen::Matrix< scalar_type, Eigen::Dynamic, 1 > vector_element_type
typename float_traits< scalar_type >::type float_type
typename Expr1::space_type space_type
const space_type & get_space() const
typename Expr1::geo_type geo_type
field_lazy_add(const Expr1 &expr1, const Expr2 &expr2)
geo_element::size_type size_type
void evaluate(const geo_type &omega_K, const geo_element &K, vector_element_type &uk) const
void initialize(const geo_type &omega_K)
typename Expr::geo_type geo_type
typename Expr::scalar_type scalar_type
typename Expr::memory_type memory_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, 1 > vector_element_type
typename float_traits< scalar_type >::type float_type
const geo_type & get_geo() const
const space_type & get_space() const
typename Expr::space_type space_type
field_lazy_unop(const Unop &unop, const Expr &expr)
see the geo_element page for the full documentation
reference_element::size_type size_type
#define trace_macro(message)
Definition dis_macros.h:111
#define error_macro(message)
Definition dis_macros.h:49
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_lazy_unop(OP, NAME)
-u, +u: see the field page for the full documentation
#define _RHEOLEF_field_lazy_add(OP, NAME)
u+v, u-v: see the field page for the full documentation
This file is part of Rheolef.