Loading...
Searching...
No Matches
space_constitution.cc
Go to the documentation of this file.
//
// helper for dof numbering with space product and component access
//
// contents:
// 1. allocators
// 2. accessors
// 3. inquire
// 4. initialize
// 5. output
// 6. do_act: block & unblock on a domain
// 7. ios accessors
// 8. comp_dis_idof2dis_idof : for wdof_sliced
// 9. dis_idof, for assembly: moved to space_constitution_assembly.cc
//
#include "rheolef/geo_domain.h"
#include "rheolef/space.h"
#include "rheolef/space_numbering.h"
#include "rheolef/space_mult.h"
#include "rheolef/piola_util.h"
#include "rheolef/basis_get.h"
#include <sstream>
namespace rheolef {
// ======================================================================
// 1. allocators
// ======================================================================
template <class T, class M>
space_constitution_terminal_rep<T,M>::space_constitution_terminal_rep(
const geo_basic<T,M>& omega,
std::string approx)
: _acts(),
_omega(compact(omega)),
_fem_basis()
{
if (approx == "") return;
const size_type unset = std::numeric_limits<basis_option::size_type>::max();
family_index_option_type fio;
basis_parse_from_string (approx, fio);
if (fio.option.valued_tag() != space_constant::scalar && fio.option.dimension() == unset) {
// when vector/tensor on surface geometry: fix the number of components by forcing the physical dimension
// e.g. 3D-vector on a surface (map_dimension = 2)
fio.option.set_dimension (omega.dimension());
}
if (fio.option.valued_tag() == space_constant::tensor &&
omega.coordinate_system() != space_constant::cartesian) {
// when tensor on an axisymmetric geometry: should add a theta-theta tensor component
fio.option.set_coordinate_system (omega.coordinate_system());
}
std::string approx_d = basis_rep<T>::standard_naming (fio.family, fio.index, fio.option);
_fem_basis = basis_basic<T>(approx_d);
}
template <class T, class M>
void
space_constitution_terminal_rep<T,M>::do_act (const space_act& act)
{
check_macro (get_geo().map_dimension() < get_geo().dimension() ||
!get_basis().have_compact_support_inside_element(),
"try to [un]block domain `" << act.get_domain_name() << "' on discontinuous or bubble space("
<< get_basis().name()<<"(" <<_omega.name()<<"))");
_acts.push_back (act);
}
template <class T, class M>
void
space_constitution_rep<T,M>::do_act (const space_act& act)
{
typedef distributor::size_type size_type;
if (! is_hierarchical()) {
space_constitution_terminal<T,M>& terminal_constit = get_terminal();
terminal_constit.do_act (act);
return;
}
// hierarchical case:
for (iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
space_constitution<T,M>& constit = *iter;
constit.do_act (act); // recursive call
}
}
// -----------------------------------------------------------------------
// loop on domains: mark blocked dofs (called by space::freeze)
// -----------------------------------------------------------------------
template <class T, class M>
void
space_constitution_terminal_rep<T,M>::build_blocked_flag (
disarray<size_type,M>& blocked_flag, // disarray<bool,M> not supported
const distributor& comp_ownership,
const distributor& start_by_flattened_component) const
{
check_macro (get_basis().is_initialized(), "space with undefined finite element method cannot be used");
std::vector<size_type> comp_dis_idof_t;
distributor dof_ownership = blocked_flag.ownership();
size_type dis_ndof = dof_ownership.dis_size();
bool prev_act = space_act::block;
size_type n_comp = get_basis().size();
size_type dim = get_geo().dimension();
for (const_iterator iter = begin(), last = end(); iter != last; iter++) {
typename space_act::act_type act = (*iter).get_act();
const std::string& dom_name = (*iter).get_domain_name();
size_type i_comp = (*iter).get_component_index();
check_macro (i_comp == space_act::unset_index || i_comp < n_comp,
"invalid blocked domain for the "<<i_comp << "-th component in a "
<<n_comp<<"-component non-hierarchical space with basis=\""
<< get_basis().name() << "\"");
// sync all blocked_flags when there is an alternance of block and unblock (bug fixed)
if (prev_act != act) {
blocked_flag.dis_entry_assembly();
prev_act = act;
}
const domain_indirect_basic<M>& dom = _omega.get_domain_indirect(dom_name);
size_type dom_dim = dom.map_dimension();
distributor ige_ownership = _omega.geo_element_ownership (dom_dim);
size_type first_dis_ige = ige_ownership.first_index();
size_type last_dis_ige = ige_ownership.last_index();
bool blk = (act == space_act::block || act == space_act::block_n) ? true : false;
for (size_type ioige = 0, noige = dom.size(); ioige < noige; ioige++) {
size_type ige = dom.oige (ioige).index();
size_type dis_ige = ige + first_dis_ige;
const geo_element& S = _omega.get_geo_element (dom_dim, ige);
space_numbering::dis_idof (get_basis(), _omega.sizes(), S, comp_dis_idof_t);
size_type loc_idof_start, loc_idof_incr;
if (act == space_act::block || act == space_act::unblock) {
loc_idof_start = (i_comp == space_act::unset_index) ? 0 : i_comp;
loc_idof_incr = (i_comp == space_act::unset_index) ? 1 : n_comp;
} else { // block_n or unblock_n
loc_idof_start = dim-1;
loc_idof_incr = dim;
}
// vector-valued : do not work yet with RTk, but only with (Pk)^d
// note that RTk Hdiv-conform could block_n in theory
for (size_type loc_idof = loc_idof_start, loc_ndof = comp_dis_idof_t.size(); loc_idof < loc_ndof; loc_idof += loc_idof_incr) {
size_type comp_dis_idof = comp_dis_idof_t [loc_idof];
size_type iproc = comp_ownership.find_owner (comp_dis_idof);
size_type first_comp_dis_idof = comp_ownership.first_index (iproc);
assert_macro (comp_dis_idof >= first_comp_dis_idof, "unexpected comp_dis_idof");
size_type comp_idof = comp_dis_idof - first_comp_dis_idof;
size_type comp_start_idof = start_by_flattened_component.size(iproc);
size_type idof = comp_start_idof + comp_idof;
size_type first_dis_idof = dof_ownership.first_index(iproc);
size_type dis_idof = first_dis_idof + idof;
assert_macro (dis_idof < dis_ndof, "unexpected dis_idof");
blocked_flag.dis_entry (dis_idof) = blk;
}
#ifdef TODO
basis scalar_basis = ...; // scalar Pk
space_numbering::dis_idof (scalar_basis, _omega.sizes(), S, scalar_dis_idof_t);
for (size_type loc_scalar_idof = 0, loc_scalar_ndof = comp_dis_idof_t.size()/n_comp; loc_scalar_idof < loc_scalar_ndof; ++loc_scalar_idof) {
size_type dis_scalar_idof = scalar_dis_idof_t [loc_idof]; // as if we do a scalar Pk element
has_nt_basis.dis_entry (dis_scalar_idof) = (act == space_act::block_n || act == space_act::unblock_n);
normal.dis_entry (dis_scalar_idof) = copy_of_a_previous_computation;
}
#endif // TODO
}
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::build_blocked_flag_recursive (
disarray<size_type,M>& blocked_flag, // disarray<bool,M> not supported
const std::vector<distributor>& start_by_flattened_component,
size_type& i_flat_comp) const
{
if (! is_hierarchical()) {
const space_constitution_terminal<T,M>& terminal_constit = get_terminal();
terminal_constit.data().build_blocked_flag (blocked_flag, ownership(), start_by_flattened_component [i_flat_comp]);
i_flat_comp++;
return;
}
// hierarchical case:
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
constit.data().build_blocked_flag_recursive (blocked_flag, start_by_flattened_component, i_flat_comp); // recursive call
}
}
template <class T, class M>
disarray<typename space_constitution_rep<T,M>::size_type,M>
space_constitution_rep<T,M>::build_blocked_flag() const
{
disarray<size_type,M> blocked_flag (ownership(), 0); // disarray<bool,M> not supported
size_type i_flat_comp = 0;
build_blocked_flag_recursive (blocked_flag, _start_by_flattened_component, i_flat_comp);
blocked_flag.dis_entry_assembly();
return blocked_flag;
}
// ======================================================================
// 2. accessors
// ======================================================================
template <class T, class M>
const geo_basic<T,M>&
space_constitution_rep<T,M>::get_geo() const
{
if (! is_hierarchical()) {
return get_terminal().get_geo();
}
// heterogeneous: get as geo the maximum domain of definition
// => it is the intersection of all domain definition
// implementation note: use "const geo*" ptr_dom for returning a "const geo&"
check_macro (_hier_constit.size() > 0, "get_geo: empty space product");
const geo_basic<T,M>* ptr_dom = &(_hier_constit[0].get_geo()); // recursive call
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
const geo_basic<T,M>* ptr_comp_dom = &(constit.get_geo()); // recursive call
if (ptr_comp_dom->name() == ptr_dom->name()) continue;
if (ptr_dom->get_background_geo().name() == ptr_comp_dom->name()) continue;
if (ptr_comp_dom->get_background_geo().name() == ptr_dom->name()) {
ptr_dom = ptr_comp_dom;
} else {
error_macro ("get_geo: incompatible domains: \""<<ptr_dom->name()<<"\" and \""<<ptr_comp_dom->name() << "\"");
}
}
return *(ptr_dom);
}
template <class T, class M>
const geo_basic<T,M>&
space_constitution_rep<T,M>::get_background_geo() const
{
if (! is_hierarchical()) {
return get_terminal().get_background_geo();
}
// component have the same background mesh: assume it without check (TODO: constit.check_have_same_bgd_geo())
check_macro (_hier_constit.size() > 0, "get_background_geo: empty space product");
const_iterator iter = _hier_constit.begin();
const space_constitution<T,M>& constit = (*iter);
return constit.get_background_geo(); // recursive call
}
template <class T, class M>
const basis_basic<T>&
space_constitution_rep<T,M>::get_basis() const
{
check_macro(! is_hierarchical(), "get_basis: undefined for heterogeneous space products");
return get_terminal().get_basis();
}
// ======================================================================
// 3. inquire
// ======================================================================
template <class T, class M>
bool
space_constitution_rep<T,M>::have_compact_support_inside_element() const
{
if (! is_hierarchical()) {
return get_terminal().get_basis().have_compact_support_inside_element();
}
bool has = true;
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
has = has && constit.have_compact_support_inside_element(); // recursive call
}
return has;
}
template <class T, class M>
bool
space_constitution_rep<T,M>::is_discontinuous() const
{
if (! is_hierarchical()) {
return get_terminal().get_basis().is_discontinuous();
}
bool is = true;
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
is = is && constit.is_discontinuous(); // recursive call
}
return is;
}
// build a space::constitution hierrachy from a list of spaces
template <class T, class M>
inline
space_constitution_rep<T,M>::space_constitution_rep(const space_mult_list<T,M>& expr)
: _is_initialized(false),
_flattened_size(0),
_start_by_flattened_component(),
_start_by_component(),
_ownership(),
_valued_tag(space_constant::mixed),
_is_hier(true),
_terminal_constit(),
_hier_constit(expr.size()),
_loc_ndof()
{
_loc_ndof.fill (std::numeric_limits<size_type>::max());
typename space_constitution_rep<T,M>::hierarchy_type::iterator iter_constit = _hier_constit.begin();
for (typename space_mult_list<T,M>::const_iterator iter = expr.begin(), last = expr.end(); iter != last; ++iter, ++iter_constit) {
const space_basic<T,M>& Xi = *iter;
*iter_constit = Xi.get_constitution();
}
initialize();
}
template <class T, class M>
bool
space_constitution_rep<T,M>::operator== (const space_constitution_rep<T,M>& V2) const
{
if (_is_hier != V2._is_hier) { return false; }
if (!_is_hier) { return (_terminal_constit == V2._terminal_constit); }
// here, two hierarchies:
if (_hier_constit.size() != V2._hier_constit.size()) return false;
for (const_iterator iter1 = _hier_constit.begin(), iter2 = V2._hier_constit.begin(), last1 = _hier_constit.end(); iter1 != last1; ++iter1, ++iter2) {
if (! (*iter1).data().operator==((*iter2).data())) { // recursive call
return false;
}
}
return true;
}
// =======================================================================
// 4. initialize
// =======================================================================
template <class T, class M>
typename space_constitution_rep<T,M>::size_type
space_constitution_rep<T,M>::_init_flattened_size() const
{
if (! is_hierarchical()) return 1;
size_type flattened_size = 0;
for (size_type i_comp = 0, n_comp = size(); i_comp < n_comp; i_comp++) {
const space_constitution<T,M>& comp_constit = operator[] (i_comp);
flattened_size += comp_constit.data()._init_flattened_size(); // recursive call
}
return flattened_size;
}
template <class T, class M>
void
space_constitution_rep<T,M>::_init_start_by_flattened_component(
size_type& i_flat_comp,
size_type& start_flat_comp_idof,
size_type& dis_start_flat_comp_idof,
std::vector<distributor>& start_by_flattened_component) const
{
if (! is_hierarchical()) {
if (! get_basis().is_initialized()) return; // empty numbering => empty space
start_by_flattened_component [i_flat_comp] = distributor (dis_start_flat_comp_idof, comm(), start_flat_comp_idof);
size_type ndof = space_numbering:: ndof (get_basis(), get_geo().sizes(), get_geo().map_dimension());
size_type dis_ndof = space_numbering::dis_ndof (get_basis(), get_geo().sizes(), get_geo().map_dimension());
i_flat_comp++;
start_flat_comp_idof += ndof;
dis_start_flat_comp_idof += dis_ndof;
return;
}
// hierarchical case:
for (size_type i_comp = 0, n_comp = size(); i_comp < n_comp; i_comp++) {
const space_constitution<T,M>& comp_constit = operator[] (i_comp);
comp_constit.data()._init_start_by_flattened_component (i_flat_comp, start_flat_comp_idof, dis_start_flat_comp_idof, start_by_flattened_component); // recursive call
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::_init_start_by_component() const
{
if (! is_hierarchical()) {
if (! get_basis().is_initialized()) return; // empty numbering => empty space
_start_by_component.resize (1);
_start_by_component [0] = distributor (0, comm(), 0);
return;
}
// hierarchical case:
_start_by_component.resize (size());
size_type comp_start_idof = 0;
size_type comp_start_dis_idof = 0;
for (size_type i_comp = 0, n_comp = size(); i_comp < n_comp; i_comp++) {
const space_constitution<T,M>& comp_constit = operator[] (i_comp);
_start_by_component [i_comp] = distributor (comp_start_dis_idof, comm(), comp_start_idof);
comp_start_idof += comp_constit.ownership(). size();
comp_start_dis_idof += comp_constit.ownership().dis_size();
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::initialize() const
{
if (_is_initialized) return;
_is_initialized = true;
_flattened_size = _init_flattened_size();
_start_by_flattened_component.resize (_flattened_size);
size_type i_flat_comp = 0;
size_type start_flat_comp_idof = 0;
size_type dis_start_flat_comp_idof = 0;
_init_start_by_flattened_component (i_flat_comp, start_flat_comp_idof, dis_start_flat_comp_idof, _start_by_flattened_component);
_ownership = distributor (dis_start_flat_comp_idof, comm(), start_flat_comp_idof);
_init_start_by_component();
}
// ----------------------------------------------------------------------
// get external idofs: used by space<distributed>::freeze
// ---------------------------------------------------------------,--------
static
void
local_append_external_dis_idof (
const std::vector<size_t>& comp_dis_idof_tab,
const distributor& comp_ownership,
const distributor& dof_ownership,
const distributor& start_by_flattened_component,
std::set<size_t>& ext_dof_set)
{
using size_type = size_t;
size_type comp_dis_ndof = comp_ownership.dis_size();
for (size_type loc_idof = 0, loc_ndof = comp_dis_idof_tab.size(); loc_idof < loc_ndof; loc_idof++) {
size_type comp_dis_idof = comp_dis_idof_tab [loc_idof];
assert_macro (comp_dis_idof < comp_dis_ndof, "idof " << comp_dis_idof_tab [loc_idof] << " out of range[0:"<< comp_dis_ndof << "[");
if (! comp_ownership.is_owned (comp_dis_idof)) {
size_type iproc = comp_ownership.find_owner (comp_dis_idof);
size_type comp_first_dis_idof = comp_ownership.first_index(iproc);
assert_macro (comp_dis_idof >= comp_first_dis_idof, "unexpected comp_dis_idof");
size_type comp_idof = comp_dis_idof - comp_first_dis_idof;
size_type comp_start_idof = start_by_flattened_component.size(iproc);
size_type idof = comp_start_idof + comp_idof;
size_type first_dis_idof = dof_ownership.first_index(iproc);
size_type dis_idof = first_dis_idof + idof;
assert_macro (! dof_ownership.is_owned (dis_idof), "unexpected dis_idof="<<dis_idof<<" in range ["
<< first_dis_idof << ":" << dof_ownership.last_index() << "[");
ext_dof_set.insert (dis_idof);
}
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::append_external_dof (
const geo_basic<T,M>& omega,
std::set<size_type>& ext_dof_set,
const distributor& dof_ownership,
const distributor& start_by_flattened_component) const
{
// assume here a scalar (non-multi valued) case:
distributor comp_ownership = ownership();
size_type comp_dis_ndof = comp_ownership.dis_size();
std::vector<size_type> comp_dis_idof_tab;
// loop on internal elements
for (size_type ie = 0, ne = omega.size(); ie < ne; ie++) {
const geo_element& K = omega [ie];
assembly_dis_idof (omega, K, comp_dis_idof_tab);
local_append_external_dis_idof (comp_dis_idof_tab, comp_ownership, dof_ownership, start_by_flattened_component, ext_dof_set);
}
// loop also on external elements
size_type map_d = omega.map_dimension();
for (size_type variant = reference_element::first_variant_by_dimension (map_d);
variant < reference_element:: last_variant_by_dimension (map_d); ++variant) {
// for (auto iter : omega._geo_element[variant].get_dis_map_entries()) {
for (auto iter : omega.get_external_geo_element_map(variant)) {
const geo_element& K = iter.second;
assembly_dis_idof (omega, K, comp_dis_idof_tab);
local_append_external_dis_idof (comp_dis_idof_tab, comp_ownership, dof_ownership, start_by_flattened_component, ext_dof_set);
}
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::compute_external_dofs (
std::set<size_type>& ext_dof_set,
const distributor& dof_ownership,
const std::vector<distributor>& start_by_flattened_component,
size_type& i_flat_comp) const
{
if (! is_hierarchical()) {
const space_constitution_terminal<T,M>& terminal_constit = get_terminal();
append_external_dof (terminal_constit.get_geo(), ext_dof_set, dof_ownership, start_by_flattened_component [i_flat_comp]);
i_flat_comp++;
return;
}
// hierarchical case:
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
(*iter).data().compute_external_dofs (ext_dof_set, dof_ownership, start_by_flattened_component, i_flat_comp);
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::compute_external_dofs (
std::set<size_type>& ext_dof_set) const
{
ext_dof_set.clear();
size_type i_flat_comp = 0;
compute_external_dofs (ext_dof_set, ownership(), _start_by_flattened_component, i_flat_comp);
}
// ======================================================================
// 5. output
// ======================================================================
template<class T, class M>
void
space_constitution_rep<T,M>::put (std::ostream& out, size_type level) const
{
if (! is_hierarchical()) {
const space_constitution_terminal<T,M>& terminal_constit = get_terminal();
if (!terminal_constit.get_basis().is_initialized()) return;
out << terminal_constit.get_basis().name() << "{" << terminal_constit.get_geo().name() << "}";
} else {
if (level > 0) out << "(";
typename space_constitution<T,M>::hierarchy_type::const_iterator x = get_hierarchy().begin();
for (size_type i = 0, n = get_hierarchy().size(); i < n; i++) {
const space_constitution<T,M>& xi = x[i];
xi.data().put (out, level+1); // recursive call
if (i+1 < n) { out << "*"; }
}
if (level > 0) out << ")";
}
}
template<class T, class M>
std::string
space_constitution_rep<T,M>::name() const
{
std::ostringstream ostrstr;
put (ostrstr, 0);
return ostrstr.str();
}
// ======================================================================
// 6. do_act: block & unblock on a domain
// ======================================================================
template <class T, class M>
typename space_constitution_rep<T,M>::size_type
space_constitution_rep<T,M>::degree_max() const
{
if (! is_hierarchical()) {
return get_terminal().get_basis().degree();
}
size_type degree_max = 0;
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
degree_max = std::max(degree_max, constit.degree_max()); // recursive call
}
return degree_max;
}
template <class T, class M>
void
space_constitution_rep<T,M>::neighbour_guard() const
{
if (! is_hierarchical()) {
if (get_geo().dimension() == get_geo().map_dimension()) {
// 3d surface mesh or 2d lineique mesh are not yet treated for neighbours
get_terminal().neighbour_guard();
}
return;
}
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
constit.neighbour_guard(); // recursive call
}
}
// ======================================================================
// 7. ios accessors
// ======================================================================
template <class T, class M>
typename space_constitution_rep<T,M>::size_type
space_constitution_rep<T,M>::ios_ndof () const
{
if (!_is_hier) {
communicator comm =_terminal_constit.get_geo().comm();
size_type dis_ndof = space_numbering::dis_ndof (_terminal_constit.get_basis(), _terminal_constit.get_geo().sizes(), _terminal_constit.get_geo().map_dimension());
// TODO: memorize ios_ownership : avoid comms & risks of errors
distributor ios_ownership (dis_ndof, comm, distributor::decide);
return ios_ownership.size();
}
size_type ios_ndof = 0;
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
ios_ndof += constit.ios_ndof(); // recursive call
}
return ios_ndof;
}
template <class T, class M>
void
space_constitution_terminal_rep<T,M>::set_ios_permutations (
disarray<size_type,M>& idof2ios_dis_idof,
disarray<size_type,M>& ios_idof2dis_idof) const
{
space_numbering::set_ios_permutations (get_basis(), get_geo(), idof2ios_dis_idof, ios_idof2dis_idof);
}
template <class T, class M>
void
space_constitution_rep<T,M>::set_ios_permutation_recursion (
disarray<size_type,M>& idof2ios_dis_idof,
size_type& comp_start_idof,
size_type& comp_start_dis_idof) const
{
if (!_is_hier) {
// non-hierarchical case:
disarray<size_type,M> comp_idof2ios_dis_idof;
disarray<size_type,M> comp_ios_idof2dis_idof;
// TODO: avoid allocating comp_idof2ios_dis_idof: numbering supports directly comp_start_{dis_}idof
// TODO: avoid invert permut here: numbering support no invert perm arg
_terminal_constit.set_ios_permutations (comp_idof2ios_dis_idof, comp_ios_idof2dis_idof);
// then shift
size_type comp_ndof = comp_idof2ios_dis_idof.size();
size_type comp_dis_ndof = comp_idof2ios_dis_idof.dis_size();
size_type ndof = idof2ios_dis_idof.size();
size_type dis_ndof = idof2ios_dis_idof.dis_size();
for (size_type comp_idof = 0; comp_idof < comp_ndof; comp_idof++) {
size_type comp_ios_dis_idof = comp_idof2ios_dis_idof [comp_idof];
size_type ios_dis_idof = comp_start_dis_idof + comp_ios_dis_idof;
size_type idof = comp_start_idof + comp_idof;
assert_macro (idof < ndof, "unexpected idof="<<idof<<" out of range [0:"<<ndof<<"[");
assert_macro (ios_dis_idof < dis_ndof, "unexpected ios_dis_idof="<<ios_dis_idof<<" out of range [0:"<<dis_ndof<<"[");
idof2ios_dis_idof [idof] = ios_dis_idof;
}
comp_start_idof += comp_ndof;
comp_start_dis_idof += comp_dis_ndof;
return;
}
// hierarchical case:
for (const_iterator iter = _hier_constit.begin(), last = _hier_constit.end(); iter != last; ++iter) {
const space_constitution<T,M>& constit = *iter;
constit.set_ios_permutation_recursion (idof2ios_dis_idof, comp_start_idof, comp_start_dis_idof); // recursive call
}
}
template <class T, class M>
void
space_constitution_rep<T,M>::set_ios_permutations (
disarray<size_type,M>& idof2ios_dis_idof,
disarray<size_type,M>& ios_idof2dis_idof) const
{
if (!_is_hier) {
// non-hierarchical case: direct
_terminal_constit.set_ios_permutations (idof2ios_dis_idof, ios_idof2dis_idof);
return;
}
// hierarchical case:
// ----------------------------------------------
// 1) compute permutation
// ----------------------------------------------
communicator comm1 = comm();
distributor dof_ownership = ownership();
size_type ndof1 = dof_ownership.size();
size_type dis_ndof1 = dof_ownership.dis_size();
idof2ios_dis_idof.resize (dof_ownership, std::numeric_limits<size_type>::max());
size_type comp_start_idof = 0;
size_type comp_start_dis_idof = 0;
set_ios_permutation_recursion (idof2ios_dis_idof, comp_start_idof, comp_start_dis_idof);
// ----------------------------------------------
// 2) invert permutation into ios_idof2dis_idof
// ----------------------------------------------
size_type ios_ndof1 = ios_ndof();
distributor ios_dof_ownership (dis_ndof1, idof2ios_dis_idof.comm(), ios_ndof1);
ios_idof2dis_idof.resize (ios_dof_ownership, std::numeric_limits<size_type>::max());
idof2ios_dis_idof.reverse_permutation (ios_idof2dis_idof);
}
// ======================================================================
// 8. comp_dis_idof2dis_idof : for wdof_sliced
// ======================================================================
template <class T, class M>
typename space_constitution_rep<T,M>::size_type
space_constitution_rep<T,M>::comp_dis_idof2dis_idof (
size_type i_comp,
size_type comp_dis_idof) const
{
if (! is_hierarchical()) {
// component of a "vector" or "tensor" valued space
size_type n_comp = get_terminal().get_basis().size();
size_type dis_idof = comp_dis_idof*n_comp + i_comp;
return dis_idof;
}
// here: any space product such as Zh=Xh*Yh
const distributor& comp_ownership = _hier_constit [i_comp].ownership();
size_type iproc = comp_ownership.find_owner (comp_dis_idof);
size_type first_comp_dis_idof = comp_ownership.first_index (iproc);
check_macro (comp_dis_idof >= first_comp_dis_idof, "comp_dis_idof="<<comp_dis_idof << " is out of range");
size_type comp_idof = comp_dis_idof - first_comp_dis_idof;
size_type comp_start_idof = _start_by_flattened_component[i_comp].size (iproc);
size_type idof = comp_start_idof + comp_idof;
size_type first_dis_idof = _ownership.first_index (iproc);
size_type dis_idof = first_dis_idof + idof;
return dis_idof;
}
// ----------------------------------------------------------------------------
// instanciation in library
// ----------------------------------------------------------------------------
template class space_constitution_terminal_rep<Float,sequential>;
template class space_constitution_rep<Float,sequential>;
template class space_constitution<Float,sequential>;
#ifdef _RHEOLEF_HAVE_MPI
template class space_constitution_terminal_rep<Float,distributed>;
template class space_constitution_rep<Float,distributed>;
template class space_constitution<Float,distributed>;
#endif // _RHEOLEF_HAVE_MPI
} // namespace rheolef
size_type
field::size_type size_type
Definition branch.cc:430
basis
see the basis page for the full documentation
rheolef::basis_basic
Definition basis.h:566
rheolef::basis_option::set_coordinate_system
void set_coordinate_system(coordinate_type sc)
Definition basis_option.h:151
rheolef::basis_option::set_dimension
void set_dimension(size_type d)
Definition basis_option.h:150
rheolef::basis_option::dimension
size_type dimension() const
Definition basis_option.h:138
rheolef::basis_option::valued_tag
valued_type valued_tag() const
Definition basis_option.h:245
rheolef::basis_rep::standard_naming
static std::string standard_naming(std::string family_name, size_t degree, const basis_option &sopt)
Definition basis_rep.cc:44
rheolef::disarray
see the disarray page for the full documentation
Definition disarray.h:497
rheolef::distributor
see the distributor page for the full documentation
Definition distributor.h:69
rheolef::distributor::last_index
size_type last_index(size_type iproc) const
Definition distributor.h:164
rheolef::distributor::find_owner
size_type find_owner(size_type dis_i) const
find iproc associated to a global index dis_i: CPU=log(nproc)
Definition distributor.cc:106
rheolef::distributor::dis_size
size_type dis_size() const
global and local sizes
Definition distributor.h:214
rheolef::distributor::size
size_type size(size_type iproc) const
Definition distributor.h:170
rheolef::distributor::first_index
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
Definition distributor.h:158
rheolef::distributor::is_owned
bool is_owned(size_type dis_i, size_type iproc) const
true when dis_i in [first_index(iproc):last_index(iproc)[
Definition distributor.h:220
rheolef::distributor::decide
static const size_type decide
Definition distributor.h:83
rheolef::distributor::size_type
std::allocator< int >::size_type size_type
Definition distributor.h:74
rheolef::domain_indirect_basic
the finite element boundary domain
Definition domain_indirect.h:335
rheolef::geo_basic
generic mesh with rerefence counting
Definition geo.h:1089
rheolef::geo_element
see the geo_element page for the full documentation
Definition geo_element.h:102
rheolef::reference_element::last_variant_by_dimension
static variant_type last_variant_by_dimension(size_type dim)
Definition reference_element.h:150
rheolef::reference_element::first_variant_by_dimension
static variant_type first_variant_by_dimension(size_type dim)
Definition reference_element.h:148
rheolef::smart_pointer_base::data
const T & data() const
Definition smart_pointer.h:266
rheolef::space_act
Definition space_constitution.h:38
rheolef::space_act::get_domain_name
const std::string & get_domain_name() const
Definition space_constitution.h:66
rheolef::space_act::act_type
act_type
Definition space_constitution.h:46
rheolef::space_act::unblock
@ unblock
Definition space_constitution.h:48
rheolef::space_act::block_n
@ block_n
Definition space_constitution.h:49
rheolef::space_act::unblock_n
@ unblock_n
Definition space_constitution.h:50
rheolef::space_act::block
@ block
Definition space_constitution.h:47
rheolef::space_act::unset_index
static const size_type unset_index
Definition space_constitution.h:44
rheolef::space_basic
the finite element space
Definition space.h:382
rheolef::space_constitution_rep
Definition space_constitution.h:208
rheolef::space_constitution_rep::append_external_dof
void append_external_dof(const geo_basic< T, M > &dom, std::set< size_type > &ext_dof_set, const distributor &dof_ownership, const distributor &start_by_component) const
Definition space_constitution.cc:431
rheolef::space_constitution_rep::build_blocked_flag
disarray< size_type, M > build_blocked_flag() const
Definition space_constitution.cc:196
rheolef::space_constitution_rep::_hier_constit
hierarchy_type _hier_constit
Definition space_constitution.h:338
rheolef::space_constitution_rep::name
std::string name() const
Definition space_constitution.cc:511
rheolef::space_constitution_rep::have_compact_support_inside_element
bool have_compact_support_inside_element() const
Definition space_constitution.cc:257
rheolef::space_constitution_rep::set_ios_permutations
void set_ios_permutations(disarray< size_type, M > &idof2ios_dis_idof, disarray< size_type, M > &ios_idof2dis_idof) const
Definition space_constitution.cc:618
rheolef::space_constitution_rep::get_basis
const basis_basic< T > & get_basis() const
Definition space_constitution.cc:247
rheolef::space_constitution_rep::ios_ndof
size_type ios_ndof() const
Definition space_constitution.cc:555
rheolef::space_constitution_rep::_init_start_by_component
void _init_start_by_component() const
Definition space_constitution.cc:362
rheolef::space_constitution_rep::get_background_geo
const geo_basic< T, M > & get_background_geo() const
Definition space_constitution.cc:234
rheolef::space_constitution_rep::space_constitution_rep
space_constitution_rep()
Definition space_constitution.h:347
rheolef::space_constitution_rep::_loc_ndof
std::array< size_type, reference_element::max_variant > _loc_ndof
Definition space_constitution.h:339
rheolef::space_constitution_rep::put
void put(std::ostream &out, size_type level=0) const
Definition space_constitution.cc:492
rheolef::space_constitution_rep::_init_flattened_size
size_type _init_flattened_size() const
Definition space_constitution.cc:326
rheolef::space_constitution_rep::is_discontinuous
bool is_discontinuous() const
Definition space_constitution.cc:271
rheolef::space_constitution_rep::build_blocked_flag_recursive
void build_blocked_flag_recursive(disarray< size_type, M > &blocked_flag, const std::vector< distributor > &start_by_component, size_type &i_comp) const
Definition space_constitution.cc:177
rheolef::space_constitution_rep::_init_start_by_flattened_component
void _init_start_by_flattened_component(size_type &i_flat_comp, size_type &start_flat_comp_idof, size_type &dis_start_flat_comp_idof, std::vector< distributor > &start_by_flattened_component) const
Definition space_constitution.cc:338
rheolef::space_constitution_rep::set_ios_permutation_recursion
void set_ios_permutation_recursion(disarray< size_type, M > &idof2ios_dis_idof, size_type &comp_start_idof, size_type &comp_start_dis_idof) const
Definition space_constitution.cc:581
rheolef::space_constitution_rep::iterator
hierarchy_type::iterator iterator
Definition space_constitution.h:215
rheolef::space_constitution_rep::operator==
bool operator==(const space_constitution_rep< T, M > &V2) const
Definition space_constitution.cc:308
rheolef::space_constitution_rep::_terminal_constit
scalar_type _terminal_constit
Definition space_constitution.h:337
rheolef::space_constitution_rep::degree_max
size_type degree_max() const
Definition space_constitution.cc:522
rheolef::space_constitution_rep::const_iterator
hierarchy_type::const_iterator const_iterator
Definition space_constitution.h:216
rheolef::space_constitution_rep::initialize
void initialize() const
Definition space_constitution.cc:383
rheolef::space_constitution_rep::size_type
hierarchy_type::size_type size_type
Definition space_constitution.h:214
rheolef::space_constitution_rep::get_geo
const geo_basic< T, M > & get_geo() const
Definition space_constitution.cc:209
rheolef::space_constitution_rep::compute_external_dofs
void compute_external_dofs(std::set< size_type > &ext_dof_set) const
Definition space_constitution.cc:480
rheolef::space_constitution_rep::_is_hier
bool _is_hier
Definition space_constitution.h:336
rheolef::space_constitution_rep::neighbour_guard
void neighbour_guard() const
Definition space_constitution.cc:536
rheolef::space_constitution_rep::do_act
void do_act(const space_act &act)
Definition space_constitution.cc:85
rheolef::space_constitution_rep::comp_dis_idof2dis_idof
size_type comp_dis_idof2dis_idof(size_type i_comp, size_type comp_dis_idof) const
Definition space_constitution.cc:652
rheolef::space_constitution_terminal_rep
Definition space_constitution.h:81
rheolef::space_constitution_terminal_rep::space_constitution_terminal_rep
space_constitution_terminal_rep()
Definition space_constitution.h:89
rheolef::space_constitution_terminal_rep::size_type
container_type::size_type size_type
Definition space_constitution.h:84
rheolef::space_constitution_terminal_rep::set_ios_permutations
void set_ios_permutations(disarray< size_type, M > &idof2ios_dis_idof, disarray< size_type, M > &ios_idof2dis_idof) const
Definition space_constitution.cc:573
rheolef::space_constitution_terminal_rep::const_iterator
container_type::const_iterator const_iterator
Definition space_constitution.h:85
rheolef::space_constitution_terminal_rep::build_blocked_flag
void build_blocked_flag(disarray< size_type, M > &blocked_flag, const distributor &comp_ownership, const distributor &start_by_component) const
Definition space_constitution.cc:104
rheolef::space_constitution_terminal_rep::_fem_basis
basis_basic< T > _fem_basis
Definition space_constitution.h:145
rheolef::space_constitution_terminal_rep::do_act
void do_act(const space_act &act)
Definition space_constitution.cc:75
rheolef::space_constitution_terminal
Definition space_constitution.h:148
rheolef::space_constitution_terminal::get_basis
const basis_basic< T > & get_basis() const
Definition space_constitution.h:170
rheolef::space_constitution_terminal::get_geo
const geo_basic< T, M > & get_geo() const
Definition space_constitution.h:168
rheolef::space_constitution_terminal::do_act
void do_act(const space_act &act)
Definition space_constitution.h:197
rheolef::space_constitution
Definition space_constitution.h:405
rheolef::space_constitution::have_compact_support_inside_element
bool have_compact_support_inside_element() const
Definition space_constitution.h:460
rheolef::space_constitution::degree_max
size_type degree_max() const
Definition space_constitution.h:462
rheolef::space_constitution::get_background_geo
const geo_basic< T, M > & get_background_geo() const
Definition space_constitution.h:441
rheolef::space_constitution::is_discontinuous
bool is_discontinuous() const
Definition space_constitution.h:461
rheolef::space_constitution::set_ios_permutation_recursion
void set_ios_permutation_recursion(disarray< size_type, M > &idof2ios_dis_idof, size_type &comp_start_idof, size_type &comp_start_dis_idof) const
Definition space_constitution.h:500
rheolef::space_constitution::ios_ndof
size_type ios_ndof() const
Definition space_constitution.h:438
rheolef::space_constitution::get_geo
const geo_basic< T, M > & get_geo() const
Definition space_constitution.h:440
rheolef::space_constitution::ownership
const distributor & ownership() const
Definition space_constitution.h:434
rheolef::space_constitution::neighbour_guard
void neighbour_guard() const
Definition space_constitution.h:463
rheolef::space_constitution::do_act
void do_act(const space_act &act)
Definition space_constitution.h:448
rheolef::space_mult_list
Definition space_mult.h:54
rheolef::space_mult_list::const_iterator
rep::const_iterator const_iterator
Definition space_mult.h:61
assert_macro
#define assert_macro(ok_condition, message)
Definition dis_macros.h:113
error_macro
#define error_macro(message)
Definition dis_macros.h:49
dimension
const size_t dimension
Definition edge.icc:64
get_geo
void get_geo(istream &in, my_geo &omega)
Definition field2gmsh_pos.cc:126
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::space_constant::tensor
@ tensor
Definition space_constant.h:136
rheolef::space_constant::scalar
@ scalar
Definition space_constant.h:134
rheolef::space_constant::cartesian
@ cartesian
Definition space_constant.h:120
rheolef::space_numbering::dis_idof
void dis_idof(const basis_basic< T > &b, const geo_size &gs, const geo_element &K, typename std::vector< size_type >::iterator dis_idof_tab)
Definition space_numbering.cc:187
rheolef::space_numbering::set_ios_permutations
void set_ios_permutations(const basis_basic< T > &b, const geo_basic< T, distributed > &omega, disarray< size_type, distributed > &idof2ios_dis_idof, disarray< size_type, distributed > &ios_idof2dis_idof)
Definition space_numbering.cc:275
rheolef::space_numbering::dis_ndof
size_type dis_ndof(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
Definition space_numbering.cc:41
rheolef::space_numbering::ndof
size_type ndof(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
Definition space_numbering.cc:28
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::compact
geo_basic< T, M > compact(const geo_basic< T, M > &gamma)
Definition geo.cc:219
rheolef::normal
details::field_expr_v2_nonlinear_terminal_function< details::normal_pseudo_function< Float > > normal()
normal: see the expression page for the full documentation
Definition field_expr_terminal.h:432
rheolef::put
void put(std::ostream &out, std::string name, const tiny_matrix< T > &a)
Definition tiny_lu.h:155
rheolef::basis_parse_from_string
void basis_parse_from_string(const std::string &str, family_index_option_type &fio)
Definition basis_get.cc:142
rheolef::family_index_option_type
Definition basis_get.h:31
rheolef::family_index_option_type::option
basis_option option
Definition basis_get.h:36
rheolef::family_index_option_type::index
size_t index
Definition basis_get.h:35
rheolef::family_index_option_type::family
std::string family
Definition basis_get.h:34
M
Expr1::memory_type M
Definition vec_expr_v2.h:416