Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ExtraGhostParticlesBuilder.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* ExtraGhostParticlesBuilder.cc (C) 2000-2024 */
9/* */
10/* Construction des mailles fantômes supplémentaires. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/ExtraGhostParticlesBuilder.h"
15#include "arcane/mesh/DynamicMesh.h"
16
17#include "arcane/utils/ScopedPtr.h"
18
19#include "arcane/IExtraGhostParticlesBuilder.h"
20#include "arcane/IParallelExchanger.h"
21#include "arcane/IParallelMng.h"
22#include "arcane/ISerializeMessage.h"
23#include "arcane/SerializeBuffer.h"
24#include "arcane/ParallelMngUtils.h"
25
26#include "arcane/mesh/ParticleFamily.h"
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane::mesh
32{
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37ExtraGhostParticlesBuilder::
38ExtraGhostParticlesBuilder(DynamicMesh* mesh)
39: TraceAccessor(mesh->traceMng())
40, m_mesh(mesh)
41{
42}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47void ExtraGhostParticlesBuilder::
48addExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder* builder)
49{
50 if (m_builders.contains(builder))
51 ARCANE_FATAL("Instance {0} is already registered",builder);
52 m_builders.add(builder);
53}
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58void ExtraGhostParticlesBuilder::
59removeExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder* builder)
60{
61 auto iter_begin = m_builders.begin();
62 auto iter_end = m_builders.end();
63 auto x = std::find(iter_begin,iter_end,builder);
64 if (x==iter_end)
65 ARCANE_FATAL("Instance {0} is not registered",builder);
66 m_builders.remove(x - iter_begin);
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72bool ExtraGhostParticlesBuilder::
73hasBuilder() const
74{
75 return !m_builders.empty();
76}
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81void ExtraGhostParticlesBuilder::
82computeExtraGhostParticles()
83{
84 const size_t nb_builder = m_builders.size();
85
86 if (nb_builder == 0)
87 return;
88
89 info() << "Compute extra ghost particles";
90
91 for( IExtraGhostParticlesBuilder* v : m_builders ){
92 // Calcul de mailles extraordinaires à envoyer
93 v->computeExtraParticlesToSend();
94 }
95
96 for( IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i; ) {
97 IItemFamily* family = *i;
98 if (family->itemKind()!=IK_Particle)
99 continue;
100 ParticleFamily* particle_family = ARCANE_CHECK_POINTER(dynamic_cast<ParticleFamily*>(family));
101 if (particle_family && particle_family->getEnableGhostItems()==true){
102 _computeForFamily(particle_family);
103 }
104 }
105}
106
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
109
110void ExtraGhostParticlesBuilder::
111_computeForFamily(ParticleFamily* particle_family)
112{
113 IParallelMng* pm = particle_family->itemFamily()->parallelMng();
114 const Int32 nsd = pm->commSize();
115
116 auto exchanger { ParallelMngUtils::createExchangerRef(pm) };
117
118 // Construction des entités à envoyer
119 UniqueArray<std::set<Integer> > to_sends(nsd);
120
121 // Initialisation de l'échangeur de données
122 for(Integer isd=0;isd<nsd;++isd){
123 std::set<Integer>& particle_set = to_sends[isd];
124 for( IExtraGhostParticlesBuilder* builder : m_builders ){
125 Int32ConstArrayView extra_particles = builder->extraParticlesToSend(particle_family->name(),isd);
126 // On trie les lids à envoyer pour éviter les doublons
127 for(Integer j=0, size=extra_particles.size(); j<size; ++j)
128 particle_set.insert(extra_particles[j]);
129 }
130 if (!particle_set.empty())
131 exchanger->addSender(isd);
132 }
133 exchanger->initializeCommunicationsMessages();
134
135
136 ItemInternalList items_internal(particle_family->itemsInternal());
137 for( Integer i=0, ns=exchanger->nbSender(); i<ns; ++i){
138 ISerializeMessage* comm = exchanger->messageToSend(i);
139 const Int32 rank = comm->destination().value();
140 //ISerializer* s = comm->serializer();
141 const std::set<Integer>& particle_set = to_sends[rank];
142 Int32UniqueArray dest_items_local_id(particle_set.size());
143 std::copy(std::begin(particle_set), std::end(particle_set), std::begin(dest_items_local_id));
144 //particle_family->serializeParticles(s, items_to_send);
145
146 Int64 nb_item = particle_set.size();
147 Int64UniqueArray dest_items_unique_id(nb_item);
148 for( Integer z=0; z<nb_item; ++z ){
149 ItemInternal* item = items_internal[ dest_items_local_id[z] ];
150 dest_items_unique_id[z] = item->uniqueId().asInt64();
151 }
152
153 ISerializer* isbuf = comm->serializer();
154 SerializeBuffer* sbuf = dynamic_cast<SerializeBuffer*>(isbuf);
155 if (!sbuf)
156 ARCANE_FATAL("buffer has to have type 'SerializeBuffer'");
157
158 // Sauve les uid des mailles dans lesquelles se trouvent les particules
159 // Il est possible qu'une particule n'appartienne pas à une maille.
160 Int64UniqueArray particles_cell_uid(nb_item);
161 for( Integer z=0; z<nb_item; ++z ){
162 Particle item(items_internal[dest_items_local_id[z]]);
163 bool has_cell = item.hasCell();
164 particles_cell_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
165 }
166
167 // Réserve la mémoire pour la sérialisation
168 sbuf->setMode(ISerializer::ModeReserve);
169 sbuf->reserve(DT_Int64,1); // Pour le nombre de particules
170 sbuf->reserveArray(dest_items_unique_id); // Pour les uniqueId() des particules. NOTE: A supprimer
171 sbuf->reserveArray(particles_cell_uid); // Pour les uniqueId() des mailles dans lesquelles se trouve les particules
172
173 sbuf->allocateBuffer();
174 sbuf->setMode(ISerializer::ModePut);
175
176 sbuf->putInt64(nb_item);
177 sbuf->putArray(dest_items_unique_id);
178 sbuf->putArray(particles_cell_uid);
179 }
180 exchanger->processExchange();
181
182 Int64UniqueArray particles_uid;
183 Int64UniqueArray cells_unique_id;
184 Int32UniqueArray cells_local_id;
185 Int32UniqueArray particles_owner;
186 IItemFamily* cell_family = m_mesh->cellFamily();
187 CellInfoListView internal_cells(cell_family);
188
189 // Réception des particules
190 for( Integer i=0, ns=exchanger->nbReceiver(); i<ns; ++i ){
191 ISerializeMessage* sm = exchanger->messageToReceive(i);
192 ISerializer* sbuf = sm->serializer();
193 //particle_family->addParticles(s);
194
195 Int64 nb_item = sbuf->getInt64();
196 sbuf->getArray(particles_uid);
197 sbuf->getArray(cells_unique_id);
198 cells_local_id.resize(nb_item);
199 Int32UniqueArray particles_local_id(nb_item);
200
201 cell_family->itemsUniqueIdToLocalId(cells_local_id,cells_unique_id,true);
202 particles_owner.resize(nb_item) ;
203 for( Integer zz=0; zz<nb_item; ++zz ){
204 Int32 cell_lid = cells_local_id[zz];
205 Cell c = internal_cells[ cell_lid ];
206 particles_owner[zz] = c.owner() ;
207 }
208
209 particle_family->addParticles2(particles_uid,particles_owner,particles_local_id);
210 particle_family->endUpdate();
211 // IMPORTANT: il faut le faire ici car cela peut changer via le endUpdate()
212 ItemInternalList internal_particles(particle_family->itemsInternal());
213 for( Integer zz=0; zz<nb_item; ++zz ){
214 Particle p = internal_particles[ particles_local_id[zz] ];
215 Int32 cell_lid = cells_local_id[zz];
216 if (cell_lid!=NULL_ITEM_LOCAL_ID){
217 Cell c = internal_cells[ cell_lid ];
218 particle_family->setParticleCell(p,c);
219 }
220 else
221 particle_family->setParticleCell(p,Cell());
222 }
223 }
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229} // End namespace Arcane::mesh
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
#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.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
Definition ItemTypes.h:466
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
@ IK_Particle
Entité de maillage de genre particule.