14#include "arcane/mesh/ExtraGhostParticlesBuilder.h"
15#include "arcane/mesh/DynamicMesh.h"
17#include "arcane/utils/ScopedPtr.h"
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"
26#include "arcane/mesh/ParticleFamily.h"
37ExtraGhostParticlesBuilder::
38ExtraGhostParticlesBuilder(DynamicMesh* mesh)
39: TraceAccessor(mesh->traceMng())
47void ExtraGhostParticlesBuilder::
48addExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder* builder)
50 if (m_builders.contains(builder))
51 ARCANE_FATAL(
"Instance {0} is already registered",builder);
52 m_builders.add(builder);
58void ExtraGhostParticlesBuilder::
59removeExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder* builder)
61 auto iter_begin = m_builders.begin();
62 auto iter_end = m_builders.end();
63 auto x = std::find(iter_begin,iter_end,builder);
66 m_builders.remove(x - iter_begin);
72bool ExtraGhostParticlesBuilder::
75 return !m_builders.empty();
81void ExtraGhostParticlesBuilder::
82computeExtraGhostParticles()
84 const size_t nb_builder = m_builders.size();
89 info() <<
"Compute extra ghost particles";
91 for( IExtraGhostParticlesBuilder* v : m_builders ){
93 v->computeExtraParticlesToSend();
96 for( IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i; ) {
97 IItemFamily* family = *i;
101 if (particle_family && particle_family->getEnableGhostItems()==
true){
102 _computeForFamily(particle_family);
110void ExtraGhostParticlesBuilder::
111_computeForFamily(ParticleFamily* particle_family)
113 IParallelMng* pm = particle_family->itemFamily()->parallelMng();
116 auto exchanger { ParallelMngUtils::createExchangerRef(pm) };
119 UniqueArray<std::set<Integer> > to_sends(nsd);
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);
127 for(Integer j=0, size=extra_particles.size(); j<size; ++j)
128 particle_set.insert(extra_particles[j]);
130 if (!particle_set.empty())
131 exchanger->addSender(isd);
133 exchanger->initializeCommunicationsMessages();
137 for( Integer i=0, ns=exchanger->nbSender(); i<ns; ++i){
138 ISerializeMessage* comm = exchanger->messageToSend(i);
139 const Int32 rank = comm->destination().value();
141 const std::set<Integer>& particle_set = to_sends[rank];
143 std::copy(std::begin(particle_set), std::end(particle_set), std::begin(dest_items_local_id));
146 Int64 nb_item = particle_set.size();
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();
153 ISerializer* isbuf = comm->serializer();
154 SerializeBuffer* sbuf =
dynamic_cast<SerializeBuffer*
>(isbuf);
156 ARCANE_FATAL(
"buffer has to have type 'SerializeBuffer'");
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;
168 sbuf->setMode(ISerializer::ModeReserve);
169 sbuf->reserve(DT_Int64,1);
170 sbuf->reserveArray(dest_items_unique_id);
171 sbuf->reserveArray(particles_cell_uid);
173 sbuf->allocateBuffer();
174 sbuf->setMode(ISerializer::ModePut);
176 sbuf->putInt64(nb_item);
177 sbuf->putArray(dest_items_unique_id);
178 sbuf->putArray(particles_cell_uid);
180 exchanger->processExchange();
186 IItemFamily* cell_family = m_mesh->cellFamily();
187 CellInfoListView internal_cells(cell_family);
190 for( Integer i=0, ns=exchanger->nbReceiver(); i<ns; ++i ){
191 ISerializeMessage* sm = exchanger->messageToReceive(i);
192 ISerializer* sbuf = sm->serializer();
195 Int64 nb_item = sbuf->getInt64();
196 sbuf->getArray(particles_uid);
197 sbuf->getArray(cells_unique_id);
198 cells_local_id.resize(nb_item);
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() ;
209 particle_family->addParticles2(particles_uid,particles_owner,particles_local_id);
210 particle_family->endUpdate();
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);
221 particle_family->setParticleCell(p,Cell());
#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.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ IK_Particle
Entité de maillage de genre particule.