21#include "rheolef/config.h"
22#ifdef _RHEOLEF_HAVE_MPI
23#include "rheolef/geo.h"
24#include "rheolef/geo_domain.h"
25#include "rheolef/space_numbering.h"
26#include "rheolef/dis_macros.h"
27#include "rheolef/rheostream.h"
28#include "rheolef/iorheo.h"
29#include "rheolef/index_set.h"
47build_true_ios_ge_ownership_by_dimension (
56 if (first_variant >= last_variant)
return distributor();
57 const communicator& comm = ios_geo_element [first_variant].ownership().comm();
60 size_type dis_nge = 0;
63 nge += ios_geo_element [
variant].size();
64 dis_nge += ios_geo_element [
variant].dis_size();
70build_apparent_ios_ownership(
83 if (first_variant >= last_variant)
return;
84 const communicator& comm = ios_geo_element [first_variant].ownership().comm();
87 size_type dis_nge = 0;
90 dis_nge += ios_geo_element [
variant].dis_size();
97 size_type first_dis_v = 0;
101 size_type dis_ngev = ios_geo_element [
variant].dis_size();
102 size_type last_dis_v = first_dis_v + dis_ngev;
103 size_type first_ios_dis_nge = ios_ownership.first_index();
104 size_type last_ios_dis_nge = ios_ownership. last_index();
105 size_type first_ios_dis_ngev = min (max (first_ios_dis_nge, first_dis_v), last_ios_dis_nge);
106 size_type last_ios_dis_ngev = max (min ( last_ios_dis_nge, last_dis_v), first_ios_dis_nge);
107 size_type ios_ngev = last_ios_dis_ngev - first_ios_dis_ngev;
109 first_dis_v = last_dis_v;
127 std::array<std::vector<size_t>, 4>& massive_partition_by_dimension,
130 typedef size_t size_type;
132 size_type dis_nv = ios_vertex_ownership.
dis_size();
133 size_type first_ios_dis_iv = ios_vertex_ownership.
first_index();
139 size_type K_dim = S_dim + 1;
140 size_type K_ios_ige = 0;
141 distributor true_K_ios_ge_ownership = build_true_ios_ge_ownership_by_dimension (ios_geo_element, K_dim);
142 size_type first_K_ios_dis_ige = true_K_ios_ge_ownership.
first_index();
145 distributor K_ios_gev_ownership = ios_geo_element [K_variant].ownership();
146 for (size_type K_ios_igev = 0, K_ios_ngev = K_ios_gev_ownership.
size(); K_ios_igev < K_ios_ngev; K_ios_igev++, K_ios_ige++) {
147 const geo_element& K = ios_geo_element [K_variant] [K_ios_igev];
148 size_type K_ios_dis_ige = first_K_ios_dis_ige + K_ios_ige;
149 for (size_type iloc = 0, nloc = K.
size(); iloc < nloc; iloc++) {
150 size_type ios_dis_iv = K[iloc];
151 assert_macro (ios_dis_iv < dis_nv,
"K={"<<K<<
"}: "<<iloc<<
"-vertex index " << ios_dis_iv <<
" out of range [0:"<<dis_nv<<
"[");
152 if (ios_vertex_ownership.
is_owned(ios_dis_iv)) {
153 size_type ios_iv = ios_dis_iv - first_ios_dis_iv;
154 K_ball[ios_iv] += K_ios_dis_ige;
157 K_ios_dis_ige_set += K_ios_dis_ige;
158 K_ball.dis_entry (ios_dis_iv) += K_ios_dis_ige_set;
163 K_ball.dis_entry_assembly();
170 distributor ios_gev_ownership = ios_geo_element [S_variant].ownership();
171 for (size_type ios_igev = 0, ios_ngev = ios_gev_ownership.
size(); ios_igev < ios_ngev; ios_igev++) {
172 const geo_element& S = ios_geo_element [S_variant] [ios_igev];
173 for (size_type iloc = 0, nloc = S.
size(); iloc < nloc; iloc++) {
174 size_type ios_dis_iv = S[iloc];
175 if (! ios_vertex_ownership.
is_owned (ios_dis_iv)) {
176 ext_ios_dis_iv += ios_dis_iv;
181 K_ball.set_dis_indexes (ext_ios_dis_iv);
185 distributor true_S_ios_ge_ownership = build_true_ios_ge_ownership_by_dimension (ios_geo_element, S_dim);
186 size_type S_dis_nge = true_S_ios_ge_ownership.
dis_size();
187 size_type first_S_ios_dis_ige = true_S_ios_ge_ownership.
first_index();
188 std::vector<size_type> tmp_S_massive_partition (S_dis_nge, 0);
189 size_type S_ios_ige = 0;
192 distributor ios_gev_ownership = ios_geo_element [S_variant].ownership();
193 size_type first_ios_dis_igev = ios_gev_ownership.
first_index();
194 for (size_type ios_igev = 0, ios_ngev = ios_gev_ownership.
size(); ios_igev < ios_ngev; ios_igev++, S_ios_ige++) {
195 const geo_element& S = ios_geo_element [S_variant] [ios_igev];
196 index_set K_ios_ige_set = K_ball.dis_at (S[0]);
197 for (size_type iloc = 0, nloc = S.
size(); iloc < nloc; iloc++) {
200 check_macro (K_ios_ige_set.size() > 0,
"connectivity: S={"<<S<<
"} not found in the side set");
201 size_type S_owner = 0;
202 for (index_set::const_iterator iter = K_ios_ige_set.begin(), last = K_ios_ige_set.end(); iter != last; iter++) {
203 size_type K_ios_ige = *iter;
204 S_owner = std::max(S_owner, massive_partition_by_dimension[K_dim][K_ios_ige]);
206 size_type S_ios_dis_ige = first_S_ios_dis_ige + S_ios_ige;
207 tmp_S_massive_partition [S_ios_dis_ige] = S_owner;
213 massive_partition_by_dimension[S_dim].resize (tmp_S_massive_partition.size(), 0);
217 tmp_S_massive_partition.begin().operator->(),
218 tmp_S_massive_partition.size(),
219 massive_partition_by_dimension[S_dim].begin().operator->(),
220 mpi::maximum<size_type>());
224 size_type S_ios_dis_ige = first_S_ios_dis_ige;
227 partition_by_variant [S_variant].resize (ios_geo_element [S_variant].ownership());
228 for (size_type S_ios_igev = 0, S_ios_negv = partition_by_variant [S_variant].size();
229 S_ios_igev < S_ios_negv; S_ios_igev++, S_ios_dis_ige++) {
230 partition_by_variant [S_variant][S_ios_igev] = massive_partition_by_dimension[S_dim] [S_ios_dis_ige];
256 partition_by_variant)
262 communicator comm = ios_geo_element[0].ownership().comm();
271 ios_geo_element [variant].repartition (
272 partition_by_variant [variant],
274 igev2ios_dis_igev [variant],
275 ios_igev2dis_igev [variant]);
285 size_type first_v = 0;
305 for (size_type igev = 0, ngev =
geo_element [variant].size(); igev < ngev; igev++, ige++) {
307 size_type dis_ige = first_dis_ige + ige;
310 ios_ige2dis_ige [side_dim].dis_entry (ios_dis_ige) = dis_ige;
313 ios_ige2dis_ige [side_dim].dis_entry_assembly();
319 const std::vector<geo_element::size_type>& new_global_node_num,
330 size_type first_dis_igev = gev.ownership().first_index();
331 for (size_type igev = 0, ngev = gev.size(); igev < ngev; igev++) {
333 for (size_type iloc = 0, nloc = S.
n_node(); iloc < nloc; iloc++) {
334 assert_macro (S[iloc] < dis_nnod,
"node index "<<S[iloc]<<
" out of range [0:"<<dis_nnod<<
"[");
335 assert_macro (new_global_node_num[S[iloc]] < dis_nnod,
"new node index "<<new_global_node_num[S[iloc]] <<
" out of range [0:"<<dis_nnod<<
"[");
336 S[iloc] = new_global_node_num [S[iloc]];
362 std::set<size_type> ext_vertex_set;
363 std::set<size_type> ext_node_set;
364 std::vector<size_type> dis_inod1;
370 for (
size_type loc_inod = 0, loc_nnod = dis_inod1.size(); loc_inod < loc_nnod; loc_inod++) {
375 if (loc_inod >= K.
size())
continue;
378 check_macro (dis_iv < dis_nv,
"vertex index "<< dis_iv <<
" out of range [0:"<<dis_nv<<
"[");
380 ext_vertex_set.insert (dis_iv);
394 for (
auto i: ext_gev) { ext_dis_ie_set.
insert (i.first); }
398 std::array<index_set,reference_element::max_variant> ext_dis_igev_set;
405 for (
size_type loc_is = 0, loc_ns = K.
n_subgeo(subgeo_dim); loc_is < loc_ns; ++loc_is) {
407 check_macro(dis_ige != std::numeric_limits<size_type>::max(),
"invalid external subgeo dis_index");
408 if (
base::sizes().ownership_by_dimension [subgeo_dim].is_owned (dis_ige))
continue;
411 check_macro(dis_ige <
dis_size,
"invalid external "<<subgeo_dim<<
"d subgeo dis_index = "<<dis_ige<<
" out of range [0:"<<
dis_size<<
"[");
415 ext_dis_igev_set [
variant].insert (dis_igev);
433 for (
size_type loc_inod = 0, loc_nnod = dis_inod1.size(); loc_inod < loc_nnod; loc_inod++) {
468 for (
size_type iloc = 0, nloc = K.
size(); iloc < nloc; iloc++) {
472 ext_iv_set.
insert (dis_iv);
490 size_type dis_igev = first_dis_igev + igev;
491 for (
size_type iloc = 0, nloc = S.
size(); iloc < nloc; iloc++) {
497 ball [
variant][iv] += dis_igev;
500 dis_igev_set += dis_igev;
501 ball [
variant].dis_entry (dis_iv) += dis_igev_set;
505 ball [
variant].dis_entry_assembly();
514 ball [
variant].set_dis_indexes (ext_iv_set);
526 std::set<size_type> ext_igev_set;
532 for (index_set::const_iterator iter = ball_iv.begin(), last = ball_iv.end(); iter != last; iter++) {
534 assert_macro (dis_igev < dis_ngev,
"index "<<dis_igev<<
" of element variant="<<
variant<<
" is out of range [0:"<<dis_ngev<<
"[");
535 if (! gev_ownership.
is_owned (dis_igev)) {
536 ext_igev_set.insert (dis_igev);
542 const map_type& ball_dis = ball [
variant].get_dis_map_entries();
543 for (
typename map_type::const_iterator iter_b = ball_dis.begin(), last_b = ball_dis.end(); iter_b != last_b; iter_b++) {
545 const index_set& ball_dis_iv = (*iter_b).second;
546 for (index_set::const_iterator iter = ball_dis_iv.begin(), last = ball_dis_iv.end(); iter != last; iter++) {
548 assert_macro (dis_igev < dis_ngev,
"index "<<dis_igev<<
" of element variant="<<
variant<<
" is out of range [0:"<<dis_ngev<<
"[");
549 if (! gev_ownership.
is_owned (dis_igev)) {
550 ext_igev_set.insert (dis_igev);
572 for (
size_type loc_isid = 0, loc_nsid = K.
n_subgeo(side_dim); loc_isid < loc_nsid; loc_isid++) {
576 S_inod [0] = K[loc_jv0];
579 index_set igev_set = ball_S_variant.dis_at (S_iv[0]);
580 for (
size_type sid_jloc = 1, sid_nloc = S_size; sid_jloc < sid_nloc; sid_jloc++) {
582 S_inod [sid_jloc] = K[loc_jv];
584 const index_set& ball_jv = ball_S_variant.dis_at (S_iv[sid_jloc]);
587 check_macro (igev_set.size() > 0,
"connectivity: "<<S_size<<
"-side ("
588 <<S_iv[0]<<
","<<S_iv[1]<<
","<<S_iv[2]<<
","<<S_iv[3]<<
") not found in the side set");
589 check_macro (igev_set.size() == 1,
"connectivity: the same side is multiply represented");
590 size_type dis_igev = *(igev_set.begin());
628 std::array<size_type,reference_element::max_variant> loc_ndof_by_variant;
658 "unsupported geo without connectivity in the distributed version: HINT: use geo_upgrade");
683 ios_nv = ios_node.size();
692 ios_geo_element [
variant].get_values (ips);
694 ios_ne += ios_geo_element [
variant].size();
695 dis_ne += ios_geo_element [
variant].dis_size();
697 build_apparent_ios_ownership(
703 vector<size_type> local_is_vertex (dis_nnod, 0);
707 size_type first_ios_dis_igev = ios_geo_element [
variant].ownership().first_index();
710 iter != last; iter++, ios_igev++) {
712 size_type ios_dis_ie = first_ios_dis_v + first_ios_dis_igev + ios_igev;
714 ios_size_by_variant [K.
variant()]++;
716 for (
size_type iloc = 0, nloc = K.
size(); iloc < nloc; iloc++) {
717 local_is_vertex [K[iloc]] = 1;
723 ios_nv = ios_node.size();
725 vector<size_type> global_is_vertex (dis_nnod, 0);
728 local_is_vertex.begin().operator->(),
729 local_is_vertex.size(),
730 global_is_vertex.begin().operator->(),
731 mpi::maximum<size_type>());
732 ios_nv = accumulate (global_is_vertex.begin() + ios_node.ownership().first_index(),
733 global_is_vertex.begin() + ios_node.ownership().last_index(), 0);
738 ios_vertex_ownership = ios_node.ownership();
752 _ios_gs.ownership_by_dimension [0] = ios_vertex_ownership;
754 for (
size_type ios_iv = 0, ios_nv = ios_vertex_ownership.
size(); ios_iv < ios_nv; ios_iv++) {
756 size_type ios_dis_iv = first_ios_dis_iv + ios_iv;
759 ios_size_by_variant [P.
variant()]++;
773 ios_geo_element [
variant].get_values (ips);
775 ios_ngev += ios_geo_element [
variant].size();
776 dis_ngev += ios_geo_element [
variant].dis_size();
778 build_apparent_ios_ownership(
781 _ios_gs.ownership_by_dimension [side_dim],
788 size_type first_ios_dis_igev = ios_geo_element [
variant].ownership().first_index();
790 iter != last; iter++, ios_igev++) {
792 size_type ios_dis_igev = first_dis_v + first_ios_dis_igev + ios_igev;
794 ios_size_by_variant [S.
variant()]++;
803 true_ios_ownership_by_dimension [
base::_gs._map_dimension]
804 = build_true_ios_ge_ownership_by_dimension (ios_geo_element,
base::_gs._map_dimension);
808 true_ios_ownership_by_dimension [
base::_gs._map_dimension],
820 last_by_var = partition_by_variant [
variant].
end();
821 iter_by_var != last_by_var; iter_by_var++, iter++) {
822 *iter_by_var = *iter;
836 partition_by_variant);
840 std::array<std::vector<size_t>, 4> massive_partition_by_dimension;
842 std::vector<size_t> tmp_massive_partition (dis_ne, 0);
844 for (
size_type ios_ie = 0, ios_ne = partition.size(); ios_ie < ios_ne; ios_ie++) {
845 size_type ios_dis_ie = true_first_dis_ige + ios_ie;
846 tmp_massive_partition [ios_dis_ie] = partition [ios_ie];
848 massive_partition_by_dimension [
base::_gs._map_dimension].resize (dis_ne);
851 tmp_massive_partition.begin().operator->(),
852 tmp_massive_partition.size(),
853 massive_partition_by_dimension[
base::_gs._map_dimension].begin().operator->(),
854 mpi::maximum<size_type>());
862 massive_partition_by_dimension,
863 partition_by_variant);
873 for (
size_type ios_iv = 0, ios_nv = ios_vertex_ownership.
size(); ios_iv < ios_nv; ios_iv++) {
874 size_type ios_dis_iv = first_ios_dis_iv + ios_iv;
875 partition_by_variant [
reference_element::p] [ios_iv] = massive_partition_by_dimension[0] [ios_dis_iv];
917 partition_by_variant);
925 bool status = dom.get (ips, *
this);
934 base::_gs.node_ownership = node_ownership;
938 _ios_inod2dis_inod.resize (ios_node.ownership(), std::numeric_limits<size_type>::max());
950 vector<size_type> new_local_node_num (dis_nnod, 0);
953 for (
size_type dis_ios_inod = first_ios_inod; dis_ios_inod < last_ios_inod; dis_ios_inod++) {
954 size_type ios_inod = dis_ios_inod - first_ios_inod;
957 vector<size_type> new_global_node_num (dis_nnod, 0);
960 new_local_node_num.begin().operator->(),
961 new_local_node_num.size(),
962 new_global_node_num.begin().operator->(),
963 mpi::maximum<size_type>());
999 std::string filename,
1004 check_macro(ips.
good(),
"\"" << filename <<
"[.geo[.gz]]\" not found.");
see the communicator page for the full documentation
see the disarray page for the full documentation
rep::base::const_iterator const_iterator
rep::base::iterator iterator
see the distributor page for the full documentation
size_type last_index(size_type iproc) const
size_type dis_size() const
global and local sizes
size_type size(size_type iproc) const
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
bool is_owned(size_type dis_i, size_type iproc) const
true when dis_i in [first_index(iproc):last_index(iproc)[
static const size_type decide
const communicator_type & comm() const
the finite element boundary domain
void dis_inod(const geo_element &K, std::vector< size_type > &dis_inod) const
std::vector< domain_indirect_basic< distributed > > _domains
const basis_basic< T > & get_piola_basis() const
coordinate_type _sys_coord
basis_basic< T > _piola_basis
size_type dis_inod2dis_iv(size_type dis_inod) const
disarray< node_type, distributed > _node
size_type variant() const
const geo_size & sizes() const
std::array< hack_array< geo_element_hack, distributed >, reference_element::max_variant > _geo_element
const distributor & ownership() const
const communicator & comm() const
size_type dis_size(size_type dim) const
void set(orientation_type orient, size_type ige, size_type shift=0)
see the geo_element page for the full documentation
geo_element_indirect::orientation_type orientation_type
bool get_orientation_and_shift(const geo_element &S, orientation_type &orient, shift_type &shift) const
return orientation and shift between *this element and S
size_type edge(size_type i) const
size_type face(size_type i) const
size_type subgeo_local_vertex(size_type subgeo_dim, size_type i_subgeo, size_type i_subgeo_vertex) const
reference_element::size_type size_type
void set_ios_dis_ie(size_type ios_dis_ie)
size_type dimension() const
size_type ios_dis_ie() const
size_type subgeo_size(size_type subgeo_dim, size_type loc_isid) const
const geo_element_indirect & edge_indirect(size_type i) const
variant_type variant() const
orientation_type get_edge_orientation(size_type dis_iv0, size_type dis_iv1) const
geo_element_indirect::shift_type shift_type
size_type n_subgeo(size_type subgeo_dim) const
const geo_element_indirect & face_indirect(size_type i) const
void set_dis_ie(size_type dis_ie)
const_iterator end(size_type dim) const
size_type size(size_type dim) const
void node_renumbering(const distributor &ios_node_ownership)
idiststream & get(idiststream &)
void set_ios_permutation(disarray< size_type, distributed > &idof2ios_dis_idof) const
base::iterator_by_variant iterator_by_variant
size_type map_dimension() const
std::array< disarray< size_type, distributed >, reference_element::max_variant > _ios_igev2dis_igev
std::array< disarray< size_type >, 4 > _ios_ige2dis_ige
std::array< disarray< size_type, distributed >, reference_element::max_variant > _igev2ios_dis_igev
base::size_type size_type
const distributor & vertex_ownership() const
disarray< size_type > _ios_inod2dis_inod
disarray< size_type > _inod2ios_dis_inod
void build_external_entities()
const_reference get_geo_element(size_type dim, size_type ige) const
const_iterator begin(size_type dim) const
void set_element_side_index(size_type side_dim)
sequential mesh representation
std::vector< T, A >::iterator iterator
std::vector< T, A >::const_iterator const_iterator
idiststream: see the diststream page for the full documentation
static size_type io_proc()
This routine returns the rank of a process that can perform i/o.
void open(std::string filename, std::string suffix="", const communicator &comm=communicator())
This routine opens a physical input file.
const communicator & comm() const
void inplace_intersection(const index_set &b)
void insert(size_type dis_i)
static const variant_type max_variant
static void init_local_nnode_by_variant(size_type order, std::array< size_type, reference_element::max_variant > &loc_nnod_by_variant)
static variant_type last_variant_by_dimension(size_type dim)
static variant_type first_variant_by_dimension(size_type dim)
static const variant_type p
variant_type variant() const
#define assert_macro(ok_condition, message)
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
void generic_set_ios_permutation(const basis_basic< T > &b, size_t map_d, const geo_size &gs, const std::array< disarray< size_t, distributed >, reference_element::max_variant > &igev2ios_dis_igev, disarray< size_t, distributed > &idof2ios_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)
This file is part of Rheolef.
string delete_suffix(const string &name, const string &suffix)
delete_suffix: see the rheostream page for the full documentation
void geo_element_renumbering_part1_new(const std::array< hack_array< geo_element_hack >, reference_element::max_variant > &ios_geo_element, const geo_size &ios_gs, size_t S_dim, std::array< std::vector< size_t >, 4 > &massive_partition_by_dimension, std::array< disarray< size_t >, reference_element::max_variant > &partition_by_variant)
string get_basename(const string &name)
get_basename: see the rheostream page for the full documentation
disarray< size_t > geo_mpi_partition(const std::array< hack_array< geo_element_hack >, reference_element::max_variant > &ios_geo_element, const distributor &ownership_by_dimension, size_t map_dim, size_t dis_nv)
bool dis_scatch(idiststream &ips, const communicator &comm, std::string ch)
distributed version of scatch(istream&,string)
void geo_element_renumbering_propagate(const std::vector< geo_element::size_type > &new_global_node_num, size_t dis_nnod, hack_array< geo_element_hack > &gev)
void geo_element_renumbering_part2(const std::array< hack_array< geo_element_hack >, reference_element::max_variant > &ios_geo_element, const geo_size &ios_gs, size_t dis_nv, size_t side_dim, std::array< hack_array< geo_element_hack >, reference_element::max_variant > &geo_element, geo_size &gs, std::array< disarray< size_t >, reference_element::max_variant > &igev2ios_dis_igev, std::array< disarray< size_t >, reference_element::max_variant > &ios_igev2dis_igev, std::array< disarray< size_t >, 4 > &ios_ige2dis_ige, std::array< disarray< size_t >, reference_element::max_variant > &partition_by_variant)
distributor ownership_by_variant[reference_element::max_variant]
distributor ownership_by_dimension[4]
distributor first_by_variant[reference_element::max_variant]