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