Loading...
Searching...
No Matches
field_wdof_convert.h
Go to the documentation of this file.
#ifndef _RHEO_FIELD_WDOF_CONVERT_H
#define _RHEO_FIELD_WDOF_CONVERT_H
// convert to field an un-assembled lazy_field expression
// AUTHOR: Pierre.Saramito@imag.fr
// DATE: 6 april 2020
/*
Let:
uh = interpolate (Xh, expr);
or
l(v) = int_omega expr(v) dx
with v in Xh.
The expression is evaluated by a loop for each element K of the domain.
IMPLEMENTATION NOTE:
It writes
lh = integrate(omega, expr(v), iopt);
and the support for
lh += integrate(omega, expr(v), iopt);
lh -= integrate(omega, expr(v), iopt);
is provided with the "my_set_plus_op" argument, that is replaced
by details::generic_set_minus_op for -=
Supports for integration on a band or an usual domain.
*/
#include "rheolef/field_lazy.h"
#include "rheolef/field_wdof.h"
#include "rheolef/band.h"
namespace rheolef { namespace details {
template<class FieldWdof, class FieldLazy, class SetPlusOp>
typename std::enable_if<
has_field_lazy_interface<FieldLazy>::value
&& has_field_wdof_interface<FieldWdof>::value
,FieldWdof&
>::type
convert_lazy2wdof (
const FieldLazy& expr0,
const SetPlusOp& my_set_plus_op,
FieldWdof& uh)
{
using size_type = typename FieldWdof::size_type;
using scalar_type = typename FieldWdof::scalar_type;
using memory_type = typename FieldWdof::memory_type;
using geo_type = typename FieldWdof::geo_type;
using space_type = typename FieldWdof::space_type;
using band_type = band_basic<scalar_type,memory_type>;
FieldLazy expr = expr0; // so could call expr.initialize() which is non-const
// ------------------------------------
// 1) initialize the loop
// ------------------------------------
const space_type& Xh = expr.get_space();
check_macro (uh.get_space() == Xh, "invalid spaces");
geo_type omega = expr.get_geo();
expr.initialize (omega);
std::vector<size_type> dis_idx;
Eigen::Matrix<scalar_type,Eigen::Dynamic,1> lk;
size_type d = omega.dimension();
size_type map_d = omega.map_dimension();
if (Xh.get_constitution().is_discontinuous()) {
Xh.get_constitution().neighbour_guard(); // TODO: obsolete ?
}
bool is_on_band = expr.is_on_band();
band_type gh;
if (is_on_band) gh = expr.get_band();
// ------------------------------------
// 2) loop on elements
// ------------------------------------
for (size_type ie = 0, ne = omega.size(map_d); ie < ne; ie++) {
const geo_element& K = omega.get_geo_element (map_d, ie);
// ------------------------------------
// 2.1) locally compute dofs
// ------------------------------------
if (! is_on_band) {
Xh.get_constitution().assembly_dis_idof (omega, K, dis_idx);
} else { // on a band
size_type L_ie = gh.sid_ie2bnd_ie (ie);
const geo_element& L = gh.band() [L_ie];
Xh.dis_idof (L, dis_idx);
}
// ------------------------------------
// 2.2) locally compute values
// ------------------------------------
expr.evaluate (omega, K, lk);
// -----------------------------------------
// 2.3) assembly local lk in global field lh
// -----------------------------------------
check_macro (dis_idx.size() == size_type(lk.size()),
"incompatible sizes dis_idx("<<dis_idx.size()<<") and lk("<<lk.size()<<")");
for (size_type loc_idof = 0, loc_ndof = lk.size(); loc_idof < loc_ndof; loc_idof++) {
const scalar_type& value = lk [loc_idof];
size_type dis_idof = dis_idx [loc_idof];
my_set_plus_op (uh.dis_dof_entry (dis_idof), value);
}
}
// -----------------------------------------
// 3) finalize the assembly process
// -----------------------------------------
uh.dis_dof_update (generic_set_plus_op());
return uh;
}
} // namespace details
}// namespace rheolef
#endif // _RHEO_FIELD_WDOF_CONVERT_H
gh
field gh(Float epsilon, Float t, const field &uh, const test &v)
Definition burgers_diffusion_operators.icc:37
rheolef::band_basic
Definition band.h:95
rheolef::geo_element
see the geo_element page for the full documentation
Definition geo_element.h:102
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::details
Definition compiler_eigen.h:39
rheolef::details::convert_lazy2wdof
std::enable_if< has_field_lazy_interface< FieldLazy >::value &&has_field_wdof_interface< FieldWdof >::value, FieldWdof & >::type convert_lazy2wdof(const FieldLazy &expr0, const SetPlusOp &my_set_plus_op, FieldWdof &uh)
Definition field_wdof_convert.h:59
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
d
size_t d
Definition neumann-laplace-lambda.cc:28
rheolef::details::has_field_lazy_interface
Definition field_concept.h:74
rheolef::details::has_field_wdof_interface
Definition field_concept.h:42