Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
geo_mpi_get.cc
Go to the documentation of this file.
1
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"
30
31namespace rheolef {
32
33extern
34disarray<size_t>
36 const std::array<hack_array<geo_element_hack>,reference_element::max_variant>&
37 ios_geo_element,
38 const distributor& ownership_by_dimension,
39 size_t map_dim,
40 size_t dis_nv);
41
42// --------------------------------------------------------------------------
43// utility for geo get
44// --------------------------------------------------------------------------
45static
46distributor
47build_true_ios_ge_ownership_by_dimension (
48 const std::array<hack_array<geo_element_hack>,reference_element::max_variant>&
49 ios_geo_element,
50 size_t side_dim)
51{
52 using namespace std;
56 if (first_variant >= last_variant) return distributor();
57 const communicator& comm = ios_geo_element [first_variant].ownership().comm();
58
59 size_type nge = 0;
60 size_type dis_nge = 0;
63 nge += ios_geo_element [variant].size();
64 dis_nge += ios_geo_element [variant].dis_size();
65 }
66 return distributor (dis_nge, comm, nge);
67}
68static
69void
70build_apparent_ios_ownership(
71// input:
72 const std::array<hack_array<geo_element_hack>,reference_element::max_variant>&
73 ios_geo_element,
74 size_t side_dim,
75// output:
76 distributor& ios_ownership,
77 distributor ios_ownership_by_variant [reference_element::max_variant])
78{
79 using namespace std;
83 if (first_variant >= last_variant) return;
84 const communicator& comm = ios_geo_element [first_variant].ownership().comm();
85
86 // 1) build ios_ownership = ios_geo_element ownership by dimension
87 size_type dis_nge = 0;
90 dis_nge += ios_geo_element [variant].dis_size();
91 }
92 ios_ownership = distributor (dis_nge, comm, distributor::decide);
93
94 // 2) build ios_ownership_by_variant as if it was readed in sequence, by dimension
95 // Note: used by P1d and P2 element numbering, for output of results in the same
96 // vertex, edges, faces & volume as these entities was readed
97 size_type first_dis_v = 0;
100
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;
108 ios_ownership_by_variant [variant] = distributor (dis_ngev, comm, ios_ngev);
109 first_dis_v = last_dis_v;
110 }
111}
112// ----------------------------------------------------------------------------
113// new renumbering:
114// - a vertex belongs to the same proc as at least an edge that contains this vertex
115// - an edge belongs to the same proc as at least a face that contains this edge
116// - a face belongs to the same proc as at least a volume that contains this face
117// => a side S belongs to the same proc as at least a super-side K that contains it
118// ----------------------------------------------------------------------------
119void
121// input:
123 ios_geo_element,
124 const geo_size& ios_gs, // TODO: not used...
125 size_t S_dim,
126// output:
127 std::array<std::vector<size_t>, 4>& massive_partition_by_dimension,
128 std::array<disarray<size_t>, reference_element::max_variant>& partition_by_variant)
129{
130 typedef size_t size_type;
131 distributor ios_vertex_ownership = ios_geo_element [reference_element::p].ownership();
132 size_type dis_nv = ios_vertex_ownership.dis_size();
133 size_type first_ios_dis_iv = ios_vertex_ownership.first_index();
134 // ------------------------------------------------------------------------
135 // 1) K_ball(X) := { K; X is a vertex of K }
136 // ------------------------------------------------------------------------
137 index_set empty_set; // TODO: add a global allocator to empty_set
138 disarray<index_set,distributed> K_ball (ios_vertex_ownership, empty_set);
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();
144 K_variant < reference_element:: last_variant_by_dimension(K_dim); K_variant++) {
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;
155 } else {
156 index_set K_ios_dis_ige_set;
157 K_ios_dis_ige_set += K_ios_dis_ige;
158 K_ball.dis_entry (ios_dis_iv) += K_ios_dis_ige_set; // not so efficient: union with {dis_iegv}
159 }
160 }
161 }
162 }
163 K_ball.dis_entry_assembly();
164 // ------------------------------------------------------------------------
165 // 2) import ball[ios_dis_iv] when dis_iv is referenced by a side S
166 // ------------------------------------------------------------------------
167 index_set ext_ios_dis_iv;
169 S_variant < reference_element:: last_variant_by_dimension(S_dim); S_variant++) {
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;
177 }
178 }
179 }
180 }
181 K_ball.set_dis_indexes (ext_ios_dis_iv);
182 // ------------------------------------------------------------------------
183 // 3) owner(S) := max { owner(K); K is a super-subgeo containing S }
184 // ------------------------------------------------------------------------
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); // TODO: massive memory area
189 size_type S_ios_ige = 0;
191 S_variant < reference_element:: last_variant_by_dimension(S_dim); S_variant++) {
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++) {
198 K_ios_ige_set.inplace_intersection (K_ball.dis_at(S[iloc]));
199 }
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]);
205 }
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;
208 }
209 }
210 // ------------------------------------------------------------------------
211 // 4) all_reduce: TODO: massive memory area comms
212 // ------------------------------------------------------------------------
213 massive_partition_by_dimension[S_dim].resize (tmp_S_massive_partition.size(), 0);
214 communicator comm = ios_vertex_ownership.comm();
215 mpi::all_reduce (
216 comm,
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>());
221 // ------------------------------------------------------------------------
222 // 5) copy the massive_partition_by_dimension into a distributed disarray "partition", variant by variant
223 // ------------------------------------------------------------------------
224 size_type S_ios_dis_ige = first_S_ios_dis_ige;
226 S_variant < reference_element:: last_variant_by_dimension(S_dim); S_variant++) {
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];
231 }
232 }
233}
234// --------------------------------------------------------------------------
235// edges & faces renumbering subroutine
236// --------------------------------------------------------------------------
237void
239 // input:
241 ios_geo_element,
242 const geo_size& ios_gs,
243 size_t dis_nv,
244 size_t side_dim,
245 // output:
248 geo_size& gs,
250 igev2ios_dis_igev,
252 ios_igev2dis_igev,
253 std::array<disarray<size_t>,4>& ios_ige2dis_ige,
254 // tmp:
256 partition_by_variant)
257{
259 typedef hack_array<geo_element_hack>::iterator iterator_by_variant;
260 typedef hack_array<geo_element_hack>::const_iterator const_iterator_by_variant;
261
262 communicator comm = ios_geo_element[0].ownership().comm();
263 //
264 // 3) build geo_elemen [variant]:
265 //
266 // MERGE: could be done from here:
267 size_type nge = 0;
269 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
270
271 ios_geo_element [variant].repartition (
272 partition_by_variant [variant],
273 geo_element [variant],
274 igev2ios_dis_igev [variant],
275 ios_igev2dis_igev [variant]);
276
277 gs.ownership_by_variant [variant] = geo_element [variant].ownership();
278 nge += geo_element [variant].size();
279 }
280 gs.ownership_by_dimension [side_dim] = distributor (distributor::decide, comm, nge);
281 //
282 // 4) build first_by_variant [variant]
283 //
284 {
285 size_type first_v = 0;
287 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
288
289 gs.first_by_variant[variant] = distributor (distributor::decide, comm, first_v);
290 first_v += geo_element [variant].size();
291 }
292 }
293 //
294 // 5) set element number
295 // & build ios_ige2dis_ige[map_dim] from ios_igev2dis_igev[variant]
296 // TODO: a way to build directly ios_ige2dis_ige without assembly (and many comms)
297 //
298 ios_ige2dis_ige [side_dim].resize (ios_gs.ownership_by_dimension [side_dim]); // OK
299 {
300 size_type first_dis_ige = gs.ownership_by_dimension [side_dim].first_index();
301 size_type ige = 0;
303 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
304 size_type first_v = gs.first_by_variant [variant].size();
305 for (size_type igev = 0, ngev = geo_element [variant].size(); igev < ngev; igev++, ige++) {
306 ::rheolef::geo_element& S = geo_element [variant] [igev]; // GNU C++ 4.5 BUG : add ::rheolef::
307 size_type dis_ige = first_dis_ige + ige;
308 S.set_dis_ie (dis_ige);
309 size_type ios_dis_ige = S.ios_dis_ie();
310 ios_ige2dis_ige [side_dim].dis_entry (ios_dis_ige) = dis_ige;
311 }
312 }
313 ios_ige2dis_ige [side_dim].dis_entry_assembly();
314 }
315}
316void
318// input:
319 const std::vector<geo_element::size_type>& new_global_node_num,
320 size_t dis_nnod,
321// modified:
323{
324 using namespace std;
326 //
327 // vertices S[iloc] of new numbered element table still have ios numbering: fix it
328 //
329 // TODO: iterator loop on ge instead of gev
330 size_type first_dis_igev = gev.ownership().first_index();
331 for (size_type igev = 0, ngev = gev.size(); igev < ngev; igev++) {
332 geo_element& S = gev [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]];
337 }
338 }
339}
347template <class T>
348void
350{
351 distributor vertex_ownership = base::_geo_element[reference_element::p].ownership();
352 size_type first_dis_iv = vertex_ownership.first_index();
353 size_type last_dis_iv = vertex_ownership.last_index();
354 size_type dis_nv = vertex_ownership.dis_size();
355
356 distributor node_ownership = base::_node.ownership();
357 size_type first_dis_inod = node_ownership.first_index();
358 size_type last_dis_inod = node_ownership.last_index();
359 size_type dis_nnod = node_ownership.dis_size();
360
361 // 1a) list external vertex & nodes indexes from internal elements
362 std::set<size_type> ext_vertex_set;
363 std::set<size_type> ext_node_set;
364 std::vector<size_type> dis_inod1;
365 for (size_type dim = 1; dim <= base::_gs._map_dimension; dim++) {
366 // loop on elements
367 for (size_type ige = 0, nge = base::_gs.ownership_by_dimension[dim].size(); ige < nge; ige++) {
368 const geo_element& K = get_geo_element(dim,ige);
369 space_numbering::dis_idof (base::_piola_basis, base::_gs, K, dis_inod1);
370 for (size_type loc_inod = 0, loc_nnod = dis_inod1.size(); loc_inod < loc_nnod; loc_inod++) {
371 size_type dis_inod = dis_inod1 [loc_inod];
372 assert_macro (dis_inod < dis_nnod, "node index "<< dis_inod <<" out of range [0:"<<dis_nnod<<"[");
373 if (node_ownership.is_owned (dis_inod)) continue;
374 ext_node_set.insert (dis_inod);
375 if (loc_inod >= K.size()) continue;
376 // then reports vertex to node: same owner
377 size_type dis_iv = base::dis_inod2dis_iv (dis_inod);
378 check_macro (dis_iv < dis_nv, "vertex index "<< dis_iv <<" out of range [0:"<<dis_nv<<"[");
379 check_macro (!vertex_ownership.is_owned (dis_iv), "strange bug: not owned (nod) but is_owned(ver)");
380 ext_vertex_set.insert (dis_iv);
381 }
382 }
383 }
384 // 1b) pull external vertices & nodes:
385 base::_node.append_dis_indexes (ext_node_set);
386 base::_geo_element [reference_element::p].append_dis_indexes (ext_vertex_set);
387
388 // 2) K.edge(i) and K.face(i) have been completed by set set_element_side_index
389 // but not propagated to external elements : update them by refreshing the external data
391 variant < reference_element:: last_variant_by_dimension (base::_gs._map_dimension); ++variant) {
392 const std::map<size_type,geo_element_auto<>>& ext_gev = base::_geo_element [variant].get_dis_map_entries();
393 index_set ext_dis_ie_set;
394 for (auto i: ext_gev) { ext_dis_ie_set.insert (i.first); }
395 base::_geo_element [variant].set_dis_indexes (ext_dis_ie_set);
396 }
397 // 3a) list external vertex indexes from external elements
398 std::array<index_set,reference_element::max_variant> ext_dis_igev_set;
399 for (size_type dim = base::_gs._map_dimension; dim >= 1; dim--) {
401 variant < reference_element:: last_variant_by_dimension (dim); ++variant) {
402 for (auto x : base::_geo_element[variant].get_dis_map_entries()) {
403 const geo_element& K = x.second;
404 for (size_type subgeo_dim = 0; subgeo_dim < K.dimension(); ++subgeo_dim) {
405 for (size_type loc_is = 0, loc_ns = K.n_subgeo(subgeo_dim); loc_is < loc_ns; ++loc_is) {
406 size_type dis_ige = (subgeo_dim == 0) ? base::dis_inod2dis_iv(K[loc_is]) : (subgeo_dim == 1) ? K.edge(loc_is) : K.face(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;
409 // this subgeo is external: add it to ext_dis_igev_set[variant] :
410 size_type dis_size = base::sizes().ownership_by_dimension [subgeo_dim].dis_size();
411 check_macro(dis_ige < dis_size, "invalid external "<<subgeo_dim<<"d subgeo dis_index = "<<dis_ige<<" out of range [0:"<<dis_size<<"[");
412 // convert dis_ige to dis_igev and get its variant
413 size_type variant;
414 size_type dis_igev = base::sizes().dis_ige2dis_igev_by_dimension (subgeo_dim, dis_ige, variant);
415 ext_dis_igev_set [variant].insert (dis_igev);
416 }
417 }
418 }
419 }
420 }
421 // 3b) append external subgeo entities from all external elements
423 variant < reference_element:: last_variant_by_dimension (base::_gs._map_dimension); ++variant) {
424 base::_geo_element [variant].append_dis_indexes (ext_dis_igev_set [variant]);
425 }
426 // 4a) list external nodes from all external entities, based on dis_idof(), for high order meshes
427 for (size_type dim = base::_gs._map_dimension; dim >= 1; dim--) {
429 variant < reference_element:: last_variant_by_dimension (dim); ++variant) {
430 for (auto x : base::_geo_element[variant].get_dis_map_entries()) {
431 const geo_element& K = x.second;
432 space_numbering::dis_idof (base::_piola_basis, base::_gs, K, dis_inod1);
433 for (size_type loc_inod = 0, loc_nnod = dis_inod1.size(); loc_inod < loc_nnod; loc_inod++) {
434 size_type dis_inod = dis_inod1 [loc_inod];
435 assert_macro (dis_inod < dis_nnod, "node index "<< dis_inod <<" out of range [0:"<<dis_nnod<<"[");
436 if (node_ownership.is_owned (dis_inod)) continue;
437 ext_node_set.insert (dis_inod);
438 }
439 }
440 }
441 }
442 // 4b) pull external nodes:
443 base::_node.set_dis_indexes (ext_node_set);
444}
449template <class T>
450void
452{
453 distributor vertex_ownership = base::_gs.ownership_by_dimension [0];
454 distributor node_ownership = base::_node.ownership();
455 size_type nv = vertex_ownership.size();
456 size_type first_dis_iv = vertex_ownership.first_index();
457 size_type last_dis_iv = vertex_ownership. last_index();
458 size_type dis_nnod = node_ownership.dis_size(); // for bound checks
459 // ------------------------------------------------------------------------
460 // 0) build external vertices index set
461 // ------------------------------------------------------------------------
462 index_set ext_iv_set; // size=O((N/nproc)^((d-1)/d))
463 for (size_type dim = side_dim; dim <= base::_gs._map_dimension; dim++) {
466 for (size_type igev = 0, ngev = base::_geo_element[var].size(); igev < ngev; igev++) {
467 const geo_element& K = base::_geo_element [var] [igev];
468 for (size_type iloc = 0, nloc = K.size(); iloc < nloc; iloc++) {
469 size_type dis_inod = K[iloc];
470 if (! node_ownership.is_owned(dis_inod)) { // vertex ownership follows node ownership
471 size_type dis_iv = base::dis_inod2dis_iv (dis_inod);
472 ext_iv_set.insert (dis_iv);
473 }
474 }
475 }
476 }
477 }
478 // ------------------------------------------------------------------------
479 // 1) ball(X) := { E; X is a vertex of E }
480 // ------------------------------------------------------------------------
481 index_set empty_set; // TODO: add a global allocator to empty_set
484 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
485 ball [variant].resize (vertex_ownership, empty_set);
486 distributor gev_ownership = base::_gs.ownership_by_variant [variant];
487 size_type first_dis_igev = gev_ownership.first_index();
488 for (size_type igev = 0, ngev = base::_geo_element [variant].size(); igev < ngev; igev++) {
489 const geo_element& S = base::_geo_element [variant] [igev];
490 size_type dis_igev = first_dis_igev + igev;
491 for (size_type iloc = 0, nloc = S.size(); iloc < nloc; iloc++) {
492 size_type dis_inod = S[iloc];
493 assert_macro (dis_inod < dis_nnod, "S={"<<S<<"}: "<<iloc<<"-node index " << dis_inod << " out of range [0:"<<dis_nnod<<"[");
494 size_type dis_iv = base::dis_inod2dis_iv (dis_inod);
495 if (vertex_ownership.is_owned(dis_iv)) {
496 size_type iv = dis_iv - first_dis_iv;
497 ball [variant][iv] += dis_igev;
498 } else {
499 index_set dis_igev_set;
500 dis_igev_set += dis_igev;
501 ball [variant].dis_entry (dis_iv) += dis_igev_set; // not so efficient: union with {dis_iegv}
502 }
503 }
504 }
505 ball [variant].dis_entry_assembly();
506 // ------------------------------------------------------------------------
507 // for all the dis_iv that are not handled by the current process
508 // but are referenced by at least a side, get ext_ball[dis_iv]
509 // ------------------------------------------------------------------------
510 // Question: faudra-t'il inclure d'autres sommets dans ext_iv_set ?
511 // -> ceux issus des triangles, tetra, ect, et externes a la partition ?
512 // Question : est-ce que ca en ajouterait ? reponse : OUI (teste')
513 // mais c'est pas utile pour l'instant : ball sert juste aux aretes
514 ball [variant].set_dis_indexes (ext_iv_set);
515 }
516 // ------------------------------------------------------------------------
517 // 2) on parcourt chaque dis_E de ball(iv) et ext_ball(dis_iv) :
518 // si dis_E n'est pas local, on le met dans une liste ext_isid_set
519 // et on importe l'arete en tant que geo_element
520 // ------------------------------------------------------------------------
521 // scan ball(iv) for external sides
523 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
524
525 // 2.1) scan ball(iv) for external sides
526 std::set<size_type> ext_igev_set; // size=O((N/nproc)^((d-1)/d))
527 distributor gev_ownership = base::_gs.ownership_by_variant [variant];
528 size_type dis_ngev = gev_ownership.dis_size();
529 for (size_type iv = 0, nv = vertex_ownership.size(); iv < nv; iv++) {
530
531 const index_set& ball_iv = ball [variant] [iv];
532 for (index_set::const_iterator iter = ball_iv.begin(), last = ball_iv.end(); iter != last; iter++) {
533 size_type dis_igev = *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);
537 }
538 }
539 }
540 // 2.2) scan ball(dis_iv) for external sides
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++) {
544 size_type dis_iv = (*iter_b).first;
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++) {
547 size_type dis_igev = *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);
551 }
552 }
553 }
554 // 2.3) import external sides
555 base::_geo_element[variant].append_dis_indexes (ext_igev_set);
556 }
557 // ------------------------------------------------------------------------
558 // 3) pour K dans partition(iproc)
559 // pour (dis_A,dis_B) arete de K
560 // set = dis_ball(dis_A) inter dis_ball(dis_B) = {dis_iedg}
561 // E = dis_edges(dis_iedg)
562 // => on numerote dis_iedg cette arete dans le geo_element K
563 // et on indique son orient en comparant a E, arete qui definit l'orient
564 // ------------------------------------------------------------------------
565 for (size_type dim = side_dim+1; dim <= base::_gs._map_dimension; dim++) {
568 for (size_type igev = 0, ngev = base::_geo_element [var].size(); igev < ngev; igev++) {
569 geo_element& K = base::_geo_element [var] [igev];
570 size_type S_iv [4];
571 size_type S_inod[4];
572 for (size_type loc_isid = 0, loc_nsid = K.n_subgeo(side_dim); loc_isid < loc_nsid; loc_isid++) {
573 size_type S_size = K.subgeo_size (side_dim, loc_isid);
574 size_type S_variant = reference_element::variant (S_size, side_dim);
575 size_type loc_jv0 = K.subgeo_local_vertex (side_dim, loc_isid, 0);
576 S_inod [0] = K[loc_jv0];
577 S_iv [0] = base::dis_inod2dis_iv (S_inod[0]);
578 const disarray<index_set,distributed>& ball_S_variant = ball [S_variant];
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++) {
581 size_type loc_jv = K.subgeo_local_vertex (side_dim, loc_isid, sid_jloc);
582 S_inod [sid_jloc] = K[loc_jv];
583 S_iv [sid_jloc] = base::dis_inod2dis_iv (S_inod[sid_jloc]);
584 const index_set& ball_jv = ball_S_variant.dis_at (S_iv[sid_jloc]);
585 igev_set.inplace_intersection (ball_jv);
586 }
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());
591 const geo_element& S = base::_geo_element[S_variant].dis_at(dis_igev);
592 size_type dis_isid = S.dis_ie();
593 if (side_dim == 1) {
594 // side: edge
595 geo_element::orientation_type orient = S.get_edge_orientation (S_inod[0], S_inod[1]);
596 K.edge_indirect (loc_isid).set (orient, dis_isid);
597 } else { // side_dim == 2
600 if (K.subgeo_size (side_dim, loc_isid) == 3) {
601 // side: triangle
602 S.get_orientation_and_shift (S_inod[0], S_inod[1], S_inod[2], orient, shift);
603 } else {
604 // side: quadrangle
605 S.get_orientation_and_shift (S_inod[0], S_inod[1], S_inod[2], S_inod[3], orient, shift);
606 }
607 K.face_indirect (loc_isid).set (orient, dis_isid, shift);
608 }
609 }
610 }
611 }
612 }
613}
614// --------------------------------------------------------------------------
615// set permutation for nodes: ios_inod2dis_inod & inod2ios_dis_inod
616// and redistribute ios_node[] into _node[]
617// --------------------------------------------------------------------------
618template <class T>
619void
621{
622 space_numbering::generic_set_ios_permutation (base::get_piola_basis(), map_dimension(), base::sizes(), _igev2ios_dis_igev, idof2ios_dis_idof);
623}
624template <class T>
625void
627{
628 std::array<size_type,reference_element::max_variant> loc_ndof_by_variant;
629 reference_element::init_local_nnode_by_variant (base::order(), loc_ndof_by_variant);
630 set_ios_permutation (_inod2ios_dis_inod);
631}
632// --------------------------------------------------------------------------
633// get geo
634// --------------------------------------------------------------------------
635template <class T>
638{
639 using namespace std;
640 check_macro (ips.good(), "bad input stream for geo.");
641 communicator comm = base::_geo_element[reference_element::p].ownership().comm();
642
644 size_type my_proc = comm.rank();
645 // ------------------------------------------------------------------------
646 // 1) read file
647 // ------------------------------------------------------------------------
648 //
649 // 1.1) get header
650 //
651 check_macro (dis_scatch(ips, ips.comm(), "\nmesh"), "input stream does not contains a geo.");
652 ips >> base::_version;
653 check_macro (base::_version == 4, "geo version < 4 not supported (HINT: see geo -upgrade)");
654
655 geo_header hdr;
656 ips >> hdr;
657 check_macro (! hdr.need_upgrade(),
658 "unsupported geo without connectivity in the distributed version: HINT: use geo_upgrade");
659 base::_have_connectivity = true;
660 base::_dimension = hdr.dimension;
661 base::_gs._map_dimension = hdr.map_dimension;
662 base::_sys_coord = hdr.sys_coord;
663 base::_name = "unnamed";
664 base::_piola_basis.reset_family_index (hdr.order);
665 size_type dis_nnod = hdr.dis_size_by_dimension [0];
666 size_type dis_nedg = hdr.dis_size_by_dimension [1];
667 size_type dis_nfac = hdr.dis_size_by_dimension [2];
668 size_type dis_ne = hdr.dis_size_by_dimension [base::_gs._map_dimension];
669 //
670 // 1.2) get node coordinates
671 //
672 size_type ios_size_by_variant [reference_element::max_variant];
673 std::fill (ios_size_by_variant, ios_size_by_variant+reference_element::max_variant, 0);
674 disarray<node_type> ios_node (dis_nnod);
675 ios_node.get_values (ips, _point_get<T>(base::_dimension));
676 check_macro (ips.good(), "bad input stream for geo.");
677 //
678 // 1.3) get elements
679 //
680 std::array<hack_array<geo_element_hack>, reference_element::max_variant> ios_geo_element;
681 size_type ios_nv = 0;
682 if (base::_gs._map_dimension == 0) {
683 ios_nv = ios_node.size();
684 } else {
685 // set elt ios index and compute map_dim & ios_nv (ios_nv < ios_nnod when order > 1)
686 size_type ios_ne = 0;
687 size_type dis_ne = 0;
688 for (size_type variant = reference_element::first_variant_by_dimension(base::_gs._map_dimension);
689 variant < reference_element:: last_variant_by_dimension(base::_gs._map_dimension); variant++) {
690 geo_element::parameter_type param (variant, 1);
691 ios_geo_element [variant].resize (hdr.dis_size_by_variant [variant], param);
692 ios_geo_element [variant].get_values (ips);
693 _ios_gs.first_by_variant [variant] = distributor (distributor::decide, base::comm(), ios_ne);
694 ios_ne += ios_geo_element [variant].size();
695 dis_ne += ios_geo_element [variant].dis_size();
696 }
697 build_apparent_ios_ownership(
698 ios_geo_element,
699 base::_gs._map_dimension,
700 _ios_gs.ownership_by_dimension [base::_gs._map_dimension],
701 _ios_gs.ownership_by_variant);
702
703 vector<size_type> local_is_vertex (dis_nnod, 0);
704 for (size_type variant = reference_element::first_variant_by_dimension(base::_gs._map_dimension);
705 variant < reference_element:: last_variant_by_dimension(base::_gs._map_dimension); variant++) {
706 size_type first_ios_dis_v = _ios_gs.first_by_variant [variant].dis_size();
707 size_type first_ios_dis_igev = ios_geo_element [variant].ownership().first_index();
708 size_type ios_igev = 0;
709 for (iterator_by_variant iter = ios_geo_element [variant].begin(), last = ios_geo_element [variant].end();
710 iter != last; iter++, ios_igev++) {
711 geo_element& K = *iter;
712 size_type ios_dis_ie = first_ios_dis_v + first_ios_dis_igev + ios_igev;
713 K.set_ios_dis_ie (ios_dis_ie); // OK
714 ios_size_by_variant [K.variant()]++;
715 if (base::order() > 1) {
716 for (size_type iloc = 0, nloc = K.size(); iloc < nloc; iloc++) {
717 local_is_vertex [K[iloc]] = 1;
718 }
719 }
720 }
721 }
722 if (base::order() == 1) {
723 ios_nv = ios_node.size();
724 } else {
725 vector<size_type> global_is_vertex (dis_nnod, 0);
726 mpi::all_reduce (
727 comm,
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);
734 }
735 }
736 distributor ios_vertex_ownership;
737 if (base::order() == 1) {
738 ios_vertex_ownership = ios_node.ownership();
739 } else {
740 ios_vertex_ownership = distributor (distributor::decide, base::comm(), ios_nv); // not sure...
741 }
742 size_type dis_nv = ios_vertex_ownership.dis_size();
743 //
744 // 1.4) create 0d vertex-elements
745 //
746 // set ios_dis_iv index as fisrt field of the idx_vertex pair:
747 // # of node that are vertices:
748 {
750 ios_geo_element [reference_element::p].resize (ios_vertex_ownership, param);
751 _ios_gs.ownership_by_variant [reference_element::p] = ios_vertex_ownership;
752 _ios_gs.ownership_by_dimension [0] = ios_vertex_ownership;
753 size_type first_ios_dis_iv = ios_vertex_ownership.first_index();
754 for (size_type ios_iv = 0, ios_nv = ios_vertex_ownership.size(); ios_iv < ios_nv; ios_iv++) {
755 geo_element& P = ios_geo_element [reference_element::p] [ios_iv];
756 size_type ios_dis_iv = first_ios_dis_iv + ios_iv;
757 P [0] = ios_dis_iv;
758 P.set_ios_dis_ie (ios_dis_iv);
759 ios_size_by_variant [P.variant()]++;
760 }
761 }
762 //
763 // 1.5) get faces & edges
764 //
765 if (base::_gs._map_dimension > 0) {
766 for (size_type side_dim = base::_gs._map_dimension - 1; side_dim >= 1; side_dim--) {
767 size_type ios_ngev = 0;
768 size_type dis_ngev = 0;
770 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
771 geo_element::parameter_type param (variant, 1);
772 ios_geo_element [variant].resize (hdr.dis_size_by_variant [variant], param);
773 ios_geo_element [variant].get_values (ips);
774 _ios_gs.first_by_variant [variant] = distributor (distributor::decide, base::comm(), ios_ngev);
775 ios_ngev += ios_geo_element [variant].size();
776 dis_ngev += ios_geo_element [variant].dis_size();
777 }
778 build_apparent_ios_ownership(
779 ios_geo_element,
780 side_dim,
781 _ios_gs.ownership_by_dimension [side_dim],
782 _ios_gs.ownership_by_variant);
783
785 variant < reference_element:: last_variant_by_dimension(side_dim); variant++) {
786 size_type ios_igev = 0;
787 size_type first_dis_v = _ios_gs.first_by_variant [variant].dis_size();
788 size_type first_ios_dis_igev = ios_geo_element [variant].ownership().first_index();
789 for (iterator_by_variant iter = ios_geo_element [variant].begin(), last = ios_geo_element [variant].end();
790 iter != last; iter++, ios_igev++) {
791 geo_element& S = *iter;
792 size_type ios_dis_igev = first_dis_v + first_ios_dis_igev + ios_igev;
793 S.set_ios_dis_ie (ios_dis_igev); // OK
794 ios_size_by_variant [S.variant()]++;
795 }
796 }
797 }
798 }
799 // ------------------------------------------------------------------------
800 // 2) mesh partition & element renumbering
801 // ------------------------------------------------------------------------
802 distributor true_ios_ownership_by_dimension [4];
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);
805
807 ios_geo_element,
808 true_ios_ownership_by_dimension [base::_gs._map_dimension],
809 base::_gs._map_dimension,
810 dis_nv);
811
812 // copy partition into partition_by_variant[]:
813 std::array<disarray<size_t>, reference_element::max_variant> partition_by_variant;
814 {
815 typename disarray<size_type>::const_iterator iter = partition.begin();
816 for (size_type variant = reference_element::first_variant_by_dimension(base::_gs._map_dimension);
817 variant < reference_element:: last_variant_by_dimension(base::_gs._map_dimension); variant++) {
818 partition_by_variant [variant].resize (ios_geo_element [variant].ownership());
819 for (typename disarray<size_type>::iterator iter_by_var = partition_by_variant [variant].begin(),
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;
823 }
824 }
825 }
827 ios_geo_element,
828 _ios_gs,
829 dis_nv,
830 base::_gs._map_dimension,
831 base::_geo_element,
832 base::_gs,
833 _igev2ios_dis_igev,
834 _ios_igev2dis_igev,
835 _ios_ige2dis_ige,
836 partition_by_variant);
837
838
839 // copy partition into massive_partition_by_dimension[map_dim]:
840 std::array<std::vector<size_t>, 4> massive_partition_by_dimension;
841 {
842 std::vector<size_t> tmp_massive_partition (dis_ne, 0);
843 size_type true_first_dis_ige = true_ios_ownership_by_dimension [base::_gs._map_dimension].first_index();
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];
847 }
848 massive_partition_by_dimension [base::_gs._map_dimension].resize (dis_ne);
849 mpi::all_reduce (
850 comm,
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>());
855 }
856 // propagate partition to subgeo : faces, edges & vertices
857 for (size_type supergeo_dim = base::_gs.map_dimension(); supergeo_dim > 0; supergeo_dim--) {
859 ios_geo_element,
860 _ios_gs,
861 supergeo_dim-1,
862 massive_partition_by_dimension,
863 partition_by_variant);
864 }
865 // ------------------------------------------------------------------------
866 // 3) vertices renumbering
867 // ------------------------------------------------------------------------
868 //
869 // 3.1) redistribute the _geo_element[p] vertices
870 //
871 partition_by_variant [reference_element::p].resize (ios_vertex_ownership);
872 size_type first_ios_dis_iv = ios_vertex_ownership.first_index();
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];
876 }
877 disarray<size_type> iv2ios_dis_iv;
878 ios_geo_element [reference_element::p].repartition (
879 partition_by_variant [reference_element::p],
880 base::_geo_element [reference_element::p],
881 iv2ios_dis_iv,
882 _ios_ige2dis_ige[0]);
883
884 distributor vertex_ownership = base::_geo_element[reference_element::p].ownership();
885 base::_gs.ownership_by_dimension [0] = vertex_ownership;
886 base::_gs.ownership_by_variant [reference_element::p] = vertex_ownership;
887 base::_gs.first_by_variant [reference_element::p] = distributor (0, base::comm(), 0);
888 //
889 // 3.2) set the element[0] disarray
890 //
891 size_type first_dis_iv = vertex_ownership.first_index();
892 size_type last_dis_iv = vertex_ownership.last_index();
893 _igev2ios_dis_igev [reference_element::p].resize (vertex_ownership);
894 for (size_type iv = 0, nv = base::_geo_element[reference_element::p].size(); iv < nv; iv++) {
895 geo_element& P = base::_geo_element[reference_element::p] [iv];
896 size_type dis_iv = first_dis_iv + iv;
897 P[0] = dis_iv;
898 P.set_dis_ie (dis_iv);
899 _igev2ios_dis_igev [reference_element::p] [iv] = P.ios_dis_ie();
900 }
901 // ------------------------------------------------------------------------
902 // 4) edge & face renumbering
903 // ------------------------------------------------------------------------
904 if (base::_gs._map_dimension > 0) {
905 for (size_type side_dim = base::_gs._map_dimension-1; side_dim > 0; side_dim--) {
906
908 ios_geo_element,
909 _ios_gs,
910 dis_nv,
911 side_dim,
912 base::_geo_element,
913 base::_gs,
914 _igev2ios_dis_igev,
915 _ios_igev2dis_igev,
916 _ios_ige2dis_ige,
917 partition_by_variant);
918 }
919 }
920 // ------------------------------------------------------------------------
921 // 5) get domain, until end-of-file (requires ios_ige2dis_ige renumbering)
922 // ------------------------------------------------------------------------
923 do {
925 bool status = dom.get (ips, *this);
926 if (!status) break;
927 base::_domains.push_back (dom);
928 } while (true);
929 // ------------------------------------------------------------------------
930 // 6) renumbering ios_nodes[]: set permutations inod2ios_dis_inod[]
931 // ------------------------------------------------------------------------
932 node_renumbering (ios_node.ownership());
933 distributor node_ownership = _inod2ios_dis_inod.ownership();
934 base::_gs.node_ownership = node_ownership;
935 // ------------------------------------------------------------------------
936 // 7) redistribute the nodes : from ios_node[] to node() disarrays
937 // ------------------------------------------------------------------------
938 _ios_inod2dis_inod.resize (ios_node.ownership(), std::numeric_limits<size_type>::max());
939 _inod2ios_dis_inod.reverse_permutation (_ios_inod2dis_inod);
940
941 // ------------------------------------------------------------------------
942 // 8) propagate new node numbering
943 // ------------------------------------------------------------------------
944 // 8.1) build new node disarray: base::_node
945 base::_node.resize (node_ownership);
946 ios_node.permutation_apply (_ios_inod2dis_inod, base::_node);
947 //
948 // 8.2) global table of node renumbering
949 //
950 vector<size_type> new_local_node_num (dis_nnod, 0);
951 size_type first_ios_inod = _ios_inod2dis_inod.ownership().first_index();
952 size_type last_ios_inod = _ios_inod2dis_inod.ownership(). last_index();
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;
955 new_local_node_num [dis_ios_inod] = _ios_inod2dis_inod[ios_inod];
956 }
957 vector<size_type> new_global_node_num (dis_nnod, 0);
958 mpi::all_reduce (
959 comm,
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>());
964 //
965 // 8.3) propagate the new node numbering into geo_elements:
966 // vertices K[iloc] of new numbered element table K still have ios numbering: fix it
967 //
968 for (size_type dim = base::_gs._map_dimension; dim > 0; dim--) {
970 variant < reference_element:: last_variant_by_dimension(dim); variant++) {
972 new_global_node_num,
973 dis_nnod,
974 base::_geo_element [variant]);
975 }
976 }
977 // ------------------------------------------------------------------------
978 // 9) set indexes on faces and edges of elements, for P2 approx
979 // ------------------------------------------------------------------------
980 for (size_type dim = base::_gs._map_dimension - 1; base::_gs._map_dimension > 0 && dim > 0; dim--) {
981 set_element_side_index (dim);
982 }
983 // ------------------------------------------------------------------------
984 // 10) set external entities, at partition boundaries
985 // ------------------------------------------------------------------------
986 build_external_entities ();
987 // ------------------------------------------------------------------------
988 // 11) bounding box: _xmin, _xmax
989 // ------------------------------------------------------------------------
990 base::compute_bbox();
991 return ips;
992}
993// ----------------------------------------------------------------------------
994// read from file
995// ----------------------------------------------------------------------------
996template <class T>
997void
999 std::string filename,
1000 const communicator& comm)
1001{
1002 idiststream ips;
1003 ips.open (filename, "geo", comm);
1004 check_macro(ips.good(), "\"" << filename << "[.geo[.gz]]\" not found.");
1005 get (ips);
1006 std::string root_name = delete_suffix (delete_suffix(filename, "gz"), "geo");
1007 std::string name = get_basename (root_name);
1008 base::_name = name;
1009}
1010// ----------------------------------------------------------------------------
1011// instanciation in library
1012// ----------------------------------------------------------------------------
1013template class geo_rep<Float,distributed>;
1014
1015} // namespace rheolef
1016#endif // _RHEOLEF_HAVE_MPI
field::size_type size_type
Definition branch.cc:430
see the communicator page for the full documentation
see the disarray page for the full documentation
Definition disarray.h:497
rep::base::const_iterator const_iterator
Definition disarray.h:503
rep::base::iterator iterator
Definition disarray.h:502
see the distributor page for the full documentation
Definition distributor.h:69
size_type last_index(size_type iproc) const
void resize(size_type dis_size=0, const communicator_type &c=communicator_type(), size_type loc_size=decide)
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
Definition distributor.h:83
const communicator_type & comm() const
the finite element boundary domain
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 n_node() const
size_type subgeo_local_vertex(size_type subgeo_dim, size_type i_subgeo, size_type i_subgeo_vertex) const
size_type size() 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
size_type dis_ie() const
const geo_element_indirect & face_indirect(size_type i) const
void set_dis_ie(size_type dis_ie)
base::iterator_by_variant iterator_by_variant
Definition geo.h:942
base::size_type size_type
Definition geo.h:934
sequential mesh representation
Definition geo.h:778
std::vector< T, A >::iterator iterator
Definition hack_array.h:350
std::vector< T, A >::const_iterator const_iterator
Definition hack_array.h:351
idiststream: see the diststream page for the full documentation
Definition diststream.h:336
static size_type io_proc()
This routine returns the rank of a process that can perform i/o.
Definition diststream.cc:64
void open(std::string filename, std::string suffix="", const communicator &comm=communicator())
This routine opens a physical input file.
Definition diststream.cc:85
const communicator & comm() const
Definition diststream.h:356
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)
Definition dis_macros.h:113
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)
Definition diststream.cc:44
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)
STL namespace.
point input helper
Definition geo.h:155
bool need_upgrade() const
Definition geo_header.cc:79
size_type map_dimension
Definition geo_header.h:40
size_type dis_size_by_dimension[4]
Definition geo_header.h:44
coordinate_type sys_coord
Definition geo_header.h:41
size_type dimension
Definition geo_header.h:39
size_type dis_size_by_variant[reference_element::max_variant]
Definition geo_header.h:43
distributor ownership_by_variant[reference_element::max_variant]
Definition geo_size.h:64
distributor ownership_by_dimension[4]
Definition geo_size.h:63
distributor first_by_variant[reference_element::max_variant]
Definition geo_size.h:66