Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MeshExchange.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MeshExchange.cc (C) 2000-2024 */
9/* */
10/* Echange un maillage entre entre sous-domaines. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iterator.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/Collection.h"
18
19#include "arcane/IMesh.h"
20#include "arcane/ISubDomain.h"
21#include "arcane/IParallelMng.h"
22#include "arcane/IParallelExchanger.h"
23#include "arcane/IItemFamily.h"
24#include "arcane/ItemEnumerator.h"
25#include "arcane/Item.h"
26#include "arcane/MeshVariable.h"
27#include "arcane/IParticleFamily.h"
28#include "arcane/ParallelMngUtils.h"
29
30#include "arcane/ConnectivityItemVector.h"
31#include "arcane/IndexedItemConnectivityView.h"
32#include "arcane/mesh/IndexedItemConnectivityAccessor.h"
33#include "arcane/mesh/MeshExchange.h"
34#include "arcane/mesh/NewItemOwnerBuilder.h"
35
36#include "arcane/ItemPrinter.h"
37#include "arcane/IParallelMng.h"
38
39#include "arcane/VariableTypes.h"
40
41#include "arcane/IItemFamilyNetwork.h"
42#include "arcane/IGhostLayerMng.h"
43#include "arcane/ConnectivityItemVector.h"
44
45#include "arcane/IVariableSynchronizer.h"
46
47#include <algorithm>
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
51
52namespace Arcane::mesh
53{
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57template<typename T>
59{
60 public:
61
63 : m_current_increment(-1), m_current_size(0), m_index(size, -1),
64 m_size(size, 0)
65 {
66 }
67
69 : m_current_increment(-1), m_current_size(0) {}
70
71 inline void resize(Integer size)
72 {
73 m_index.resize(size, -1);
74 m_size.resize(size, 0);
75 }
76
77 inline Integer size() const
78 {
79 return m_index.size();
80 }
81
82 inline void dataReserve(Integer size)
83 {
84 m_data.reserve(size);
85 }
86
87 inline void addData(const T data)
88 {
89 m_data.add(data);
90 m_current_size++;
91 }
92
93 inline Int32 index(Integer id) const
94 {
95 return m_index[id];
96 }
97
98 inline void beginIncrement(Integer id)
99 {
100 ARCANE_ASSERT((m_current_increment == -1),("call endIncrement before begin"));
101 m_current_increment = id;
102 m_current_size = 0;
103 m_index[m_current_increment] = m_data.size();
104 }
105
106 inline void endIncrement()
107 {
108 m_size[m_current_increment] = m_current_size;
109 m_current_increment = -1;
110 m_current_size = 0;
111 }
112
113 inline ArrayView<T> at(Integer id)
114 {
115 return m_data.subView(m_index[id],m_size[id]);
116 }
117
118 inline ConstArrayView<T> at(Integer id) const
119 {
120 return m_data.subView(m_index[id],m_size[id]);
121 }
122
123 private:
124 Integer m_current_increment;
125 Integer m_current_size;
126 Int32UniqueArray m_index;
127 Int32UniqueArray m_size;
128 UniqueArray<T> m_data;
129};
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
134template<typename T>
136{
137public:
138
139 DynamicMultiArray(Integer size)
140 : m_data(size) {}
141
143
144 inline void resize(Integer size) {
145 m_data.resize(size);
146 }
147
148 inline Integer size() const {
149 return m_data.size();
150 }
151
152 inline void addData(Integer id, const T data) {
153 m_data[id].add(data);
154 }
155
156 inline UniqueArray<T>& at(Integer id) {
157 return m_data[id];
158 }
159
160 inline ConstArrayView<T> at(Integer id) const {
161 return m_data[id];
162 }
163
164
165private:
166
168};
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173MeshExchange::
174MeshExchange(IMesh* mesh)
175: TraceAccessor(mesh->traceMng())
176, m_mesh(mesh)
177, m_parallel_mng(mesh->parallelMng())
178, m_nb_rank(m_parallel_mng->commSize())
179, m_rank(m_parallel_mng->commRank())
180, m_cell_family(mesh->itemFamily(IK_Cell))
181, m_neighbour_cells_owner(NULL)
182, m_neighbour_cells_new_owner(NULL)
183, m_neighbour_extra_cells_owner(NULL)
184, m_neighbour_extra_cells_new_owner(NULL)
185{
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191MeshExchange::
192~MeshExchange()
193{
194 for( const auto& itosend : m_items_to_send )
196 delete m_neighbour_cells_owner;
197 delete m_neighbour_cells_new_owner;
198 delete m_neighbour_extra_cells_owner;
199 delete m_neighbour_extra_cells_new_owner;
200 for( const auto& idestrank : m_item_dest_ranks_map)
202 for (const auto& ighostdestrank_map : m_ghost_item_dest_ranks_map)
205}
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
212getItemsToSend(IItemFamily* family) const
213{
214 auto iter = m_items_to_send.find(family);
215 if (iter==m_items_to_send.end())
216 ARCANE_FATAL("No items to send for family '{0}'",family->name());
217 return iter->second->constView();
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
226{
227 auto iter = m_items_to_send.find(family);
228 if (iter==m_items_to_send.end())
229 ARCANE_FATAL("No items to send for family '{0}'",family->name());
230 return iter->second->view();
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
238{
239 // Créé les tableaux contenant pour chaque famille la liste des entités
240 // à envoyer.
241 for( IItemFamily* family : m_mesh->itemFamilies()){
242 m_items_to_send.insert(std::make_pair(family,new UniqueArray< std::set<Int32> >));
243 }
244
245 Int32ConstArrayView cells_new_owner(m_cell_family->itemsNewOwner().asArray());
247 if(m_mesh->isAmrActivated()){
249 _computeGraphConnectivityInfos();
250 _exchangeCellDataInfos(cells_new_owner,true);
251 _markRemovableCells(cells_new_owner,true);
252 _markRemovableParticles();
253 _computeItemsToSend2();
254 }
255 else if (m_mesh->itemFamilyNetwork() && m_mesh->itemFamilyNetwork()->isActivated())
256 {
258 {
260 _computeGraphConnectivityInfos();
261 _exchangeCellDataInfos3(); // todo renommer itemDataInfo
262 _exchangeGhostItemDataInfos();
263 _markRemovableItems();
264 _markRemovableParticles();
265 _computeItemsToSend3();
266 }
267 else
268 {
269 //Manage Mesh item_families in standard way
270 _computeMeshConnectivityInfos(cells_new_owner);
272 _computeGraphConnectivityInfos();
273 _exchangeCellDataInfos(cells_new_owner,false);
274 _exchangeCellDataInfos3();
275 //_exchangeGhostItemDataInfos();
276 //_markRemovableItems();
277 _markRemovableDoFs();
278 _markRemovableCells(cells_new_owner,false);
279 _markRemovableParticles();
280 _computeItemsToSend(true);
281 }
282 }
283 else
284 {
285 _computeMeshConnectivityInfos(cells_new_owner);
286 _computeGraphConnectivityInfos();
287 _exchangeCellDataInfos(cells_new_owner,false);
288 _markRemovableCells(cells_new_owner,false);
289 _markRemovableParticles();
290 _computeItemsToSend();
291 }
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297void MeshExchange::
298_computeGraphConnectivityInfos()
299{
300 const Integer cell_variable_size = m_cell_family->maxLocalId();
301
303 tmp_new_owner.fill(NULL_ITEM_ID);
304 Int32UniqueArray tmp_owner(m_nb_rank);
305 tmp_owner.fill(NULL_ITEM_ID);
306
308 tmp_link_new_owner.fill(NULL_ITEM_ID);
310 tmp_link_owner.fill(NULL_ITEM_ID);
311
312 mesh::NewItemOwnerBuilder owner_builder;
313
314 m_neighbour_extra_cells_owner = new DynamicMultiArray<Int32>(cell_variable_size);
315 m_neighbour_extra_cells_new_owner = new DynamicMultiArray<Int32>(cell_variable_size);
316
317 if (m_mesh->itemFamilyNetwork() && m_mesh->itemFamilyNetwork()->isActivated())
318 {
319 _addGraphConnectivityToNewConnectivityInfo();
320 }
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326void MeshExchange::
327_addGraphConnectivityToNewConnectivityInfo()
328{
329 ENUMERATE_CELL(icell, m_cell_family->allItems()) {
330 Int32Array& extra_new_owners = m_neighbour_extra_cells_new_owner->at(icell.localId());
331 Int32Array& extra_owners = m_neighbour_extra_cells_owner->at(icell.localId());
332 ItemDestRankArray* item_dest_ranks = nullptr;
333 if (icell->isOwn())
334 item_dest_ranks = m_item_dest_ranks_map[m_cell_family];
335 else
336 item_dest_ranks= m_ghost_item_dest_ranks_map[icell->owner()][m_cell_family];
337 item_dest_ranks->at(icell.localId()).addRange(extra_new_owners);
338 item_dest_ranks->at(icell.localId()).addRange(extra_owners);
339 }
340 // This exchange modify dest ranks of cells => need to update their dependencies (costly ??)
341 _propagatesToChildDependencies(m_cell_family);
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347void MeshExchange::
348_computeMeshConnectivityInfos(Int32ConstArrayView cells_new_owner)
349{
350 Integer cell_variable_size = m_cell_family->maxLocalId();
351
352 m_neighbour_cells_owner = new IncrementalUnorderedMultiArray<Int32>(cell_variable_size);
353 m_neighbour_cells_new_owner = new IncrementalUnorderedMultiArray<Int32>(cell_variable_size);
354
355 Int32UniqueArray tmp_new_owner(m_nb_rank);
356 tmp_new_owner.fill(NULL_ITEM_ID);
357 Int32UniqueArray tmp_owner(m_nb_rank);
358 tmp_owner.fill(NULL_ITEM_ID);
359
360 ENUMERATE_CELL(icell,m_cell_family->allItems().own()){
361 Cell cell = *icell;
362 Integer cell_local_id = cell.localId();
363 // On ne se rajoute pas à notre liste de maille connectée
364 tmp_owner[m_rank] = cell_local_id;
365
366 m_neighbour_cells_owner->beginIncrement(cell_local_id);
367 m_neighbour_cells_new_owner->beginIncrement(cell_local_id);
368
369 for( NodeEnumerator inode(cell.nodes()); inode.hasNext(); ++inode ){
370 for( CellEnumerator icell2((*inode).cells()); icell2.hasNext(); ++icell2 ){
371 Integer cell2_local_id = icell2.localId();
372 Integer cell2_new_owner = cells_new_owner[cell2_local_id];
373 Integer cell2_owner = icell2->owner();
374 // Regarde si on n'est pas dans la liste et si on n'y est pas,
375 // s'y rajoute
376 if (tmp_new_owner[cell2_new_owner]!=cell_local_id){
377 tmp_new_owner[cell2_new_owner] = cell_local_id;
378 m_neighbour_cells_new_owner->addData(cell2_new_owner);
379 }
380 if (tmp_owner[cell2_owner]!=cell_local_id){
381 tmp_owner[cell2_owner] = cell_local_id;
382 m_neighbour_cells_owner->addData(cell2_owner);
383 }
384 }
385 }
386 m_neighbour_cells_owner->endIncrement();
387 m_neighbour_cells_new_owner->endIncrement();
388 }
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
394void MeshExchange::
395_exchangeCellDataInfos([[maybe_unused]] Int32ConstArrayView cells_new_owner,bool use_active_cells)
396{
397 auto sd_exchange { ParallelMngUtils::createExchangerRef(m_parallel_mng) };
398
399 Int32UniqueArray recv_sub_domains;
400 m_cell_family->getCommunicatingSubDomains(recv_sub_domains);
401 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i )
402 sd_exchange->addSender(recv_sub_domains[i]);
403
404 sd_exchange->initializeCommunicationsMessages(recv_sub_domains);
405
406 UniqueArray<Int64> cells_to_comm_uid;
407 UniqueArray<Int32> cells_to_comm_owner;
408 UniqueArray<Int32> cells_to_comm_owner_size;
409 UniqueArray<Int32> cells_to_comm_new_owner;
410 UniqueArray<Int32> cells_to_comm_new_owner_size;
411
412 ItemGroup own_items = m_cell_family->allItems().own();
413 ItemGroup all_items = m_cell_family->allItems();
414 // Avec l'AMR, on utilise les mailles actives et pas toutes les mailles.
415 if (use_active_cells){
416 own_items = m_cell_family->allItems().ownActiveCellGroup();
417 all_items = m_cell_family->allItems().activeCellGroup();
418 }
419
420 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i ){
421 ISerializeMessage* comm = sd_exchange->messageToSend(i);
422 Int32 dest_sub_domain = comm->destination().value();
423 ISerializer* sbuf = comm->serializer();
424
425 cells_to_comm_uid.clear();
426 cells_to_comm_owner.clear();
427 cells_to_comm_owner_size.clear();
428 cells_to_comm_new_owner.clear();
429 cells_to_comm_new_owner_size.clear();
430
431 ENUMERATE_CELL(icell,own_items){
432 Cell cell = *icell;
433 Integer cell_local_id = cell.localId();
434 Int32ConstArrayView owners = m_neighbour_cells_owner->at(cell_local_id);
435 bool need_send = owners.contains(dest_sub_domain);
436 Int32ConstArrayView extra_owners = m_neighbour_extra_cells_owner->at(cell_local_id);
437 if (!need_send){
438 need_send = extra_owners.contains(dest_sub_domain);
439 }
440 if (!need_send)
441 continue;
442
443 Int32ConstArrayView new_owners = m_neighbour_cells_new_owner->at(cell_local_id);
444 const Integer nb_new_owner = new_owners.size();
445 const Integer nb_owner = owners.size();
446
447 Int32ConstArrayView extra_new_owner = m_neighbour_extra_cells_new_owner->at(cell_local_id);
448 const Integer nb_extra_new_owner = extra_new_owner.size();
449
450 cells_to_comm_uid.add(cell.uniqueId().asInt64());
451 cells_to_comm_owner_size.add(nb_owner);
452 cells_to_comm_new_owner_size.add(nb_new_owner+nb_extra_new_owner);
453 for( Integer zz=0; zz<nb_owner; ++zz )
454 cells_to_comm_owner.add(owners[zz]);
455 for( Integer zz=0; zz<nb_new_owner; ++zz )
456 cells_to_comm_new_owner.add(new_owners[zz]);
457 for( Integer zz=0; zz<nb_extra_new_owner; ++zz )
458 cells_to_comm_new_owner.add(extra_new_owner[zz]);
459 }
460 sbuf->setMode(ISerializer::ModeReserve);
461
462 sbuf->reserve(DT_Int64,1); // Pour le nombre de mailles
463 sbuf->reserveArray(cells_to_comm_uid);
464 sbuf->reserveArray(cells_to_comm_owner_size);
465 sbuf->reserveArray(cells_to_comm_owner);
466 sbuf->reserveArray(cells_to_comm_new_owner_size);
467 sbuf->reserveArray(cells_to_comm_new_owner);
468
469 sbuf->allocateBuffer();
470 sbuf->setMode(ISerializer::ModePut);
471
472 sbuf->putInt64(cells_to_comm_uid.size());
473 sbuf->putArray(cells_to_comm_uid);
474 sbuf->putArray(cells_to_comm_owner_size);
475 sbuf->putArray(cells_to_comm_owner);
476 sbuf->putArray(cells_to_comm_new_owner_size);
477 sbuf->putArray(cells_to_comm_new_owner);
478 }
479
480 sd_exchange->processExchange();
481
482 Int32UniqueArray cells_to_comm_local_id;
483 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i ){
484 ISerializeMessage* comm = sd_exchange->messageToReceive(i);
485 ISerializer* sbuf = comm->serializer();
486 Integer owner_index = 0;
487 Integer new_owner_index = 0;
488 Int64 nb_cell = sbuf->getInt64();
489 sbuf->getArray(cells_to_comm_uid);
490 sbuf->getArray(cells_to_comm_owner_size);
491 sbuf->getArray(cells_to_comm_owner);
492 sbuf->getArray(cells_to_comm_new_owner_size);
493 sbuf->getArray(cells_to_comm_new_owner);
494 cells_to_comm_local_id.resize(nb_cell);
495 m_cell_family->itemsUniqueIdToLocalId(cells_to_comm_local_id,cells_to_comm_uid);
496 for( Integer icell=0; icell<nb_cell; ++icell ){
497 Integer cell_local_id = cells_to_comm_local_id[icell];
498 Integer cell_nb_owner = cells_to_comm_owner_size[icell];
499 Integer cell_nb_new_owner = cells_to_comm_new_owner_size[icell];
500#ifdef DEBUG
501 info()<< " cell "<<icell
502 << " lid=" <<cell_local_id
503 << " uid=" <<cells_to_comm_uid[icell]
504 << " ind=" <<m_neighbour_cells_owner->index(cell_local_id);
505#endif
506 if (m_neighbour_cells_owner->index(cell_local_id)!=(-1))
507 fatal() << "Cell uid=" << cells_to_comm_uid[icell] << " already has neighbours 'owner'!";
508 if (m_neighbour_cells_new_owner->index(cell_local_id)!=(-1))
509 fatal() << "Cell uid=" << cells_to_comm_uid[icell] << " already has neighbours 'new_owner'!";
510 m_neighbour_cells_owner->beginIncrement(cell_local_id);
511 m_neighbour_cells_new_owner->beginIncrement(cell_local_id);
512#ifdef DEBUG
513 info()<< " cell "<< icell
514 << " lid=" << cell_local_id
515 << " uid=" << cells_to_comm_uid[icell]
516 << " ind=" << m_neighbour_cells_owner->index(cell_local_id);
517#endif
518 for( Integer zz=0; zz<cell_nb_owner; ++zz )
519 m_neighbour_cells_owner->addData(cells_to_comm_owner[owner_index+zz]);
520 owner_index += cell_nb_owner;
521 m_neighbour_cells_owner->endIncrement();
522
523 for( Integer zz=0; zz<cell_nb_new_owner; ++zz )
524 m_neighbour_cells_new_owner->addData(cells_to_comm_new_owner[new_owner_index+zz]);
525 new_owner_index += cell_nb_new_owner;
526 m_neighbour_cells_new_owner->endIncrement();
527 }
528 }
529}
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
533
534void MeshExchange::
535_addItemToSend(ArrayView< std::set<Int32> > items_to_send,
536 Int32 local_id,Int32 cell_local_id,
537 bool use_itemfamily_network)
538{
539 Int32ConstArrayView new_owners = m_neighbour_cells_new_owner->at(cell_local_id);
540 for( Integer zz=0, nb_new_owner = new_owners.size(); zz<nb_new_owner; ++zz )
541 items_to_send[new_owners[zz]].insert(local_id);
542
543 Int32ConstArrayView extra_new_owners = m_neighbour_extra_cells_new_owner->at(cell_local_id);
544 for( Integer zz=0, nb_extra_new_owner = extra_new_owners.size(); zz<nb_extra_new_owner; ++zz )
545 items_to_send[extra_new_owners[zz]].insert(local_id);
546
547 if(use_itemfamily_network)
548 {
549 Int32ConstArrayView network_new_owners = m_item_dest_ranks_map[m_cell_family]->at(cell_local_id);
550 for( Integer zz=0, nb_network_new_owner = network_new_owners.size(); zz<nb_network_new_owner; ++zz )
551 {
552 items_to_send[network_new_owners[zz]].insert(local_id);
553 }
554 }
555}
556
557/*---------------------------------------------------------------------------*/
558/*---------------------------------------------------------------------------*/
559
560void MeshExchange::
561_computeItemsToSend(bool send_dof)
562{
563 for( const auto& iter : m_items_to_send )
564 iter.second->resize(m_nb_rank);
565
566 IItemFamily* node_family = mesh()->nodeFamily();
567 IItemFamily* edge_family = mesh()->edgeFamily();
568 IItemFamily* face_family = mesh()->faceFamily();
569 IItemFamily* cell_family = m_cell_family;
570
571 ArrayView<std::set<Int32>> nodes_to_send = _getItemsToSend(node_family);
572 ArrayView<std::set<Int32>> edges_to_send = _getItemsToSend(edge_family);
573 ArrayView<std::set<Int32>> faces_to_send = _getItemsToSend(face_family);
574 ArrayView<std::set<Int32>> cells_to_send = _getItemsToSend(cell_family);
575
576 Int32ConstArrayView cells_new_owner(cell_family->itemsNewOwner().asArray());
577 Int32ConstArrayView faces_new_owner(face_family->itemsNewOwner().asArray());
578 bool use_itemfamily_network = m_mesh->itemFamilyNetwork() && m_mesh->itemFamilyNetwork()->isActivated() ;
579 ENUMERATE_CELL(icell,cell_family->allItems().own()){
580 _addItemToSend(cells_to_send,icell.itemLocalId(),icell.itemLocalId(),use_itemfamily_network);
581 }
582
583 ENUMERATE_NODE(inode,node_family->allItems().own()){
584 Node node = *inode;
585 Integer node_local_id = node.localId();
586 for( CellEnumerator icell(node.cells()); icell.hasNext(); ++icell )
587 _addItemToSend(nodes_to_send,node_local_id,icell.localId(),use_itemfamily_network);
588 }
589
590 ENUMERATE_EDGE(iedge,edge_family->allItems().own()){
591 Edge edge = *iedge;
592 Integer edge_local_id = edge.localId();
593 for( CellEnumerator icell(edge.cells()); icell.hasNext(); ++icell )
594 _addItemToSend(edges_to_send,edge_local_id,icell.localId(),use_itemfamily_network);
595 }
596
597 ENUMERATE_FACE(iface,face_family->allItems().own()){
598 Face face = *iface;
599 Integer face_local_id = face.localId();
600 for( CellEnumerator icell(face.cells()); icell.hasNext(); ++icell ){
601 _addItemToSend(faces_to_send,face_local_id,icell.localId(),use_itemfamily_network);
602 }
603 }
604
605 {
606 for( IItemFamily* family : m_mesh->itemFamilies())
607 {
608 IParticleFamily* particle_family = family->toParticleFamily();
609 if (particle_family && particle_family->getEnableGhostItems()==true){
610 ArrayView<std::set<Int32>> to_send = _getItemsToSend(family);
611 ENUMERATE_PARTICLE(iparticle,particle_family->allItems().own()){
612 _addItemToSend(to_send,iparticle->localId(),iparticle->cell().localId(),use_itemfamily_network);
613 }
614 }
615 if(send_dof && family->itemKind()==IK_DoF)
616 {
617 _setItemsToSend(family);
618 }
619 }
620 }
621
622 // S'assure qu'on ne s'envoie pas les entités
623 for( const auto& iter : m_items_to_send )
624 (*(iter.second))[m_rank].clear();
625
626 const bool is_print = false;
627 if (is_print){
628 debug() << "PRINT ITEM TO SEND V1";
629 _printItemToSend(node_family);
630 _printItemToSend(edge_family);
631 _printItemToSend(face_family);
632 _printItemToSend(cell_family);
633 }
634}
635
636/*---------------------------------------------------------------------------*/
637/*---------------------------------------------------------------------------*/
638/*
639 * Cette version est plus générale que la première puisque elle prend en compte
640 * le cas AMR. En revanche, la version actuelle est moins performante que la première.
641 * C'est pour cela, la version initiale restera comme version par defaut dans le cas
642 * non AMR.
643 * NOTE: la version initiale, peut être utiliser dans le cas amr comme les échanges
644 * ce font par rapport à la connectivité autour des noeuds. Donc l'échange se fait
645 * sur l'arbre d'une maille active. Cette idée n'a pas été TODO testée pour la confirmer.
646 */
647/*---------------------------------------------------------------------------*/
648/*---------------------------------------------------------------------------*/
649
652{
653 Integer cell_variable_size = m_cell_family->maxLocalId();
654
655 m_neighbour_cells_owner = new IncrementalUnorderedMultiArray<Int32>(cell_variable_size);
656 m_neighbour_cells_new_owner = new IncrementalUnorderedMultiArray<Int32>(cell_variable_size);
657
659 tmp_new_owner.fill(NULL_ITEM_ID);
660 Int32UniqueArray tmp_owner(m_nb_rank);
661 tmp_owner.fill(NULL_ITEM_ID);
662
663 ENUMERATE_CELL(icell,m_cell_family->allItems().ownActiveCellGroup()){
664 const Cell& cell = *icell;
665 Integer cell_local_id = cell.localId();
666 // On ne se rajoute pas à notre liste de maille connectée
667 tmp_owner[m_rank] = cell_local_id;
668
669 m_neighbour_cells_owner->beginIncrement(cell_local_id);
670 m_neighbour_cells_new_owner->beginIncrement(cell_local_id);
671
672 for( NodeEnumerator inode(cell.nodes()); inode.hasNext(); ++inode ){
674 for( CellEnumerator icell2((*inode)._internalActiveCells(local_ids)); icell2.hasNext(); ++icell2 ){
675 Integer cell2_local_id = icell2.localId();
677 Integer cell2_owner = icell2->owner();
678 // Regarde si on n'est pas dans la liste et si on n'y est pas,
679 // s'y rajoute
682 m_neighbour_cells_new_owner->addData(cell2_new_owner);
683 }
686 m_neighbour_cells_owner->addData(cell2_owner);
687 }
688 }
689 local_ids.clear();
690 }
691 m_neighbour_cells_owner->endIncrement();
692 m_neighbour_cells_new_owner->endIncrement();
693 }
694}
695
696/*---------------------------------------------------------------------------*/
697/*---------------------------------------------------------------------------*/
698
699void MeshExchange::
700_addTreeCellToSend(ArrayView< std::set<Int32> > items_to_send,
701 Int32 local_id,Int32 cell_local_id,
702 CellInfoListView cells)
703{
704 Int32ConstArrayView new_owners = m_neighbour_cells_new_owner->at(cell_local_id);
705
706 Cell cell(cells[local_id]);
707 if(cell.level() == 0){
708 for( Integer zz=0, nb_new_owner = new_owners.size(); zz<nb_new_owner; ++zz )
709 items_to_send[new_owners[zz]].insert(local_id);
710 // Graphe ok sur le niveau actif
711 Int32ConstArrayView extra_new_owners = m_neighbour_extra_cells_new_owner->at(cell_local_id);
712 for( Integer zz=0, nb_extra_new_owner = extra_new_owners.size(); zz<nb_extra_new_owner; ++zz )
713 items_to_send[extra_new_owners[zz]].insert(local_id);
714 }
715 else {
716 Int32UniqueArray family;
717 Cell top_parent= cell.topHParent();
718 _familyTree(family,top_parent);
719 for(Integer c=0,cs=family.size();c<cs;c++){
720 for( Integer zz=0, nb_new_owner = new_owners.size(); zz<nb_new_owner; ++zz )
721 items_to_send[new_owners[zz]].insert(family[c]);
722 }
723 }
724}
725
726/*---------------------------------------------------------------------------*/
727/*---------------------------------------------------------------------------*/
728
729void MeshExchange::
730_addTreeItemToSend(Int32 cell_local_id,CellInfoListView cells)
731{
732 Int32UniqueArray tree_cells_lid;
733
734 Int32ConstArrayView new_owners = m_neighbour_cells_new_owner->at(cell_local_id);
735
736 Cell cell(cells[cell_local_id]);
737
738 Int32UniqueArray family;
739
740 Cell top_parent= cell.topHParent();
741 _familyTree(family,top_parent);
742
743 IItemFamily* node_family = mesh()->nodeFamily();
744 IItemFamily* edge_family = mesh()->edgeFamily();
745 IItemFamily* face_family = mesh()->faceFamily();
746
747 ArrayView<std::set<Int32>> nodes_to_send = _getItemsToSend(node_family);
748 ArrayView<std::set<Int32>> edges_to_send = _getItemsToSend(edge_family);
749 ArrayView<std::set<Int32>> faces_to_send = _getItemsToSend(face_family);
750
751 // On suppose que les containers nodes_to_send, edges_to_send et face_to_send
752 // sont deja alloues
753 for(Integer c=0,cs=family.size();c<cs;c++) // c=0 est la maille topParent.
754 for( Integer zz=0, nb_new_owner = new_owners.size(); zz<nb_new_owner; ++zz ){
755 Cell cell2 = cells[family[c]];
756 for( Node node : cell2.nodes() )
757 nodes_to_send[new_owners[zz]].insert(node.localId());
758 for( Edge edge : cell2.edges() )
759 edges_to_send[new_owners[zz]].insert(edge.localId());
760 for( Face face : cell2.faces() )
761 faces_to_send[new_owners[zz]].insert(face.localId());
762 }
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
768void MeshExchange::
769_familyTree (Int32Array& family,Cell item, const bool reset) const
770{
771 ARCANE_ASSERT((!item.itemBase().isSubactive()),("The family tree doesn't include subactive items"));
772 // Clear the array if the flag reset tells us to.
773 if (reset)
774 family.clear();
775 // Add this item to the family tree.
776 family.add(item.localId());
777 // Recurse into the items children, if it has them.
778 // Do not clear the array any more.
779 if (!item.isActive())
780 for (Integer c=0, cs=item.nbHChildren(); c<cs; c++){
781 Item ichild = item.hChild(c);
782 if (ichild.isOwn())
783 _familyTree (family,ichild.toCell(), false);
784 }
785}
786
787/*---------------------------------------------------------------------------*/
788/*---------------------------------------------------------------------------*/
789
790void MeshExchange::
791_computeItemsToSend2()
792{
793 for( const auto& iter : m_items_to_send )
794 iter.second->resize(m_nb_rank);
795
796 IItemFamily* node_family = mesh()->nodeFamily();
797 IItemFamily* edge_family = mesh()->edgeFamily();
798 IItemFamily* face_family = mesh()->faceFamily();
799
800 ArrayView<std::set<Int32>> nodes_to_send = _getItemsToSend(node_family);
801 ArrayView<std::set<Int32>> edges_to_send = _getItemsToSend(edge_family);
802 ArrayView<std::set<Int32>> faces_to_send = _getItemsToSend(face_family);
803 ArrayView<std::set<Int32>> cells_to_send = _getItemsToSend(m_cell_family);
804
805 Int32ConstArrayView cells_new_owner(m_cell_family->itemsNewOwner().asArray());
806 Int32ConstArrayView faces_new_owner(face_family->itemsNewOwner().asArray());
807
808 CellInfoListView cells(m_cell_family);
809 ENUMERATE_CELL(icell,m_cell_family->allItems().ownActiveCellGroup()){
810 Cell cell = *icell;
811 _addTreeCellToSend(cells_to_send,icell.itemLocalId(),icell.itemLocalId(),cells);
812
813 if(cell.level() == 0){
814
815 for( NodeEnumerator inode(cell.nodes()); inode.hasNext(); ++inode ){
816 Node node= *inode;
817 if(node.isOwn()){
818 Integer node_local_id = node.localId();
819 for( CellEnumerator icell2(node.cells()); icell2.hasNext(); ++icell2 ){
820 Cell cc= *icell2;
821 if(cc.isActive())
822 _addItemToSend(nodes_to_send,node_local_id,icell2.localId());
823 }
824 }
825 }
826
827 for( EdgeEnumerator iedge(cell.edges()); iedge.hasNext(); ++iedge ){
828 Edge edge = *iedge;
829 if(edge.isOwn()){
830 Integer edge_local_id = edge.localId();
831 for( CellEnumerator icell2(edge.cells()); icell2.hasNext(); ++icell2 )
832 _addItemToSend(edges_to_send,edge_local_id,icell2.localId());
833 }
834 }
835
836 for(FaceEnumerator iface(cell.faces());iface.hasNext();++iface){
837 Face face = *iface;
838 if(face.isOwn()){
839 Integer face_local_id = face.localId();
840 for( CellEnumerator icell2(face.cells()); icell2.hasNext(); ++icell2 ){
841 _addItemToSend(faces_to_send,face_local_id,icell2.localId());
842 }
843 }
844 }
845
846 }
847 else if(cell.level() > 0)
848 _addTreeItemToSend(icell.itemLocalId(),cells);
849 }
850
851 for( IItemFamily* family : m_mesh->itemFamilies()){
852 IParticleFamily* particle_family = family->toParticleFamily();
853 if (particle_family && particle_family->getEnableGhostItems()==true){
854 ArrayView<std::set<Int32>> to_send = _getItemsToSend(family);
855 ENUMERATE_PARTICLE(iparticle,particle_family->allItems().own()){
856 _addItemToSend(to_send,iparticle->localId(),iparticle->cell().localId());
857 }
858 }
859 }
860
861 // S'assure qu'on ne s'envoie pas les entités
862 for( const auto& iter : m_items_to_send )
863 (*(iter.second))[m_rank].clear();
864}
865
866/*---------------------------------------------------------------------------*/
867/*---------------------------------------------------------------------------*/
868
870
871/*---------------------------------------------------------------------------*/
872/*---------------------------------------------------------------------------*/
873/*
874 * Cette version propose une implémentation du calcul des items à échanger
875 * utilisant le graphe de dépendances des familles (ItemFamilyNetwork)
876 * NOTE: Pour l'instant les algos pour le graphe d'arcane IGraph et pour les familles
877 * de particules sont inchangés.
878 */
879/*---------------------------------------------------------------------------*/
880/*---------------------------------------------------------------------------*/
881
883
886{
887 if (!m_mesh->itemFamilyNetwork()) info() << "Should have an IItemFamilyNetwork. Exiting.";
888 //1-Prepare data structure
889 m_ghost_item_dest_ranks_map.resize(m_parallel_mng->commSize());
890 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
891 _allocData(family);
892 },
893 IItemFamilyNetwork::TopologicalOrder);
894
895 // Here the algorithm propagates the owner to the neighborhood
896 // The propagation to the items owned (dependencies) has already been done in updateOwnersFromCell
897 // Todo include also the owned item propagation (would avoid to call updateOwnersFromCell...)
898 // What we do here is to build the number of ghost layers needed
899 //-For each ghost layer wanted :
900 // 1- For all items add Item new owner and all its dest ranks to all child item connected (dependency or relation) dest ranks
901 // This is done for all family, parsing the family graph from head to leaves
902 // 2- For all items add new dest ranks to its depending child (move with your downward dependencies)
903 if (!m_mesh->ghostLayerMng()) info() << "Should have a IGhostLayerMng. Exiting";
904 for (int ghost_layer_index = 0; ghost_layer_index < m_mesh->ghostLayerMng()->nbGhostLayer(); ++ghost_layer_index)
905 {
906 //2-Diffuse destination rank info to connected items
907 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
908 _propagatesToChildConnectivities(family);
909 },
910 IItemFamilyNetwork::TopologicalOrder);
911
912 //m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
913 // _propagatesToChildDependencies(family);
914 //},
915 //IItemFamilyNetwork::TopologicalOrder);
916 }
917}
918
919/*---------------------------------------------------------------------------*/
920/*---------------------------------------------------------------------------*/
921
922void MeshExchange::
923_propagatesToChildConnectivities(IItemFamily* family)
924{
926 /* TODO : this propagation should be needed for all child dependencies and not all relations but only ghost providing relations
927 * eg for node to cell connectivity if ghosts are found via node neighbouring. This notion of ghost providing relations must be added
928 * In traditional case only node to cell is a ghost providing relation => a test can be made to add only this relation (along with all dependencies) :
929 * auto child_connectivities = m_mesh->itemFamilyNetwork()->getChildDependencies(family); // instead of getChildConnectivities
930 * if (family->itemKind()==IK_Node) {
931 * child_connectivities.add(m_mesh->itemFamilyNetwork()->getConnectivity(family,m_mesh->cellFamily(),mesh::connectivityName(family,m_mesh->cellFamily())));
932 * }
933 */
934 //auto child_connectivities = m_mesh->itemFamilyNetwork()->getChildConnectivities(family);
935 auto child_connectivities = m_mesh->itemFamilyNetwork()->getChildDependencies(family); // Only dependencies are required to propagate owner
936 for (const auto& child_connectivity : child_connectivities){
937 //if(!child_connectivity->isEmpty())
938 {
939 VariableItemInt32& conn_item_new_owner = child_connectivity->targetFamily()->itemsNewOwner();
941 ENUMERATE_ITEM(item, family->allItems()){
942 // Parse child relations
943 _addDestRank(*item,family,item_new_owner[item]);
945 _addDestRank(*item,family,conn_item_new_owner[connected_item]);
946 }
947
949 _addDestRank(*connected_item,child_connectivity->targetFamily(),*item,family);
950 }
951 }
952 }
953 }
955 switch(family->itemKind()){
956 case IK_Face:
957 ENUMERATE_(Face, item, family->allItems()) {
958 for( Cell cell : item->cells())
959 _addDestRank(cell,m_cell_family,*item,family);
960 }
961 break;
962 case IK_Edge:
963 ENUMERATE_(Edge, item, family->allItems()){
964 for( Cell cell : item->cells() )
965 _addDestRank(cell,m_cell_family,*item,family);
966 }
967 break;
968 case IK_Node:
969 ENUMERATE_(Node, item, family->allItems()){
970 for( Cell cell : item->cells())
971 _addDestRank(cell,m_cell_family,*item,family);
972 }
973 break;
974 default:
975 break;
976 }
977}
978}
979
980/*---------------------------------------------------------------------------*/
981/*---------------------------------------------------------------------------*/
982
983void MeshExchange::
984_propagatesToChildDependencies(IItemFamily* family)
985{
986 // Here we only propagates dest_ranks, since owner propagation to children has already been done in updateOwnersFromCell
987 // todo 1 use these new algo to propagates the owner
988 // todo 2 when using the graph we do not need to access to all child connectivities, only the one of the immediately inferior level.
989 // => we should allow graph task to take the signature task(IItemFamily*,FirstRankChildren) where FirstRankChildren (better name ?)
990 // would contain the immediate children (FirstRankChildren) would be an EdgeSet or smthg near
991 // => thus we would need to add to the DAG a method children(const Edge&) (see for the name firstRankChildren ??)
992 auto child_dependencies = m_mesh->itemFamilyNetwork()->getChildDependencies(family);
993 for (const auto& child_dependency :child_dependencies){
994 //if(!child_dependency->isEmpty())
995 {
996 auto accessor = IndexedItemConnectivityAccessor(child_dependency);
997 ENUMERATE_ITEM(item, family->allItems()){
998 // Parse child dependencies
999 ENUMERATE_ITEM(connected_item,accessor(ItemLocalId(item))){
1000 _addDestRank(*connected_item,child_dependency->targetFamily(),*item, family); // as simple as that ??
1001 }
1002 }
1003 }
1004 }
1005}
1006
1007/*---------------------------------------------------------------------------*/
1008/*---------------------------------------------------------------------------*/
1009
1010void MeshExchange::
1011_addDestRank(const Item& item, IItemFamily* item_family, const Integer new_owner) // take an ItemInternal* ?
1012{
1013 ItemDestRankArray* item_dest_ranks = nullptr;
1014 if (item.owner() == m_rank) {
1015 item_dest_ranks = m_item_dest_ranks_map[item_family];// this search could be written outside the enumerate (but the enumerate is cheap : on connected items)
1016 }
1017 else {
1018 item_dest_ranks= m_ghost_item_dest_ranks_map[item.owner()][item_family];
1019 }
1020 // Insert element only if not present
1021 auto& item_ranks_internal = item_dest_ranks->at(item.localId());
1022 if (!item_ranks_internal.contains(new_owner))
1023 item_dest_ranks->at(item.localId()).add(new_owner);
1024}
1025
1026/*---------------------------------------------------------------------------*/
1027/*---------------------------------------------------------------------------*/
1028
1029void MeshExchange::
1030_addDestRank(const Item& item, IItemFamily* item_family, const Item& followed_item, IItemFamily* followed_item_family)
1031{
1032 // todo : a getDestRank method
1033 ItemDestRankArray* item_dest_ranks = nullptr;
1034 if (item.owner() == m_rank)
1035 {
1036 item_dest_ranks = m_item_dest_ranks_map[item_family];// this search could be written outside the enumerate (but the enumerate is cheap : on connected items)
1037 }
1038 else
1039 {
1040 item_dest_ranks= m_ghost_item_dest_ranks_map[item.owner()][item_family];
1041 }
1042 ItemDestRankArray* followed_item_dest_ranks = nullptr;
1043 if (followed_item.owner() == m_rank)
1044 followed_item_dest_ranks = m_item_dest_ranks_map[followed_item_family];// this search could be written outside the enumerate (but the enumerate is cheap : on connected items)
1045 else
1046 followed_item_dest_ranks= m_ghost_item_dest_ranks_map[followed_item.owner()][followed_item_family];
1047 // Add only new dest rank only if not already present
1048 auto& new_dest_ranks = followed_item_dest_ranks->at(followed_item.localId());
1049 auto& current_dest_ranks = item_dest_ranks->at(item.localId());
1050 IntegerUniqueArray new_dest_rank_to_add;
1051 new_dest_rank_to_add.reserve((new_dest_ranks.size()));
1052 for (auto& new_dest_rank : new_dest_ranks){
1053 if (!current_dest_ranks.contains(new_dest_rank))
1054 new_dest_rank_to_add.add(new_dest_rank);
1055 }
1056 current_dest_ranks.addRange(new_dest_rank_to_add);
1057}
1058
1059/*---------------------------------------------------------------------------*/
1060/*---------------------------------------------------------------------------*/
1061
1062void MeshExchange::
1063_allocData(IItemFamily* family)
1064{
1065 m_item_dest_ranks_map[family] = new ItemDestRankArray(family->maxLocalId());
1066 for (auto& ghost_item_map : m_ghost_item_dest_ranks_map) {
1067 ghost_item_map[family] = new ItemDestRankArray(family->maxLocalId());
1068 }
1069}
1070/*---------------------------------------------------------------------------*/
1071/*---------------------------------------------------------------------------*/
1072
1073void MeshExchange::
1074_debugPrint()
1075{
1076 info() << "-ENTERING NEW EXCHANGE DEBUG PRINT";
1077 for(auto& item_dest_ranks : m_item_dest_ranks_map){
1078 info() << "--PRINT NEW EXCHANGE INFO";
1079 info() << "---Destination rank for family " << item_dest_ranks.first->name();
1080 for (int item_lid = 0; item_lid < item_dest_ranks.first->maxLocalId(); ++item_lid) {
1081 info() << "---Destination rank for item lid " << item_lid;
1082 for (auto& item_dest_rank : item_dest_ranks.second->at(item_lid)) {
1083 info() << "---- Rank " << item_dest_rank;
1084 }
1085 }
1086 }
1087}
1088
1089/*---------------------------------------------------------------------------*/
1090/*---------------------------------------------------------------------------*/
1091
1092void MeshExchange::
1093_exchangeCellDataInfos3()
1094{
1095 // Graph connectivity taken into account thanks to the call to _addGraphConnectivityToNewConnectivityInfo
1096 auto sd_exchange { ParallelMngUtils::createExchangerRef(m_parallel_mng) };
1097
1098 Int32UniqueArray recv_sub_domains;
1099 m_cell_family->getCommunicatingSubDomains(recv_sub_domains);
1100 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i )
1101 sd_exchange->addSender(recv_sub_domains[i]);
1102
1103 sd_exchange->initializeCommunicationsMessages(recv_sub_domains);
1104
1105 UniqueArray<IItemFamily*> item_families;
1106 Int32UniqueArray item_lids;
1107 Int32UniqueArray item_dest_ranks;
1108 Int32UniqueArray item_nb_dest_ranks;
1109 Int32UniqueArray family_nb_items;
1110 Int64UniqueArray item_uids;
1111
1112 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i ){
1113 ISerializeMessage* comm = sd_exchange->messageToSend(i);
1114 Int32 dest_sub_domain = comm->destination().value();
1115 ISerializer* sbuf = comm->serializer();
1116 item_families.clear();
1117 item_dest_ranks.clear();
1118 item_nb_dest_ranks.clear();
1119 family_nb_items.clear();
1120 item_uids.clear();
1121 for (const auto& family_ghost_item_dest_ranks : m_ghost_item_dest_ranks_map[dest_sub_domain]) {
1122 Integer family_nb_item = 0;
1123 item_lids.clear();
1124 item_families.add(family_ghost_item_dest_ranks.first);
1125 for (Integer item_lid = 0; item_lid < family_ghost_item_dest_ranks.second->size(); ++item_lid)
1126 {
1127 if (family_ghost_item_dest_ranks.second->at(item_lid).size() == 0) continue;
1128 item_lids.add(item_lid);
1129 item_dest_ranks.addRange(family_ghost_item_dest_ranks.second->at(item_lid));
1130 item_nb_dest_ranks.add(family_ghost_item_dest_ranks.second->at(item_lid).size());
1131 family_nb_item++;
1132 }
1133 family_nb_items.add(family_nb_item);
1134 ENUMERATE_ITEM(item, family_ghost_item_dest_ranks.first->view(item_lids))
1135 {
1136 item_uids.add(item->uniqueId().asInt64());
1137 }
1138 }
1139 sbuf->setMode(ISerializer::ModeReserve);
1140 sbuf->reserve(DT_Int64,1); // nb_item_family
1141 for (const auto& family: item_families)
1142 sbuf->reserve(family->name()); // ItemFamily->name
1143 sbuf->reserveInteger(item_families.size()); // ItemFamily->itemKind
1144 sbuf->reserveArray(item_uids);
1145 sbuf->reserveArray(family_nb_items);
1146 sbuf->reserveArray(item_nb_dest_ranks);
1147 sbuf->reserveArray(item_dest_ranks);
1148
1149 sbuf->allocateBuffer();
1150 sbuf->setMode(ISerializer::ModePut);
1151
1152 sbuf->putInt64(item_families.size());
1153 for (const auto& family: item_families)
1154 sbuf->put(family->name()); // ItemFamily->name
1155 for (const auto& family: item_families)
1156 sbuf->putInteger(family->itemKind()); // ItemFamily->itemKind
1157 sbuf->putArray(item_uids);
1158 sbuf->putArray(family_nb_items);
1159 sbuf->putArray(item_nb_dest_ranks);
1160 sbuf->putArray(item_dest_ranks);
1161 }
1162
1163 sd_exchange->processExchange();
1164
1165 for( Integer i=0, n=recv_sub_domains.size(); i<n; ++i ){
1166 ISerializeMessage* comm = sd_exchange->messageToReceive(i);
1167 ISerializer* sbuf = comm->serializer();
1168 Int64 nb_families = sbuf->getInt64();
1169 StringUniqueArray item_family_names(nb_families);
1170 Int32UniqueArray item_family_kinds(nb_families);
1171 for (auto& family_name: item_family_names)
1172 sbuf->get(family_name); // ItemFamily->name
1173 for (auto& family_kind: item_family_kinds)
1174 family_kind = sbuf->getInteger(); // ItemFamily->itemKind
1175 sbuf->getArray(item_uids);
1176 sbuf->getArray(family_nb_items);
1177 sbuf->getArray(item_nb_dest_ranks);
1178 sbuf->getArray(item_dest_ranks);
1179 Integer item_uid_index = 0;
1180 Integer item_nb_dest_rank_index = 0;
1181 Integer item_dest_rank_index = 0;
1182 for (int family_index = 0; family_index < nb_families; ++family_index)
1183 {
1184 IItemFamily* family = m_mesh->findItemFamily(eItemKind(item_family_kinds[family_index]),
1185 item_family_names[family_index],false);
1186 Int64ArrayView family_item_uids = item_uids.subView(item_uid_index,family_nb_items[family_index]);
1187 item_lids.resize(family_item_uids.size());
1188 family->itemsUniqueIdToLocalId(item_lids,family_item_uids,true);
1189 for (const auto& item_lid : item_lids){
1190 auto sub_view = item_dest_ranks.subView(item_dest_rank_index,item_nb_dest_ranks[item_nb_dest_rank_index]);
1191 m_item_dest_ranks_map[family]->at(item_lid).addRange(sub_view);
1192 item_dest_rank_index+= item_nb_dest_ranks[item_nb_dest_rank_index++];
1193 }
1194 item_uid_index+= family_nb_items[family_index];
1195 }
1196 }
1197 // Dest rank propagation needed since they have been updated for own items
1198 // copy of propagation part of method computeMeshConnectivityInfo3
1199 for (int ghost_layer_index = 0; ghost_layer_index < m_mesh->ghostLayerMng()->nbGhostLayer(); ++ghost_layer_index)
1200 {
1201 //2-Diffuse destination rank info to connected items
1202 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
1203 _propagatesToChildConnectivities(family);
1204 },
1205 IItemFamilyNetwork::TopologicalOrder);
1206
1207 //m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
1208 // _propagatesToChildDependencies(family);
1209 //},
1210 //IItemFamilyNetwork::TopologicalOrder);
1211 }
1212}
1213/*---------------------------------------------------------------------------*/
1214/*---------------------------------------------------------------------------*/
1215
1216void MeshExchange::
1217_computeItemsToSend3()
1218{
1219 for( const auto& iter : m_items_to_send )
1220 iter.second->resize(m_nb_rank);
1221
1222 IItemFamily* node_family = mesh()->nodeFamily();
1223 IItemFamily* edge_family = mesh()->edgeFamily();
1224 IItemFamily* face_family = mesh()->faceFamily();
1225 IItemFamily* cell_family = m_cell_family;
1226
1227 _setItemsToSend(node_family);
1228 _setItemsToSend(edge_family);
1229 _setItemsToSend(face_family);
1230 _setItemsToSend(cell_family);
1231
1232 // Tmp for particles : they should be in the family graph
1233 {
1234 for( IItemFamily* family : m_mesh->itemFamilies()){
1235 IParticleFamily* particle_family = family->toParticleFamily();
1236 if (particle_family && particle_family->getEnableGhostItems()==true){
1237 ArrayView<std::set<Int32>> to_send = _getItemsToSend(family);
1238 ENUMERATE_PARTICLE(iparticle,particle_family->allItems().own()){
1239 for (const auto& dest_rank : m_item_dest_ranks_map[m_cell_family]->at(iparticle->cell().localId())) {
1240 to_send[dest_rank].insert(iparticle->localId());
1241 }
1242 }
1243 }
1244 }
1245 }
1246
1247 // S'assure qu'on ne s'envoie pas les entités
1248 for( const auto& iter : m_items_to_send )
1249 (*(iter.second))[m_rank].clear();
1250
1251 // SDC DEBUG
1252// debug() << "PRINT ITEM TO SEND V2";
1253// _printItemToSend(node_family);
1254// _printItemToSend(edge_family);
1255// _printItemToSend(face_family);
1256// _printItemToSend(cell_family);
1257}
1258
1259/*---------------------------------------------------------------------------*/
1260/*---------------------------------------------------------------------------*/
1261
1262void MeshExchange::
1263_setItemsToSend(IItemFamily* family)
1264{
1265 if(family->nbItem()==0)
1266 return ;
1267 auto iter = m_items_to_send.find(family);
1268 if (iter==m_items_to_send.end())
1269 ARCANE_FATAL("No items to send for family '{0}'",family->name());
1270 ArrayView<std::set<Int32>> items_to_send = iter->second->view();
1271 for (Integer item_lid = 0 ; item_lid < m_item_dest_ranks_map[family]->size(); ++item_lid){
1272 for (const auto& dest_rank : m_item_dest_ranks_map[family]->at(item_lid)){
1273 items_to_send[dest_rank].insert(item_lid);
1274 }
1275 }
1276}
1277
1278/*---------------------------------------------------------------------------*/
1279/*---------------------------------------------------------------------------*/
1280
1283{
1284 auto iter = m_items_to_send.find(family);
1285 if (iter==m_items_to_send.end())
1286 ARCANE_FATAL("No items to send for family '{0}'",family->name());
1287 ArrayView<std::set<Int32>> items_to_send = iter->second->view();
1288 // SDC DEBUG print
1289 Integer rank = 0;
1290 debug() << "= ITEM TO SEND FOR FAMILY " << family->name();
1291 for (const auto& owner_lids : items_to_send) {
1292 debug() << "== RANK " << rank++;
1293 for (auto item_lid : owner_lids){
1294 debug() << "=== has items " << item_lid;
1295 }
1296 }
1297}
1298
1299/*---------------------------------------------------------------------------*/
1300/*---------------------------------------------------------------------------*/
1301
1302void MeshExchange::
1303_printItemToRemove(IItemFamily* family)
1304{
1305 // SDC DEBUG PRINT
1306 debug() << "= ITEM TO REMOVE FOR FAMILY " << family->name();
1307 ENUMERATE_ITEM(item, family->allItems()) {
1308 if (item->itemBase().flags() & ItemFlags::II_NeedRemove)
1309 debug() << "== TO REMOVE ITEM " << item->uniqueId() << " kind " << item->kind();
1310 }
1311}
1312
1313/*---------------------------------------------------------------------------*/
1314/*---------------------------------------------------------------------------*/
1315void MeshExchange::
1316_markRemovableDoFs()
1317{
1318 for (const auto& item_dest_ranks_iter : m_item_dest_ranks_map){
1319 // todo use C++17 structured bindings
1320 IItemFamily* family = item_dest_ranks_iter.first;
1321 if(family->itemKind() == IK_DoF ){
1322 auto & item_new_owners = family->itemsNewOwner();
1323 ENUMERATE_ITEM(item, family->allItems()){
1324 Int32ArrayView item_dest_ranks;
1325 // Get destination rank for item (depending if it's ghost or own)
1326 if (item->isOwn())
1327 item_dest_ranks = item_dest_ranks_iter.second->at(item->localId()).view();
1328 else
1329 item_dest_ranks = m_ghost_item_dest_ranks_map[item->owner()][family]->at(item->localId()).view();
1330 // Check if the item must stay on the subdomain (ie dest_rank or new_owner contain the subdomain)
1331 if (!item_dest_ranks.contains(m_rank) && item_new_owners[item] != m_rank){
1332 item->mutableItemBase().addFlags(ItemFlags::II_NeedRemove);
1333 }
1334 }
1335 }
1336// _printItemToRemove(item_dest_ranks_iter.first); // SDC DEBUG
1337 }
1338}
1339
1340void MeshExchange::
1341_markRemovableItems(bool with_cell_family)
1342{
1343 for (const auto& item_dest_ranks_iter : m_item_dest_ranks_map){
1344 // todo use C++17 structured bindings
1345 IItemFamily* family = item_dest_ranks_iter.first;
1346 if(with_cell_family || family->name()!=m_cell_family->name() ){
1347 auto & item_new_owners = family->itemsNewOwner();
1348 ENUMERATE_ITEM(item, family->allItems()){
1349 Int32ArrayView item_dest_ranks;
1350 // Get destination rank for item (depending if it's ghost or own)
1351 if (item->isOwn())
1352 item_dest_ranks = item_dest_ranks_iter.second->at(item.localId()).view();
1353 else
1354 item_dest_ranks = m_ghost_item_dest_ranks_map[item->owner()][family]->at(item.localId()).view();
1355 // Check if the item must stay on the subdomain (ie dest_rank or new_owner contain the subdomain)
1356 if (!item_dest_ranks.contains(m_rank) && item_new_owners[item] != m_rank){
1357 item->mutableItemBase().addFlags(ItemFlags::II_NeedRemove);
1358 }
1359 }
1360 }
1361 // _printItemToRemove(item_dest_ranks_iter.first); // SDC DEBUG
1362 }
1363}
1364
1365void MeshExchange::
1366_markRemovableCells(Int32ConstArrayView cells_new_owner,bool use_active_cells)
1367{
1368 // Ce test n'est plus représentatif avec le concept extraghost
1369 // Faut il trouver une alternative ??
1370 // // Vérifie que toutes les mailles ont eues leur voisines calculées
1371 // ENUMERATE_CELL(icell,m_cell_family->allItems()){
1372 // const Cell& cell = *icell;
1373 // Integer cell_local_id = cell.localId();
1374 // if (m_neighbour_cells_owner->index(cell_local_id) == -1 &&
1375 // m_neighbour_extra_cells_owner->at(cell_local_id).size() == 0 )
1376 // fatal() << ItemPrinter(cell) << " has no neighbours! (no owner)";
1377 // if (m_neighbour_cells_new_owner->index(cell_local_id)==(-1))
1378 // fatal() << ItemPrinter(cell) << " has no neighbours! (no new owner index)";
1379 // }
1380
1381 // Détermine les mailles qui peuvent être supprimées.
1382 // Une maille peut-être supprimée si la liste de ses nouveaux propriétaires ne
1383 // contient pas ce sous-domaine.
1384
1385 ItemGroup all_items = m_cell_family->allItems();
1386
1387 auto itemfamily_network = m_mesh->itemFamilyNetwork() ;
1388 bool use_itemfamily_network = ( itemfamily_network!= nullptr && itemfamily_network->isActivated() );
1389
1390 // Avec l'AMR, on utilise les mailles actives et pas toutes les mailles.
1391 if (use_active_cells)
1392 all_items = m_cell_family->allItems().activeCellGroup();
1393
1394 ENUMERATE_CELL(icell,all_items){
1395 Cell cell = *icell;
1396 Integer cell_local_id = cell.localId();
1397 if (cells_new_owner[cell_local_id]==m_rank)
1398 continue;
1399
1400 Int32ConstArrayView new_owners = m_neighbour_cells_new_owner->at(cell_local_id);
1401 bool keep_cell = new_owners.contains(m_rank);
1402 if (!keep_cell){
1403 Int32ConstArrayView extra_new_owners = m_neighbour_extra_cells_new_owner->at(cell_local_id);
1404 keep_cell = extra_new_owners.contains(m_rank);
1405 }
1406 if(!keep_cell && use_itemfamily_network)
1407 {
1408 Int32ArrayView item_dest_ranks;
1409 // Get destination rank for item (depending if it's ghost or own)
1410 if (icell->isOwn())
1411 item_dest_ranks = m_item_dest_ranks_map[m_cell_family]->at(icell->localId()).view();
1412 else
1413 item_dest_ranks = m_ghost_item_dest_ranks_map[icell->owner()][m_cell_family]->at(icell->localId()).view();
1414 // Check if the item must stay on the subdomain (ie dest_rank or new_owner contain the subdomain)
1415 keep_cell = item_dest_ranks.contains(m_rank) ;
1416 }
1417 if (!keep_cell)
1418 {
1419 cell.mutableItemBase().addFlags(ItemFlags::II_NeedRemove);
1420 }
1421 }
1422}
1423/*---------------------------------------------------------------------------*/
1424/*---------------------------------------------------------------------------*/
1425
1426void MeshExchange::
1427_markRemovableParticles()
1428{
1429 for( IItemFamily* family : m_mesh->itemFamilies()){
1430 IParticleFamily* particle_family = family->toParticleFamily();
1431 if(particle_family && particle_family->getEnableGhostItems()==true){
1432 mesh::NewItemOwnerBuilder owner_builder;
1433
1434 ENUMERATE_PARTICLE(iparticle,particle_family->allItems()){
1435 Particle particle = *iparticle;
1436 Cell cell = owner_builder.connectedCellOfItem(particle);
1437 particle.mutableItemBase().setFlags(cell.itemBase().flags());
1438 }
1439 }
1440 }
1441}
1442
1443/*---------------------------------------------------------------------------*/
1444/*---------------------------------------------------------------------------*/
1445
1446void MeshExchange::
1447_checkSubItemsDestRanks()
1448{
1449 // Check subitems dest_ranks contain parent dest_rank (even after exchangeDataInfo...)
1450 // Check for items that the subdomain do send : ie own items
1451 m_mesh->itemFamilyNetwork()->schedule([this](IItemFamily* family){
1452 ENUMERATE_ITEM(item, family->allItems().own()) {
1453 const auto& item_dest_ranks = m_item_dest_ranks_map[family]->at(item.localId());
1454 for (const auto& child_dependency : m_mesh->itemFamilyNetwork()->getChildDependencies(family))
1455 {
1456 auto accessor = IndexedItemConnectivityAccessor(child_dependency);
1457 ENUMERATE_ITEM(connected_item,accessor(ItemLocalId(item))){
1458 Int32ConstArrayView subitem_dest_ranks;
1459 // test can only be done for own subitems, otherwise their dest_ranks are only partially known => to see
1460 if (connected_item->isOwn()) {
1461 subitem_dest_ranks = m_item_dest_ranks_map[child_dependency->targetFamily()]->at(connected_item.localId()).constView();
1462 for (auto dest_rank : item_dest_ranks) {
1463 if (! subitem_dest_ranks.contains(dest_rank))
1464 fatal() << "Dest Rank " << dest_rank << " for item " << item->kind() << " uid "<< item->uniqueId()
1465 << " not present in subitem " << connected_item->kind() << " uid " << connected_item->uniqueId()
1466 << " dest ranks " << subitem_dest_ranks << " ower " << connected_item->owner();
1467 }
1468 }
1469 }
1470 }
1471 }
1472 }, IItemFamilyNetwork::TopologicalOrder);
1473}
1474
1475/*---------------------------------------------------------------------------*/
1476/*---------------------------------------------------------------------------*/
1477
1478
1479void MeshExchange::
1480_exchangeGhostItemDataInfos()
1481{
1482 /* necessary for dark corner cases (with graph for example) :
1483 * we need to know if a ghost item will stay ghost
1484 * otherwise we will destroy it and when we receive it again
1485 * we won't be able to restore some relations pointing on it
1486 * ex a cell ghost on Sd_0(subdomain 0) is removed while a face (owner = 0) stays on the subdomain
1487 * when the cell comes back, send by Sd_1, the face is not send by Sd_1 since it belongs to Sd_0
1488 * the relation from the cell to the face is restored but the one from the face to the cell is not
1489 * This case should not happen with contiguous partitions,
1490 * but when you start to add extra ghost to follow graph for example, it occurs...
1491 */
1492
1493 // Graph connectivity taken into account thanks to the call to _addGraphConnectivityToNewConnectivityInfo
1494 auto sd_exchange { ParallelMngUtils::createExchangerRef(m_parallel_mng) };
1495
1496 Int32UniqueArray recv_sub_domains;
1497 m_cell_family->getCommunicatingSubDomains(recv_sub_domains);
1498 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i )
1499 sd_exchange->addSender(recv_sub_domains[i]);
1500
1501 sd_exchange->initializeCommunicationsMessages(recv_sub_domains);
1502
1503 UniqueArray<IItemFamily*> item_families;
1504 Int32UniqueArray item_dest_ranks;
1505 Int32UniqueArray item_nb_dest_ranks;
1506 Int32UniqueArray family_nb_items;
1507 Int64UniqueArray item_uids;
1508
1509 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i ){
1510 ISerializeMessage* comm = sd_exchange->messageToSend(i);
1511 Int32 dest_sub_domain = comm->destination().value();
1512 ISerializer* sbuf = comm->serializer();
1513 item_families.clear();
1514 item_dest_ranks.clear();
1515 item_nb_dest_ranks.clear();
1516 family_nb_items.clear();
1517 item_uids.clear();
1518 for (const auto& family_item_dest_ranks : m_item_dest_ranks_map){
1519 Integer family_nb_item = 0;
1520 IItemFamily* family = family_item_dest_ranks.first;
1521 if (family->nbItem() == 0) continue; // skip empty family
1522 item_families.add(family);
1523 // Get shared items with dest_sub_domain
1524 auto subdomain_index = _getSubdomainIndexInCommunicatingRanks(dest_sub_domain, family->allItemsSynchronizer()->communicatingRanks());
1525 auto shared_item_lids = family->allItemsSynchronizer()->sharedItems(subdomain_index);
1526 for (const auto& item_lid : shared_item_lids){
1527 if (family_item_dest_ranks.second->at(item_lid).size() == 0) continue;
1528 item_dest_ranks.addRange(family_item_dest_ranks.second->at(item_lid));
1529 item_nb_dest_ranks.add(family_item_dest_ranks.second->at(item_lid).size());
1530 family_nb_item++;
1531 }
1532 family_nb_items.add(family_nb_item);
1533 ENUMERATE_ITEM(item, family_item_dest_ranks.first->view(shared_item_lids)) {
1534 item_uids.add(item->uniqueId().asInt64());
1535 }
1536 }
1537 sbuf->setMode(ISerializer::ModeReserve);
1538
1539 sbuf->reserve(DT_Int64,1); // nb_item_family
1540 for (const auto& family: item_families)
1541 sbuf->reserve(family->name()); // ItemFamily->name
1542 sbuf->reserve(DT_Int64,item_families.size()); // ItemFamily->itemKind
1543
1544 sbuf->reserveArray(item_uids);
1545 sbuf->reserveArray(family_nb_items);
1546 sbuf->reserveArray(item_nb_dest_ranks);
1547 sbuf->reserveArray(item_dest_ranks);
1548
1549 sbuf->allocateBuffer();
1550 sbuf->setMode(ISerializer::ModePut);
1551
1552 sbuf->putInt64(item_families.size());
1553 for (const auto& family: item_families)
1554 sbuf->put(family->name()); // ItemFamily->name
1555 for (const auto& family: item_families)
1556 sbuf->putInteger(family->itemKind()); // ItemFamily->itemKind
1557
1558 sbuf->putArray(item_uids);
1559 sbuf->putArray(family_nb_items);
1560 sbuf->putArray(item_nb_dest_ranks);
1561 sbuf->putArray(item_dest_ranks);
1562 }
1563
1564 sd_exchange->processExchange();
1565
1566 for( Integer i=0, is=recv_sub_domains.size(); i<is; ++i ){
1567 ISerializeMessage* comm = sd_exchange->messageToReceive(i);
1568 ISerializer* sbuf = comm->serializer();
1569 Int64 nb_families = sbuf->getInt64();
1570 StringUniqueArray item_family_names(nb_families);
1571 Int32UniqueArray item_family_kinds(nb_families);
1572 for (auto& family_name: item_family_names)
1573 sbuf->get(family_name); // ItemFamily->name
1574 for (auto& family_kind: item_family_kinds)
1575 family_kind = sbuf->getInteger(); // ItemFamily->itemKind
1576 sbuf->getArray(item_uids);
1577 sbuf->getArray(family_nb_items);
1578 sbuf->getArray(item_nb_dest_ranks);
1579 sbuf->getArray(item_dest_ranks);
1580 Integer item_uid_index = 0;
1581 Integer item_nb_dest_rank_index = 0;
1582 Integer item_dest_rank_index = 0;
1583 for (int family_index = 0; family_index < nb_families; ++family_index) {
1584 IItemFamily* family = m_mesh->findItemFamily(eItemKind(item_family_kinds[family_index]),item_family_names[family_index],false);
1585 Int64ArrayView family_item_uids = item_uids.subView(item_uid_index,family_nb_items[family_index]);
1586 Int32UniqueArray item_lids(family_item_uids.size());
1587 family->itemsUniqueIdToLocalId(item_lids,family_item_uids,true);
1588 for (const auto& item_lid : item_lids) {
1589 auto sub_view = item_dest_ranks.subView(item_dest_rank_index,item_nb_dest_ranks[item_nb_dest_rank_index]);
1590 Int32 dest_rank = comm->destination().value();
1591 m_ghost_item_dest_ranks_map[dest_rank][family]->at(item_lid).addRange(sub_view);
1592 item_dest_rank_index+= item_nb_dest_ranks[item_nb_dest_rank_index++];
1593 }
1594 item_uid_index+= family_nb_items[family_index];
1595 }
1596 }
1597// _checkSubItemsDestRanks();
1598}
1599
1600/*---------------------------------------------------------------------------*/
1601/*---------------------------------------------------------------------------*/
1602
1603Integer MeshExchange::
1604_getSubdomainIndexInCommunicatingRanks(Integer rank, Int32ConstArrayView communicating_ranks)
1605{
1606 Integer i = 0;
1607 while (communicating_ranks[i]!=rank) {
1608 ++i;
1609 }
1610 return i;
1611}
1612
1613/*---------------------------------------------------------------------------*/
1614/*---------------------------------------------------------------------------*/
1615
1616ISubDomain* MeshExchange::
1617subDomain() const
1618{
1619 return m_mesh->subDomain();
1620}
1621
1622/*---------------------------------------------------------------------------*/
1623/*---------------------------------------------------------------------------*/
1624
1625} // End namespace Arcane::mesh
1626
1627/*---------------------------------------------------------------------------*/
1628/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_PARTICLE(name, group)
Enumérateur générique d'un groupe de particules.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_EDGE(name, group)
Enumérateur générique d'un groupe d'arêtes.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Vue sur les informations des mailles.
Maille d'un maillage.
Definition Item.h:1178
Cell topHParent() const
parent de niveau 0 pour l'AMR
Definition Item.h:1299
Interface d'une famille d'entités.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
virtual Int32 maxLocalId() const =0
virtual String name() const =0
Nom de la famille.
virtual eItemKind itemKind() const =0
Genre des entités.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable contenant le numéro du nouveau sous-domaine propriétaire de l'entité.
virtual void getCommunicatingSubDomains(Int32Array &sub_domains) const =0
Liste des sous-domaines communiquants pour les entités.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Retourne la famille de nom name.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual ISubDomain * subDomain()=0
Sous-domaine associé
virtual IGhostLayerMng * ghostLayerMng() const =0
Gestionnare de couche fantômes associé
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Interface du réseau de familles (familles connectées)
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
Enumérateur sur une liste typée d'entités de type ItemType.
@ II_NeedRemove
L'entité doit être supprimé
Definition ItemFlags.h:55
Index d'un Item dans une variable.
Definition ItemLocalId.h:40
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:771
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
ConstArrayView< std::set< Int32 > > getItemsToSend(IItemFamily *family) const
Liste par sous-domaine des entités à envoyer pour la famille family.
void computeInfos()
Calcule les infos.
IMesh * m_mesh
Maillage.
ArrayView< std::set< Int32 > > _getItemsToSend(IItemFamily *family)
Liste par sous-domaine des entités à envoyer pour la famille family.
void _printItemToSend(IItemFamily *family)
Utilisant ItemFamilyNetwork.
void _computeMeshConnectivityInfos2(Int32ConstArrayView cells_new_owner)
AMR.
void _computeMeshConnectivityInfos3()
AMR OFF.
bool contains(ConstReferenceType v) const
Vrai si le tableau contient l'élément de valeur v.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
constexpr ArrayView< T > subView(Integer abegin, Integer asize) noexcept
Sous-vue à partir de l'élément abegin et contenant asize éléments.
bool contains(const_reference v) const
true si le tableau contient l'élément de valeur v
ConstReferenceType at(Int64 i) const
Elément d'indice i. Vérifie toujours les débordements.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemEnumeratorT< Node > NodeEnumerator
Enumérateurs sur des noeuds.
Definition ItemTypes.h:254
ItemEnumeratorT< Face > FaceEnumerator
Enumérateurs sur des faces.
Definition ItemTypes.h:265
ItemEnumeratorT< Edge > EdgeEnumerator
Enumérateurs sur des arêtes.
Definition ItemTypes.h:259
ItemEnumeratorT< Cell > CellEnumerator
Enumérateurs sur des mailles.
Definition ItemTypes.h:271
Ref< IParallelExchanger > createExchangerRef(IParallelMng *pm)
Retourne une interface pour transférer des messages entre rangs.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:609
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:327
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:525
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Definition UtilsTypes.h:519
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:611
Int32 Integer
Type représentant un entier.