field_expr.h
Go to the documentation of this file.
#ifndef _RHEOLEF_FIELD_EXPR_H
#define _RHEOLEF_FIELD_EXPR_H
//
// field assignement from expresions, e.g.
//
// field xh = expr;
//
// author: Pierre.Saramito@imag.fr
//
// date: 13 september 2015
//
// Notes:
// check at compile time that the expression is affine
// check at run time that it is also homogneous in terms of approximation space
//
// 1. field assignments
// 1.1. field assignment members
// 1.2. computed assignment
// 2. misc
// 2.1. duality product
// 2.2. form d = diag (expr)
// 2.3. output a linear expession
#include "rheolef/field_expr_recursive.h"
namespace rheolef {
// -------------------------------------------
// 1. field assignments
// -------------------------------------------
// 1.1. field assignment members
// -------------------------------------------
// 1.1.1 field
// -------------------------------------------
// uh = expr;
template<class T, class M>
template<class Expr>
inline
typename std::enable_if<
details::is_field_expr_affine_homogeneous<Expr>::value
&& ! details::is_field_expr_v2_constant <Expr>::value
&& ! details::is_field <Expr>::value
,field_basic<T, M>&
>::type
field_basic<T,M>::operator= (const Expr& expr)
{
space_basic<T,M> Xh;
check_macro (expr.have_homogeneous_space (Xh),
"field = expr; expr should have homogeneous space. HINT: use field = interpolate(Xh, expr)");
if (name() != Xh.name()) {
resize (Xh);
}
details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
return *this;
}
// field uh = expr;
template<class T, class M>
template<class Expr, class Sfinae>
inline
field_basic<T,M>::field_basic (const Expr& expr)
: _V (),
_u (),
_b (),
_dis_dof_indexes_requires_update(true),
_dis_dof_assembly_requires_update(false)
{
operator= (expr);
}
// -------------------------------------------
// 1.1.2. field_component
// -------------------------------------------
// uh [i_comp] = expr;
template<class T, class M>
template<class Expr, class Sfinae>
inline
field_component<T,M>&
field_component<T,M>::operator= (const Expr& expr)
{
space_basic<T,M> Xh;
check_macro (expr.have_homogeneous_space (Xh),
"field [idx] = expr; expr should have homogeneous space. HINT: use field [idx] = interpolate(Xh, expr)");
check_macro (name() == Xh.name(), "field [i_comp] = expr : incompatible spaces "
<< name() << " and " << Xh.name());
details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
return *this;
}
// -------------------------------------------
// 1.1.2. field_indirect
// -------------------------------------------
// uh [domain] = expr;
template<class T, class M>
template<class Expr, class Sfinae>
inline
field_indirect<T,M>&
field_indirect<T,M>::operator= (const Expr& expr) {
space_basic<T,M> Xh;
check_macro (expr.have_homogeneous_space (Xh),
"field [domain] = expr; expr should have homogeneous space. HINT: use field [domain] = interpolate(Xh, expr)");
check_macro (name() == Xh.name(), "field [domain] = field_expression : incompatible spaces "
<< name() << " and " << Xh.name());
details::assign_with_operator (begin_dof(), end_dof(), expr.begin_dof(), details::assign_op());
return *this;
}
// ---------------------------------------------------------------------------
// 1.2. computed assignment
// ---------------------------------------------------------------------------
// uh -+= expr
// uh [i_comp] -+= expr; // note: requires a move &&
// uh [domain] -+= expr;
#define _RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
template<class T, class M, class Expr> \
inline \
typename std::enable_if< \
details::is_field_expr_affine_homogeneous<Expr>::value, \
field_basic<T,M>& \
>::type \
operator OP (field_basic<T,M>& uh, const Expr& expr) \
{ \
space_basic<T,M> Xh; \
check_macro (expr.have_homogeneous_space (Xh), \
"field [domain] " << #OP << " expr; expr should have homogeneous space. " \
<< "HINT: use field [domain] " << #OP << " interpolate(Xh, expr)"); \
check_macro (uh.name() == Xh.name(), "field " << #OP << " field_expression : incompatible spaces " \
<< uh.name() << " and " << Xh.name()); \
details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
return uh; \
}
#define _RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, NAME, IDX) \
template<class T, class M, class Expr> \
inline \
typename std::enable_if< \
details::is_field_expr_affine_homogeneous<Expr>::value, \
NAME<T,M>& \
>::type \
operator OP (NAME<T,M>&& uh, const Expr& expr) \
{ \
space_basic<T,M> Xh; \
check_macro (expr.have_homogeneous_space (Xh), \
"field [" << #IDX << "] " << #OP << " expr; expr should have homogeneous space. " \
<< "HINT: use field [" << #IDX << "] " << #OP << " interpolate(Xh, expr)"); \
check_macro (uh.name() == Xh.name(), "field [" << #IDX << "] " << #OP << " field_expression : incompatible spaces " \
<< uh.name() << " and " << Xh.name()); \
details::assign_with_operator (uh.begin_dof(), uh.end_dof(), expr.begin_dof(), FUNCTOR()); \
return uh; \
}
#define _RHEOLEF_field_expr_v2_op_assign(OP, FUNCTOR) \
_RHEOLEF_field_expr_v2_op_assign_field(OP, FUNCTOR) \
_RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, field_component, "i_comp") \
_RHEOLEF_field_expr_v2_op_assign_auxil(OP, FUNCTOR, field_indirect, "domain")
_RHEOLEF_field_expr_v2_op_assign (+=, details::plus_assign)
_RHEOLEF_field_expr_v2_op_assign (-=, details::minus_assign)
#undef _RHEOLEF_field_expr_v2_op_assign_field
#undef _RHEOLEF_field_expr_v2_op_assign_auxil
#undef _RHEOLEF_field_expr_v2_op_assign
// uh -+*/= c
// uh [i_comp] -+*/= c; // requires a move &&
// uh [domain] -+*/= c; // TODO
#define _RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
template<class T, class M, class Expr> \
inline \
typename std::enable_if< \
details::is_field_expr_v2_constant<Expr>::value \
,field_basic<T,M>& \
>::type \
operator OP (field_basic<T,M>& uh, const Expr& expr) \
{ \
details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
return uh; \
}
#define _RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, NAME, IDX) \
template<class T, class M, class Expr> \
inline \
typename std::enable_if< \
details::is_field_expr_v2_constant<Expr>::value \
,NAME<T,M>& \
>::type \
operator OP (NAME<T,M>&& uh, const Expr& expr) \
{ \
details::assign_with_operator (uh.begin_dof(), uh.end_dof(), details::iterator_on_constant<Expr>(expr), FUNCTOR()); \
return uh; \
}
#define _RHEOLEF_field_expr_v2_op_assign_constant(OP, FUNCTOR) \
_RHEOLEF_field_expr_v2_op_assign_constant_field(OP, FUNCTOR) \
_RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, field_component, "i_comp") \
_RHEOLEF_field_expr_v2_op_assign_constant_auxil(OP, FUNCTOR, field_indirect, "domain")
_RHEOLEF_field_expr_v2_op_assign_constant (+=, details::plus_assign)
_RHEOLEF_field_expr_v2_op_assign_constant (-=, details::minus_assign)
_RHEOLEF_field_expr_v2_op_assign_constant (*=, details::multiplies_assign)
_RHEOLEF_field_expr_v2_op_assign_constant (/=, details::divides_assign)
#undef _RHEOLEF_field_expr_v2_op_assign_constant_field
#undef _RHEOLEF_field_expr_v2_op_assign_constant_auxil
#undef _RHEOLEF_field_expr_v2_op_assign_constant
// ---------------------------------------------------------------------------
// 2. misc
// ---------------------------------------------------------------------------
// 2.1. duality product
// ---------------------------------------------------------------------------
// dual (uh,vh)
template <class Expr1, class Expr2>
inline
typename
std::enable_if<
details::is_field_expr_affine_homogeneous<Expr1>::value &&
details::is_field_expr_affine_homogeneous<Expr2>::value,
typename promote<
typename Expr1::float_type,
typename Expr2::float_type>::type
>::type
dual (const Expr1& expr1, const Expr2& expr2)
{
typedef typename Expr1::float_type T;
typedef typename Expr1::memory_type M;
space_basic<T,M> Xh1, Xh2;
check_macro (expr1.have_homogeneous_space (Xh1),
"dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)");
check_macro (expr2.have_homogeneous_space (Xh2),
"dual(expr1,expr2); expr2 should have homogeneous space. HINT: use dual(expr1,interpolate(Xh, expr2))");
check_macro (Xh1.name() == Xh2.name(),
"dual(expr1,expr2); incompatible \""<<Xh1.name()<<"\" and \""<<Xh2.name()<<" spaces for expr1 and expr2");
return dis_inner_product (expr1.begin_dof(), expr2.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M());
}
// dual (c,uh)
template <class Expr1, class Expr2>
inline
typename
std::enable_if<
details::is_field_expr_v2_constant <Expr1>::value &&
details::is_field_expr_affine_homogeneous<Expr2>::value
,typename Expr2::float_type
>::type
dual (const Expr1& expr1, const Expr2& expr2)
{
typedef typename Expr2::float_type T;
typedef typename Expr2::memory_type M;
space_basic<T,M> Xh2;
check_macro (expr2.have_homogeneous_space (Xh2),
"dual(cte,expr2); expr2 should have homogeneous space. HINT: use dual(cte,interpolate(Xh, expr2))");
return expr1*dis_accumulate (expr2.begin_dof(), Xh2.ndof(), Xh2.ownership().comm(), M());
}
// dual (uh,c)
template <class Expr1, class Expr2>
inline
typename
std::enable_if<
details::is_field_expr_affine_homogeneous<Expr1>::value &&
details::is_field_expr_v2_constant <Expr2>::value
,typename Expr1::float_type
>::type
dual (const Expr1& expr1, const Expr2& expr2)
{
typedef typename Expr1::float_type T;
typedef typename Expr1::memory_type M;
space_basic<T,M> Xh1;
check_macro (expr1.have_homogeneous_space (Xh1),
"dual(expr1,cte); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),cte)");
return dis_accumulate (expr1.begin_dof(), Xh1.ndof(), Xh1.ownership().comm(), M())*expr2;
}
// ---------------------------------------------------------------------------
// 2.2. form d = diag (expr)
// ---------------------------------------------------------------------------
template<class Expr>
inline
typename
std::enable_if<
details::is_field_convertible<Expr>::value
&& ! details::is_field<Expr>::value
,form_basic <typename Expr::value_type, typename Expr::memory_type>
>::type
diag (const Expr& expr)
{
typedef typename Expr::value_type T;
typedef typename Expr::memory_type M;
return diag (field_basic<T,M>(expr));
}
// -------------------------------------------
// 2.3. output a linear expession
// -------------------------------------------
template <class Expr>
inline
typename
std::enable_if<
details::is_field_convertible<Expr>::value
&& ! details::is_field<Expr>::value
,odiststream&
>::type
operator<< (odiststream& ops, const Expr& expr) {
// distributed case: communications requires to store in memory
// and create a temporary
typedef typename Expr::value_type T;
typedef typename Expr::memory_type M;
field_basic<T,M> tmp = expr;
return tmp.put (ops);
}
} // namespace rheolef
#endif // _RHEOLEF_FIELD_EXPR_H
rheolef::field_basic
Definition: field.h:235
rheolef::field_basic::operator=
field_basic< T, M > & operator=(const field_basic< T, M > &)
Definition: field.h:619
rheolef::field_component
Definition: field_component.h:61
rheolef::field_component::operator=
field_component< T, M > & operator=(const T &alpha)
Definition: field_component.h:322
rheolef::field_indirect
Definition: field_indirect.h:39
rheolef::field_indirect::operator=
field_indirect< T, M > & operator=(const T &alpha)
Definition: field_indirect.h:131
rheolef::form_basic
Definition: form.h:144
rheolef::odiststream
odiststream: see the diststream page for the full documentation
Definition: diststream.h:126
rheolef::space_basic< T, M >
rheolef::type
rheolef::std type
rheolef::Expr1
rheolef::std Expr1
dot(x,y): see the expression page for the full documentation
T
Expr1::float_type T
Definition: field_expr.h:261
Xh1
space_basic< T, M > Xh1
Definition: field_expr.h:263
M
Expr1::memory_type M
Definition: field_expr.h:262
check_macro
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
Xh2
space_basic< T, M > Xh2
Definition: field_expr.h:263
mkgeo_ball.expr
expr
Definition: mkgeo_ball.sh:361
mkgeo_ball.tmp
tmp
Definition: mkgeo_ball.sh:380
mkgeo_contraction.name
string name
Definition: mkgeo_contraction.sh:133
rheolef::details::assign_with_operator
void assign_with_operator(ForwardIterator first, ForwardIterator last, InputIterator iter_rhs, OpAssign op_assign)
Definition: expr_utilities.h:137
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
rheolef::dis_accumulate
std::iterator_traits< InputIterator >::value_type dis_accumulate(InputIterator first, Size n, const distributor::communicator_type &comm, sequential)
Definition: dis_accumulate.h:61
rheolef::_RHEOLEF_field_expr_v2_op_assign
_RHEOLEF_field_expr_v2_op_assign(+=, details::plus_assign) _RHEOLEF_field_expr_v2_op_assign(-
rheolef::dis_inner_product
promote< typename std::iterator_traits< InputIterator1 >::value_type, typename std::iterator_traits< InputIterator2 >::value_type >::type dis_inner_product(InputIterator1 first1, InputIterator2 first2, Size n, const distributor::communicator_type &comm, sequential)
Definition: dis_inner_product.h:72
rheolef::diag
csr< T, M > diag(const vec< T, M > &d)
Definition: csr.cc:56
rheolef::_RHEOLEF_field_expr_v2_op_assign_constant
_RHEOLEF_field_expr_v2_op_assign_constant(+=, details::plus_assign) _RHEOLEF_field_expr_v2_op_assign_constant(-
rheolef::operator<<
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition: catchmark.h:99
rheolef::dual
rheolef::std enable_if ::type dual const Expr1 expr1, const Expr2 expr2 dual(const Expr1 &expr1, const Expr2 &expr2)
Definition: field_expr.h:260
rheolef::begin_dof
const_iterator begin_dof() const
Definition: field_expr_recursive.h:569
rheolef::details::assign_op
Definition: expr_utilities.h:115
rheolef::details::is_field_convertible
Definition: field_expr_terminal.h:65
rheolef::details::is_field_expr_affine_homogeneous
Definition: field.h:229
rheolef::details::is_field_expr_v2_constant
Definition: field.h:225
rheolef::details::is_field
Definition: field_expr_terminal.h:61
rheolef::details::minus_assign
Definition: expr_utilities.h:123
rheolef::details::multiplies_assign
Definition: expr_utilities.h:127
rheolef::details::plus_assign
Definition: expr_utilities.h:119
rheolef::promote
Definition: promote.h:29
M
Expr1::memory_type M
Definition: vec_expr_v2.h:416