14#include "arcane/mesh/ExtraGhostParticlesBuilder.h"
15#include "arcane/mesh/DynamicMesh.h"
17#include "arcane/utils/ScopedPtr.h"
19#include "arcane/core/IExtraGhostParticlesBuilder.h"
20#include "arcane/core/IParallelExchanger.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/ISerializeMessage.h"
23#include "arcane/core/SerializeBuffer.h"
24#include "arcane/core/ParallelMngUtils.h"
26#include "arcane/mesh/ParticleFamily.h"
37ExtraGhostParticlesBuilder::
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;
98 if (family->itemKind() != IK_Particle)
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();
114 const Int32 nsd = pm->commSize();
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();
136 for (Integer i = 0, ns = exchanger->nbSender(); i < ns; ++i) {
137 ISerializeMessage* comm = exchanger->messageToSend(i);
138 const Int32 rank = comm->destination().value();
140 const std::set<Integer>& particle_set = to_sends[rank];
142 std::copy(std::begin(particle_set), std::end(particle_set), std::begin(dest_items_local_id));
145 Int64 nb_item = particle_set.size();
147 for (Integer z = 0; z < nb_item; ++z) {
148 ItemInternal* item = items_internal[dest_items_local_id[z]];
149 dest_items_unique_id[z] = item->uniqueId().asInt64();
152 ISerializer* isbuf = comm->serializer();
153 SerializeBuffer* sbuf =
dynamic_cast<SerializeBuffer*
>(isbuf);
155 ARCANE_FATAL(
"buffer has to have type 'SerializeBuffer'");
160 for (Integer z = 0; z < nb_item; ++z) {
161 Particle item(items_internal[dest_items_local_id[z]]);
162 bool has_cell = item.hasCell();
163 particles_cell_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
167 sbuf->setMode(ISerializer::ModeReserve);
168 sbuf->reserve(DT_Int64, 1);
169 sbuf->reserveArray(dest_items_unique_id);
170 sbuf->reserveArray(particles_cell_uid);
172 sbuf->allocateBuffer();
173 sbuf->setMode(ISerializer::ModePut);
175 sbuf->putInt64(nb_item);
176 sbuf->putArray(dest_items_unique_id);
177 sbuf->putArray(particles_cell_uid);
179 exchanger->processExchange();
185 IItemFamily* cell_family = m_mesh->cellFamily();
186 CellInfoListView internal_cells(cell_family);
189 for (Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
190 ISerializeMessage* sm = exchanger->messageToReceive(i);
191 ISerializer* sbuf = sm->serializer();
194 Int64 nb_item = sbuf->getInt64();
195 sbuf->getArray(particles_uid);
196 sbuf->getArray(cells_unique_id);
197 cells_local_id.resize(nb_item);
200 cell_family->itemsUniqueIdToLocalId(cells_local_id, cells_unique_id,
true);
201 particles_owner.resize(nb_item);
202 for (Integer zz = 0; zz < nb_item; ++zz) {
203 Int32 cell_lid = cells_local_id[zz];
204 Cell c = internal_cells[cell_lid];
205 particles_owner[zz] = c.owner();
208 particle_family->addParticles2(particles_uid, particles_owner, particles_local_id);
209 particle_family->endUpdate();
212 for (Integer zz = 0; zz < nb_item; ++zz) {
213 Particle p = internal_particles[particles_local_id[zz]];
214 Int32 cell_lid = cells_local_id[zz];
215 if (cell_lid != NULL_ITEM_LOCAL_ID) {
216 Cell c = internal_cells[cell_lid];
217 particle_family->setParticleCell(p, c);
220 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.
Implementation of a mesh.
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.
@ Cell
Le maillage est AMR par maille.