diff --git a/arcane/src/arcane/mesh/DynamicMeshChecker.cc b/arcane/src/arcane/mesh/DynamicMeshChecker.cc index 90388b13e..499ac0f13 100644 --- a/arcane/src/arcane/mesh/DynamicMeshChecker.cc +++ b/arcane/src/arcane/mesh/DynamicMeshChecker.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* DynamicMeshChecker.cc (C) 2000-2023 */ +/* DynamicMeshChecker.cc (C) 2000-2024 */ /* */ /* Classe fournissant des méthodes de vérification sur le maillage. */ /*---------------------------------------------------------------------------*/ @@ -215,7 +215,7 @@ checkValidMeshFull() void DynamicMeshChecker:: checkValidConnectivity() { - String func_name = "DynamicMesh::checkValidConnectivity"; + String func_name = "MeshChecker::checkValidConnectivity"; debug() << func_name << " check"; // Appelle la méthode de vérification de chaque famille. @@ -389,7 +389,7 @@ checkValidConnectivity() void DynamicMeshChecker:: updateAMRFaceOrientation() { - String func_name = "DynamicMesh::updateAMRFaceOrientation"; + String func_name = "MeshChecker::updateAMRFaceOrientation"; FaceReorienter fr(m_mesh); ENUMERATE_FACE(iface,m_mesh->allFaces()){ Face face = *iface; @@ -447,7 +447,7 @@ _checkFacesOrientation() if (is_1d) return; - String func_name = "DynamicMesh::_checkFacesOrientation"; + String func_name = "MeshChecker::_checkFacesOrientation"; Int64UniqueArray m_work_face_sorted_nodes; IntegerUniqueArray m_work_face_nodes_index; @@ -522,7 +522,7 @@ _checkFacesOrientation() void DynamicMeshChecker:: _checkValidItemOwner(IItemFamily* family) { - String func_name = "DynamicMesh::_checkValidItemOwner"; + String func_name = "MeshChecker::_checkValidItemOwner"; // Pour les maillages non sous-maillages, il faut que tout sub-item est une cellule voisine de même propriétaire // Pour les sous-maillages, il faut, en plus, que tout item soit de même propriétaire que son parent diff --git a/arcane/src/arcane/mesh/EmptyMeshModifier.h b/arcane/src/arcane/mesh/EmptyMeshModifier.h new file mode 100644 index 000000000..ebabf55ec --- /dev/null +++ b/arcane/src/arcane/mesh/EmptyMeshModifier.h @@ -0,0 +1,139 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* EmptyMeshModifier (C) 2000-2024 */ +/* */ +/* Brief code description */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_EMPTYMESHMODIFIER_H +#define ARCANE_EMPTYMESHMODIFIER_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/core/IMeshModifier.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane::mesh +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class EmptyMeshModifier +: public IMeshModifier +{ + + public: + + explicit EmptyMeshModifier() = default; + + ~EmptyMeshModifier() override = default; + + private: + + void _error() const { ARCANE_FATAL("Using EmptyMeshModifier"); } + + public: + + void build() override { _error(); } + + public: + + //! Maillage associé + IMesh* mesh() override { _error(); } + + public: + + void setDynamic(bool) override { _error(); } + void addCells(Integer, Int64ConstArrayView, + Int32ArrayView) override { _error(); } + void addCells(const MeshModifierAddCellsArgs&) { _error(); } + void addFaces(Integer, Int64ConstArrayView, + Int32ArrayView) override { _error(); } + void addFaces(const MeshModifierAddFacesArgs&) { _error(); } + void addEdges(Integer, Int64ConstArrayView, + Int32ArrayView) override { _error(); } + void addNodes(Int64ConstArrayView, + Int32ArrayView) override { _error(); } + + void removeCells(Int32ConstArrayView) override { _error(); } + void removeCells(Int32ConstArrayView, bool) override { _error(); } + void detachCells(Int32ConstArrayView) override { _error(); } + + void removeDetachedCells(Int32ConstArrayView) override { _error(); } + + void flagCellToRefine(Int32ConstArrayView) override { _error(); } + void flagCellToCoarsen(Int32ConstArrayView) override { _error(); } + void refineItems() override { _error(); } + void coarsenItems() override { _error(); } + void coarsenItemsV2(bool) override { _error(); } + bool adapt() override { _error(); } + void registerCallBack(IAMRTransportFunctor*) override { _error(); } + void unRegisterCallBack(IAMRTransportFunctor*) override { _error(); } + void addHChildrenCells(Cell, Integer, + Int64ConstArrayView, Int32ArrayView) override { _error(); } + + void addParentCellToCell(Cell, Cell) override { _error(); } + void addChildCellToCell(Cell, Cell) override { _error(); } + + void addParentFaceToFace(Face, Face) override { _error(); } + void addChildFaceToFace(Face, Face) override { _error(); } + + void addParentNodeToNode(Node, Node) override { _error(); } + void addChildNodeToNode(Node, Node) override { _error(); } + + void clearItems() override { _error(); } + + ARCANE_DEPRECATED_240 void addCells(ISerializer*) override { _error(); } + ARCANE_DEPRECATED_240 void addCells(ISerializer*, Int32Array&) override { _error(); } + + void endUpdate() override { _error(); } + + void endUpdate(bool, bool) override { _error(); } // SDC: this signature is needed @IFPEN. + + public: + + void updateGhostLayers() override { _error(); } + + //! AMR + void updateGhostLayerFromParent(Array&, + Array&, + bool) override { _error(); } + + void addExtraGhostCellsBuilder(IExtraGhostCellsBuilder*) override { _error(); } + + void removeExtraGhostCellsBuilder(IExtraGhostCellsBuilder*) override { _error(); } + + void addExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder*) override { _error(); } + + void removeExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder*) override { _error(); } + + public: + + void mergeMeshes(ConstArrayView) override { _error(); } + + public: + + IMeshModifierInternal* _modifierInternalApi() override + { + _error(); + return nullptr; + } +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane::mesh + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif //ARCANE_EMPTYMESHMODIFIER_H diff --git a/arcane/src/arcane/mesh/PolyhedralMesh.cc b/arcane/src/arcane/mesh/PolyhedralMesh.cc index b32adff33..c7000ec16 100644 --- a/arcane/src/arcane/mesh/PolyhedralMesh.cc +++ b/arcane/src/arcane/mesh/PolyhedralMesh.cc @@ -31,6 +31,7 @@ #include "arcane/mesh/ItemFamily.h" #include "arcane/mesh/DynamicMeshKindInfos.h" +#include "arcane/mesh/UnstructuredMeshUtilities.h" #include "arcane/utils/ITraceMng.h" #include "arcane/utils/FatalErrorException.h" @@ -42,6 +43,7 @@ #include "arcane/core/internal/IMeshInternal.h" #include "arcane/utils/Collection.h" #include "arcane/utils/List.h" +#include "arcane/utils/PlatformUtils.h" #include "neo/Mesh.h" #include "ItemConnectivityMng.h" @@ -756,6 +758,7 @@ PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi) , m_mesh_checker{ this } , m_internal_api{std::make_unique(this)} , m_compact_mng{std::make_unique(this)} +, m_mesh_utilities{std::make_unique(this)} { m_mesh_handle._setMesh(this); m_mesh_item_internal_list.mesh = this; @@ -1327,6 +1330,79 @@ removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_na /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void mesh::PolyhedralMesh:: +addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid) +{ + addItems(nodes_uid, nodes_lid, IK_Node, nodeFamily()->name()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void mesh::PolyhedralMesh:: +exchangeItems() +{ + m_trace_mng->info() << "PolyhedralMesh::_exchangeItems() do_compact?=" << "false" + << " nb_exchange=" << 0 << " version=" << 0; + _exchangeItems(); + String check_exchange = platform::getEnvironmentVariable("ARCANE_CHECK_EXCHANGE"); + if (!check_exchange.null()){ + m_mesh_checker.checkGhostCells(); + m_trace_mng->pwarning() << "CHECKING SYNCHRONISATION !"; + m_mesh_checker.checkVariablesSynchronization(); + m_mesh_checker.checkItemGroupsSynchronization(); + } + if (checkLevel()>=2) + m_mesh_checker.checkValidMesh(); + else if (checkLevel()>=1) + m_mesh_checker.checkValidConnectivity(); + +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void mesh::PolyhedralMesh:: +_exchangeItems() +{ + ; //todo +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void mesh::PolyhedralMesh:: +prepareForDump() +{ + // do nothing for now + auto want_dump = false; + auto need_compact = false; + m_trace_mng->info(4) << "DynamicMesh::prepareForDump() name=" << name() + << " need_compact?=" << need_compact + << " want_dump?=" << want_dump + << " timestamp=" << 0; + + { + eMeshEventType t = eMeshEventType::BeginPrepareDump; + m_mesh_events.eventObservable(t).notify(MeshEventArgs(this,t)); + } + + // todo use Properties + if (want_dump) { + for (auto& family : m_arcane_families) { + family->prepareForDump(); + } + } + + { + eMeshEventType t = eMeshEventType::EndPrepareDump; + m_mesh_events.eventObservable(t).notify(MeshEventArgs(this,t)); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CellGroup mesh::PolyhedralMesh:: allActiveCells() { @@ -1389,11 +1465,42 @@ innerActiveFaces() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -FaceGroup mesh::PolyhedralMesh::outerActiveFaces() +FaceGroup mesh::PolyhedralMesh:: +outerActiveFaces() { return allCells().outerActiveFaceGroup(); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +IMeshUtilities* mesh::PolyhedralMesh:: +utilities() +{ + return m_mesh_utilities.get(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +VariableItemInt32& mesh::PolyhedralMesh:: +itemsNewOwner(eItemKind ik) +{ + IItemFamily* item_family = _itemFamily(ik); + ARCANE_CHECK_POINTER(item_family); + return item_family->itemsNewOwner(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer mesh::PolyhedralMesh:: +checkLevel() const +{ + return m_mesh_checker.checkLevel(); +} + + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/mesh/PolyhedralMesh.h b/arcane/src/arcane/mesh/PolyhedralMesh.h index 3305d55e7..2563ba295 100644 --- a/arcane/src/arcane/mesh/PolyhedralMesh.h +++ b/arcane/src/arcane/mesh/PolyhedralMesh.h @@ -23,6 +23,7 @@ #include "arcane/core/ArcaneTypes.h" #include "arcane/mesh/EmptyMesh.h" +#include "arcane/mesh/EmptyMeshModifier.h" #include "arcane/mesh/MeshEventsImpl.h" #include "arcane/core/ItemAllocationInfo.h" @@ -65,6 +66,7 @@ class PolyhedralFamily; class PolyhedralMesh : public EmptyMesh +, public EmptyMeshModifier , public IPolyhedralMeshInitialAllocator { @@ -144,6 +146,7 @@ class PolyhedralMesh List m_item_family_collection; std::unique_ptr m_internal_api; std::unique_ptr m_compact_mng; + std::unique_ptr m_mesh_utilities; // IPrimaryMeshBase interface IMeshInitialAllocator* initialAllocator() override { return &m_initial_allocator; } @@ -250,8 +253,16 @@ class PolyhedralMesh IMeshCompactMng* _compactMng() override; + void exchangeItems() override; + // For now, use _internalAPI()->polyhedralMeshModifier instead of IMeshModifier not implemented yet - IMeshModifier* modifier() override {return nullptr;} + IMeshModifier* modifier() override {return this;} + bool isDynamic() const override {return true;} // wip parallel, IMesh API + void setDynamic(bool) override {} // wip parallel, IMeshModifier API + + IMeshUtilities* utilities() override; + + void addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid) override; // wip: add IMeshModifierAPI // AMR is not activated with Polyhedral mesh. All items are thus active. CellGroup allActiveCells() override; @@ -263,9 +274,19 @@ class PolyhedralMesh FaceGroup innerActiveFaces() override; FaceGroup outerActiveFaces() override; + IMeshPartitionConstraintMng* partitionConstraintMng() override { return nullptr; } + + VariableItemInt32& itemsNewOwner(eItemKind ik) override; + + IItemFamilyNetwork* itemFamilyNetwork() override { return nullptr; } + + Integer checkLevel() const override; IUserDataList* userDataList() override { return m_mesh_handle.meshUserDataList(); } const IUserDataList* userDataList() const override { return m_mesh_handle.meshUserDataList(); } + + void prepareForDump() override; + private: void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name); @@ -275,6 +296,8 @@ class PolyhedralMesh PolyhedralFamily* _itemFamily(eItemKind ik); PolyhedralFamily* _findItemFamily(eItemKind ik, const String& name, bool create_if_needed = false); + void _exchangeItems(); + #endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS private: diff --git a/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc b/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc index 821cd4a73..d6a330acc 100644 --- a/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc +++ b/arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* UnstructuredMeshUtilities.cc (C) 2000-2023 */ +/* UnstructuredMeshUtilities.cc (C) 2000-2024 */ /* */ /* Fonctions utilitaires sur un maillage. */ /*---------------------------------------------------------------------------*/ @@ -118,7 +118,7 @@ changeOwnersFromCells() const Node node = *i_node; const Cell cell = owner_builder.connectedCellOfItem(node); #ifdef ARCANE_DEBUG_LOAD_BALANCING - if (m_nodes_owner[node]!=m_cells_owner[cell]){ + if (nodes_owner[node]!= cells_owner[cell]){ info() << "New owner for node: " << ItemPrinter(node) << " cell=" << ItemPrinter(cell) << " old_owner=" << nodes_owner[node] << " current_cell_owner=" << cell.owner() @@ -136,11 +136,11 @@ changeOwnersFromCells() const Edge edge = *i_edge; const Cell cell = owner_builder.connectedCellOfItem(edge); #ifdef ARCANE_DEBUG_LOAD_BALANCING - if (m_edges_owner[edge]!=m_cells_owner[cell]){ + if (edges_owner[edge] != cells_owner[cell]) { info() << "New owner for edge: " << ItemPrinter(edge) << " cell=" << ItemPrinter(cell) - << " old_owner=" << edges_owner[edge] - << " current_cell_owner=" << cell.owner() - << " new_owner=" << cells_owner[cell]; + << " old_owner=" << edges_owner[edge] + << " current_cell_owner=" << cell.owner() + << " new_owner=" << cells_owner[cell]; } #endif /* ARCANE_DEBUG_LOAD_BALANCING */ edges_owner[edge] = cells_owner[cell]; diff --git a/arcane/src/arcane/tests/MeshPolyhedralTestModule.cc b/arcane/src/arcane/tests/MeshPolyhedralTestModule.cc index dc383dcfe..2f1807a7e 100644 --- a/arcane/src/arcane/tests/MeshPolyhedralTestModule.cc +++ b/arcane/src/arcane/tests/MeshPolyhedralTestModule.cc @@ -54,6 +54,7 @@ class MeshPolyhedralTestModule : public ArcaneMeshPolyhedralTestObject _testEnumerationAndConnectivities(mesh()); _testVariables(mesh()); _testGroups(mesh()); + _testMeshUtilities(mesh()); } else info() << "No Mesh"; @@ -69,6 +70,7 @@ class MeshPolyhedralTestModule : public ArcaneMeshPolyhedralTestObject void _testGroups(IMesh* mesh); void _testDimensions(IMesh* mesh); void _testCoordinates(IMesh* mesh); + void _testMeshUtilities(IMesh* mesh); void _buildGroup(IItemFamily* family, String const& group_name); void _checkBoundaryFaceGroup(IMesh* mesh, String const& boundary_face_group_name) const; void _checkInternalFaceGroup(IMesh* mesh, String const& internal_face_group_name) const; @@ -384,6 +386,9 @@ _testGroups(IMesh* mesh) } ValueChecker vc{ A_FUNCINFO }; auto nb_internal_group = 19; + if (subDomain()->parallelMng()->isParallel()) { + nb_internal_group = 23; + } auto nb_group = nb_internal_group + options()->nbMeshGroup; vc.areEqual(nb_group, mesh->groups().count(), "check number of groups in the mesh"); @@ -435,6 +440,41 @@ _testCoordinates(Arcane::IMesh* mesh) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void MeshPolyhedralTestModule:: +_testMeshUtilities(Arcane::IMesh* mesh) +{ + auto* mesh_utilities = mesh->utilities(); + ARCANE_CHECK_POINTER(mesh_utilities); + // Test change owner from cells + // wip test in sequential: virtually change all cell owners to 1 and check all items have 1 as owner + auto& cell_owners = mesh->cellFamily()->itemsNewOwner(); + auto& face_owners = mesh->faceFamily()->itemsNewOwner(); + auto& edge_owners = mesh->edgeFamily()->itemsNewOwner(); + auto& node_owners = mesh->nodeFamily()->itemsNewOwner(); + ENUMERATE_(Cell,icell,allCells()) { + cell_owners[icell] = 1; + info() << "Cell uid " << icell->uniqueId() << " cell_owner[icell] " << cell_owners[icell]; + info() << "Cell uid " << icell->uniqueId() << " has owner " << icell->owner(); + } + mesh_utilities->changeOwnersFromCells(); + bool has_error = false; + ENUMERATE_ (Face,iface,allFaces()) { + has_error |= face_owners[iface] != 1; + } + ENUMERATE_ (Node,inode,allNodes()) { + has_error |= node_owners[inode] != 1; + } + ENUMERATE_ (Edge,iedge,allEdges()) { + has_error |= edge_owners[iedge] != 1; + } + if (has_error) { + ARCANE_FATAL("changeOwnerFromCells does not work with PolyhedralMesh"); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void MeshPolyhedralTestModule:: _buildGroup(IItemFamily* family, String const& group_name) { diff --git a/arcane/src/arcane/tests/dof/DoFTester.cc b/arcane/src/arcane/tests/dof/DoFTester.cc index 71464a1b5..2cc7c4f47 100644 --- a/arcane/src/arcane/tests/dof/DoFTester.cc +++ b/arcane/src/arcane/tests/dof/DoFTester.cc @@ -1101,15 +1101,8 @@ _addNodes(Int32Array2View new_nodes_lids, Int64Array2View new_nodes_uids) { for (Integer i = 0; i < nb_new_nodes;++i) new_nodes_uids[rank][i] = max_uid*(rank+1) +i+1; IMeshModifier* mesh_modifier = mesh()->modifier(); - if (mesh_modifier) { + ARCANE_CHECK_POINTER(mesh_modifier); mesh_modifier->addNodes(new_nodes_uids[rank], new_nodes_lids[rank]); - } - else {// no mesh modifier for now in polyhedral mesh, use polyhedral mesh modifier - info() << "Use polyhedral mesh modifier"; - IPolyhedralMeshModifier* polyhedral_modifier = mesh()->_internalApi()->polyhedralMeshModifier(); - ARCANE_CHECK_POINTER(polyhedral_modifier); - polyhedral_modifier->addItems(new_nodes_uids[rank], new_nodes_lids[rank], IK_Node, mesh()->nodeFamily()->name()); - } added_items[rank] = mesh()->nodeFamily()->view(new_nodes_lids[rank]); ENUMERATE_NODE(inode,added_items[rank]) {