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"
51SubMeshTools(DynamicMesh * mesh, DynamicMeshIncrementalBuilder * mesh_builder)
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();
105 ItemInternalMap&
items_map = family->itemsMap();
106 Int32 rank = m_parallel_mng->commRank();
109 if (item.
owner() != rank) {
110 items_local_id.add(item.localId());
122 ItemInternalMap&
items_map = family->itemsMap();
125 items_local_id.add(item.localId());
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();
233 UniqueArray<Int32> items_to_remove;
235 _fillGhostItems(&cell_family, items_to_remove);
236 ENUMERATE_ (Cell, icell, cell_family.view(items_to_remove)) {
240 _fillGhostItems(&face_family, items_to_remove);
241 ENUMERATE_ (Face, iface, face_family.view(items_to_remove)) {
242 face_family.removeFaceIfNotConnected(*iface);
245 _fillGhostItems(&edge_family, items_to_remove);
246 ENUMERATE_ (Edge, iedge, edge_family.view(items_to_remove)) {
248 if (edge.nbCell() == 0 && edge.nbFace() == 0)
249 edge_family.removeEdgeIfNotConnected(edge);
252 _fillGhostItems(&node_family, items_to_remove);
253 ENUMERATE_ (Node, inode, node_family.view(items_to_remove)) {
255 if (node.nbCell() == 0 && node.nbFace() == 0 && node.nbEdge() == 0)
256 node_family.removeItem(node);
268 FaceFamily& face_family = m_mesh->trueFaceFamily();
269 EdgeFamily& edge_family = m_mesh->trueEdgeFamily();
270 NodeFamily& node_family = m_mesh->trueNodeFamily();
278 SharedArray<Int32> items_to_remove;
279 _fillFloatingItems(&face_family, items_to_remove);
280 ENUMERATE_ (Face, iface, face_family.view(items_to_remove)) {
282 if (face.nbCell() == 0)
283 face_family.removeFaceIfNotConnected(face);
285 items_to_remove.clear();
286 _fillFloatingItems(&edge_family, items_to_remove);
287 ENUMERATE_ (Edge, iedge, edge_family.view(items_to_remove)) {
289 if (edge.nbCell() == 0 && edge.nbFace() == 0)
290 edge_family.removeEdgeIfNotConnected(edge);
292 items_to_remove.clear();
293 _fillFloatingItems(&node_family, items_to_remove);
294 ENUMERATE_ (Node, inode, node_family.view(items_to_remove)) {
296 if (node.nbCell() == 0 && node.nbFace() == 0 && node.nbEdge() == 0)
297 node_family.removeItem(node);
311 _checkValidItemOwner();
314 Integer nb_kind =
sizeof(kinds)/
sizeof(eItemKind);
315 for(Integer i_kind=0;i_kind<nb_kind;++i_kind){
316 IItemFamily * family = m_mesh->itemFamily(kinds[i_kind]);
317 updateGhostFamily(family);
320 removeFloatingItems();
321 _checkFloatingItems();
322 _checkValidItemOwner();
332updateGhostFamily(IItemFamily * family)
334 const eItemKind kind = family->itemKind();
336 IItemFamily * parent_family = family->parentFamily();
338 debug(
Trace::High) <<
"Process ghost on submesh " << m_mesh->name() <<
" with kind=" << kind;
340 auto exchanger { ParallelMngUtils::createExchangerRef(m_parallel_mng) };
341 IVariableSynchronizer * synchronizer = parent_family->allItemsSynchronizer();
343 std::map<Integer, SharedArray<Int64> > to_send_items;
344 for(Integer i=0;i<ranks.size();++i){
346 debug(
Trace::High) <<
"Has " << kind <<
" comm with " << rank <<
" : " << i <<
" / " << ranks.size() <<
" ranks";
349 ItemVectorView shared_items(parent_family->view(synchronizer->sharedItems(i)));
350 ItemVector shared_submesh_items = MeshToMeshTransposer::transpose(parent_family, family, shared_items);
351 SharedArray<Int64> current_to_send_items;
354 if (iitem.localId() != NULL_ITEM_LOCAL_ID){
355 const Item & item = *iitem;
356 ARCANE_ASSERT((item.uniqueId() == item.parent().uniqueId()),(
"Inconsistent item/parent uid"));
357 debug(
Trace::Highest) <<
"Send shared submesh item to " << rank <<
" " << ItemPrinter(item);
358 current_to_send_items.add(item.parent().uniqueId());
362 debug(
Trace::High) <<
"SubMesh ghost comm " << kind <<
" with " << rank <<
" : "
363 << shared_items.size() <<
" / " << current_to_send_items.size();
367 if (!current_to_send_items.empty()){
368 exchanger->addSender(rank);
369 to_send_items[rank] = current_to_send_items;
373 exchanger->initializeCommunicationsMessages();
375 for(Integer i=0, ns=exchanger->nbSender(); i<ns; ++i){
376 ISerializeMessage* sm = exchanger->messageToSend(i);
377 const Int32 rank = sm->destination().value();
378 ISerializer* s = sm->serializer();
379 const Int64Array & current_to_send_items = to_send_items[rank];
380 s->setMode(ISerializer::ModeReserve);
382 s->reserveArray(current_to_send_items);
385 s->setMode(ISerializer::ModePut);
387 s->putArray(current_to_send_items);
390 to_send_items.
clear();
391 exchanger->processExchange();
393 for( Integer i=0, ns=exchanger->nbReceiver(); i<ns; ++i ){
394 ISerializeMessage* sm = exchanger->messageToReceive(i);
395 const Int32 rank = sm->destination().value();
396 ISerializer* s = sm->serializer();
401 parent_family->itemsUniqueIdToLocalId(lids, uids);
402 ItemVectorView new_submesh_ghosts = parent_family->view(lids);
404 if (iitem->owner() != rank)
405 fatal() <<
"Bad ghost owner " << ItemPrinter(*iitem) <<
" : expected owner=" << rank;
406 debug(
Trace::Highest) <<
"Add ghost submesh item from " << rank <<
" : " << FullItemPrinter(*iitem);
408 m_mesh_builder->addParentItems(new_submesh_ghosts, kind);
416display(IMesh* mesh,
const String msg)
418 ITraceMng * traceMng = mesh->traceMng();
419 traceMng->info() <<
"Display mesh " << mesh->name() <<
" : " << msg;
421 Integer nb_kind =
sizeof(kinds)/
sizeof(eItemKind);
422 for(Integer i_kind=0;i_kind<nb_kind;++i_kind){
423 IItemFamily* family = mesh->itemFamily(kinds[i_kind]);
424 ItemInfoListView items(family);
426 for( Integer z=0, zs=family->maxLocalId(); z<zs; ++z )
427 if (!items[z].itemBase().isSuppressed())
429 traceMng->info() <<
"\t" << family->itemKind() <<
" " << count;
431 for( Integer z=0, zs=family->maxLocalId(); z<zs; ++z ){
432 Item item = items[z];
433 if (!item.itemBase().isSuppressed()){
434 traceMng->info() << ItemPrinter(item);
444_checkValidItemOwner()
450 Integer nb_kind =
sizeof(kinds)/
sizeof(eItemKind);
451 for(Integer i_kind=0;i_kind<nb_kind;++i_kind){
452 IItemFamily * family = m_mesh->itemFamily(kinds[i_kind]);
453 IItemFamily * parent_family = family->parentFamily();
454 ItemInfoListView items(family);
455 for( Integer z=0, zs=family->maxLocalId(); z<zs; ++z ){
456 Item item = items[z];
457 if (!item.itemBase().isSuppressed()){
458 if (item.uniqueId() != item.itemBase().parentBase(0).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 envoyant une exception FatalErrorException.
Classe de base pour les entités du maillage.
Integer nbEdge() const
Nombre d'arêtes de l'entité ou nombre d'arêtes connectés à l'entités (pour les noeuds)
bool isSuppressed() const
Vrai si l'entité est supprimée.
Integer nbCell() const
Nombre de mailles connectées à l'entité (pour les noeuds, arêtes et faces)
Integer nbFace() const
Nombre de faces de l'entité ou nombre de faces connectés à l'entités (pour les noeuds et arêtes)
bool isOwn() const
Vrai si l'entité appartient au sous-domaine.
Classe de base d'un élément de maillage.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Lecteur des fichiers de maillage via la bibliothèque LIMA.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
Array< Int64 > Int64Array
Tableau dynamique à une dimension d'entiers 64 bits.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
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.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
@ Highest
Niveau le plus élevé
Int32 Integer
Type représentant un entier.