newton_add_missing.h
Go to the documentation of this file.
#ifndef _RHEOLEF_NEWTON_ADD_MISSING_H
#define _RHEOLEF_NEWTON_ADD_MISSING_H
// there are two versions of this algorithm
// - one with imbeded mesh adaptation loop
// - one without this feature
// the algorithm is automatically selected when there is an adapt() method
// in the supplied problem definition
//
#include "rheolef/continuation_option.h"
#include "rheolef/damped_newton.h"
#include <type_traits>
namespace rheolef { namespace details {
// -----------------------------------------------------------------------------
// predicates: have some member functions ?
// -----------------------------------------------------------------------------
// => will provides a default behavior when the member is missing
//
// solution from:
// https://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions
// note: it works with derived classes but do not check yet
// whether the named member is a data or a function
// and do not check for its profile.
//
#define _RHEOLEF_has_inherited_member_macro(NAME) \
template <typename Type> \
class has_inherited_member_##NAME { \
class yes { char m;}; \
class no { yes m[2];}; \
struct base_mixin { void NAME(){} }; \
struct base : public Type, public base_mixin {}; \
template <typename T, T t> class helper{}; \
template <typename U> \
static no deduce(U*, helper<void (base_mixin::*)(), &U::NAME>* = 0); \
static yes deduce(...); \
public: \
static const bool value = sizeof(yes) == sizeof(deduce((base*)(0))); \
typedef std::integral_constant<bool, value> type; \
};
// -----------------------------------------------------------------------------
// void adapt (const value_type&, const adapt_option&);
// -----------------------------------------------------------------------------
_RHEOLEF_has_inherited_member_macro(adapt)
template<class Problem, class Sfinae = typename has_inherited_member_adapt<Problem>::type>
struct add_adapt{};
template<class Problem>
class add_adapt<Problem,std::true_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_adapt(const add_adapt& f) : Problem(f) {}
explicit add_adapt(const Problem& f) : Problem(f) {}
add_adapt<Problem>& operator= (add_adapt<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_adapt<Problem,std::false_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_adapt(const add_adapt& f) : Problem(f) {}
explicit add_adapt(const Problem& f) : Problem(f) {}
void adapt (const value_type&, const adapt_option&) const {}
void reset_geo (const value_type&) {}
value_type reinterpolate (const value_type& uh) { return uh; }
add_adapt<Problem>& operator= (add_adapt<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
// -----------------------------------------------------------------------------
// void refresh (float_type, const value_type&, const value_type&) const;
// -----------------------------------------------------------------------------
// note: used by the keller continuation method
_RHEOLEF_has_inherited_member_macro(refresh)
template<class Problem, class Sfinae = typename has_inherited_member_refresh<Problem>::type>
struct add_refresh{};
template<class Problem>
class add_refresh<Problem,std::true_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_refresh(const add_refresh& f) : Problem(f) {}
explicit add_refresh(const Problem& f) : Problem(f) {}
add_refresh<Problem>& operator= (add_refresh<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_refresh<Problem,std::false_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_refresh(const add_refresh& f) : Problem(f) {}
explicit add_refresh(const Problem& f) : Problem(f) {}
void refresh (float_type, const value_type&, const value_type&) const {}
add_refresh<Problem>& operator= (add_refresh<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
// -----------------------------------------------------------------------------
// value_type direction (const value_type&) const;
// -----------------------------------------------------------------------------
// used by the continuation method ; redefined by keller
_RHEOLEF_has_inherited_member_macro(direction)
template<class Problem, class Sfinae = typename has_inherited_member_direction<Problem>::type>
struct add_direction{};
template<class Problem>
class add_direction<Problem,std::true_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_direction(const add_direction& f) : Problem(f) {}
explicit add_direction(const Problem& f) : Problem(f) {}
add_direction<Problem>& operator= (add_direction<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_direction<Problem,std::false_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_direction(const add_direction& f) : Problem(f) {}
explicit add_direction(const Problem& f) : Problem(f) {}
value_type direction (const value_type& uh) const {
Problem::update_derivative (uh);
return - Problem::derivative_solve (Problem::derivative_versus_parameter(uh));
}
add_direction<Problem>& operator= (add_direction<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
// -----------------------------------------------------------------------------
// float_type space_norm (const value_type&) const;
// -----------------------------------------------------------------------------
_RHEOLEF_has_inherited_member_macro(space_norm)
template<class Problem, class Sfinae = typename has_inherited_member_space_norm<Problem>::type>
struct add_space_norm{};
template<class Problem>
class add_space_norm<Problem,std::true_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_space_norm(const add_space_norm& f) : Problem(f) {}
explicit add_space_norm(const Problem& f) : Problem(f) {}
add_space_norm<Problem>& operator= (add_space_norm<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_space_norm<Problem,std::false_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_space_norm(const add_space_norm& f) : Problem(f) {}
explicit add_space_norm(const Problem& f) : Problem(f) {}
float_type space_norm (const value_type& uh) const {
return sqrt(Problem::space_dot (uh,uh));
}
add_space_norm<Problem>& operator= (add_space_norm<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
// -----------------------------------------------------------------------------
// float_type dual_space_norm (const value_type&) const;
// -----------------------------------------------------------------------------
_RHEOLEF_has_inherited_member_macro(dual_space_norm)
template<class Problem, class Sfinae = typename details::has_inherited_member_dual_space_norm<Problem>::type>
struct add_dual_space_norm{};
template<class Problem>
class add_dual_space_norm<Problem,std::true_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_dual_space_norm(const add_dual_space_norm& f) : Problem(f) {}
explicit add_dual_space_norm(const Problem& f) : Problem(f) {}
add_dual_space_norm<Problem>& operator= (add_dual_space_norm<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_dual_space_norm<Problem,std::false_type>: public virtual Problem {
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_dual_space_norm(const add_dual_space_norm& f) : Problem(f) {}
explicit add_dual_space_norm(const Problem& f) : Problem(f) {}
float_type dual_space_norm (const value_type& uh) const {
return sqrt(Problem::dual_space_dot (uh,uh));
}
add_dual_space_norm<Problem>& operator= (add_dual_space_norm<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
// -----------------------------------------------------------------------------
// add_missing: complete the problem class used by the continuation method
// -----------------------------------------------------------------------------
template<class Problem>
class add_missing_damped_newton:
public virtual add_space_norm<Problem>
,public virtual add_dual_space_norm<Problem>
{
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_missing_damped_newton(const add_missing_damped_newton<Problem>& f) :
Problem(f)
,add_space_norm<Problem>(f)
,add_dual_space_norm<Problem>(f)
{}
add_missing_damped_newton(const Problem& f) :
Problem(f)
,add_space_norm<Problem>(f)
,add_dual_space_norm<Problem>(f)
{}
add_missing_damped_newton<Problem>& operator= (add_missing_damped_newton<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
template<class Problem>
class add_missing_continuation:
public virtual add_adapt <Problem>
,public virtual add_refresh <Problem>
,public virtual add_direction <Problem>
,public virtual add_space_norm<Problem>
,public virtual add_dual_space_norm<Problem>
{
public:
typedef typename Problem::float_type float_type;
typedef typename Problem::value_type value_type;
add_missing_continuation(const add_missing_continuation<Problem>& f) :
Problem(f)
,add_adapt<Problem>(f)
,add_refresh<Problem>(f)
,add_direction<Problem>(f)
,add_space_norm<Problem>(f)
,add_dual_space_norm<Problem>(f)
{}
add_missing_continuation(const Problem& f) :
Problem(f)
,add_adapt<Problem>(f)
,add_refresh<Problem>(f)
,add_direction<Problem>(f)
,add_space_norm<Problem>(f)
,add_dual_space_norm<Problem>(f)
{}
add_missing_continuation<Problem>& operator= (add_missing_continuation<Problem>&& f) {
static_cast<Problem&>(*this) = static_cast<Problem&&>(f);
return *this;
}
};
#undef _RHEOLEF_has_inherited_member_macro
}} // namespace rheolef::details
#endif // _RHEOLEF_NEWTON_ADD_MISSING_H
rheolef::details::add_adapt< Problem, std::false_type >::add_adapt
add_adapt(const Problem &f)
Definition: newton_add_missing.h:88
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_adapt< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:86
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::false_type >::adapt
void adapt(const value_type &, const adapt_option &) const
Definition: newton_add_missing.h:89
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 >::add_adapt
add_adapt(const add_adapt &f)
Definition: newton_add_missing.h:87
rheolef::details::add_adapt< Problem, std::true_type >::add_adapt
add_adapt(const Problem &f)
Definition: newton_add_missing.h:76
rheolef::details::add_adapt< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:74
rheolef::details::add_adapt< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:73
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_direction< Problem, std::false_type >::add_direction
add_direction(const add_direction &f)
Definition: newton_add_missing.h:159
rheolef::details::add_direction< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:158
rheolef::details::add_direction< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:157
rheolef::details::add_direction< Problem, std::false_type >::add_direction
add_direction(const Problem &f)
Definition: newton_add_missing.h:160
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_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 >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:146
rheolef::details::add_direction< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:145
rheolef::details::add_direction< Problem, std::true_type >::add_direction
add_direction(const Problem &f)
Definition: newton_add_missing.h:148
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
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_dual_space_norm< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:231
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_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_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::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::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:219
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_missing_continuation
Definition: newton_add_missing.h:275
rheolef::details::add_missing_continuation::add_missing_continuation
add_missing_continuation(const Problem &f)
Definition: newton_add_missing.h:287
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_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::details::add_missing_continuation::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:277
rheolef::details::add_missing_damped_newton
Definition: newton_add_missing.h:249
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::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:252
rheolef::details::add_missing_damped_newton::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:251
rheolef::details::add_missing_damped_newton::add_missing_damped_newton
add_missing_damped_newton(const Problem &f)
Definition: newton_add_missing.h:258
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_refresh< Problem, std::false_type >::add_refresh
add_refresh(const Problem &f)
Definition: newton_add_missing.h:125
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_refresh< Problem, std::false_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:123
rheolef::details::add_refresh< Problem, std::false_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:122
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_refresh< Problem, std::true_type >::add_refresh
add_refresh(const Problem &f)
Definition: newton_add_missing.h:113
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::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:111
rheolef::details::add_refresh< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:110
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::false_type >::add_space_norm
add_space_norm(const add_space_norm &f)
Definition: newton_add_missing.h:196
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 >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:195
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_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 >::add_space_norm
add_space_norm(const Problem &f)
Definition: newton_add_missing.h:185
rheolef::details::add_space_norm< Problem, std::true_type >::value_type
Problem::value_type value_type
Definition: newton_add_missing.h:183
rheolef::details::add_space_norm< Problem, std::true_type >::float_type
Problem::float_type float_type
Definition: newton_add_missing.h:182
rheolef::std
Definition: vec_expr_v2.h:402
mkgeo_ball.f
int f
Definition: mkgeo_ball.sh:221
rheolef::details::_RHEOLEF_has_inherited_member_macro
_RHEOLEF_has_inherited_member_macro(adapt) template< class Problem
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
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
f
Definition: cavity_dg.h:29
rheolef::adapt_option
adapt_option: see the adapt page for the full documentation
Definition: adapt.h:147