Arcane  v3.16.0.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-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/* BasicParticleExchanger.cc (C) 2000-2025 */
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
73 info() << "Initialize BasicParticleExchanger family=" << item_family->name();
74 info() << "-- MaxNbMessageWithoutReduce = " << m_max_nb_message_without_reduce;
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80void BasicParticleExchanger::
81_clearMessages()
82{
83 for( auto msg : m_accumulate_infos )
84 delete msg;
85 m_accumulate_infos.clear();
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91void BasicParticleExchanger::
92beginNewExchange(Integer i_nb_particle)
93{
94 _checkInitialized();
95 String function_id = "BasicParticleExchanger::beginNewExchange >>> ";
96 IParallelMng* pm = m_parallel_mng;
97
98 if (options()){
99 m_debug_exchange_items_level = options()->debugExchangeItemsLevel();
100 m_max_nb_message_without_reduce = options()->maxNbMessageWithoutReduce();
101 }
102
103 m_nb_loop = 0;
104 m_last_nb_to_exchange = 0;
105 m_exchange_finished = false;
106 m_print_info = false;
107 m_current_nb_reduce = 0;
108 m_nb_particle_send = 0;
109
110 //TODO: utiliser un tag spécifique pour cet échange.
111 Int64 nb_particle = i_nb_particle;
112 Int64 min_nb_particle = 0;
113 Int64 max_nb_particle = 0;
114 Int64 nb_total_particle = 0;
115 Int32 min_rank = 0;
116 Int32 max_rank = 0;
117 pm->computeMinMaxSum(nb_particle,min_nb_particle,max_nb_particle,
118 nb_total_particle,min_rank,max_rank);
119 //m_nb_total_particle = pm->reduce(Parallel::ReduceSum,nb_particle);
120 if (m_verbose_level>=1)
121 info() << function_id << "** NB PARTICLES IN VOL total=" << nb_total_particle
122 << " min=" << min_nb_particle << " max=" << max_nb_particle
123 << " min_rank=" << min_rank << " max_rank=" << max_rank
124 << " date=" << platform::getCurrentDateTime();
125
126 m_nb_total_particle_finish_exchange = 0;
127
128 // Récupère la liste des variables à transférer.
129 // Il s'agit des variables qui ont la même famille que celle passée
130 // en paramètre.
131 // IMPORTANT: tous les sous-domaines doivent avoir ces mêmes variables
133 m_item_family->usedVariables(m_variables_to_exchange);
134 m_variables_to_exchange.sortByName(true);
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140void BasicParticleExchanger::
141sendItems(Integer nb_particle_finish_exchange,
142 Int32ConstArrayView local_ids,
143 Int32ConstArrayView sub_domains_to_send)
144{
145 ARCANE_UNUSED(nb_particle_finish_exchange);
146
147 m_nb_particle_send = local_ids.size();
148 {
150 _generateSendItems(local_ids,sub_domains_to_send);
151 }
152 info(5) << A_FUNCINFO << "sendItems " << m_timer->lastActivationTime();
153
154 _sendPendingMessages();
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
160bool BasicParticleExchanger::
161exchangeItems(Integer nb_particle_finish_exchange,
162 Int32ConstArrayView local_ids,
163 Int32ConstArrayView sub_domains_to_send,
164 ItemGroup item_group,
165 IFunctor* functor)
166{
167 ++m_nb_loop;
168 sendItems(nb_particle_finish_exchange,local_ids,sub_domains_to_send);
169
170 if (!item_group.null())
171 item_group.clear();
172
173 return _waitMessages(0,item_group,nullptr,functor);
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179bool BasicParticleExchanger::
180exchangeItems(Integer nb_particle_finish_exchange,
181 Int32ConstArrayView local_ids,
182 Int32ConstArrayView sub_domains_to_send,
183 Int32Array* new_particle_local_ids,
184 IFunctor* functor)
185{
186 ++m_nb_loop;
187 sendItems(nb_particle_finish_exchange,local_ids,sub_domains_to_send);
188
189 if (new_particle_local_ids)
190 new_particle_local_ids->clear();
191
192 return _waitMessages(0,ItemGroup(),new_particle_local_ids,functor);
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198void BasicParticleExchanger::
199_generateSendItems(Int32ConstArrayView local_ids,
200 Int32ConstArrayView sub_domains_to_send)
201{
202 Timer::Phase tphase(subDomain(),TP_Communication);
203
204 IMesh* mesh = m_item_family->mesh();
205
206 String func_name("BasicParticleExchanger::sendItems()");
207
208 Int32UniqueArray communicating_sub_domains;
209 mesh->cellFamily()->getCommunicatingSubDomains(communicating_sub_domains);
210
211 Integer nb_connected_sub_domain = communicating_sub_domains.size();
212 //Integer max_sub_domain_id = 0;
213 UniqueArray< SharedArray<Int32> > ids_to_send(nb_connected_sub_domain);
214 // Infos pour chaque sous-domaine connecté
215 //_clearMessages();
216 m_accumulate_infos.clear();
217 m_accumulate_infos.resize(nb_connected_sub_domain);
218 for( Integer i=0; i<nb_connected_sub_domain; ++i ){
219 m_accumulate_infos[i] = new SerializeMessage(m_rank,communicating_sub_domains[i],
220 ISerializeMessage::MT_Send);
221#if 0
222 // Utile uniquement pour tester le timeout avec blocage
223 if (m_rank==0 && i==0){
224 warning() << " WRONG MESSAGE";
225 ISerializeMessage* sm = new SerializeMessage(m_rank,communicating_sub_domains[i],
226 ISerializeMessage::MT_Recv);
227 m_pending_messages.add(sm);
228 }
229#endif
230 }
231
232 _addItemsToSend(local_ids,sub_domains_to_send,communicating_sub_domains,ids_to_send);
233
234 if (m_debug_exchange_items_level>=1){
235 info() << "-- Subdomain " << m_rank << ". NB to send: " << local_ids.size()
236 << " NB connected subdomain: " << nb_connected_sub_domain;
237 debug() << "NB connected subdomain for " << m_rank << " : " << m_accumulate_infos.size();
238 for( Integer i=0, s=m_accumulate_infos.size(); i<s; ++i ){
239 debug() << "NB for the subdomain " << m_accumulate_infos[i]->destRank()
240 << " " << ids_to_send[i].size();
241 }
242 }
243
244 Int64UniqueArray items_to_send_uid;
245 Int64UniqueArray items_to_send_cells_uid; // Uniquement pour les particules;
246
247 for( Integer j=0; j<nb_connected_sub_domain; ++j ){
248 ISerializeMessage* sm = m_accumulate_infos[j];
249 // En mode bloquant, envoie toujours le message car le destinataire a posté
250 // un message de réception. Sinon, le message n'a besoin d'être envoyé que
251 // s'il contient des particules.
252 _serializeMessage(sm,ids_to_send[j],items_to_send_uid,
253 items_to_send_cells_uid);
254
255 m_pending_messages.add(sm);
256
257 // En mode bloquant, il faut un message de réception par envoie
258 auto* recv_sm = new SerializeMessage(m_rank,sm->destination().value(),
259 ISerializeMessage::MT_Recv);
260 m_pending_messages.add(recv_sm);
261 }
262
263 m_accumulate_infos.clear();
264 // Détruit les entités qui viennent d'être envoyées
265 m_item_family->toParticleFamily()->removeParticles(local_ids);
266 m_item_family->endUpdate();
267}
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
272void BasicParticleExchanger::
273_addItemsToSend(Int32ConstArrayView local_ids,
274 Int32ConstArrayView sub_domains_to_send,
275 Int32ConstArrayView communicating_sub_domains,
276 UniqueArray< SharedArray<Int32> >& ids_to_send)
277{
278 const Int32 debug_exchange_items_level = m_debug_exchange_items_level;
279 Int32 nb_connected_sub_domain = ids_to_send.size();
280 // Cherche pour chaque élément à quel sous-domaine il doit être transféré.
281 // Cette recherche se fait en se basant sur les \a local_ids
282 Int32 id_size = local_ids.size();
283 for( Integer i=0; i<id_size; ++i ){
284 Int32 item_local_id = local_ids[i];
285 Int32 sd_to_send = sub_domains_to_send[i];
286 if (sd_to_send==m_rank)
287 // Il s'agit d'une entité propre à ce sous-domaine
288 ARCANE_FATAL("The entity with local index {0} should not be sent to its own subdomain",
289 item_local_id);
290 // Recherche l'index du sous-domaine auquel l'entité appartient
291 // dans la liste \a sync_list
292 // TODO: utiliser une table indirect (tableau alloué au nombre de sous-domaines)
293 Integer sd_index = nb_connected_sub_domain;
294 for( Integer i_sd=0; i_sd<nb_connected_sub_domain; ++i_sd )
295 if (sd_to_send==communicating_sub_domains[i_sd]){
296 sd_index = i_sd;
297 break;
298 }
299 if (sd_index==nb_connected_sub_domain)
300 ARCANE_FATAL("Internal: bad rank index");
301 ids_to_send[sd_index].add(item_local_id);
302 if (debug_exchange_items_level>=1)
303 pinfo() << "ADD ITEM TO SEND lid=" << item_local_id << " sd_index=" << sd_index
304 << " sd=" << communicating_sub_domains[sd_index] << " n=" << ids_to_send[sd_index].size()
305 << " begin=" << ids_to_send[sd_index].data();
306 }
307 if (debug_exchange_items_level>=1)
308 for( Integer i=0; i<nb_connected_sub_domain; ++i )
309 pinfo() << "SEND INFO sd_index=" << i
310 << " sd=" << communicating_sub_domains[i] << " n=" << ids_to_send[i].size()
311 << " begin=" << ids_to_send[i].data();
312
313 if ((debug_exchange_items_level>=1 && m_print_info) || debug_exchange_items_level>=2){
314 IParallelMng* pm = m_parallel_mng;
315 Int32 rank = pm->commRank();
316 ParticleInfoListView items(m_item_family);
317 Integer nb_print = math::min(5,id_size);
318 for( Integer i=0; i<nb_print; ++i ){
319 Particle part(items[local_ids[i]]);
320 pinfo() << " RANK=" << rank << " LID=" << local_ids[i] << " SD=" << sub_domains_to_send[i]
321 << " uid=" << part.uniqueId() << " cell=" << ItemPrinter(part.cell());
322 }
323 pm->barrier();
324 }
325}
326
327/*---------------------------------------------------------------------------*/
328/*---------------------------------------------------------------------------*/
329
330bool BasicParticleExchanger::
331waitMessages(Integer nb_pending_particle,Int32Array* new_particle_local_ids,IFunctor* functor)
332{
333 return _waitMessages(nb_pending_particle,ItemGroup(),new_particle_local_ids,functor);
334}
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
338
339bool BasicParticleExchanger::
340_waitMessages(Integer nb_pending_particle,ItemGroup item_group,
341 Int32Array* new_particle_local_ids,IFunctor* functor)
342{
343 String func_name = "BasicParticleExchanger::waitMessages";
344 _waitMessages(item_group,new_particle_local_ids,functor);
345
346 bool do_reduce = m_current_nb_reduce>m_last_nb_reduce;
347 if (m_max_nb_message_without_reduce!=(-1))
348 do_reduce |= m_current_nb_reduce>m_max_nb_message_without_reduce;
349
350 if (do_reduce){
351 Int64 nb_to_exchange = 0;
352 IParallelMng* pm = m_parallel_mng;
353 {
354 Timer::Sentry ts(m_timer);
355 Int64 current_exchange = m_nb_particle_send+nb_pending_particle;
356 nb_to_exchange = pm->reduce(Parallel::ReduceSum,current_exchange);
357 }
358 info(4) << func_name << "TimeReduce=" << m_timer->lastActivationTime()
359 << " nbtoexchange=" << nb_to_exchange;
360 m_exchange_finished = (nb_to_exchange==0);
361 if (nb_to_exchange>0 && m_last_nb_to_exchange==nb_to_exchange && m_nb_loop>300){
362 m_print_info = true;
363 }
364 m_last_nb_to_exchange = nb_to_exchange;
365 }
366
367 ++m_current_nb_reduce;
368 debug() << func_name << " ** RETURN EXCHANGE m_exchange_finished: " << m_exchange_finished;
369 if (m_exchange_finished){
370 m_last_nb_reduce = m_current_nb_reduce - 4;
371 if (m_verbose_level>=1)
372 info() << func_name << " exchange finished "
373 << " n=" << m_current_nb_reduce
374 << " date=" << platform::getCurrentDateTime();
375 }
376 return m_exchange_finished;
377}
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
382void BasicParticleExchanger::
383_waitMessages(ItemGroup item_group,Int32Array* new_particle_local_ids,IFunctor* functor)
384{
385 if (functor){
386 {
387 Timer::Sentry ts(m_timer);
388 functor->executeFunctor();
389 }
390 m_total_time_functor += m_timer->lastActivationTime();
391 if (m_debug_exchange_items_level>=1)
392 info() << "TimeFunctor: current=" << m_timer->lastActivationTime()
393 << " total=" << m_total_time_functor;
394 }
395
396 {
397 Timer::Sentry ts(m_timer);
398 m_message_list->waitMessages(Parallel::WaitAll);
399 }
400 m_total_time_waiting += m_timer->lastActivationTime();
401 if (m_debug_exchange_items_level>=1)
402 info() << "TimeWaiting: current=" << m_timer->lastActivationTime()
403 << " total=" << m_total_time_waiting;
404
405 // Sauve les communications actuellements traitées car le traitement
406 // peut en ajouter de nouvelles
407 UniqueArray<ISerializeMessage*> current_messages(m_waiting_messages);
408 m_waiting_messages.clear();
409
410 Int64UniqueArray items_to_create_unique_id;
411 Int64UniqueArray items_to_create_cells_unique_id;
412 Int32UniqueArray items_to_create_local_id;
413 Int32UniqueArray items_to_create_cells_local_id;
414 for( ISerializeMessage* sm : current_messages ){
415 if (!sm->isSend())
416 _deserializeMessage(sm,items_to_create_unique_id,items_to_create_cells_unique_id,
417 items_to_create_local_id,items_to_create_cells_local_id,
418 item_group,new_particle_local_ids);
419 delete sm;
420 }
421 if (!m_waiting_messages.empty())
422 ARCANE_FATAL("Pending messages n={0}",m_waiting_messages.size());
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
427
428void BasicParticleExchanger::
429_sendPendingMessages()
430{
431 IParallelMng* pm = m_parallel_mng;
432
433 if (!m_message_list.get())
434 m_message_list = pm->createSerializeMessageListRef();
435
436 {
437 Timer::Sentry ts(m_timer);
438 // Ajoute les messages en attente de traitement
439 Integer nb_message = m_pending_messages.size();
440 for( Integer i=0; i<nb_message; ++i ){
441 m_message_list->addMessage(m_pending_messages[i]);
442 m_waiting_messages.add(m_pending_messages[i]);
443 }
444 m_message_list->processPendingMessages();
445 m_pending_messages.clear();
446 }
447}
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
452void BasicParticleExchanger::
453_serializeMessage(ISerializeMessage* sm,
454 Int32ConstArrayView acc_ids,
455 Int64Array& items_to_send_uid,
456 Int64Array& items_to_send_cells_uid)
457{
458 ParticleInfoListView internal_items(m_item_family);
459
460 ISerializer* sbuf = sm->serializer();
461 sbuf->setMode(ISerializer::ModeReserve);
462
463 //for( Integer j=0; j<nb_connected_sub_domain; ++j ){
464 //ConstArrayView<Integer> acc_ids = m_ids_to_send[j];
465 Integer nb_item = acc_ids.size();
466 // Réserve pour le type de message
467 //sbuf->reserveInteger(1);
468 // Réserve pour l'id du message
469 sbuf->reserveInt64(1);
470 // Réserve pour le nombre de uniqueId()
471 sbuf->reserveInt64(1);
472 sbuf->reserveSpan(eBasicDataType::Int64,nb_item);
473 // Réserve pour les uniqueId() des mailles dans lesquelles se trouvent les particules
474 //sbuf->reserve(DT_Size,1);
475 sbuf->reserveSpan(eBasicDataType::Int64,nb_item);
476
477 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
478 IVariable* var = *i_var;
479 var->serialize(sbuf,acc_ids);
480 }
481
482 // Sérialise les données en écriture
483 sbuf->allocateBuffer();
484
485 if (m_debug_exchange_items_level>=1)
486 info() << "BSE_SerializeMessage nb_item=" << nb_item
487 << " id=" << m_serialize_id
488 << " dest=" << sm->destination();
489
490 sbuf->setMode(ISerializer::ModePut);
491
492 sbuf->putInt64(m_serialize_id);
493 ++m_serialize_id;
494
495 sbuf->putInt64(nb_item);
496 items_to_send_uid.resize(nb_item);
497 items_to_send_cells_uid.resize(nb_item);
498 for( Integer z=0; z<nb_item; ++z ){
499 Particle item = internal_items[acc_ids[z]];
500 items_to_send_uid[z] = item.uniqueId();
501 bool has_cell = item.hasCell();
502 items_to_send_cells_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
503 if (m_debug_exchange_items_level>=2){
504 info() << "Particle BufID=" << acc_ids[z]
505 << " LID=" << item.localId()
506 << " UID=" << items_to_send_uid[z]
507 << " CellIUID=" << items_to_send_cells_uid[z]
508 << " (owner=" << item.cell().owner() << ")";
509 }
510 }
511 sbuf->putSpan(items_to_send_uid);
512 sbuf->putSpan(items_to_send_cells_uid);
513
514 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
515 IVariable* var = *i_var;
516 var->serialize(sbuf,acc_ids);
517 }
518
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
524void BasicParticleExchanger::
525_deserializeMessage(ISerializeMessage* message,
526 Int64Array& items_to_create_unique_id,
527 Int64Array& items_to_create_cells_unique_id,
528 Int32Array& items_to_create_local_id,
529 Int32Array& items_to_create_cells_local_id,
530 ItemGroup item_group,
531 Int32Array* new_particle_local_ids)
532{
533
534 IMesh* mesh = m_item_family->mesh();
535 ISerializer* sbuf = message->serializer();
536 IItemFamily* cell_family = mesh->cellFamily();
537
538 // Indique qu'on souhaite sérialiser les données en lecture
539 sbuf->setMode(ISerializer::ModeGet);
540 sbuf->setReadMode(ISerializer::ReadReplace);
541
542 {
543 Int64 serialize_id = sbuf->getInt64();
544 Int64 nb_item = sbuf->getInt64();
545 if (m_debug_exchange_items_level>=1)
546 info() << "BSE_DeserializeMessage id=" << serialize_id << " nb=" << nb_item
547 << " orig=" << message->destination();
548
549 items_to_create_local_id.resize(nb_item);
550 items_to_create_unique_id.resize(nb_item);
551 items_to_create_cells_unique_id.resize(nb_item);
552 items_to_create_cells_local_id.resize(nb_item);
553 sbuf->getSpan(items_to_create_unique_id);
554 sbuf->getSpan(items_to_create_cells_unique_id);
555 if (m_debug_exchange_items_level>=2){
556 //info() << "Recv from SID " << sync_infos[i].subDomain() << " N=" << nb_item;
557 for( Integer z=0; z<nb_item; ++z ){
558 info() << "Particle UID=" << items_to_create_unique_id[z]
559 << " CellIUID=" << items_to_create_cells_unique_id[z];
560 }
561 }
562
563 items_to_create_cells_local_id.resize(nb_item);
564 cell_family->itemsUniqueIdToLocalId(items_to_create_cells_local_id,items_to_create_cells_unique_id);
565
566 m_item_family->toParticleFamily()->addParticles(items_to_create_unique_id,
567 items_to_create_cells_local_id,
568 items_to_create_local_id);
569
570 // Notifie la famille qu'on a fini nos modifs.
571 // Après appel à cette méthode, les variables sont à nouveau utilisables
572 m_item_family->endUpdate();
573
574 // Converti les uniqueId() récupérée en localId() et pour les particules
575 // renseigne la maille correspondante
576 ParticleInfoListView internal_items(m_item_family);
577
578 for( Integer z=0; z<nb_item; ++z ){
579 Particle item = internal_items[items_to_create_local_id[z]];
580 //item.setCell( internal_cells[items_to_create_cells_local_id[z]] );
581 // Je suis le nouveau propriétaire (TODO: ne pas faire ici)
582 item.mutableItemBase().setOwner(m_rank,m_rank);
583 }
584 if (!item_group.null())
585 item_group.addItems(items_to_create_local_id,false);
586 if (new_particle_local_ids)
587 new_particle_local_ids->addRange(items_to_create_local_id);
588 for( VariableCollection::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
589 IVariable* var = *i_var;
590 var->serialize(sbuf,items_to_create_local_id);
591 }
592 }
593}
594
595/*---------------------------------------------------------------------------*/
596/*---------------------------------------------------------------------------*/
597
598void BasicParticleExchanger::
599reset()
600{
601 if (!m_waiting_messages.empty())
602 ARCANE_FATAL("waiting parallel requests");
603 _clearMessages();
604}
605
606/*---------------------------------------------------------------------------*/
607/*---------------------------------------------------------------------------*/
608
609void BasicParticleExchanger::
610addNewParticles(Integer nb_particle)
611{
612 ARCANE_UNUSED(nb_particle);
613 throw NotImplementedException(A_FUNCINFO);
614}
615
616/*---------------------------------------------------------------------------*/
617/*---------------------------------------------------------------------------*/
618
619void BasicParticleExchanger::
620_checkInitialized()
621{
622 if (!m_item_family)
623 ARCANE_FATAL("method initialized() not called");
624 _clearMessages();
625}
626
627/*---------------------------------------------------------------------------*/
628/*---------------------------------------------------------------------------*/
629
630ARCANE_REGISTER_SERVICE_BASICPARTICLEEXCHANGER(BasicParticleExchanger,BasicParticleExchanger);
631
633 BasicParticleExchanger);
634
635/*---------------------------------------------------------------------------*/
636/*---------------------------------------------------------------------------*/
637
638} // End namespace Arcane::mesh
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
#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:428
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: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
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:214
std::int32_t Int32
Type entier signé sur 32 bits.