Rheolef  7.1
an efficient C++ finite element environment
newton_add_missing.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_NEWTON_ADD_MISSING_H
2 #define _RHEOLEF_NEWTON_ADD_MISSING_H
3 // there are two versions of this algorithm
24 // - one with imbeded mesh adaptation loop
25 // - one without this feature
26 // the algorithm is automatically selected when there is an adapt() method
27 // in the supplied problem definition
28 //
29 #include "rheolef/continuation_option.h"
30 #include "rheolef/damped_newton.h"
31 #include <type_traits>
32 
33 namespace rheolef { namespace details {
34 
35 // -----------------------------------------------------------------------------
36 // predicates: have some member functions ?
37 // -----------------------------------------------------------------------------
38 // => will provides a default behavior when the member is missing
39 //
40 // solution from:
41 // https://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions
42 // note: it works with derived classes but do not check yet
43 // whether the named member is a data or a function
44 // and do not check for its profile.
45 //
46 #define _RHEOLEF_has_inherited_member_macro(NAME) \
47 template <typename Type> \
48 class has_inherited_member_##NAME { \
49  class yes { char m;}; \
50  class no { yes m[2];}; \
51  struct base_mixin { void NAME(){} }; \
52  struct base : public Type, public base_mixin {}; \
53  template <typename T, T t> class helper{}; \
54  template <typename U> \
55  static no deduce(U*, helper<void (base_mixin::*)(), &U::NAME>* = 0); \
56  static yes deduce(...); \
57 public: \
58  static const bool value = sizeof(yes) == sizeof(deduce((base*)(0))); \
59  typedef std::integral_constant<bool, value> type; \
60 };
61 
62 // -----------------------------------------------------------------------------
63 // void adapt (const value_type&, const adapt_option&);
64 // -----------------------------------------------------------------------------
66 
67 template<class Problem, class Sfinae = typename has_inherited_member_adapt<Problem>::type>
68 struct add_adapt{};
69 
70 template<class Problem>
71 class add_adapt<Problem,std::true_type>: public virtual Problem {
72 public:
73  typedef typename Problem::float_type float_type;
74  typedef typename Problem::value_type value_type;
75  add_adapt(const add_adapt& f) : Problem(f) {}
76  explicit add_adapt(const Problem& f) : Problem(f) {}
77  add_adapt<Problem>& operator= (add_adapt<Problem>&& f) {
78  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
79  return *this;
80  }
81 };
82 template<class Problem>
83 class add_adapt<Problem,std::false_type>: public virtual Problem {
84 public:
85  typedef typename Problem::float_type float_type;
86  typedef typename Problem::value_type value_type;
87  add_adapt(const add_adapt& f) : Problem(f) {}
88  explicit add_adapt(const Problem& f) : Problem(f) {}
89  void adapt (const value_type&, const adapt_option&) const {}
90  void reset_geo (const value_type&) {}
91  value_type reinterpolate (const value_type& uh) { return uh; }
92  add_adapt<Problem>& operator= (add_adapt<Problem>&& f) {
93  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
94  return *this;
95  }
96 };
97 // -----------------------------------------------------------------------------
98 // void refresh (float_type, const value_type&, const value_type&) const;
99 // -----------------------------------------------------------------------------
100 // note: used by the keller continuation method
101 
103 
104 template<class Problem, class Sfinae = typename has_inherited_member_refresh<Problem>::type>
105 struct add_refresh{};
106 
107 template<class Problem>
108 class add_refresh<Problem,std::true_type>: public virtual Problem {
109 public:
110  typedef typename Problem::float_type float_type;
111  typedef typename Problem::value_type value_type;
112  add_refresh(const add_refresh& f) : Problem(f) {}
113  explicit add_refresh(const Problem& f) : Problem(f) {}
114  add_refresh<Problem>& operator= (add_refresh<Problem>&& f) {
115  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
116  return *this;
117  }
118 };
119 template<class Problem>
120 class add_refresh<Problem,std::false_type>: public virtual Problem {
121 public:
122  typedef typename Problem::float_type float_type;
123  typedef typename Problem::value_type value_type;
124  add_refresh(const add_refresh& f) : Problem(f) {}
125  explicit add_refresh(const Problem& f) : Problem(f) {}
126  void refresh (float_type, const value_type&, const value_type&) const {}
127  add_refresh<Problem>& operator= (add_refresh<Problem>&& f) {
128  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
129  return *this;
130  }
131 };
132 // -----------------------------------------------------------------------------
133 // value_type direction (const value_type&) const;
134 // -----------------------------------------------------------------------------
135 // used by the continuation method ; redefined by keller
136 
138 
139 template<class Problem, class Sfinae = typename has_inherited_member_direction<Problem>::type>
140 struct add_direction{};
141 
142 template<class Problem>
143 class add_direction<Problem,std::true_type>: public virtual Problem {
144 public:
145  typedef typename Problem::float_type float_type;
146  typedef typename Problem::value_type value_type;
147  add_direction(const add_direction& f) : Problem(f) {}
148  explicit add_direction(const Problem& f) : Problem(f) {}
149  add_direction<Problem>& operator= (add_direction<Problem>&& f) {
150  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
151  return *this;
152  }
153 };
154 template<class Problem>
155 class add_direction<Problem,std::false_type>: public virtual Problem {
156 public:
157  typedef typename Problem::float_type float_type;
158  typedef typename Problem::value_type value_type;
159  add_direction(const add_direction& f) : Problem(f) {}
160  explicit add_direction(const Problem& f) : Problem(f) {}
161  value_type direction (const value_type& uh) const {
162  Problem::update_derivative (uh);
163  return - Problem::derivative_solve (Problem::derivative_versus_parameter(uh));
164  }
165  add_direction<Problem>& operator= (add_direction<Problem>&& f) {
166  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
167  return *this;
168  }
169 };
170 // -----------------------------------------------------------------------------
171 // float_type space_norm (const value_type&) const;
172 // -----------------------------------------------------------------------------
173 
175 
176 template<class Problem, class Sfinae = typename has_inherited_member_space_norm<Problem>::type>
177 struct add_space_norm{};
178 
179 template<class Problem>
180 class add_space_norm<Problem,std::true_type>: public virtual Problem {
181 public:
182  typedef typename Problem::float_type float_type;
183  typedef typename Problem::value_type value_type;
184  add_space_norm(const add_space_norm& f) : Problem(f) {}
185  explicit add_space_norm(const Problem& f) : Problem(f) {}
186  add_space_norm<Problem>& operator= (add_space_norm<Problem>&& f) {
187  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
188  return *this;
189  }
190 };
191 template<class Problem>
192 class add_space_norm<Problem,std::false_type>: public virtual Problem {
193 public:
194  typedef typename Problem::float_type float_type;
195  typedef typename Problem::value_type value_type;
196  add_space_norm(const add_space_norm& f) : Problem(f) {}
197  explicit add_space_norm(const Problem& f) : Problem(f) {}
198  float_type space_norm (const value_type& uh) const {
199  return sqrt(Problem::space_dot (uh,uh));
200  }
201  add_space_norm<Problem>& operator= (add_space_norm<Problem>&& f) {
202  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
203  return *this;
204  }
205 };
206 // -----------------------------------------------------------------------------
207 // float_type dual_space_norm (const value_type&) const;
208 // -----------------------------------------------------------------------------
209 
211 
212 template<class Problem, class Sfinae = typename details::has_inherited_member_dual_space_norm<Problem>::type>
213 struct add_dual_space_norm{};
214 
215 template<class Problem>
216 class add_dual_space_norm<Problem,std::true_type>: public virtual Problem {
217 public:
218  typedef typename Problem::float_type float_type;
219  typedef typename Problem::value_type value_type;
220  add_dual_space_norm(const add_dual_space_norm& f) : Problem(f) {}
221  explicit add_dual_space_norm(const Problem& f) : Problem(f) {}
222  add_dual_space_norm<Problem>& operator= (add_dual_space_norm<Problem>&& f) {
223  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
224  return *this;
225  }
226 };
227 template<class Problem>
228 class add_dual_space_norm<Problem,std::false_type>: public virtual Problem {
229 public:
230  typedef typename Problem::float_type float_type;
231  typedef typename Problem::value_type value_type;
232  add_dual_space_norm(const add_dual_space_norm& f) : Problem(f) {}
233  explicit add_dual_space_norm(const Problem& f) : Problem(f) {}
235  return sqrt(Problem::dual_space_dot (uh,uh));
236  }
237  add_dual_space_norm<Problem>& operator= (add_dual_space_norm<Problem>&& f) {
238  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
239  return *this;
240  }
241 };
242 // -----------------------------------------------------------------------------
243 // add_missing: complete the problem class used by the continuation method
244 // -----------------------------------------------------------------------------
245 template<class Problem>
247  public virtual add_space_norm<Problem>
248  ,public virtual add_dual_space_norm<Problem>
249 {
250 public:
251  typedef typename Problem::float_type float_type;
252  typedef typename Problem::value_type value_type;
254  Problem(f)
255  ,add_space_norm<Problem>(f)
256  ,add_dual_space_norm<Problem>(f)
257  {}
258  add_missing_damped_newton(const Problem& f) :
259  Problem(f)
260  ,add_space_norm<Problem>(f)
261  ,add_dual_space_norm<Problem>(f)
262  {}
264  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
265  return *this;
266  }
267 };
268 template<class Problem>
270  public virtual add_adapt <Problem>
271  ,public virtual add_refresh <Problem>
272  ,public virtual add_direction <Problem>
273  ,public virtual add_space_norm<Problem>
274  ,public virtual add_dual_space_norm<Problem>
275 {
276 public:
277  typedef typename Problem::float_type float_type;
278  typedef typename Problem::value_type value_type;
280  Problem(f)
281  ,add_adapt<Problem>(f)
282  ,add_refresh<Problem>(f)
283  ,add_direction<Problem>(f)
284  ,add_space_norm<Problem>(f)
285  ,add_dual_space_norm<Problem>(f)
286  {}
287  add_missing_continuation(const Problem& f) :
288  Problem(f)
289  ,add_adapt<Problem>(f)
290  ,add_refresh<Problem>(f)
291  ,add_direction<Problem>(f)
292  ,add_space_norm<Problem>(f)
293  ,add_dual_space_norm<Problem>(f)
294  {}
296  static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
297  return *this;
298  }
299 };
300 
301 #undef _RHEOLEF_has_inherited_member_macro
302 
303 }} // namespace rheolef::details
304 #endif // _RHEOLEF_NEWTON_ADD_MISSING_H
rheolef::details::add_space_norm< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:195
rheolef::details::add_direction< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:157
rheolef::details::add_refresh< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:123
rheolef::details::add_missing_damped_newton::add_missing_damped_newton
add_missing_damped_newton(const Problem &f)
Definition: newton_add_missing.h:258
rheolef::adapt
geo_basic< T, M > adapt(const field_basic< T, M > &uh, const adapt_option &opts)
adapt(uh,opts): see the adapt page for the full documentation
Definition: adapt.cc:172
rheolef::details::add_direction< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:158
rheolef::details::add_missing_continuation
Definition: newton_add_missing.h:269
rheolef::details::add_adapt< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:85
rheolef::details::add_adapt< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:73
rheolef::details::add_direction< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:146
rheolef::details::add_missing_continuation::operator=
add_missing_continuation< Problem > & operator=(add_missing_continuation< Problem > &&f)
Definition: newton_add_missing.h:295
rheolef::details::add_dual_space_norm< Problem, std::false_type >::add_dual_space_norm
add_dual_space_norm(const add_dual_space_norm &f)
Definition: newton_add_missing.h:232
rheolef::details::add_missing_damped_newton::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:251
rheolef::details::add_space_norm< Problem, std::true_type >::add_space_norm
add_space_norm(const Problem &f)
Definition: newton_add_missing.h:185
rheolef::adapt_option
adapt_option: see the adapt page for the full documentation
Definition: adapt.h:147
rheolef::details::add_direction< Problem, std::false_type >::add_direction
add_direction(const add_direction &f)
Definition: newton_add_missing.h:159
rheolef::details::add_adapt< Problem, std::false_type >::add_adapt
add_adapt(const add_adapt &f)
Definition: newton_add_missing.h:87
rheolef::details::add_adapt< Problem, std::false_type >::add_adapt
add_adapt(const Problem &f)
Definition: newton_add_missing.h:88
rheolef::details::add_direction< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:145
rheolef::details::add_missing_continuation::add_missing_continuation
add_missing_continuation(const Problem &f)
Definition: newton_add_missing.h:287
rheolef::details::add_dual_space_norm< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:218
rheolef::details::add_adapt< Problem, std::false_type >::reinterpolate
value_type reinterpolate(const value_type &uh)
Definition: newton_add_missing.h:91
rheolef::details::add_adapt< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:86
rheolef::details::add_dual_space_norm< Problem, std::true_type >::add_dual_space_norm
add_dual_space_norm(const Problem &f)
Definition: newton_add_missing.h:221
rheolef::details::add_dual_space_norm< Problem, std::false_type >::dual_space_norm
float_type dual_space_norm(const value_type &uh) const
Definition: newton_add_missing.h:234
rheolef::details::add_space_norm< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:194
rheolef::details::add_refresh< Problem, std::false_type >::refresh
void refresh(float_type, const value_type &, const value_type &) const
Definition: newton_add_missing.h:126
rheolef::details::add_missing_continuation::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:277
rheolef::details::add_missing_damped_newton::operator=
add_missing_damped_newton< Problem > & operator=(add_missing_damped_newton< Problem > &&f)
Definition: newton_add_missing.h:263
rheolef::details::add_missing_damped_newton
Definition: newton_add_missing.h:246
rheolef::details::add_refresh< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:122
rheolef::details::add_missing_damped_newton::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:252
rheolef::details::add_adapt< Problem, std::false_type >::adapt
void adapt(const value_type &, const adapt_option &) const
Definition: newton_add_missing.h:89
rheolef::details::add_space_norm< Problem, std::false_type >::add_space_norm
add_space_norm(const Problem &f)
Definition: newton_add_missing.h:197
rheolef::details::add_space_norm< Problem, std::false_type >::space_norm
float_type space_norm(const value_type &uh) const
Definition: newton_add_missing.h:198
rheolef::details::add_space_norm< Problem, std::true_type >::add_space_norm
add_space_norm(const add_space_norm &f)
Definition: newton_add_missing.h:184
rheolef::details::add_space_norm< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:182
rheolef::details::add_direction< Problem, std::false_type >::add_direction
add_direction(const Problem &f)
Definition: newton_add_missing.h:160
rheolef::details::add_missing_continuation::add_missing_continuation
add_missing_continuation(const add_missing_continuation< Problem > &f)
Definition: newton_add_missing.h:279
rheolef::details::add_missing_continuation::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:278
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
rheolef::details::add_refresh< Problem, std::false_type >::add_refresh
add_refresh(const add_refresh &f)
Definition: newton_add_missing.h:124
rheolef::details::add_direction< Problem, std::false_type >::direction
value_type direction(const value_type &uh) const
Definition: newton_add_missing.h:161
rheolef::details::add_refresh< Problem, std::true_type >::add_refresh
add_refresh(const add_refresh &f)
Definition: newton_add_missing.h:112
rheolef::details::add_refresh< Problem, std::false_type >::add_refresh
add_refresh(const Problem &f)
Definition: newton_add_missing.h:125
rheolef::details::add_dual_space_norm< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:219
rheolef::details::add_refresh< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:110
rheolef::details::add_adapt< Problem, std::true_type >::add_adapt
add_adapt(const add_adapt &f)
Definition: newton_add_missing.h:75
rheolef::details::add_dual_space_norm< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:231
rheolef::details::add_missing_damped_newton::add_missing_damped_newton
add_missing_damped_newton(const add_missing_damped_newton< Problem > &f)
Definition: newton_add_missing.h:253
rheolef::details::add_direction< Problem, std::true_type >::add_direction
add_direction(const add_direction &f)
Definition: newton_add_missing.h:147
rheolef::details::add_direction< Problem, std::true_type >::add_direction
add_direction(const Problem &f)
Definition: newton_add_missing.h:148
rheolef::details::add_adapt< Problem, std::false_type >::reset_geo
void reset_geo(const value_type &)
Definition: newton_add_missing.h:90
rheolef::details::add_refresh< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:111
rheolef::details::add_dual_space_norm< Problem, std::false_type >::add_dual_space_norm
add_dual_space_norm(const Problem &f)
Definition: newton_add_missing.h:233
f
Definition: cavity_dg.h:29
rheolef::details::add_refresh< Problem, std::true_type >::add_refresh
add_refresh(const Problem &f)
Definition: newton_add_missing.h:113
rheolef::details::add_dual_space_norm< Problem, std::true_type >::add_dual_space_norm
add_dual_space_norm(const add_dual_space_norm &f)
Definition: newton_add_missing.h:220
rheolef::details::add_dual_space_norm< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:230
rheolef::details::add_space_norm< Problem, std::false_type >::add_space_norm
add_space_norm(const add_space_norm &f)
Definition: newton_add_missing.h:196
rheolef::details::add_adapt< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:74
rheolef::std
Definition: vec_expr_v2.h:391
rheolef::details::_RHEOLEF_has_inherited_member_macro
_RHEOLEF_has_inherited_member_macro(adapt) template< class Problem
rheolef::details::add_adapt< Problem, std::true_type >::add_adapt
add_adapt(const Problem &f)
Definition: newton_add_missing.h:76
rheolef::details::add_space_norm< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:183