diff --git a/arcane/src/arcane/mesh/MeshExchange.cc b/arcane/src/arcane/mesh/MeshExchange.cc index 0450f2578..751bf0f21 100644 --- a/arcane/src/arcane/mesh/MeshExchange.cc +++ b/arcane/src/arcane/mesh/MeshExchange.cc @@ -609,7 +609,10 @@ _computeItemsToSend(bool send_dof) if (particle_family && particle_family->getEnableGhostItems() == true) { ArrayView> to_send = _getItemsToSend(family); ENUMERATE_PARTICLE (iparticle, particle_family->allItems().own()) { - _addItemToSend(to_send, iparticle->localId(), iparticle->cell().localId(), use_itemfamily_network); + Cell cell = iparticle->cell(); + // Do not send the particle if it has no cell. + if (!cell.null()) + _addItemToSend(to_send, iparticle->localId(), cell.localId(), use_itemfamily_network); } } if (send_dof && family->itemKind() == IK_DoF) { @@ -1416,13 +1419,16 @@ _markRemovableParticles() { for (IItemFamily* family : m_mesh->itemFamilies()) { IParticleFamily* particle_family = family->toParticleFamily(); - if (particle_family && particle_family->getEnableGhostItems() == true) { + if (particle_family && particle_family->getEnableGhostItems()) { mesh::NewItemOwnerBuilder owner_builder; ENUMERATE_PARTICLE (iparticle, particle_family->allItems()) { Particle particle = *iparticle; Cell cell = owner_builder.connectedCellOfItem(particle); - particle.mutableItemBase().setFlags(cell.itemBase().flags()); + // NOTE GG: 10/2026. This code is very strange + // I think we should only modify some flags (II_NeedRemove?) + if (!cell.null()) + particle.mutableItemBase().setFlags(cell.itemBase().flags()); } } } diff --git a/arcane/src/arcane/mesh/MeshExchanger.cc b/arcane/src/arcane/mesh/MeshExchanger.cc index 149f3201d..bb3131ac9 100644 --- a/arcane/src/arcane/mesh/MeshExchanger.cc +++ b/arcane/src/arcane/mesh/MeshExchanger.cc @@ -240,7 +240,7 @@ computeExchangeInfos() // of ghost items, this list has already been determined during the call to // mesh_exchange.computeInfos(). IParticleFamily* particle_family = family->toParticleFamily(); - if (particle_family && particle_family->getEnableGhostItems() == false) + if (particle_family && !particle_family->getEnableGhostItems()) exchanger->computeExchangeItems(); else exchanger->setExchangeItems(mesh_exchange.getItemsToSend(family)); diff --git a/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc b/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc index 37084e53e..fd6985bba 100644 --- a/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc +++ b/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc @@ -169,7 +169,12 @@ changeOwnersFromCells() VariableItemInt32& particles_owner(family->itemsNewOwner()); ENUMERATE_PARTICLE (i_particle, family->allItems()) { Particle particle = *i_particle; - particles_owner[particle] = cells_owner[particle.cell()]; + Cell pcell = particle.cell(); + if (!pcell.null()) + particles_owner[particle] = cells_owner[pcell]; + else + // If the particle has no cell, its new owner is the current owner. + particles_owner[particle] = particle.owner(); } } diff --git a/arcane/src/arcane/tests/ParallelTesterModule.cc b/arcane/src/arcane/tests/ParallelTesterModule.cc index 4fa900f90..17b1566dc 100644 --- a/arcane/src/arcane/tests/ParallelTesterModule.cc +++ b/arcane/src/arcane/tests/ParallelTesterModule.cc @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* ParallelTesterModule.cc (C) 2000-2024 */ +/* ParallelTesterModule.cc (C) 2000-2026 */ /* */ /* Parallelism test module. */ /*---------------------------------------------------------------------------*/ @@ -174,8 +174,8 @@ class ParticleFamilyTester Integer particle_per_cell = 12; info() << " BuildParticleFamily increment=" << particle_per_cell << " nb_particle=" << m_family->nbItem(); - Int64UniqueArray uids; - Int32UniqueArray cells_lid; + UniqueArray uids; + UniqueArray cells_lid; IParallelMng* pm = m_family->parallelMng(); CellGroup own_cells = m_family->mesh()->ownCells(); Integer nb_own_cell = own_cells.size(); @@ -191,7 +191,16 @@ class ParticleFamilyTester ++first_uid; } } - + // To check load-balance with particles with no cells, make sure some + // particles have no cells. + // NOTE: Having particles without cells is not supported when using + // graph network. + if (!m_family->mesh()->itemFamilyNetwork()) { + Int32 nb_particle_to_add = uids.size(); + for (Int32 i = 0; i < nb_particle_to_add; ++i) + if ((i % 10) == 0) + cells_lid[i] = ItemLocalId{}; + } m_first_uid = m_first_uid + uid_increment * comm_size; info() << "Create " << uids.size() << " particles"; @@ -202,7 +211,7 @@ class ParticleFamilyTester m_family->partialEndUpdateVariable(m_values1.variable()); ENUMERATE_PARTICLE (ipart, particles) { Particle particle = *ipart; - m_values1[ipart] = (Real)(particle.uniqueId().asInt64()); + m_values1[ipart] = static_cast(particle.uniqueId().asInt64()); } m_family->endUpdate(); }