Arcane  v3.16.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ItemsOwnerBuilder.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/* ItemsOwnerBuilder.cc (C) 2000-2025 */
9/* */
10/* Classe pour calculer les propriétaires des entités. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/ItemsOwnerBuilder.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/SmallArray.h"
19#include "arcane/utils/TraceAccessor.h"
20#include "arcane/utils/HashTableMap2.h"
21#include "arcane/utils/ValueConvert.h"
22
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/ParallelMngUtils.h"
25#include "arcane/core/IParallelExchanger.h"
26#include "arcane/core/ISerializeMessage.h"
27#include "arcane/core/ISerializer.h"
28
29#include "arcane/parallel/BitonicSortT.H"
30
31#include "arcane/mesh/ItemInternalMap.h"
32#include "arcane/mesh/NodeFamily.h"
33#include "arcane/mesh/EdgeFamily.h"
34#include "arcane/mesh/DynamicMesh.h"
35
36#include <unordered_set>
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41namespace Arcane::mesh
42{
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46/*
47 * Ce fichier contient un algorithme pour calculer les propriétaires des
48 * entités autres que les mailles à partir des propriétaires des mailles.
49 *
50 * L'algorithme suppose que les propriétaires des mailles sont à jours et
51 * synchronisés. Le propriétaire d'une entité sera alors le propriétaire de
52 * la maille de plus petit uniqueId() connectée à cette entité.
53 *
54 * En parallèle, si une entité est à la frontière d'un sous-domaine, il n'est
55 * pas possible de connaitre toutes les mailles qui y sont connectées.
56 * Pour résoudre ce problème, on crée une liste des entités de la frontière
57 * contenant pour chaque maille connectée un triplet (uniqueId() de l'entité,
58 * uniqueId() de la maille connectée, owner() de la maille connectées).
59 * Cette liste est ensuite triée en parallèle (via BitonicSort) par uniqueId()
60 * de l'entité, puis par uniqueId() de la maille.
61 * Pour déterminer le propriétaire d'une entité, il suffit ensuite de prendre
62 * le propriétaire de la maille associée à la première occurrence de l'entité
63 * dans cette liste triée. Une fois ceci fait, on renvoie aux rangs qui possèdent
64 * cette entité cette information.
65 */
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
71class ItemsOwnerBuilderImpl
72: public TraceAccessor
73{
75
87 class ItemOwnerInfo
88 {
89 public:
90
91 ItemOwnerInfo() = default;
92 ItemOwnerInfo(Int64 item_uid, Int64 first_node_uid, Int64 cell_uid, Int32 sender_rank, Int32 cell_owner)
93 : m_item_uid(item_uid)
94 , m_first_node_uid(first_node_uid)
95 , m_cell_uid(cell_uid)
96 , m_item_sender_rank(sender_rank)
97 , m_cell_owner(cell_owner)
98 {
99 }
100
101 public:
102
104 Int64 m_item_uid = NULL_ITEM_UNIQUE_ID;
106 Int64 m_first_node_uid = NULL_ITEM_UNIQUE_ID;
108 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
112 Int32 m_cell_owner = A_NULL_RANK;
113 };
114
115 public:
116
117 explicit ItemsOwnerBuilderImpl(IMesh* mesh);
118
119 public:
120
121 void computeFacesOwner();
122 void computeEdgesOwner();
123 void computeNodesOwner();
124
125 private:
126
127 DynamicMesh* m_mesh = nullptr;
128 Int32 m_verbose_level = 0;
129 UniqueArray<ItemOwnerInfo> m_items_owner_info;
130
131 private:
132
133 void _sortInfos();
134 void _processSortedInfos(ItemInternalMap& items_map);
135};
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
144{
145 public:
146
147 static bool compareLess(const ItemOwnerInfo& k1, const ItemOwnerInfo& k2)
148 {
150 return true;
152 return false;
153
154 if (k1.m_item_uid < k2.m_item_uid)
155 return true;
156 if (k1.m_item_uid > k2.m_item_uid)
157 return false;
158
159 if (k1.m_cell_uid < k2.m_cell_uid)
160 return true;
161 if (k1.m_cell_uid > k2.m_cell_uid)
162 return false;
163
165 return true;
167 return false;
168
169 // ke.node2_uid == k2.node2_uid
170 return (k1.m_cell_owner < k2.m_cell_owner);
171 }
172
174 {
175 const ItemOwnerInfo* fsi_base = values.data();
176 return pm->send(ByteConstArrayView(messageSize(values), reinterpret_cast<const Byte*>(fsi_base)), rank, false);
177 }
178 static Parallel::Request recv(IParallelMng* pm, Int32 rank, ArrayView<ItemOwnerInfo> values)
179 {
180 ItemOwnerInfo* fsi_base = values.data();
181 return pm->recv(ByteArrayView(messageSize(values), reinterpret_cast<Byte*>(fsi_base)), rank, false);
182 }
183 static Integer messageSize(ConstArrayView<ItemOwnerInfo> values)
184 {
185 return CheckedConvert::toInteger(values.size() * sizeof(ItemOwnerInfo));
186 }
187 static ItemOwnerInfo maxValue()
188 {
189 return ItemOwnerInfo(INT64_MAX, INT64_MAX, INT64_MAX, INT32_MAX, INT32_MAX);
190 }
191 static bool isValid(const ItemOwnerInfo& fsi)
192 {
193 return fsi.m_item_uid != INT64_MAX;
194 }
195};
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
202
203ItemsOwnerBuilderImpl::
204ItemsOwnerBuilderImpl(IMesh* mesh)
206{
207 DynamicMesh* dm = dynamic_cast<DynamicMesh*>(mesh);
208 if (!dm)
209 ARCANE_FATAL("Mesh is not an instance of 'DynamicMesh'");
210 m_mesh = dm;
211 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ITEMS_OWNER_BUILDER_IMPL_DEBUG_LEVEL", true))
212 m_verbose_level = v.value();
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218void ItemsOwnerBuilderImpl::
219computeFacesOwner()
220{
221 m_items_owner_info.clear();
222
223 IParallelMng* pm = m_mesh->parallelMng();
224 const Int32 my_rank = pm->commRank();
225 ItemInternalMap& faces_map = m_mesh->facesMap();
226 FaceFamily& face_family = m_mesh->trueFaceFamily();
227
228 info() << "** BEGIN ComputeFacesOwner nb_face=" << faces_map.count();
229
230 // Parcours toutes les faces.
231 // Ne garde que celles qui sont frontières ou dont les propriétaires des
232 // deux mailles de part et d'autre sont différents de notre sous-domaine.
233 UniqueArray<Int32> faces_to_add;
234 UniqueArray<Int64> faces_to_add_uid;
235 faces_map.eachItem([&](Face face) {
236 Int32 nb_cell = face.nbCell();
237 if (nb_cell == 2)
238 if (face.cell(0).owner() == my_rank && face.cell(1).owner() == my_rank) {
239 face.mutableItemBase().setOwner(my_rank, my_rank);
240 return;
241 }
242 faces_to_add.add(face.localId());
243 faces_to_add_uid.add(face.uniqueId());
244 });
245 info() << "ItemsOwnerBuilder: NB_FACE_TO_TRANSFER=" << faces_to_add.size();
246 const Int32 verbose_level = m_verbose_level;
247
248 FaceInfoListView faces(&face_family);
249 for (Int32 lid : faces_to_add) {
250 Face face(faces[lid]);
251 Int64 face_uid = face.uniqueId();
252 for (Cell cell : face.cells()) {
253 if (verbose_level >= 2)
254 info() << "ADD lid=" << lid << " uid=" << face_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
255 m_items_owner_info.add(ItemOwnerInfo(face_uid, face.node(0).uniqueId(), cell.uniqueId(), my_rank, cell.owner()));
256 }
257 }
258
259 // Tri les instances de ItemOwnerInfo et les place les valeurs triées
260 // dans items_owner_info.
261 _sortInfos();
262 _processSortedInfos(faces_map);
263
264 face_family.notifyItemsOwnerChanged();
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270void ItemsOwnerBuilderImpl::
271computeEdgesOwner()
272{
273 m_items_owner_info.clear();
274
275 IParallelMng* pm = m_mesh->parallelMng();
276 const Int32 my_rank = pm->commRank();
277 ItemInternalMap& edges_map = m_mesh->edgesMap();
278 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
279
280 info() << "** BEGIN ComputeEdgesOwner nb_edge=" << edges_map.count();
281
282 // Parcours toutes les arêtes.
283 // Ne garde que celles qui sont frontières ou dont au moins un des propriétaires des
284 // mailles connectées sont différents de notre sous-domaine.
285 UniqueArray<Int32> edges_to_add;
286 UniqueArray<Int64> edges_to_add_uid;
287 // La force brute ajoute toutes les arêtes.
288 // Cela permet de garantir qu'on calcule bien les propriétaires, même si
289 // on ne sait pas déterminer les arêtes frontìères.
290 // Cela n'est pas optimum, car on envoie aussi nos arêtes internes
291 // alors qu'on est certain qu'on est leur propriétaire.
292 bool do_brute_force = true;
293 edges_map.eachItem([&](Edge edge) {
294 Int32 nb_cell = edge.nbCell();
295 Int32 nb_cell_with_my_rank = 0;
296 for (Cell cell : edge.cells())
297 if (cell.owner() == my_rank)
298 ++nb_cell_with_my_rank;
299 bool do_add = (nb_cell == 1 || (nb_cell != nb_cell_with_my_rank));
300 if (do_add || do_brute_force) {
301 edges_to_add.add(edge.localId());
302 edges_to_add_uid.add(edge.uniqueId());
303 }
304 else
305 edge.mutableItemBase().setOwner(my_rank, my_rank);
306 });
307 info() << "ItemsOwnerBuilder: NB_FACE_TO_TRANSFER=" << edges_to_add.size();
308 const Int32 verbose_level = m_verbose_level;
309
310 EdgeInfoListView edges(&edge_family);
311 for (Int32 lid : edges_to_add) {
312 Edge edge(edges[lid]);
313 Int64 edge_uid = edge.uniqueId();
314 for (Cell cell : edge.cells()) {
315 if (verbose_level >= 2)
316 info() << "ADD lid=" << lid << " uid=" << edge_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
317 m_items_owner_info.add(ItemOwnerInfo(edge_uid, edge.node(0).uniqueId(), cell.uniqueId(), my_rank, cell.owner()));
318 }
319 }
320
321 // Tri les instances de ItemOwnerInfo et les place les valeurs triées
322 // dans items_owner_info.
323 _sortInfos();
324 _processSortedInfos(edges_map);
325
326 edge_family.notifyItemsOwnerChanged();
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
331
332void ItemsOwnerBuilderImpl::
333computeNodesOwner()
334{
335 m_items_owner_info.clear();
336
337 IParallelMng* pm = m_mesh->parallelMng();
338 const Int32 my_rank = pm->commRank();
339 ItemInternalMap& faces_map = m_mesh->facesMap();
340 ItemInternalMap& nodes_map = m_mesh->nodesMap();
341 NodeFamily& node_family = m_mesh->trueNodeFamily();
342
343 info() << "** BEGIN ComputeNodesOwner nb_node=" << nodes_map.count();
344
345 // Place par défaut tous les noeuds dans ce sous-domaine
346 nodes_map.eachItem([&](Node node) {
347 node.mutableItemBase().setOwner(my_rank, my_rank);
348 });
349
350 // Parcours toutes les faces.
351 // Ne garde que celles qui sont frontières ou dont les propriétaires des
352 // deux mailles de part et d'autre sont différents de notre sous-domaine.
353 //UniqueArray<Int32> faces_to_add;
354 //faces_map.eachItem([&](Face face) {
355 //Int32 nb_cell = face.nbCell();
356 // if (nb_cell == 1)
357 // faces_to_add.add(face.localId());
358 //});
359 //info() << "ItemsOwnerBuilder: NB_FACE_TO_ADD=" << faces_to_add.size();
360 const Int32 verbose_level = m_verbose_level;
361
362 // Ajoute tous les noeuds des faces frontières.
363 std::unordered_set<Int32> done_nodes;
364
365 FaceInfoListView faces(m_mesh->faceFamily());
366 UniqueArray<Int32> nodes_to_add;
367 faces_map.eachItem([&](Face face) {
368 Int32 face_nb_cell = face.nbCell();
369 if (face_nb_cell == 2)
370 return;
371 for (Node node : face.nodes()) {
372 Int32 node_id = node.localId();
373 if (done_nodes.find(node_id) == done_nodes.end()) {
374 nodes_to_add.add(node_id);
375 done_nodes.insert(node_id);
376 node.mutableItemBase().setOwner(A_NULL_RANK, my_rank);
377 }
378 }
379 });
380
381 info() << "ItemsOwnerBuilder: NB_NODE_TO_ADD=" << nodes_to_add.size();
382 NodeInfoListView nodes(&node_family);
383 for (Int32 lid : nodes_to_add) {
384 Node node(nodes[lid]);
385 Int64 node_uid = node.uniqueId();
386 for (Cell cell : node.cells()) {
387 if (verbose_level >= 2)
388 info() << "ADD lid=" << lid << " uid=" << node_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
389 m_items_owner_info.add(ItemOwnerInfo(node_uid, node_uid, cell.uniqueId(), my_rank, cell.owner()));
390 }
391 }
392
393 // Tri les instances de ItemOwnerInfo et les place les valeurs triées
394 // dans items_owner_info.
395 _sortInfos();
396 _processSortedInfos(nodes_map);
397
398 node_family.notifyItemsOwnerChanged();
399}
400
401/*---------------------------------------------------------------------------*/
402/*---------------------------------------------------------------------------*/
409{
410 IParallelMng* pm = m_mesh->parallelMng();
411 const Int32 verbose_level = m_verbose_level;
413 items_sorter.setNeedIndexAndRank(false);
414 Real sort_begin_time = platform::getRealTime();
415 items_sorter.sort(m_items_owner_info);
416 Real sort_end_time = platform::getRealTime();
417 m_items_owner_info = items_sorter.keys();
418 info() << "END_ALL_ITEM_OWNER_SORTER time=" << (Real)(sort_end_time - sort_begin_time);
419 if (verbose_level >= 2)
420 for (const ItemOwnerInfo& x : m_items_owner_info) {
421 info() << "Sorted first_node_uid=" << x.m_first_node_uid << " item_uid="
422 << x.m_item_uid << " cell_uid=" << x.m_cell_uid << " owner=" << x.m_cell_owner;
423 }
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429void ItemsOwnerBuilderImpl::
430_processSortedInfos(ItemInternalMap& items_map)
431{
432 IParallelMng* pm = m_mesh->parallelMng();
433 const Int32 my_rank = pm->commRank();
434 const Int32 nb_rank = pm->commSize();
435 ConstArrayView<ItemOwnerInfo> items_owner_info = m_items_owner_info;
436 Int32 nb_sorted = items_owner_info.size();
437 info() << "NbSorted=" << nb_sorted;
438 const bool is_last_rank = ((my_rank + 1) == nb_rank);
439 const bool is_first_rank = (my_rank == 0);
440 const Int32 verbose_level = m_verbose_level;
441
442 // Comme les informations d'une entité peuvent être réparties sur plusieurs rangs
443 // après le tri, chaque rang envoie au rang suivant les informations
444 // de la dernière entité de sa liste.
445 // Il faut faire attention à bien envoyer la liste dans le même ordre trié pour
446 // garantir la cohérence car on va prendre le premier élément de la liste pour
447 // positionner le propriétaire.
448
449 UniqueArray<ItemOwnerInfo> items_owner_info_send_to_next;
450 if (nb_sorted > 0 && !is_last_rank) {
451 Int32 send_index = nb_sorted;
452 Int64 last_uid = items_owner_info[nb_sorted - 1].m_item_uid;
453 for (Int32 i = (nb_sorted - 1); i >= 0; --i) {
454 const ItemOwnerInfo& x = items_owner_info[i];
455 if (x.m_item_uid != last_uid) {
456 send_index = i + 1;
457 break;
458 }
459 }
460 info() << "SendIndext=" << send_index << " nb_sorted=" << nb_sorted;
461 for (Int32 i = send_index; i < nb_sorted; ++i) {
462 const ItemOwnerInfo& x = items_owner_info[i];
463 items_owner_info_send_to_next.add(x);
464 if (verbose_level >= 2)
465 info() << "AddSendToNext item_uid=" << x.m_item_uid << " owner=" << x.m_cell_owner
466 << " from_rank=" << x.m_item_sender_rank << " index=" << i;
467 }
468 }
469 Int32 nb_send_to_next = items_owner_info_send_to_next.size();
470 info() << "NbSendToNext=" << nb_send_to_next;
471
472 Int32 nb_to_receive_from_previous = 0;
473 SmallArray<Parallel::Request> requests;
474 // Envoie et recoit les tailles des tableaux
475 if (!is_last_rank)
476 requests.add(pm->send(ConstArrayView<Int32>(1, &nb_send_to_next), my_rank + 1, false));
477 if (!is_first_rank)
478 requests.add(pm->recv(ArrayView<Int32>(1, &nb_to_receive_from_previous), my_rank - 1, false));
479
480 pm->waitAllRequests(requests);
481 requests.clear();
482
483 // Envoie le tableau au suivant et récupère celui du précédent.
484 UniqueArray<ItemOwnerInfo> items_owner_info_received_from_previous(nb_to_receive_from_previous);
485 if (!is_last_rank)
486 requests.add(ItemOwnerInfoSortTraits::send(pm, my_rank + 1, items_owner_info_send_to_next));
487 if (!is_first_rank)
488 requests.add(ItemOwnerInfoSortTraits::recv(pm, my_rank - 1, items_owner_info_received_from_previous));
489 pm->waitAllRequests(requests);
490
491 // Supprime de la liste les entités qu'on a envoyé au suivant
492 m_items_owner_info.resize(nb_sorted - nb_send_to_next);
493 items_owner_info = m_items_owner_info.view();
494 nb_sorted = items_owner_info.size();
495 info() << "NbRemaining=" << nb_sorted;
496
497 Int64 current_item_uid = NULL_ITEM_UNIQUE_ID;
498 Int32 current_item_owner = A_NULL_RANK;
499
500 // Parcours la liste des entités qu'on a recu.
501 // Chaque entité est présente plusieurs fois dans la liste : au moins
502 // une fois par maille connectée à cette entité. Comme cette liste est triée
503 // par uniqueId() croissant de ces mailles, et que c'est la maille de plus
504 // petit uniqueId() qui donne le propriétaire de l'entité, alors le propriétaire
505 // est celui du premier élément de cette liste.
506 // On envoie ensuite à tous les rangs qui possèdent cette entité ce nouveau propriétaire.
507 // Le tableau envoyé contient une liste de couples (item_uid, item_new_owner).
508 impl::HashTableMap2<Int32, UniqueArray<Int64>> resend_items_owner_info_map;
509 for (Int32 index = 0; index < (nb_sorted + nb_to_receive_from_previous); ++index) {
510 const ItemOwnerInfo* first_ioi = nullptr;
511 // Si \a i est inférieur à nb_to_receive_from_previous, on prend
512 // les informations de la liste recue.
513 if (index < nb_to_receive_from_previous)
514 first_ioi = &items_owner_info_received_from_previous[index];
515 else
516 first_ioi = &items_owner_info[index - nb_to_receive_from_previous];
517 Int64 item_uid = first_ioi->m_item_uid;
518
519 // Si l'id courant est différent du précédent, on commence une nouvelle liste.
520 if (item_uid != current_item_uid) {
521 current_item_uid = item_uid;
522 current_item_owner = first_ioi->m_cell_owner;
523 if (verbose_level >= 2)
524 info() << "SetOwner from sorted index=" << index << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
525 }
526 Int32 orig_sender = first_ioi->m_item_sender_rank;
527 UniqueArray<Int64>& send_array = resend_items_owner_info_map[orig_sender];
528 send_array.add(current_item_uid);
529 send_array.add(current_item_owner);
530 if (verbose_level >= 2)
531 info() << "SEND i=" << index << " rank=" << orig_sender << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
532 }
533
534 auto exchanger{ ParallelMngUtils::createExchangerRef(pm) };
535 info() << "NbResendRanks=" << resend_items_owner_info_map.size();
536 for (const auto& [key, value] : resend_items_owner_info_map) {
537 if (verbose_level >= 1)
538 info() << "RESEND_INFO to_rank=" << key << " nb=" << value.size();
539 exchanger->addSender(key);
540 }
541 exchanger->initializeCommunicationsMessages();
542 {
543 Int32 index = 0;
544 for (const auto& [key, value] : resend_items_owner_info_map) {
545 ISerializeMessage* sm = exchanger->messageToSend(index);
546 ++index;
547 ISerializer* s = sm->serializer();
548 s->setMode(ISerializer::ModeReserve);
549 s->reserveArray(value);
550 s->allocateBuffer();
551 s->setMode(ISerializer::ModePut);
552 s->putArray(value);
553 }
554 }
555 exchanger->processExchange();
556 UniqueArray<Int64> receive_info;
557
558 for (Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
559 ISerializeMessage* sm = exchanger->messageToReceive(i);
560 ISerializer* s = sm->serializer();
561 s->setMode(ISerializer::ModeGet);
562 s->getArray(receive_info);
563 Int32 receive_size = receive_info.size();
564 if (verbose_level >= 1)
565 info() << "RECEIVE_INFO size=" << receive_size << " rank2=" << sm->destination();
566 // Vérifie que la taille est un multiple de 2
567 if ((receive_size % 2) != 0)
568 ARCANE_FATAL("Size '{0}' is not a multiple of 2", receive_size);
569 Int32 buf_size = receive_size / 2;
570 for (Int32 z = 0; z < buf_size; ++z) {
571 Int64 item_uid = receive_info[z * 2];
572 Int32 item_owner = CheckedConvert::toInt32(receive_info[(z * 2) + 1]);
573 impl::ItemBase x = items_map.findItem(item_uid);
574 if (verbose_level >= 2)
575 info() << "SetOwner uid=" << item_uid << " new_owner=" << item_owner;
576 x.toMutable().setOwner(item_owner, my_rank);
577 }
578 }
579}
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
584/*---------------------------------------------------------------------------*/
585/*---------------------------------------------------------------------------*/
586
587ItemsOwnerBuilder::
588ItemsOwnerBuilder(IMesh* mesh)
589: m_p(std::make_unique<ItemsOwnerBuilderImpl>(mesh))
590{}
591
592ItemsOwnerBuilder::
593~ItemsOwnerBuilder()
594{
595 // Le destructeur doit être dans le '.cc' car 'ItemsOwnerBuilderImpl' n'est
596 // pas connu dans le '.h'.
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
601
602void ItemsOwnerBuilder::
603computeFacesOwner()
604{
605 m_p->computeFacesOwner();
606}
607
608/*---------------------------------------------------------------------------*/
609/*---------------------------------------------------------------------------*/
610
611void ItemsOwnerBuilder::
612computeEdgesOwner()
613{
614 m_p->computeEdgesOwner();
615}
616
617/*---------------------------------------------------------------------------*/
618/*---------------------------------------------------------------------------*/
619
620void ItemsOwnerBuilder::
621computeNodesOwner()
622{
623 m_p->computeNodesOwner();
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
628
629} // namespace Arcane::mesh
630
631/*---------------------------------------------------------------------------*/
632/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
constexpr const_pointer data() const noexcept
Pointeur sur le début de la vue.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Face d'une maille.
Definition Item.h:952
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1641
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1027
CellConnectedListViewType cells() const
Liste des mailles de la face.
Definition Item.h:1033
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Bloque en attendant que les requêtes rvalues soient terminées.
@ ModePut
Le sérialiseur attend des reserve()
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:782
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:374
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:238
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Requête d'un message.
Definition Request.h:77
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
Algorithme de tri bitonique parallèle.
ConstArrayView< KeyType > keys() const override
Après un tri, retourne la liste des éléments de ce rang.
void sort(ConstArrayView< KeyType > keys) override
Trie en parallèle les éléments de keys sur tous les rangs.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
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).
Implémentation d'un maillage.
Definition DynamicMesh.h:97
IParallelMng * parallelMng() override
Gestionnaire de parallèlisme.
Famille de faces.
Definition FaceFamily.h:53
void notifyItemsOwnerChanged() override
Notifie que les entités propres au sous-domaine de la famille ont été modifiées.
Tableau associatif de ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Retourne l'entité de numéro unique uid.
void eachItem(const Lambda &lambda)
Fonction template pour itérer sur les entités de l'instance.
Int32 count() const
Nombre d'éléments de la table.
Informations sur une entité partagée.
Int32 m_item_sender_rank
rang de celui qui a créé cette instance
Int64 m_first_node_uid
uniqueId() du premier noeud de l'entité
Int32 m_cell_owner
Propriétaire de la maille connectée à cette entité
Int64 m_cell_uid
uniqueId() de la maille à laquelle l'entité appartient
void _sortInfos()
Tri les instances contenues dans m_items_owner_info replace les valeurs triées dans ce même tableau.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
Ref< IParallelExchanger > createExchangerRef(IParallelMng *pm)
Retourne une interface pour transférer des messages entre rangs.
ARCCORE_BASE_EXPORT Real getRealTime()
Temps Real utilisé en secondes.
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:534
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
double Real
Type représentant un réel.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:563
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
std::int32_t Int32
Type entier signé sur 32 bits.