Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
23// 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
33namespace 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) \
47template <typename Type> \
48class 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(...); \
57public: \
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
67template<class Problem, class Sfinae = typename has_inherited_member_adapt<Problem>::type>
68struct add_adapt{};
69
70template<class Problem>
71class add_adapt<Problem,std::true_type>: public virtual Problem {
72public:
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};
82template<class Problem>
83class add_adapt<Problem,std::false_type>: public virtual Problem {
84public:
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
104template<class Problem, class Sfinae = typename has_inherited_member_refresh<Problem>::type>
105struct add_refresh{};
106
107template<class Problem>
108class add_refresh<Problem,std::true_type>: public virtual Problem {
109public:
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};
119template<class Problem>
120class add_refresh<Problem,std::false_type>: public virtual Problem {
121public:
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
139template<class Problem, class Sfinae = typename has_inherited_member_direction<Problem>::type>
140struct add_direction{};
141
142template<class Problem>
143class add_direction<Problem,std::true_type>: public virtual Problem {
144public:
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};
154template<class Problem>
155class add_direction<Problem,std::false_type>: public virtual Problem {
156public:
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
176template<class Problem, class Sfinae = typename has_inherited_member_space_norm<Problem>::type>
177struct add_space_norm{};
178
179template<class Problem>
180class add_space_norm<Problem,std::true_type>: public virtual Problem {
181public:
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};
191template<class Problem>
192class add_space_norm<Problem,std::false_type>: public virtual Problem {
193public:
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
212template<class Problem, class Sfinae = typename details::has_inherited_member_dual_space_norm<Problem>::type>
213struct add_dual_space_norm{};
214
215template<class Problem>
216class add_dual_space_norm<Problem,std::true_type>: public virtual Problem {
217public:
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};
227template<class Problem>
228class add_dual_space_norm<Problem,std::false_type>: public virtual Problem {
229public:
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// -----------------------------------------------------------------------------
245template<class Problem>
247 public virtual add_space_norm<Problem>
248 ,public virtual add_dual_space_norm<Problem>
249{
250public:
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};
268template<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{
276public:
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
void adapt(const value_type &, const adapt_option &) const
add_missing_continuation< Problem > & operator=(add_missing_continuation< Problem > &&f)
add_missing_continuation(const add_missing_continuation< Problem > &f)
add_missing_damped_newton< Problem > & operator=(add_missing_damped_newton< Problem > &&f)
add_missing_damped_newton(const add_missing_damped_newton< Problem > &f)
void refresh(float_type, const value_type &, const value_type &) const
This file is part of Rheolef.
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:179
STL namespace.
#define _RHEOLEF_has_inherited_member_macro(NAME)
Definition cavity_dg.h:29
adapt_option: see the adapt page for the full documentation
Definition adapt.h:147