Loading...
Searching...
No Matches
field_lazy_node.h
Go to the documentation of this file.
# ifndef _RHEOLEF_FIELD_LAZY_NODE_H
# define _RHEOLEF_FIELD_LAZY_NODE_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// Rheolef is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Rheolef is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =========================================================================
// field_lazy = un-assembled field
// as returned by lazy_integrate, lazy_interpolate or encapsulated field_basic
// here, they are combined with +- operators
// AUTHOR: Pierre.Saramito@imag.fr
// DATE: 6 april 1920
// SUMMARY: see also "field_lazy_terminal.h"
// 3. unary expressions
// 3.1. unary_minus & unary_plus
// 4. binary expressions
// 4.1. add & minus
//
#include "rheolef/field_lazy_terminal.h"
namespace rheolef {
// -------------------------------------------------------------------
// 3. unary expressions
// -------------------------------------------------------------------
// 3.1. unary_minus & unary_plus
// -------------------------------------------------------------------
namespace details {
template<class Unop, class Expr>
class field_lazy_unop: public field_lazy_base<field_lazy_unop<Unop,Expr>> {
public :
// definitions:
using base = field_lazy_base<field_lazy_unop<Unop,Expr>>;
using size_type = geo_element::size_type;
using memory_type = typename Expr::memory_type;
using scalar_type = typename Expr::scalar_type;
using space_type = typename Expr::space_type;
using geo_type = typename Expr::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using vector_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,1>;
// allocator:
field_lazy_unop (const Unop& unop, const Expr& expr)
: base(),
_unop(unop),
_expr(expr)
{}
// accessors:
const geo_type& get_geo() const { return _expr.get_geo(); }
const space_type& get_space() const { return _expr.get_space(); }
bool is_on_band() const { return _expr.is_on_band(); }
band_type get_band() const { return _expr.get_band(); }
void initialize (const geo_type& omega_K) { _expr.initialize (omega_K); }
void evaluate (
const geo_type& omega_K,
const geo_element& K,
vector_element_type& uk) const;
// data:
protected:
Unop _unop;
Expr _expr;
};
// concept;
template<class Unop, class Expr>
struct is_field_lazy <field_lazy_unop<Unop,Expr> > : std::true_type {};
// inlined:
template<class Unop, class Expr>
void
field_lazy_unop<Unop,Expr>::evaluate (
const geo_type& omega_K,
const geo_element& K,
vector_element_type& uk) const
{
_expr.evaluate (omega_K, K, uk);
uk = uk.unaryExpr(_unop);
}
}// namespace details
#define _RHEOLEF_field_lazy_unop(OP,NAME) \
template<class Expr, class Sfinae = typename std::enable_if<details::is_field_lazy<Expr>::value, Expr>::type> \
details::field_lazy_unop<NAME,Expr> \
operator OP (const Expr& u) \
{ \
return details::field_lazy_unop<NAME,Expr> (NAME(),u); \
}
_RHEOLEF_field_lazy_unop(+,details::unary_plus)
_RHEOLEF_field_lazy_unop(-,details::negate)
#undef _RHEOLEF_field_lazy_unop
// -------------------------------------------------------------------
// 4. binary expressions
// -------------------------------------------------------------------
// 4.1. add & minus
// -------------------------------------------------------------------
namespace details {
template<class Binop, class Expr1, class Expr2>
class field_lazy_add: public field_lazy_base<field_lazy_add<Binop,Expr1,Expr2>> {
public :
// definitions:
using base = field_lazy_base<field_lazy_add<Binop,Expr1,Expr2>>;
using size_type = geo_element::size_type;
using memory_type = typename Expr1::memory_type;
using scalar_type = typename Expr1::scalar_type;
using space_type = typename Expr1::space_type;
using geo_type = typename Expr1::geo_type;
using float_type = typename float_traits<scalar_type>::type;
using band_type = band_basic<float_type,memory_type>;
using vector_element_type = Eigen::Matrix<scalar_type,Eigen::Dynamic,1>;
// allocator:
field_lazy_add (const Expr1& expr1, const Expr2& expr2)
: base(),
_binop(),
_expr1(expr1),
_expr2(expr2) {}
// accessors:
const geo_type& get_geo() const;
const space_type& get_space() const { return _expr1.get_space(); }
bool is_on_band() const { return _expr1.is_on_band(); }
band_type get_band() const { return _expr1.get_band(); }
void initialize (const geo_type& omega_K);
void evaluate (
const geo_type& omega_K,
const geo_element& K,
vector_element_type& uk) const;
// data:
protected:
Binop _binop;
Expr1 _expr1;
Expr2 _expr2;
};
// concept;
template<class Binop, class Expr1, class Expr2>
struct is_field_lazy <field_lazy_add<Binop,Expr1,Expr2> > : std::true_type {};
// inlined:
template<class Binop, class Expr1, class Expr2>
const typename field_lazy_add<Binop,Expr1,Expr2>::geo_type&
field_lazy_add<Binop,Expr1,Expr2>::get_geo() const
{
// TODO: improve the automatic determination of the domain
// by an union that operates recursively
const geo_type& dom1 = _expr1.get_geo();
const geo_type& dom2 = _expr2.get_geo();
if (dom1 == dom2 || dom1 == dom2.get_background_geo() || dom1.is_broken()) {
trace_macro("lazy_add: union("<<dom1.name()<<","<<dom2.name()<<")="<<dom1.name());
return dom1;
} else if (dom2 == dom1.get_background_geo() || dom2.is_broken()) {
trace_macro("lazy_add: union("<<dom1.name()<<","<<dom2.name()<<")="<<dom2.name());
return dom2;
} else {
error_macro("lazy_add: incompatible domains \""<<dom1.name()
<< "\" and \"" << dom2.name() << "\"");
return dom2;
}
check_macro (_expr1.is_on_band() == _expr2.is_on_band(),
"lazy_add: invalid combination of banded and non-banded geoetry");
}
template<class Binop, class Expr1, class Expr2>
void
field_lazy_add<Binop,Expr1,Expr2>::initialize (const geo_type& omega_K)
{
check_macro (_expr1.get_space() == _expr2.get_space(),
"lazy_add: incompatible spaces "
<< "\"" <<_expr1.get_space().name()<<"\" and \"" <<_expr2.get_space().name()<<"\"");
_expr1.initialize (omega_K);
_expr2.initialize (omega_K);
}
template<class Binop, class Expr1, class Expr2>
void
field_lazy_add<Binop,Expr1,Expr2>::evaluate (
const geo_type& omega_K,
const geo_element& K,
vector_element_type& wk) const
{
vector_element_type uk, vk;
_expr1.evaluate (omega_K, K, uk);
_expr2.evaluate (omega_K, K, vk);
#ifdef _RHEOLEF_PARANO
check_macro (uk.size() == vk.size(), "u+v: invalid sizes");
#endif // _RHEOLEF_PARANO
wk = uk.binaryExpr (vk, _binop);
}
}// namespace details
#define _RHEOLEF_field_lazy_add(OP,NAME) \
template<class Expr1, class Expr2, \
class Sfinae1 = typename std::enable_if<details::is_field_lazy<Expr1>::value, Expr1>::type, \
class Sfinae2 = typename std::enable_if<details::is_field_lazy<Expr2>::value, Expr2>::type> \
details::field_lazy_add<details::NAME,Expr1,Expr2> \
operator OP (const Expr1& u, const Expr2& v) \
{ \
return details::field_lazy_add<details::NAME,Expr1,Expr2> (u,v); \
} \
template<class Expr1, \
class Sfinae1 = typename std::enable_if<details::is_field_lazy<Expr1>::value, Expr1>::type> \
details::field_lazy_add< \
details::NAME \
,Expr1 \
,details::field_lazy_terminal_field<typename Expr1::scalar_type,typename Expr1::memory_type> \
> \
operator OP (const Expr1& u, const field_basic<typename Expr1::scalar_type,typename Expr1::memory_type>& v) \
{ \
using Expr2 = details::field_lazy_terminal_field<typename Expr1::scalar_type,typename Expr1::memory_type>; \
return details::field_lazy_add<details::NAME,Expr1,Expr2> (u,Expr2(v)); \
} \
template<class Expr2, \
class Sfinae2 = typename std::enable_if<details::is_field_lazy<Expr2>::value, Expr2>::type> \
details::field_lazy_add< \
details::NAME \
,details::field_lazy_terminal_field<typename Expr2::scalar_type,typename Expr2::memory_type> \
,Expr2 \
> \
operator OP (const field_basic<typename Expr2::scalar_type,typename Expr2::memory_type>& u, const Expr2& v) \
{ \
using Expr1 = details::field_lazy_terminal_field<typename Expr2::scalar_type,typename Expr2::memory_type>; \
return details::field_lazy_add<details::NAME,Expr1,Expr2> (Expr1(u),v); \
}
_RHEOLEF_field_lazy_add(+,plus)
_RHEOLEF_field_lazy_add(-,minus)
#undef _RHEOLEF_field_lazy_add
}// namespace rheolef
# endif /* _RHEOLEF_FIELD_LAZY_NODE_H */
rheolef::band_basic< float_type, memory_type >
rheolef::details::field_lazy_add
Definition field_lazy_node.h:124
rheolef::details::field_lazy_add::size_type
geo_element::size_type size_type
Definition field_lazy_node.h:129
rheolef::details::field_lazy_add::scalar_type
typename Expr1::scalar_type scalar_type
Definition field_lazy_node.h:131
rheolef::details::field_lazy_add::memory_type
typename Expr1::memory_type memory_type
Definition field_lazy_node.h:130
rheolef::details::field_lazy_add::_expr1
Expr1 _expr1
Definition field_lazy_node.h:162
rheolef::details::field_lazy_add::_expr2
Expr2 _expr2
Definition field_lazy_node.h:163
rheolef::details::field_lazy_add::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, vector_element_type &uk) const
Definition field_lazy_node.h:205
rheolef::details::field_lazy_add::initialize
void initialize(const geo_type &omega_K)
Definition field_lazy_node.h:194
rheolef::details::field_lazy_add::get_geo
const geo_type & get_geo() const
Definition field_lazy_node.h:172
rheolef::details::field_lazy_add::_binop
Binop _binop
Definition field_lazy_node.h:161
rheolef::details::field_lazy_add::vector_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, 1 > vector_element_type
Definition field_lazy_node.h:136
rheolef::details::field_lazy_add::float_type
typename float_traits< scalar_type >::type float_type
Definition field_lazy_node.h:134
rheolef::details::field_lazy_add::space_type
typename Expr1::space_type space_type
Definition field_lazy_node.h:132
rheolef::details::field_lazy_add::is_on_band
bool is_on_band() const
Definition field_lazy_node.h:150
rheolef::details::field_lazy_add::get_band
band_type get_band() const
Definition field_lazy_node.h:151
rheolef::details::field_lazy_add::get_space
const space_type & get_space() const
Definition field_lazy_node.h:149
rheolef::details::field_lazy_add::geo_type
typename Expr1::geo_type geo_type
Definition field_lazy_node.h:133
rheolef::details::field_lazy_add::field_lazy_add
field_lazy_add(const Expr1 &expr1, const Expr2 &expr2)
Definition field_lazy_node.h:140
rheolef::details::field_lazy_base
Definition field_lazy.h:268
rheolef::details::field_lazy_unop
Definition field_lazy_node.h:47
rheolef::details::field_lazy_unop::size_type
geo_element::size_type size_type
Definition field_lazy_node.h:52
rheolef::details::field_lazy_unop::_unop
Unop _unop
Definition field_lazy_node.h:84
rheolef::details::field_lazy_unop::evaluate
void evaluate(const geo_type &omega_K, const geo_element &K, vector_element_type &uk) const
Definition field_lazy_node.h:94
rheolef::details::field_lazy_unop::initialize
void initialize(const geo_type &omega_K)
Definition field_lazy_node.h:76
rheolef::details::field_lazy_unop::geo_type
typename Expr::geo_type geo_type
Definition field_lazy_node.h:56
rheolef::details::field_lazy_unop::scalar_type
typename Expr::scalar_type scalar_type
Definition field_lazy_node.h:54
rheolef::details::field_lazy_unop::memory_type
typename Expr::memory_type memory_type
Definition field_lazy_node.h:53
rheolef::details::field_lazy_unop::_expr
Expr _expr
Definition field_lazy_node.h:85
rheolef::details::field_lazy_unop::vector_element_type
Eigen::Matrix< scalar_type, Eigen::Dynamic, 1 > vector_element_type
Definition field_lazy_node.h:59
rheolef::details::field_lazy_unop::float_type
typename float_traits< scalar_type >::type float_type
Definition field_lazy_node.h:57
rheolef::details::field_lazy_unop::is_on_band
bool is_on_band() const
Definition field_lazy_node.h:73
rheolef::details::field_lazy_unop::get_band
band_type get_band() const
Definition field_lazy_node.h:74
rheolef::details::field_lazy_unop::get_geo
const geo_type & get_geo() const
Definition field_lazy_node.h:71
rheolef::details::field_lazy_unop::get_space
const space_type & get_space() const
Definition field_lazy_node.h:72
rheolef::details::field_lazy_unop::space_type
typename Expr::space_type space_type
Definition field_lazy_node.h:55
rheolef::details::field_lazy_unop::field_lazy_unop
field_lazy_unop(const Unop &unop, const Expr &expr)
Definition field_lazy_node.h:63
rheolef::geo_element
see the geo_element page for the full documentation
Definition geo_element.h:102
rheolef::geo_element::size_type
reference_element::size_type size_type
Definition geo_element.h:125
trace_macro
#define trace_macro(message)
Definition dis_macros.h:111
error_macro
#define error_macro(message)
Definition dis_macros.h:49
check_macro
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
_RHEOLEF_field_lazy_unop
#define _RHEOLEF_field_lazy_unop(OP, NAME)
-u, +u: see the field page for the full documentation
Definition field_lazy_node.h:106
_RHEOLEF_field_lazy_add
#define _RHEOLEF_field_lazy_add(OP, NAME)
u+v, u-v: see the field page for the full documentation
Definition field_lazy_node.h:222
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::details::is_field_lazy
Definition field_concept.h:70
rheolef::details::negate
Definition expression.h:231
rheolef::details::unary_plus
Definition expression.h:209
rheolef::float_traits::type
T type
Definition Float.h:94