Arcane  v3.16.0.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/DynamicMesh.h"
34
35#include <unordered_set>
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane::mesh
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45/*
46 * Ce fichier contient un algorithme pour calculer les propriétaires des
47 * entités autres que les mailles à partir des propriétaires des mailles.
48 *
49 * L'algorithme suppose que les propriétaires des mailles sont à jours et
50 * synchronisés. Le propriétaire d'une entité sera alors le propriétaire de
51 * la maille de plus petit uniqueId() connectée à cette entité.
52 *
53 * En parallèle, si une entité est à la frontière d'un sous-domaine, il n'est
54 * pas possible de connaitre toutes les mailles qui y sont connectées.
55 * Pour résoudre ce problème, on crée une liste des entités de la frontière
56 * contenant pour chaque maille connectée un triplet (uniqueId() de l'entité,
57 * uniqueId() de la maille connectée, owner() de la maille connectées).
58 * Cette liste est ensuite triée en parallèle (via BitonicSort) par uniqueId()
59 * de l'entité, puis par uniqueId() de la maille.
60 * Pour déterminer le propriétaire d'une entité, il suffit ensuite de prendre
61 * le propriétaire de la maille associée à la première occurrence de l'entité
62 * dans cette liste triée. Une fois ceci fait, on renvoie aux rangs qui possèdent
63 * cette entité cette information.
64 */
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
70class ItemsOwnerBuilderImpl
71: public TraceAccessor
72{
74
86 class ItemOwnerInfo
87 {
88 public:
89
90 ItemOwnerInfo() = default;
91 ItemOwnerInfo(Int64 item_uid, Int64 first_node_uid, Int64 cell_uid, Int32 sender_rank, Int32 cell_owner)
92 : m_item_uid(item_uid)
93 , m_first_node_uid(first_node_uid)
94 , m_cell_uid(cell_uid)
95 , m_item_sender_rank(sender_rank)
96 , m_cell_owner(cell_owner)
97 {
98 }
99
100 public:
101
103 Int64 m_item_uid = NULL_ITEM_UNIQUE_ID;
105 Int64 m_first_node_uid = NULL_ITEM_UNIQUE_ID;
107 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
111 Int32 m_cell_owner = A_NULL_RANK;
112 };
113
114 public:
115
116 explicit ItemsOwnerBuilderImpl(IMesh* mesh);
117
118 public:
119
120 void computeFacesOwner();
121 void computeNodesOwner();
122
123 private:
124
125 DynamicMesh* m_mesh = nullptr;
126 Int32 m_verbose_level = 0;
127 UniqueArray<ItemOwnerInfo> m_items_owner_info;
128
129 private:
130
131 void _sortInfos();
132 void _processSortedInfos(ItemInternalMap& items_map);
133};
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
142{
143 public:
144
145 static bool compareLess(const ItemOwnerInfo& k1, const ItemOwnerInfo& k2)
146 {
148 return true;
150 return false;
151
152 if (k1.m_item_uid < k2.m_item_uid)
153 return true;
154 if (k1.m_item_uid > k2.m_item_uid)
155 return false;
156
157 if (k1.m_cell_uid < k2.m_cell_uid)
158 return true;
159 if (k1.m_cell_uid > k2.m_cell_uid)
160 return false;
161
163 return true;
165 return false;
166
167 // ke.node2_uid == k2.node2_uid
168 return (k1.m_cell_owner < k2.m_cell_owner);
169 }
170
172 {
173 const ItemOwnerInfo* fsi_base = values.data();
174 return pm->send(ByteConstArrayView(messageSize(values), reinterpret_cast<const Byte*>(fsi_base)), rank, false);
175 }
176 static Parallel::Request recv(IParallelMng* pm, Int32 rank, ArrayView<ItemOwnerInfo> values)
177 {
178 ItemOwnerInfo* fsi_base = values.data();
179 return pm->recv(ByteArrayView(messageSize(values), reinterpret_cast<Byte*>(fsi_base)), rank, false);
180 }
181 static Integer messageSize(ConstArrayView<ItemOwnerInfo> values)
182 {
183 return CheckedConvert::toInteger(values.size() * sizeof(ItemOwnerInfo));
184 }
185 static ItemOwnerInfo maxValue()
186 {
187 return ItemOwnerInfo(INT64_MAX, INT64_MAX, INT64_MAX, INT32_MAX, INT32_MAX);
188 }
189 static bool isValid(const ItemOwnerInfo& fsi)
190 {
191 return fsi.m_item_uid != INT64_MAX;
192 }
193};
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201ItemsOwnerBuilderImpl::
202ItemsOwnerBuilderImpl(IMesh* mesh)
204{
205 DynamicMesh* dm = dynamic_cast<DynamicMesh*>(mesh);
206 if (!dm)
207 ARCANE_FATAL("Mesh is not an instance of 'DynamicMesh'");
208 m_mesh = dm;
209 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ITEMS_OWNER_BUILDER_IMPL_DEBUG_LEVEL", true))
210 m_verbose_level = v.value();
211}
212
213/*---------------------------------------------------------------------------*/
214/*---------------------------------------------------------------------------*/
215
216void ItemsOwnerBuilderImpl::
217computeFacesOwner()
218{
219 m_items_owner_info.clear();
220
221 IParallelMng* pm = m_mesh->parallelMng();
222 const Int32 my_rank = pm->commRank();
223 ItemInternalMap& faces_map = m_mesh->facesMap();
224 FaceFamily& face_family = m_mesh->trueFaceFamily();
225
226 info() << "** BEGIN ComputeFacesOwner nb_face=" << faces_map.count();
227
228 // Parcours toutes les faces.
229 // Ne garde que celles qui sont frontières ou dont les propriétaires des
230 // deux mailles de part et d'autre sont différents de notre sous-domaine.
231 UniqueArray<Int32> faces_to_add;
232 UniqueArray<Int64> faces_to_add_uid;
233 faces_map.eachItem([&](Face face) {
234 Int32 nb_cell = face.nbCell();
235 if (nb_cell == 2)
236 if (face.cell(0).owner() == my_rank && face.cell(1).owner() == my_rank) {
237 face.mutableItemBase().setOwner(my_rank, my_rank);
238 return;
239 }
240 faces_to_add.add(face.localId());
241 faces_to_add_uid.add(face.uniqueId());
242 });
243 info() << "ItemsOwnerBuilder: NB_FACE_TO_TRANSFER=" << faces_to_add.size();
244 const Int32 verbose_level = m_verbose_level;
245
246 FaceInfoListView faces(&face_family);
247 for (Int32 lid : faces_to_add) {
248 Face face(faces[lid]);
249 Int64 face_uid = face.uniqueId();
250 for (Cell cell : face.cells()) {
251 if (verbose_level >= 2)
252 info() << "ADD lid=" << lid << " uid=" << face_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
253 m_items_owner_info.add(ItemOwnerInfo(face_uid, face.node(0).uniqueId(), cell.uniqueId(), my_rank, cell.owner()));
254 }
255 }
256
257 // Tri les instances de ItemOwnerInfo et les place les valeurs triées
258 // dans items_owner_info.
259 _sortInfos();
260 _processSortedInfos(faces_map);
261
262 face_family.notifyItemsOwnerChanged();
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
268void ItemsOwnerBuilderImpl::
269computeNodesOwner()
270{
271 m_items_owner_info.clear();
272
273 IParallelMng* pm = m_mesh->parallelMng();
274 const Int32 my_rank = pm->commRank();
275 ItemInternalMap& faces_map = m_mesh->facesMap();
276 ItemInternalMap& nodes_map = m_mesh->nodesMap();
277 NodeFamily& node_family = m_mesh->trueNodeFamily();
278
279 info() << "** BEGIN ComputeNodesOwner nb_node=" << nodes_map.count();
280
281 // Place par défaut tous les noeuds dans ce sous-domaine
282 nodes_map.eachItem([&](Node node) {
283 node.mutableItemBase().setOwner(my_rank, my_rank);
284 });
285
286 // Parcours toutes les faces.
287 // Ne garde que celles qui sont frontières ou dont les propriétaires des
288 // deux mailles de part et d'autre sont différents de notre sous-domaine.
289 //UniqueArray<Int32> faces_to_add;
290 //faces_map.eachItem([&](Face face) {
291 //Int32 nb_cell = face.nbCell();
292 // if (nb_cell == 1)
293 // faces_to_add.add(face.localId());
294 //});
295 //info() << "ItemsOwnerBuilder: NB_FACE_TO_ADD=" << faces_to_add.size();
296 const Int32 verbose_level = m_verbose_level;
297
298 // Ajoute tous les noeuds des faces frontières.
299 std::unordered_set<Int32> done_nodes;
300
301 FaceInfoListView faces(m_mesh->faceFamily());
302 UniqueArray<Int32> nodes_to_add;
303 faces_map.eachItem([&](Face face) {
304 Int32 face_nb_cell = face.nbCell();
305 if (face_nb_cell == 2)
306 return;
307 for (Node node : face.nodes()) {
308 Int32 node_id = node.localId();
309 if (done_nodes.find(node_id) == done_nodes.end()) {
310 nodes_to_add.add(node_id);
311 done_nodes.insert(node_id);
312 node.mutableItemBase().setOwner(A_NULL_RANK, my_rank);
313 }
314 }
315 });
316
317 info() << "ItemsOwnerBuilder: NB_NODE_TO_ADD=" << nodes_to_add.size();
318 NodeInfoListView nodes(&node_family);
319 for (Int32 lid : nodes_to_add) {
320 Node node(nodes[lid]);
321 Int64 node_uid = node.uniqueId();
322 for (Cell cell : node.cells()) {
323 if (verbose_level >= 2)
324 info() << "ADD lid=" << lid << " uid=" << node_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
325 m_items_owner_info.add(ItemOwnerInfo(node_uid, node_uid, cell.uniqueId(), my_rank, cell.owner()));
326 }
327 }
328
329 // Tri les instances de ItemOwnerInfo et les place les valeurs triées
330 // dans items_owner_info.
331 _sortInfos();
332 _processSortedInfos(nodes_map);
333
334 node_family.notifyItemsOwnerChanged();
335}
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
345{
346 IParallelMng* pm = m_mesh->parallelMng();
347 const Int32 verbose_level = m_verbose_level;
349 items_sorter.setNeedIndexAndRank(false);
350 Real sort_begin_time = platform::getRealTime();
351 items_sorter.sort(m_items_owner_info);
352 Real sort_end_time = platform::getRealTime();
353 m_items_owner_info = items_sorter.keys();
354 info() << "END_ALL_ITEM_OWNER_SORTER time=" << (Real)(sort_end_time - sort_begin_time);
355 if (verbose_level >= 2)
356 for (const ItemOwnerInfo& x : m_items_owner_info) {
357 info() << "Sorted first_node_uid=" << x.m_first_node_uid << " item_uid="
358 << x.m_item_uid << " cell_uid=" << x.m_cell_uid << " owner=" << x.m_cell_owner;
359 }
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365void ItemsOwnerBuilderImpl::
366_processSortedInfos(ItemInternalMap& items_map)
367{
368 IParallelMng* pm = m_mesh->parallelMng();
369 const Int32 my_rank = pm->commRank();
370 const Int32 nb_rank = pm->commSize();
371 ConstArrayView<ItemOwnerInfo> items_owner_info = m_items_owner_info;
372 Int32 nb_sorted = items_owner_info.size();
373 info() << "NbSorted=" << nb_sorted;
374 const bool is_last_rank = ((my_rank + 1) == nb_rank);
375 const bool is_first_rank = (my_rank == 0);
376 const Int32 verbose_level = m_verbose_level;
377
378 // Comme les informations d'une entité peuvent être réparties sur plusieurs rangs
379 // après le tri, chaque rang envoie au rang suivant les informations
380 // de la dernière entité de sa liste.
381 // Il faut faire attention à bien envoyer la liste dans le même ordre trié pour
382 // garantir la cohérence car on va prendre le premier élément de la liste pour
383 // positionner le propriétaire.
384
385 UniqueArray<ItemOwnerInfo> items_owner_info_send_to_next;
386 if (nb_sorted > 0 && !is_last_rank) {
387 Int32 send_index = nb_sorted;
388 Int64 last_uid = items_owner_info[nb_sorted - 1].m_item_uid;
389 for (Int32 i = (nb_sorted - 1); i >= 0; --i) {
390 const ItemOwnerInfo& x = items_owner_info[i];
391 if (x.m_item_uid != last_uid) {
392 send_index = i + 1;
393 break;
394 }
395 }
396 info() << "SendIndext=" << send_index << " nb_sorted=" << nb_sorted;
397 for (Int32 i = send_index; i < nb_sorted; ++i) {
398 const ItemOwnerInfo& x = items_owner_info[i];
399 items_owner_info_send_to_next.add(x);
400 if (verbose_level >= 2)
401 info() << "AddSendToNext item_uid=" << x.m_item_uid << " owner=" << x.m_cell_owner
402 << " from_rank=" << x.m_item_sender_rank << " index=" << i;
403 }
404 }
405 Int32 nb_send_to_next = items_owner_info_send_to_next.size();
406 info() << "NbSendToNext=" << nb_send_to_next;
407
408 Int32 nb_to_receive_from_previous = 0;
409 SmallArray<Parallel::Request> requests;
410 // Envoie et recoit les tailles des tableaux
411 if (!is_last_rank)
412 requests.add(pm->send(ConstArrayView<Int32>(1, &nb_send_to_next), my_rank + 1, false));
413 if (!is_first_rank)
414 requests.add(pm->recv(ArrayView<Int32>(1, &nb_to_receive_from_previous), my_rank - 1, false));
415
416 pm->waitAllRequests(requests);
417 requests.clear();
418
419 // Envoie le tableau au suivant et récupère celui du précédent.
420 UniqueArray<ItemOwnerInfo> items_owner_info_received_from_previous(nb_to_receive_from_previous);
421 if (!is_last_rank)
422 requests.add(ItemOwnerInfoSortTraits::send(pm, my_rank + 1, items_owner_info_send_to_next));
423 if (!is_first_rank)
424 requests.add(ItemOwnerInfoSortTraits::recv(pm, my_rank - 1, items_owner_info_received_from_previous));
425 pm->waitAllRequests(requests);
426
427 // Supprime de la liste les entités qu'on a envoyé au suivant
428 m_items_owner_info.resize(nb_sorted - nb_send_to_next);
429 items_owner_info = m_items_owner_info.view();
430 nb_sorted = items_owner_info.size();
431 info() << "NbRemaining=" << nb_sorted;
432
433 Int64 current_item_uid = NULL_ITEM_UNIQUE_ID;
434 Int32 current_item_owner = A_NULL_RANK;
435
436 // Parcours la liste des entités qu'on a recu.
437 // Chaque entité est présente plusieurs fois dans la liste : au moins
438 // une fois par maille connectée à cette entité. Comme cette liste est triée
439 // par uniqueId() croissant de ces mailles, et que c'est la maille de plus
440 // petit uniqueId() qui donne le propriétaire de l'entité, alors le propriétaire
441 // est celui du premier élément de cette liste.
442 // On envoie ensuite à tous les rangs qui possèdent cette entité ce nouveau propriétaire.
443 // Le tableau envoyé contient une liste de couples (item_uid, item_new_owner).
444 impl::HashTableMap2<Int32, UniqueArray<Int64>> resend_items_owner_info_map;
445 for (Int32 index = 0; index < (nb_sorted + nb_to_receive_from_previous); ++index) {
446 const ItemOwnerInfo* first_ioi = nullptr;
447 // Si \a i est inférieur à nb_to_receive_from_previous, on prend
448 // les informations de la liste recue.
449 if (index < nb_to_receive_from_previous)
450 first_ioi = &items_owner_info_received_from_previous[index];
451 else
452 first_ioi = &items_owner_info[index - nb_to_receive_from_previous];
453 Int64 item_uid = first_ioi->m_item_uid;
454
455 // Si l'id courant est différent du précédent, on commence une nouvelle liste.
456 if (item_uid != current_item_uid) {
457 current_item_uid = item_uid;
458 current_item_owner = first_ioi->m_cell_owner;
459 if (verbose_level >= 2)
460 info() << "SetOwner from sorted index=" << index << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
461 }
462 Int32 orig_sender = first_ioi->m_item_sender_rank;
463 UniqueArray<Int64>& send_array = resend_items_owner_info_map[orig_sender];
464 send_array.add(current_item_uid);
465 send_array.add(current_item_owner);
466 if (verbose_level >= 2)
467 info() << "SEND i=" << index << " rank=" << orig_sender << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
468 }
469
470 auto exchanger{ ParallelMngUtils::createExchangerRef(pm) };
471 info() << "NbResendRanks=" << resend_items_owner_info_map.size();
472 for (const auto& [key, value] : resend_items_owner_info_map) {
473 if (verbose_level >= 1)
474 info() << "RESEND_INFO to_rank=" << key << " nb=" << value.size();
475 exchanger->addSender(key);
476 }
477 exchanger->initializeCommunicationsMessages();
478 {
479 Int32 index = 0;
480 for (const auto& [key, value] : resend_items_owner_info_map) {
481 ISerializeMessage* sm = exchanger->messageToSend(index);
482 ++index;
483 ISerializer* s = sm->serializer();
484 s->setMode(ISerializer::ModeReserve);
485 s->reserveArray(value);
486 s->allocateBuffer();
487 s->setMode(ISerializer::ModePut);
488 s->putArray(value);
489 }
490 }
491 exchanger->processExchange();
492 UniqueArray<Int64> receive_info;
493
494 for (Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
495 ISerializeMessage* sm = exchanger->messageToReceive(i);
496 ISerializer* s = sm->serializer();
497 s->setMode(ISerializer::ModeGet);
498 s->getArray(receive_info);
499 Int32 receive_size = receive_info.size();
500 if (verbose_level >= 1)
501 info() << "RECEIVE_INFO size=" << receive_size << " rank2=" << sm->destination();
502 // Vérifie que la taille est un multiple de 2
503 if ((receive_size % 2) != 0)
504 ARCANE_FATAL("Size '{0}' is not a multiple of 2", receive_size);
505 Int32 buf_size = receive_size / 2;
506 for (Int32 z = 0; z < buf_size; ++z) {
507 Int64 item_uid = receive_info[z * 2];
508 Int32 item_owner = CheckedConvert::toInt32(receive_info[(z * 2) + 1]);
509 impl::ItemBase x = items_map.findItem(item_uid);
510 if (verbose_level >= 2)
511 info() << "SetOwner uid=" << item_uid << " new_owner=" << item_owner;
512 x.toMutable().setOwner(item_owner, my_rank);
513 }
514 }
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
520/*---------------------------------------------------------------------------*/
521/*---------------------------------------------------------------------------*/
522
523ItemsOwnerBuilder::
524ItemsOwnerBuilder(IMesh* mesh)
525: m_p(std::make_unique<ItemsOwnerBuilderImpl>(mesh))
526{}
527
528ItemsOwnerBuilder::
529~ItemsOwnerBuilder()
530{
531 // Le destructeur doit être dans le '.cc' car 'ItemsOwnerBuilderImpl' n'est
532 // pas connu dans le '.h'.
533}
534
535/*---------------------------------------------------------------------------*/
536/*---------------------------------------------------------------------------*/
537
538void ItemsOwnerBuilder::
539computeFacesOwner()
540{
541 m_p->computeFacesOwner();
542}
543
544/*---------------------------------------------------------------------------*/
545/*---------------------------------------------------------------------------*/
546
547void ItemsOwnerBuilder::
548computeNodesOwner()
549{
550 m_p->computeNodesOwner();
551}
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
556} // namespace Arcane::mesh
557
558/*---------------------------------------------------------------------------*/
559/*---------------------------------------------------------------------------*/
#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:944
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1633
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1019
CellConnectedListViewType cells() const
Liste des mailles de la face.
Definition Item.h:1025
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:779
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
std::int32_t Int32
Type entier signé sur 32 bits.