14#include "arcane/mesh/SubMeshTools.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/ScopedPtr.h"
20#include "arcane/core/Variable.h"
21#include "arcane/core/SharedVariable.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/MeshToMeshTransposer.h"
24#include "arcane/core/IVariableSynchronizer.h"
25#include "arcane/core/IParallelExchanger.h"
26#include "arcane/core/ISerializer.h"
27#include "arcane/core/ISerializeMessage.h"
28#include "arcane/core/ItemPrinter.h"
29#include "arcane/core/TemporaryVariableBuildInfo.h"
30#include "arcane/core/ParallelMngUtils.h"
33#include "arcane/mesh/DynamicMesh.h"
34#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
35#include "arcane/mesh/ItemFamily.h"
36#include "arcane/mesh/CellFamily.h"
37#include "arcane/mesh/FaceFamily.h"
38#include "arcane/mesh/EdgeFamily.h"
39#include "arcane/mesh/NodeFamily.h"
52: TraceAccessor(mesh->traceMng())
54, m_mesh_builder(mesh_builder)
55, m_parallel_mng(mesh->parallelMng())
76 for (IItemFamilyCollection::Enumerator i_family(m_mesh->itemFamilies()); ++i_family;) {
77 IItemFamily* family = *i_family;
78 for (ItemGroupCollection::Enumerator i_group((*i_family)->groups()); ++i_group;) {
79 ItemGroup group = *i_group;
81 family->partialEndUpdateGroup(group);
86 if (group.isAllItems())
89 if (group.internal()->hasComputeFunctor())
92 group.internal()->removeSuppressedItems();
104 items_local_id.
clear();
106 Int32 rank = m_parallel_mng->commRank();
109 if (item.
owner() != rank) {
123 items_map.
eachItem([&](impl::ItemBase item) {
134_removeCell(Cell cell)
136 CellFamily& cell_family = m_mesh->trueCellFamily();
137 FaceFamily& face_family = m_mesh->trueFaceFamily();
138 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
139 NodeFamily& node_family = m_mesh->trueNodeFamily();
141 ItemLocalId cell_lid(cell);
142 for (Face face : cell.faces())
143 face_family.removeCellFromFace(face, cell_lid);
144 for (Edge edge : cell.edges())
145 edge_family.removeCellFromEdge(edge, cell_lid);
146 for (Node node : cell.nodes())
147 node_family.removeCellFromNode(node, cell_lid);
148 cell_family.removeItem(cell);
155removeDeadGhostCells()
158 CellFamily& cell_family = m_mesh->trueCellFamily();
159 FaceFamily& face_family = m_mesh->trueFaceFamily();
160 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
161 NodeFamily& node_family = m_mesh->trueNodeFamily();
164 UniqueArray<Int32> items_to_remove;
165 _fillGhostItems(&cell_family, items_to_remove);
166 ENUMERATE_ (Cell, icell, cell_family.view(items_to_remove)) {
167 impl::ItemBase item(icell->itemBase());
168 ARCANE_ASSERT((!item.parentBase(0).
isSuppressed()), (
"SubMesh cell not synchronized with its support group"));
175 _fillGhostItems(&face_family, items_to_remove);
176 ENUMERATE_ (Face, iface, face_family.view(items_to_remove)) {
177 impl::ItemBase item(iface->itemBase());
179 ARCANE_ASSERT((item.
nbCell() == 0), (
"Cannot remove connected sub-item"));
180 face_family.removeFaceIfNotConnected(item);
184 _fillGhostItems(&edge_family, items_to_remove);
185 EdgeInfoListView edges(&edge_family);
186 ENUMERATE_ (Edge, iedge, edge_family.view(items_to_remove)) {
187 impl::ItemBase item(iedge->itemBase());
189 ARCANE_ASSERT((item.
nbCell() == 0 && item.
nbFace() == 0), (
"Cannot remove connected sub-item"));
190 edge_family.removeEdgeIfNotConnected(item);
194 _fillGhostItems(&node_family, items_to_remove);
195 NodeInfoListView nodes(&node_family);
196 ENUMERATE_ (Node, inode, node_family.view(items_to_remove)) {
197 impl::ItemBase item(inode->itemBase());
199 ARCANE_ASSERT((item.
nbCell() == 0 && item.
nbFace() == 0 && item.
nbEdge() == 0), (
"Cannot remove connected sub-item"));
200 node_family.removeItem(item);
213 CellFamily& cell_family = m_mesh->trueCellFamily();
214 FaceFamily& face_family = m_mesh->trueFaceFamily();
215 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
216 NodeFamily& node_family = m_mesh->trueNodeFamily();
232 UniqueArray<Int32> items_to_remove;
234 _fillGhostItems(&cell_family, items_to_remove);
235 ENUMERATE_ (Cell, icell, cell_family.view(items_to_remove)) {
239 _fillGhostItems(&face_family, items_to_remove);
240 ENUMERATE_ (Face, iface, face_family.view(items_to_remove)) {
241 face_family.removeFaceIfNotConnected(*iface);
244 _fillGhostItems(&edge_family, items_to_remove);
245 ENUMERATE_ (Edge, iedge, edge_family.view(items_to_remove)) {
247 if (edge.nbCell() == 0 && edge.nbFace() == 0)
248 edge_family.removeEdgeIfNotConnected(edge);
251 _fillGhostItems(&node_family, items_to_remove);
252 ENUMERATE_ (Node, inode, node_family.view(items_to_remove)) {
254 if (node.nbCell() == 0 && node.nbFace() == 0 && node.nbEdge() == 0)
255 node_family.removeItem(node);
267 FaceFamily& face_family = m_mesh->trueFaceFamily();
268 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
269 NodeFamily& node_family = m_mesh->trueNodeFamily();
277 SharedArray<Int32> items_to_remove;
278 _fillFloatingItems(&face_family, items_to_remove);
279 ENUMERATE_ (Face, iface, face_family.view(items_to_remove)) {
281 if (face.nbCell() == 0)
282 face_family.removeFaceIfNotConnected(face);
284 items_to_remove.clear();
285 _fillFloatingItems(&edge_family, items_to_remove);
286 ENUMERATE_ (Edge, iedge, edge_family.view(items_to_remove)) {
288 if (edge.nbCell() == 0 && edge.nbFace() == 0)
289 edge_family.removeEdgeIfNotConnected(edge);
291 items_to_remove.clear();
292 _fillFloatingItems(&node_family, items_to_remove);
293 ENUMERATE_ (Node, inode, node_family.view(items_to_remove)) {
295 if (node.nbCell() == 0 && node.nbFace() == 0 && node.nbEdge() == 0)
296 node_family.removeItem(node);
310 _checkValidItemOwner();
313 Integer nb_kind =
sizeof(kinds) /
sizeof(eItemKind);
314 for (Integer i_kind = 0; i_kind < nb_kind; ++i_kind) {
315 IItemFamily* family = m_mesh->itemFamily(kinds[i_kind]);
316 updateGhostFamily(family);
319 removeFloatingItems();
320 _checkFloatingItems();
321 _checkValidItemOwner();
331updateGhostFamily(IItemFamily* family)
333 const eItemKind kind = family->itemKind();
335 IItemFamily* parent_family = family->parentFamily();
337 debug(Trace::High) <<
"Process ghost on submesh " << m_mesh->name() <<
" with kind=" << kind;
339 auto exchanger{ ParallelMngUtils::createExchangerRef(m_parallel_mng) };
340 IVariableSynchronizer* synchronizer = parent_family->allItemsSynchronizer();
342 std::map<Integer, SharedArray<Int64>> to_send_items;
343 for (Integer i = 0; i < ranks.size(); ++i) {
345 debug(Trace::High) <<
"Has " << kind <<
" comm with " << rank <<
" : " << i <<
" / " << ranks.size() <<
" ranks";
348 ItemVectorView shared_items(parent_family->view(synchronizer->sharedItems(i)));
349 ItemVector shared_submesh_items = MeshToMeshTransposer::transpose(parent_family, family, shared_items);
350 SharedArray<Int64> current_to_send_items;
353 if (iitem.localId() != NULL_ITEM_LOCAL_ID) {
354 const Item& item = *iitem;
355 ARCANE_ASSERT((item.uniqueId() == item.parent().uniqueId()), (
"Inconsistent item/parent uid"));
356 debug(Trace::Highest) <<
"Send shared submesh item to " << rank <<
" " << ItemPrinter(item);
357 current_to_send_items.add(item.parent().uniqueId());
361 debug(Trace::High) <<
"SubMesh ghost comm " << kind <<
" with " << rank <<
" : "
362 << shared_items.
size() <<
" / " << current_to_send_items.size();
366 if (!current_to_send_items.empty()) {
367 exchanger->addSender(rank);
368 to_send_items[rank] = current_to_send_items;
372 exchanger->initializeCommunicationsMessages();
374 for (Integer i = 0, ns = exchanger->nbSender(); i < ns; ++i) {
375 ISerializeMessage* sm = exchanger->messageToSend(i);
376 const Int32 rank = sm->destination().value();
377 ISerializer* s = sm->serializer();
378 const Int64Array& current_to_send_items = to_send_items[rank];
379 s->setMode(ISerializer::ModeReserve);
381 s->reserveArray(current_to_send_items);
384 s->setMode(ISerializer::ModePut);
386 s->putArray(current_to_send_items);
389 to_send_items.clear();
390 exchanger->processExchange();
392 for (Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
393 ISerializeMessage* sm = exchanger->messageToReceive(i);
394 const Int32 rank = sm->destination().value();
395 ISerializer* s = sm->serializer();
400 parent_family->itemsUniqueIdToLocalId(lids, uids);
401 ItemVectorView new_submesh_ghosts = parent_family->view(lids);
403 if (iitem->owner() != rank)
404 fatal() <<
"Bad ghost owner " << ItemPrinter(*iitem) <<
" : expected owner=" << rank;
405 debug(Trace::Highest) <<
"Add ghost submesh item from " << rank <<
" : " << FullItemPrinter(*iitem);
407 m_mesh_builder->addParentItems(new_submesh_ghosts, kind);
415display(IMesh* mesh,
const String msg)
417 ITraceMng* traceMng = mesh->traceMng();
418 traceMng->info() <<
"Display mesh " << mesh->name() <<
" : " << msg;
420 Integer nb_kind =
sizeof(kinds) /
sizeof(eItemKind);
421 for (Integer i_kind = 0; i_kind < nb_kind; ++i_kind) {
422 IItemFamily* family = mesh->itemFamily(kinds[i_kind]);
423 ItemInfoListView items(family);
425 for (Integer z = 0, zs = family->maxLocalId(); z < zs; ++z)
426 if (!items[z].itemBase().isSuppressed())
428 traceMng->info() <<
"\t" << family->itemKind() <<
" " << count;
430 for (Integer z = 0, zs = family->maxLocalId(); z < zs; ++z) {
431 Item item = items[z];
432 if (!item.itemBase().isSuppressed()) {
433 traceMng->info() << ItemPrinter(item);
443_checkValidItemOwner()
449 Integer nb_kind =
sizeof(kinds) /
sizeof(eItemKind);
450 for (Integer i_kind = 0; i_kind < nb_kind; ++i_kind) {
451 IItemFamily* family = m_mesh->itemFamily(kinds[i_kind]);
452 IItemFamily* parent_family = family->parentFamily();
453 ItemInfoListView items(family);
454 for (Integer z = 0, zs = family->maxLocalId(); z < zs; ++z) {
455 Item item = items[z];
456 if (!item.itemBase().isSuppressed()) {
457 if (item.uniqueId() != item.itemBase().parentBase(0).uniqueId()) {
459 uids.
add(item.uniqueId());
461 parent_family->itemsUniqueIdToLocalId(lids, uids,
false);
462 ARCANE_FATAL(
"Inconsistent parent uid '{0}' now located in '{1}'",
463 ItemPrinter(item), lids[0]);
478 Integer nb_kind =
sizeof(kinds) /
sizeof(eItemKind);
479 for (Integer i_kind = 0; i_kind < nb_kind; ++i_kind) {
480 IItemFamily* family = m_mesh->itemFamily(kinds[i_kind]);
482 ItemInfoListView items(family);
483 for (Integer z = 0, zs = family->maxLocalId(); z < zs; ++z) {
484 Item item = items[z];
485 if (!item.itemBase().isSuppressed() && item.itemBase().nbCell() == 0) {
486 error() <<
"Floating item detected : " << ItemPrinter(item);
492 fatal() <<
"ERROR " << String::plural(nerror,
"floating item") <<
" detected; see above";
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Base class for 1D data vectors.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
constexpr Integer size() const noexcept
Number of elements in the array.
Integer nbEdge() const
Number of edges of the entity or number of edges connected to the entity (for nodes).
bool isSuppressed() const
True if the entity is suppressed.
Integer nbCell() const
Number of cells connected to the entity (for nodes, edges, and faces).
Integer nbFace() const
Number of faces of the entity or number of faces connected to the entity (for nodes and edges).
bool isOwn() const
True if the entity belongs to the subdomain.
Int32 localId() const
Local number (in the subdomain) of the entity.
Base class for a mesh element.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Int32 owner() const
Owner subdomain number of the entity.
Construction of a mesh incrementally.
Implementation of a mesh.
Associative array of ItemInternal.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
bool arcaneIsCheck()
True if running in check mode.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_Edge
Edge mesh entity.
std::int32_t Int32
Signed integer type of 32 bits.