Arcane  v4.1.9.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
BasicParticleExchanger.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* BasicParticleExchanger.cc (C) 2000-2026 */
9/* */
10/* Echangeur de particules. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/BasicParticleExchanger.h"
15
16#include "arcane/core/internal/SerializeMessage.h"
17
18/*
19 * NOTE :
20 * Dans exchangeItems(), le tableau new_particle_local_ids
21 * n'est valide que si le compactage n'est pas actif pour la famille de
22 * particules (c'est toujours le cas avec l'implémentation actuelle).
23 * Pour qu'il soit valide dans tous les cas, il faudrait lors
24 * de la dé-sérialisation des messages, créer toutes les entités
25 * en une fois, mettre à jour ce tableau \a new_particle_local_ids
26 * et ensuite mettre à jour les variables.
27 */
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane::mesh
32{
33
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38BasicParticleExchanger::
39BasicParticleExchanger(const ServiceBuildInfo& sbi)
40: ArcaneBasicParticleExchangerObject(sbi)
41{
42}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47BasicParticleExchanger::
48~BasicParticleExchanger()
49{
50 // TODO: ne pas lancer d'exception dans le destructeur.
51 if (!m_pending_messages.empty() || !m_waiting_messages.empty())
52 pwarning() << String::format("Pending or waiting messages nb_pending={0} nb_waiting={1}",
53 m_pending_messages.size(),m_waiting_messages.size());
54 delete m_timer;
55}
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
60void BasicParticleExchanger::
61initialize(IItemFamily* item_family)
62{
63 ARCANE_CHECK_POINTER(item_family);
64
65 m_item_family = item_family;
66 m_parallel_mng = item_family->mesh()->parallelMng();
67 m_rank = m_parallel_mng->commRank();
68 m_timer = new Timer(m_parallel_mng->timerMng(),"BasicParticleExchanger",Timer::TimerReal);
69
70 if (options()) {
71 m_max_nb_message_without_reduce = options()->maxNbMessageWithoutReduce();
72 m_support_shmem_variables = options()->supportShmemVariables();
73 }
74
75 info() << "Initialize BasicParticleExchanger family=" << item_family->name();
76 info() << "-- MaxNbMessageWithoutReduce = " << m_max_nb_message_without_reduce;
77 info() << "-- SupportShmemVariables = " << m_support_shmem_variables;
78}
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
83void BasicParticleExchanger::
84_clearMessages()
85{
86 for( auto msg : m_accumulate_infos )
87 delete msg;
88 m_accumulate_infos.clear();
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94void BasicParticleExchanger::
95beginNewExchange(Integer i_nb_particle)
96{
97 _checkInitialized();
98 String function_id = "BasicParticleExchanger::beginNewExchange >>> ";
99 IParallelMng* pm = m_parallel_mng;
100
101 if (options()){
102 m_debug_exchange_items_level = options()->debugExchangeItemsLevel();
103 m_max_nb_message_without_reduce = options()->maxNbMessageWithoutReduce();
104 }
105
106 m_nb_loop = 0;
107 m_last_nb_to_exchange = 0;
108 m_exchange_finished = false;
109 m_print_info = false;
110 m_current_nb_reduce = 0;
111 m_nb_particle_send = 0;
112
113 //TODO: utiliser un tag spécifique pour cet échange.
114 Int64 nb_particle = i_nb_particle;
115 Int64 min_nb_particle = 0;
116 Int64 max_nb_particle = 0;
117 Int64 nb_total_particle = 0;
118 Int32 min_rank = 0;
119 Int32 max_rank = 0;
120 pm->computeMinMaxSum(nb_particle,min_nb_particle,max_nb_particle,
121 nb_total_particle,min_rank,max_rank);
122 //m_nb_total_particle = pm->reduce(Parallel::ReduceSum,nb_particle);
123 if (m_verbose_level>=1)
124 info() << function_id << "** NB PARTICLES IN VOL total=" << nb_total_particle
125 << " min=" << min_nb_particle << " max=" << max_nb_particle
126 << " min_rank=" << min_rank << " max_rank=" << max_rank
127 << " date=" << platform::getCurrentDateTime();
128
129 m_nb_total_particle_finish_exchange = 0;
130
131 // Récupère la liste des variables à transférer.
132 // Il s'agit des variables qui ont la même famille que celle passée
133 // en paramètre.
134 // IMPORTANT: tous les sous-domaines doivent avoir ces mêmes variables
136 m_item_family->usedVariables(m_variables_to_exchange);
137 m_variables_to_exchange.sortByName(true);
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143void BasicParticleExchanger::
144sendItems(Integer nb_particle_finish_exchange,
145 Int32ConstArrayView local_ids,
146 Int32ConstArrayView sub_domains_to_send)
147{
148 ARCANE_UNUSED(nb_particle_finish_exchange);
149
150 m_nb_particle_send = local_ids.size();
151 {
153 _generateSendItems(local_ids,sub_domains_to_send);
154 }
155 info(5) << A_FUNCINFO << "sendItems " << m_timer->lastActivationTime();
156
157 _sendPendingMessages();
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
163bool BasicParticleExchanger::
164exchangeItems(Integer nb_particle_finish_exchange,
165 Int32ConstArrayView local_ids,
166 Int32ConstArrayView sub_domains_to_send,
167 ItemGroup item_group,
168 IFunctor* functor)
169{
170 ++m_nb_loop;
171 sendItems(nb_particle_finish_exchange,local_ids,sub_domains_to_send);
172
173 if (!item_group.null())
174 item_group.clear();
175
176 return _waitMessages(0,item_group,nullptr,functor);
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
182bool BasicParticleExchanger::
183exchangeItems(Integer nb_particle_finish_exchange,
184 Int32ConstArrayView local_ids,
185 Int32ConstArrayView sub_domains_to_send,
186 Int32Array* new_particle_local_ids,
187 IFunctor* functor)
188{
189 ++m_nb_loop;
190 sendItems(nb_particle_finish_exchange,local_ids,sub_domains_to_send);
191
192 if (new_particle_local_ids)
193 new_particle_local_ids->clear();
194
195 return _waitMessages(0,ItemGroup(),new_particle_local_ids,functor);
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201void BasicParticleExchanger::
202_generateSendItems(Int32ConstArrayView local_ids,
203 Int32ConstArrayView sub_domains_to_send)
204{
205 Timer::Phase tphase(subDomain(),TP_Communication);
206
207 IMesh* mesh = m_item_family->mesh();
208
209 String func_name("BasicParticleExchanger::sendItems()");
210
211 Int32UniqueArray communicating_sub_domains;
212 mesh->cellFamily()->getCommunicatingSubDomains(communicating_sub_domains);
213
214 Integer nb_connected_sub_domain = communicating_sub_domains.size();
215 //Integer max_sub_domain_id = 0;
216 UniqueArray< SharedArray<Int32> > ids_to_send(nb_connected_sub_domain);
217 // Infos pour chaque sous-domaine connecté
218 //_clearMessages();
219 m_accumulate_infos.clear();
220 m_accumulate_infos.resize(nb_connected_sub_domain);
221 for( Integer i=0; i<nb_connected_sub_domain; ++i ){
222 m_accumulate_infos[i] = new SerializeMessage(m_rank,communicating_sub_domains[i],
223 ISerializeMessage::MT_Send);
224#if 0
225 // Utile uniquement pour tester le timeout avec blocage
226 if (m_rank==0 && i==0){
227 warning() << " WRONG MESSAGE";
228 ISerializeMessage* sm = new SerializeMessage(m_rank,communicating_sub_domains[i],
229 ISerializeMessage::MT_Recv);
230 m_pending_messages.add(sm);
231 }
232#endif
233 }
234
235 _addItemsToSend(local_ids,sub_domains_to_send,communicating_sub_domains,ids_to_send);
236
237 if (m_debug_exchange_items_level>=1){
238 info() << "-- Subdomain " << m_rank << ". NB to send: " << local_ids.size()
239 << " NB connected subdomain: " << nb_connected_sub_domain;
240 debug() << "NB connected subdomain for " << m_rank << " : " << m_accumulate_infos.size();
241 for( Integer i=0, s=m_accumulate_infos.size(); i<s; ++i ){
242 debug() << "NB for the subdomain " << m_accumulate_infos[i]->destRank()
243 << " " << ids_to_send[i].size();
244 }
245 }
246
247 Int64UniqueArray items_to_send_uid;
248 Int64UniqueArray items_to_send_cells_uid; // Uniquement pour les particules;
249
250 for( Integer j=0; j<nb_connected_sub_domain; ++j ){
251 ISerializeMessage* sm = m_accumulate_infos[j];
252 // En mode bloquant, envoie toujours le message car le destinataire a posté
253 // un message de réception. Sinon, le message n'a besoin d'être envoyé que
254 // s'il contient des particules.
255 _serializeMessage(sm,ids_to_send[j],items_to_send_uid,
256 items_to_send_cells_uid);
257
258 m_pending_messages.add(sm);
259
260 // En mode bloquant, il faut un message de réception par envoie
261 auto* recv_sm = new SerializeMessage(m_rank,sm->destination().value(),
262 ISerializeMessage::MT_Recv);
263 m_pending_messages.add(recv_sm);
264 }
265
266 m_accumulate_infos.clear();
267 // Détruit les entités qui viennent d'être envoyées
268 m_item_family->toParticleFamily()->removeParticles(local_ids);
269 m_item_family->endUpdate();
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
275void BasicParticleExchanger::
276_addItemsToSend(Int32ConstArrayView local_ids,
277 Int32ConstArrayView sub_domains_to_send,
278 Int32ConstArrayView communicating_sub_domains,
279 UniqueArray< SharedArray<Int32> >& ids_to_send)
280{
281 const Int32 debug_exchange_items_level = m_debug_exchange_items_level;
282 Int32 nb_connected_sub_domain = ids_to_send.size();
283 // Cherche pour chaque élément à quel sous-domaine il doit être transféré.
284 // Cette recherche se fait en se basant sur les \a local_ids
285 Int32 id_size = local_ids.size();
286 for( Integer i=0; i<id_size; ++i ){
287 Int32 item_local_id = local_ids[i];
288 Int32 sd_to_send = sub_domains_to_send[i];
289 if (sd_to_send==m_rank)
290 // Il s'agit d'une entité propre à ce sous-domaine
291 ARCANE_FATAL("The entity with local index {0} should not be sent to its own subdomain",
292 item_local_id);
293 // Recherche l'index du sous-domaine auquel l'entité appartient
294 // dans la liste \a sync_list
295 // TODO: utiliser une table indirect (tableau alloué au nombre de sous-domaines)
296 Integer sd_index = nb_connected_sub_domain;
297 for( Integer i_sd=0; i_sd<nb_connected_sub_domain; ++i_sd )
298 if (sd_to_send==communicating_sub_domains[i_sd]){
299 sd_index = i_sd;
300 break;
301 }
302 if (sd_index==nb_connected_sub_domain)
303 ARCANE_FATAL("Internal: bad rank index");
304 ids_to_send[sd_index].add(item_local_id);
305 if (debug_exchange_items_level>=1)
306 pinfo() << "ADD ITEM TO SEND lid=" << item_local_id << " sd_index=" << sd_index
307 << " sd=" << communicating_sub_domains[sd_index] << " n=" << ids_to_send[sd_index].size()
308 << " begin=" << ids_to_send[sd_index].data();
309 }
310 if (debug_exchange_items_level>=1)
311 for( Integer i=0; i<nb_connected_sub_domain; ++i )
312 pinfo() << "SEND INFO sd_index=" << i
313 << " sd=" << communicating_sub_domains[i] << " n=" << ids_to_send[i].size()
314 << " begin=" << ids_to_send[i].data();
315
316 if ((debug_exchange_items_level>=1 && m_print_info) || debug_exchange_items_level>=2){
317 IParallelMng* pm = m_parallel_mng;
318 Int32 rank = pm->commRank();
319 ParticleInfoListView items(m_item_family);
320 Integer nb_print = math::min(5,id_size);
321 for( Integer i=0; i<nb_print; ++i ){
322 Particle part(items[local_ids[i]]);
323 pinfo() << " RANK=" << rank << " LID=" << local_ids[i] << " SD=" << sub_domains_to_send[i]
324 << " uid=" << part.uniqueId() << " cell=" << ItemPrinter(part.cell());
325 }
326 pm->barrier();
327 }
328}
329
330/*---------------------------------------------------------------------------*/
331/*---------------------------------------------------------------------------*/
332
333bool BasicParticleExchanger::
334waitMessages(Integer nb_pending_particle,Int32Array* new_particle_local_ids,IFunctor* functor)
335{
336 return _waitMessages(nb_pending_particle,ItemGroup(),new_particle_local_ids,functor);
337}
338
339/*---------------------------------------------------------------------------*/
340/*---------------------------------------------------------------------------*/
341
342bool BasicParticleExchanger::
343_waitMessages(Integer nb_pending_particle,ItemGroup item_group,
344 Int32Array* new_particle_local_ids,IFunctor* functor)
345{
346 String func_name = "BasicParticleExchanger::waitMessages";
347 _waitMessages(item_group,new_particle_local_ids,functor);
348
349 bool do_reduce = m_current_nb_reduce>m_last_nb_reduce;
350 if (m_max_nb_message_without_reduce!=(-1))
351 do_reduce |= m_current_nb_reduce>m_max_nb_message_without_reduce;
352
353 if (do_reduce){
354 Int64 nb_to_exchange = 0;
355 IParallelMng* pm = m_parallel_mng;
356 {
357 Timer::Sentry ts(m_timer);
358 Int64 current_exchange = m_nb_particle_send+nb_pending_particle;
359 nb_to_exchange = pm->reduce(Parallel::ReduceSum,current_exchange);
360 }
361 info(4) << func_name << "TimeReduce=" << m_timer->lastActivationTime()
362 << " nbtoexchange=" << nb_to_exchange;
363 m_exchange_finished = (nb_to_exchange==0);
364 if (nb_to_exchange>0 && m_last_nb_to_exchange==nb_to_exchange && m_nb_loop>300){
365 m_print_info = true;
366 }
367 m_last_nb_to_exchange = nb_to_exchange;
368 }
369
370 ++m_current_nb_reduce;
371 debug() << func_name << " ** RETURN EXCHANGE m_exchange_finished: " << m_exchange_finished;
372 if (m_exchange_finished){
373 m_last_nb_reduce = m_current_nb_reduce - 4;
374 if (m_verbose_level>=1)
375 info() << func_name << " exchange finished "
376 << " n=" << m_current_nb_reduce
377 << " date=" << platform::getCurrentDateTime();
378 }
379 return m_exchange_finished;
380}
381
382/*---------------------------------------------------------------------------*/
383/*---------------------------------------------------------------------------*/
384
385void BasicParticleExchanger::
386_waitMessages(ItemGroup item_group,Int32Array* new_particle_local_ids,IFunctor* functor)
387{
388 if (functor){
389 {
390 Timer::Sentry ts(m_timer);
391 functor->executeFunctor();
392 }
393 m_total_time_functor += m_timer->lastActivationTime();
394 if (m_debug_exchange_items_level>=1)
395 info() << "TimeFunctor: current=" << m_timer->lastActivationTime()
396 << " total=" << m_total_time_functor;
397 }
398
399 {
400 Timer::Sentry ts(m_timer);
401 m_message_list->waitMessages(Parallel::WaitAll);
402 }
403 m_total_time_waiting += m_timer->lastActivationTime();
404 if (m_debug_exchange_items_level>=1)
405 info() << "TimeWaiting: current=" << m_timer->lastActivationTime()
406 << " total=" << m_total_time_waiting;
407
408 // Sauve les communications actuellements traitées car le traitement
409 // peut en ajouter de nouvelles
410 UniqueArray<ISerializeMessage*> current_messages(m_waiting_messages);
411 m_waiting_messages.clear();
412
413 Int32 nb_end_update = 0;
414 Int32 max_nb_messages = 0;
415 if (m_support_shmem_variables) {
416 max_nb_messages = m_parallel_mng->reduce(MessagePassing::ReduceMax, current_messages.size());
417 }
418
419 Int64UniqueArray items_to_create_unique_id;
420 Int64UniqueArray items_to_create_cells_unique_id;
421 Int32UniqueArray items_to_create_local_id;
422 Int32UniqueArray items_to_create_cells_local_id;
423 for (ISerializeMessage* sm : current_messages) {
424 if (!sm->isSend()) {
425 _deserializeMessage(sm,items_to_create_unique_id,items_to_create_cells_unique_id,
426 items_to_create_local_id,items_to_create_cells_local_id,
427 item_group,new_particle_local_ids);
428 nb_end_update++;
429 }
430 delete sm;
431 }
432
433 if (m_support_shmem_variables) {
434 for (; nb_end_update < max_nb_messages; ++nb_end_update) {
435 m_item_family->endUpdate();
436 }
437 }
438
439 if (!m_waiting_messages.empty())
440 ARCANE_FATAL("Pending messages n={0}",m_waiting_messages.size());
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
446void BasicParticleExchanger::
447_sendPendingMessages()
448{
449 IParallelMng* pm = m_parallel_mng;
450
451 if (!m_message_list.get())
452 m_message_list = pm->createSerializeMessageListRef();
453
454 {
455 Timer::Sentry ts(m_timer);
456 // Ajoute les messages en attente de traitement
457 Integer nb_message = m_pending_messages.size();
458 for( Integer i=0; i<nb_message; ++i ){
459 m_message_list->addMessage(m_pending_messages[i]);
460 m_waiting_messages.add(m_pending_messages[i]);
461 }
462 m_message_list->processPendingMessages();
463 m_pending_messages.clear();
464 }
465}
466
467/*---------------------------------------------------------------------------*/
468/*---------------------------------------------------------------------------*/
469
470void BasicParticleExchanger::
471_serializeMessage(ISerializeMessage* sm,
472 Int32ConstArrayView acc_ids,
473 Int64Array& items_to_send_uid,
474 Int64Array& items_to_send_cells_uid)
475{
476 ParticleInfoListView internal_items(m_item_family);
477
478 ISerializer* sbuf = sm->serializer();
479 sbuf->setMode(ISerializer::ModeReserve);
480
481 //for( Integer j=0; j<nb_connected_sub_domain; ++j ){
482 //ConstArrayView<Integer> acc_ids = m_ids_to_send[j];
483 Integer nb_item = acc_ids.size();
484 // Réserve pour le type de message
485 //sbuf->reserveInteger(1);
486 // Réserve pour l'id du message
487 sbuf->reserveInt64(1);
488 // Réserve pour le nombre de uniqueId()
489 sbuf->reserveInt64(1);
490 sbuf->reserveSpan(eBasicDataType::Int64,nb_item);
491 // Réserve pour les uniqueId() des mailles dans lesquelles se trouvent les particules
492 //sbuf->reserve(DT_Size,1);
493 sbuf->reserveSpan(eBasicDataType::Int64,nb_item);
494
495 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
496 IVariable* var = *i_var;
497 var->serialize(sbuf,acc_ids);
498 }
499
500 // Sérialise les données en écriture
501 sbuf->allocateBuffer();
502
503 if (m_debug_exchange_items_level>=1)
504 info() << "BSE_SerializeMessage nb_item=" << nb_item
505 << " id=" << m_serialize_id
506 << " dest=" << sm->destination();
507
508 sbuf->setMode(ISerializer::ModePut);
509
510 sbuf->putInt64(m_serialize_id);
511 ++m_serialize_id;
512
513 sbuf->putInt64(nb_item);
514 items_to_send_uid.resize(nb_item);
515 items_to_send_cells_uid.resize(nb_item);
516 for( Integer z=0; z<nb_item; ++z ){
517 Particle item = internal_items[acc_ids[z]];
518 items_to_send_uid[z] = item.uniqueId();
519 bool has_cell = item.hasCell();
520 items_to_send_cells_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
521 if (m_debug_exchange_items_level>=2){
522 info() << "Particle BufID=" << acc_ids[z]
523 << " LID=" << item.localId()
524 << " UID=" << items_to_send_uid[z]
525 << " CellIUID=" << items_to_send_cells_uid[z]
526 << " (owner=" << item.cell().owner() << ")";
527 }
528 }
529 sbuf->putSpan(items_to_send_uid);
530 sbuf->putSpan(items_to_send_cells_uid);
531
532 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
533 IVariable* var = *i_var;
534 var->serialize(sbuf,acc_ids);
535 }
536
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
542void BasicParticleExchanger::
543_deserializeMessage(ISerializeMessage* message,
544 Int64Array& items_to_create_unique_id,
545 Int64Array& items_to_create_cells_unique_id,
546 Int32Array& items_to_create_local_id,
547 Int32Array& items_to_create_cells_local_id,
548 ItemGroup item_group,
549 Int32Array* new_particle_local_ids)
550{
551
552 IMesh* mesh = m_item_family->mesh();
553 ISerializer* sbuf = message->serializer();
554 IItemFamily* cell_family = mesh->cellFamily();
555
556 // Indique qu'on souhaite sérialiser les données en lecture
557 sbuf->setMode(ISerializer::ModeGet);
558 sbuf->setReadMode(ISerializer::ReadReplace);
559
560 {
561 Int64 serialize_id = sbuf->getInt64();
562 Int64 nb_item = sbuf->getInt64();
563 if (m_debug_exchange_items_level>=1)
564 info() << "BSE_DeserializeMessage id=" << serialize_id << " nb=" << nb_item
565 << " orig=" << message->destination();
566
567 items_to_create_local_id.resize(nb_item);
568 items_to_create_unique_id.resize(nb_item);
569 items_to_create_cells_unique_id.resize(nb_item);
570 items_to_create_cells_local_id.resize(nb_item);
571 sbuf->getSpan(items_to_create_unique_id);
572 sbuf->getSpan(items_to_create_cells_unique_id);
573 if (m_debug_exchange_items_level>=2){
574 //info() << "Recv from SID " << sync_infos[i].subDomain() << " N=" << nb_item;
575 for( Integer z=0; z<nb_item; ++z ){
576 info() << "Particle UID=" << items_to_create_unique_id[z]
577 << " CellIUID=" << items_to_create_cells_unique_id[z];
578 }
579 }
580
581 items_to_create_cells_local_id.resize(nb_item);
582 cell_family->itemsUniqueIdToLocalId(items_to_create_cells_local_id,items_to_create_cells_unique_id);
583
584 m_item_family->toParticleFamily()->addParticles(items_to_create_unique_id,
585 items_to_create_cells_local_id,
586 items_to_create_local_id);
587
588 // Notifie la famille qu'on a fini nos modifs.
589 // Après appel à cette méthode, les variables sont à nouveau utilisables
590 m_item_family->endUpdate();
591
592 // Converti les uniqueId() récupérée en localId() et pour les particules
593 // renseigne la maille correspondante
594 ParticleInfoListView internal_items(m_item_family);
595
596 for( Integer z=0; z<nb_item; ++z ){
597 Particle item = internal_items[items_to_create_local_id[z]];
598 //item.setCell( internal_cells[items_to_create_cells_local_id[z]] );
599 // Je suis le nouveau propriétaire (TODO: ne pas faire ici)
600 item.mutableItemBase().setOwner(m_rank,m_rank);
601 }
602 if (!item_group.null())
603 item_group.addItems(items_to_create_local_id,false);
604 if (new_particle_local_ids)
605 new_particle_local_ids->addRange(items_to_create_local_id);
606 for( VariableCollection::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
607 IVariable* var = *i_var;
608 var->serialize(sbuf,items_to_create_local_id);
609 }
610 }
611}
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
616void BasicParticleExchanger::
617reset()
618{
619 if (!m_waiting_messages.empty())
620 ARCANE_FATAL("waiting parallel requests");
621 _clearMessages();
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627void BasicParticleExchanger::
628addNewParticles(Integer nb_particle)
629{
630 ARCANE_UNUSED(nb_particle);
631 throw NotImplementedException(A_FUNCINFO);
632}
633
634/*---------------------------------------------------------------------------*/
635/*---------------------------------------------------------------------------*/
636
637void BasicParticleExchanger::
638_checkInitialized()
639{
640 if (!m_item_family)
641 ARCANE_FATAL("method initialized() not called");
642 _clearMessages();
643}
644
645/*---------------------------------------------------------------------------*/
646/*---------------------------------------------------------------------------*/
647
648ARCANE_REGISTER_SERVICE_BASICPARTICLEEXCHANGER(BasicParticleExchanger,BasicParticleExchanger);
649
651 BasicParticleExchanger);
652
653/*---------------------------------------------------------------------------*/
654/*---------------------------------------------------------------------------*/
655
656} // End namespace Arcane::mesh
657
658/*---------------------------------------------------------------------------*/
659/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Integer size() const
Nombre d'éléments du vecteur.
CaseOptionsBasicParticleExchanger * options() const
Options du jeu de données du service.
void clear()
Supprime les éléments du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual String name() const =0
Nom de la famille.
virtual IMesh * mesh() const =0
Maillage associé
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void computeMinMaxSum(char val, char &min_val, char &max_val, char &sum_val, Int32 &min_rank, Int32 &max_rank)=0
Calcule en une opération la somme, le min, le max d'une valeur.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Ref< ISerializeMessageList > createSerializeMessageListRef()=0
Créé une liste pour gérer les 'ISerializeMessage'.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Interface d'un échangeur de particules.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
void clear()
Supprime les entités du groupe.
Definition ItemGroup.cc:429
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Interface d'un message de sérialisation entre IMessagePassingMng.
Exception lorsqu'une fonction n'est pas implémentée.
Message utilisant un SerializeBuffer.
Chaîne de caractères unicode.
Positionne la phase de l'action en cours d'exécution.
Definition Timer.h:128
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
VariableList m_variables_to_exchange
Liste des variables à échanger.
void sendItems(Integer nb_particle_finish_exchange, Int32ConstArrayView local_ids, Int32ConstArrayView sub_domains_to_send) override
@ ReduceSum
Somme des valeurs.
ARCCORE_BASE_EXPORT String getCurrentDateTime()
Date et l'heure courante sous la forme ISO 8601.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:339
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:482
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:127
std::int32_t Int32
Type entier signé sur 32 bits.