Skip to content

Commit f7fa62b

Browse files
Merge pull request #2008 from arcaneframework/dev/gg-add-direct-compute-nodes-owner
Add support in `ItemsOwnerBuilder` to compute owners for nodes
2 parents 42b1e48 + f6b0c13 commit f7fa62b

9 files changed

+204
-12
lines changed

arcane/src/arcane/core/IMeshUtilities.h

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
22
//-----------------------------------------------------------------------------
3-
// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
3+
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
44
// See the top-level COPYRIGHT file for details.
55
// SPDX-License-Identifier: Apache-2.0
66
//-----------------------------------------------------------------------------
77
/*---------------------------------------------------------------------------*/
8-
/* IMeshUtilities.h (C) 2000-2024 */
8+
/* IMeshUtilities.h (C) 2000-2025 */
99
/* */
1010
/* Interface d'une classe proposant des fonctions utilitaires sur maillage. */
1111
/*---------------------------------------------------------------------------*/
@@ -131,9 +131,36 @@ class ARCANE_CORE_EXPORT IMeshUtilities
131131
* En considérant que les nouveaux propriétaires des mailles sont
132132
* connus (et synchronisés), détermine les nouveaux propriétaires des autres
133133
* entités et les synchronise.
134+
*
135+
* Cette méthode est collective.
136+
*
137+
* \note Cette méthode nécessite que les informations de synchronisations soient
138+
* valides. Si on souhaite déterminer les propriétaires des entités sans
139+
* information préalable, il faut utiliser computeAndSetOwnersForNodes()
140+
* ou computeAndSetOwnersForFaces().
134141
*/
135142
virtual void changeOwnersFromCells() =0;
136143

144+
/*!
145+
* \brief Détermine les propriétaires des noeuds.
146+
*
147+
* La détermination se fait en fonction des propriétaires des mailles.
148+
* Il ne doit pas y avoir de couches de mailles fantômes.
149+
*
150+
* Cette opération est collective.
151+
*/
152+
virtual void computeAndSetOwnersForNodes() =0;
153+
154+
/*!
155+
* \brief Détermine les propriétaires des faces.
156+
*
157+
* La détermination se fait en fonction des propriétaires des mailles.
158+
* Il ne doit pas y avoir de couches de mailles fantômes.
159+
*
160+
* Cette opération est collective.
161+
*/
162+
virtual void computeAndSetOwnersForFaces() =0;
163+
137164
/*!
138165
* \brief Ecrit le maillage dans un fichier.
139166
*

arcane/src/arcane/mesh/ItemsOwnerBuilder.cc

+97-4
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929
#include "arcane/parallel/BitonicSortT.H"
3030

3131
#include "arcane/mesh/ItemInternalMap.h"
32+
#include "arcane/mesh/NodeFamily.h"
3233
#include "arcane/mesh/DynamicMesh.h"
3334

35+
#include <unordered_set>
36+
3437
/*---------------------------------------------------------------------------*/
3538
/*---------------------------------------------------------------------------*/
3639

@@ -110,11 +113,12 @@ class ItemsOwnerBuilderImpl
110113

111114
public:
112115

113-
explicit ItemsOwnerBuilderImpl(DynamicMesh* mesh);
116+
explicit ItemsOwnerBuilderImpl(IMesh* mesh);
114117

115118
public:
116119

117120
void computeFacesOwner();
121+
void computeNodesOwner();
118122

119123
private:
120124

@@ -195,10 +199,13 @@ class ItemsOwnerBuilderImpl::ItemOwnerInfoSortTraits
195199
/*---------------------------------------------------------------------------*/
196200

197201
ItemsOwnerBuilderImpl::
198-
ItemsOwnerBuilderImpl(DynamicMesh* mesh)
202+
ItemsOwnerBuilderImpl(IMesh* mesh)
199203
: TraceAccessor(mesh->traceMng())
200-
, m_mesh(mesh)
201204
{
205+
DynamicMesh* dm = dynamic_cast<DynamicMesh*>(mesh);
206+
if (!dm)
207+
ARCANE_FATAL("Mesh is not an instance of 'DynamicMesh'");
208+
m_mesh = dm;
202209
if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ITEMS_OWNER_BUILDER_IMPL_DEBUG_LEVEL", true))
203210
m_verbose_level = v.value();
204211
}
@@ -209,6 +216,8 @@ ItemsOwnerBuilderImpl(DynamicMesh* mesh)
209216
void ItemsOwnerBuilderImpl::
210217
computeFacesOwner()
211218
{
219+
m_items_owner_info.clear();
220+
212221
IParallelMng* pm = m_mesh->parallelMng();
213222
const Int32 my_rank = pm->commRank();
214223
ItemInternalMap& faces_map = m_mesh->facesMap();
@@ -253,6 +262,78 @@ computeFacesOwner()
253262
face_family.notifyItemsOwnerChanged();
254263
}
255264

265+
/*---------------------------------------------------------------------------*/
266+
/*---------------------------------------------------------------------------*/
267+
268+
void ItemsOwnerBuilderImpl::
269+
computeNodesOwner()
270+
{
271+
m_items_owner_info.clear();
272+
273+
IParallelMng* pm = m_mesh->parallelMng();
274+
const Int32 my_rank = pm->commRank();
275+
ItemInternalMap& faces_map = m_mesh->facesMap();
276+
ItemInternalMap& nodes_map = m_mesh->nodesMap();
277+
NodeFamily& node_family = m_mesh->trueNodeFamily();
278+
279+
info() << "** BEGIN ComputeNodesOwner nb_node=" << nodes_map.count();
280+
281+
// Place par défaut tous les noeuds dans ce sous-domaine
282+
nodes_map.eachItem([&](Node node) {
283+
node.mutableItemBase().setOwner(my_rank, my_rank);
284+
});
285+
286+
// Parcours toutes les faces.
287+
// Ne garde que celles qui sont frontières ou dont les propriétaires des
288+
// deux mailles de part et d'autre sont différents de notre sous-domaine.
289+
//UniqueArray<Int32> faces_to_add;
290+
//faces_map.eachItem([&](Face face) {
291+
//Int32 nb_cell = face.nbCell();
292+
// if (nb_cell == 1)
293+
// faces_to_add.add(face.localId());
294+
//});
295+
//info() << "ItemsOwnerBuilder: NB_FACE_TO_ADD=" << faces_to_add.size();
296+
const Int32 verbose_level = m_verbose_level;
297+
298+
// Ajoute tous les noeuds des faces frontières.
299+
std::unordered_set<Int32> done_nodes;
300+
301+
FaceInfoListView faces(m_mesh->faceFamily());
302+
UniqueArray<Int32> nodes_to_add;
303+
faces_map.eachItem([&](Face face) {
304+
Int32 face_nb_cell = face.nbCell();
305+
if (face_nb_cell == 1)
306+
return;
307+
for (Node node : face.nodes()) {
308+
Int32 node_id = node.localId();
309+
if (done_nodes.find(node_id) == done_nodes.end()) {
310+
nodes_to_add.add(node_id);
311+
done_nodes.insert(node_id);
312+
node.mutableItemBase().setOwner(A_NULL_RANK, my_rank);
313+
}
314+
}
315+
});
316+
317+
info() << "ItemsOwnerBuilder: NB_NODE_TO_ADD=" << nodes_to_add.size();
318+
NodeInfoListView nodes(&node_family);
319+
for (Int32 lid : nodes_to_add) {
320+
Node node(nodes[lid]);
321+
Int64 node_uid = node.uniqueId();
322+
for (Cell cell : node.cells()) {
323+
if (verbose_level >= 2)
324+
info() << "ADD lid=" << lid << " uid=" << node_uid << " cell_uid=" << cell.uniqueId() << " owner=" << cell.owner();
325+
m_items_owner_info.add(ItemOwnerInfo(node_uid, node_uid, cell.uniqueId(), my_rank, cell.owner()));
326+
}
327+
}
328+
329+
// Tri les instances de ItemOwnerInfo et les place les valeurs triées
330+
// dans items_owner_info.
331+
_sortInfos();
332+
_processSortedInfos(nodes_map);
333+
334+
node_family.notifyItemsOwnerChanged();
335+
}
336+
256337
/*---------------------------------------------------------------------------*/
257338
/*---------------------------------------------------------------------------*/
258339
/*!
@@ -416,7 +497,7 @@ _processSortedInfos(ItemInternalMap& items_map)
416497
/*---------------------------------------------------------------------------*/
417498

418499
ItemsOwnerBuilder::
419-
ItemsOwnerBuilder(DynamicMesh* mesh)
500+
ItemsOwnerBuilder(IMesh* mesh)
420501
: m_p(std::make_unique<ItemsOwnerBuilderImpl>(mesh))
421502
{}
422503

@@ -427,6 +508,9 @@ ItemsOwnerBuilder::
427508
// pas connu dans le '.h'.
428509
}
429510

511+
/*---------------------------------------------------------------------------*/
512+
/*---------------------------------------------------------------------------*/
513+
430514
void ItemsOwnerBuilder::
431515
computeFacesOwner()
432516
{
@@ -436,6 +520,15 @@ computeFacesOwner()
436520
/*---------------------------------------------------------------------------*/
437521
/*---------------------------------------------------------------------------*/
438522

523+
void ItemsOwnerBuilder::
524+
computeNodesOwner()
525+
{
526+
m_p->computeNodesOwner();
527+
}
528+
529+
/*---------------------------------------------------------------------------*/
530+
/*---------------------------------------------------------------------------*/
531+
439532
} // namespace Arcane::mesh
440533

441534
/*---------------------------------------------------------------------------*/

arcane/src/arcane/mesh/ItemsOwnerBuilder.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
22
//-----------------------------------------------------------------------------
3-
// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
3+
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
44
// See the top-level COPYRIGHT file for details.
55
// SPDX-License-Identifier: Apache-2.0
66
//-----------------------------------------------------------------------------
77
/*---------------------------------------------------------------------------*/
8-
/* ItemsOwnerBuilder.h (C) 2000-2024 */
8+
/* ItemsOwnerBuilder.h (C) 2000-2025 */
99
/* */
1010
/* Classe pour calculer les propriétaires des entités. */
1111
/*---------------------------------------------------------------------------*/
@@ -20,7 +20,10 @@
2020

2121
/*---------------------------------------------------------------------------*/
2222
/*---------------------------------------------------------------------------*/
23-
23+
namespace Arcane
24+
{
25+
class IMesh;
26+
}
2427
namespace Arcane::mesh
2528
{
2629
class ItemsOwnerBuilderImpl;
@@ -39,12 +42,13 @@ class ARCANE_MESH_EXPORT ItemsOwnerBuilder
3942

4043
public:
4144

42-
explicit ItemsOwnerBuilder(DynamicMesh* mesh);
45+
explicit ItemsOwnerBuilder(IMesh* mesh);
4346
~ItemsOwnerBuilder();
4447

4548
public:
4649

4750
void computeFacesOwner();
51+
void computeNodesOwner();
4852

4953
private:
5054

arcane/src/arcane/mesh/UnstructuredMeshUtilities.cc

+21
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "arcane/mesh/BasicItemPairGroupComputeFunctor.h"
5252
#include "arcane/mesh/MeshNodeMerger.h"
5353
#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
54+
#include "arcane/mesh/ItemsOwnerBuilder.h"
5455

5556
#include <algorithm>
5657

@@ -815,6 +816,26 @@ mergeNodes(Int32ConstArrayView nodes_local_id,
815816
/*---------------------------------------------------------------------------*/
816817
/*---------------------------------------------------------------------------*/
817818

819+
void UnstructuredMeshUtilities::
820+
computeAndSetOwnersForNodes()
821+
{
822+
mesh::ItemsOwnerBuilder owner_builder(m_mesh);
823+
owner_builder.computeNodesOwner();
824+
}
825+
826+
/*---------------------------------------------------------------------------*/
827+
/*---------------------------------------------------------------------------*/
828+
829+
void UnstructuredMeshUtilities::
830+
computeAndSetOwnersForFaces()
831+
{
832+
mesh::ItemsOwnerBuilder owner_builder(m_mesh);
833+
owner_builder.computeFacesOwner();
834+
}
835+
836+
/*---------------------------------------------------------------------------*/
837+
/*---------------------------------------------------------------------------*/
838+
818839
} // End namespace Arcane
819840

820841
/*---------------------------------------------------------------------------*/

arcane/src/arcane/mesh/UnstructuredMeshUtilities.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
22
//-----------------------------------------------------------------------------
3-
// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
3+
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
44
// See the top-level COPYRIGHT file for details.
55
// SPDX-License-Identifier: Apache-2.0
66
//-----------------------------------------------------------------------------
77
/*---------------------------------------------------------------------------*/
8-
/* UnstructuredMeshUtilities.h (C) 2000-2024 */
8+
/* UnstructuredMeshUtilities.h (C) 2000-2025 */
99
/* */
1010
/* Fonctions utilitaires sur un maillage. */
1111
/*---------------------------------------------------------------------------*/
@@ -92,6 +92,9 @@ class UnstructuredMeshUtilities
9292
void mergeNodes(Int32ConstArrayView nodes_local_id,
9393
Int32ConstArrayView nodes_to_merge_local_id) override;
9494

95+
void computeAndSetOwnersForNodes() override;
96+
void computeAndSetOwnersForFaces() override;
97+
9598
private:
9699

97100
IMesh* m_mesh;

arcane/src/arcane/tests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ if (ARCANE_DEFAULT_PARTITIONER_IS_METIS)
673673
endif()
674674
arcane_add_test_sequential(mesh2_generate_edge_face_uid_env testMesh-2-env-generate-edge-face-uid.arc "-We,ARCANE_GENERATE_UNIQUE_ID_FROM_NODES,1")
675675
arcane_add_test_sequential(mesh2_sort_faces testMesh-2-sorted-faces.arc)
676+
arcane_add_test(mesh2_compute_owners_direct testMesh-2-compute-owners-direct.arc)
676677
arcane_add_test_sequential(mesh2_init_nan testMesh-2.arc "-We,ARCANE_DATA_INIT_POLICY,NAN")
677678
arcane_add_test_sequential(mesh2_init_default testMesh-2.arc "-We,ARCANE_DATA_INIT_POLICY,DEFAULT" "-We,ARCANE_ITEMFAMILY_SHRINK_AFTER_ALLOCATE,1")
678679
arcane_add_test_sequential(mesh2_init_nan_and_default testMesh-2.arc "-We,ARCANE_DATA_INIT_POLICY,NAN_AND_DEFAULT")

arcane/src/arcane/tests/MeshUnitTest.axl

+6
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,11 @@ Teste la désallocation du maillage
182182
</description>
183183
</simple>
184184

185+
<simple name = "compute-owners-direct" type = "bool" default = "false">
186+
<description>
187+
Si vrai, utilise 'ItemsOwnerBuilder' pour calculer les propriétaires des noeuds et faces.
188+
</description>
189+
</simple>
190+
185191
</options>
186192
</service>

arcane/src/arcane/tests/MeshUnitTest.cc

+18
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ class MeshUnitTest
204204
void _testFindOneItem();
205205
void _testEvents();
206206
void _testNodeNodeViaEdgeConnectivity();
207+
void _testComputeOwnersDirect();
207208
};
208209

209210
/*---------------------------------------------------------------------------*/
@@ -246,6 +247,10 @@ buildInitializeTest()
246247
void MeshUnitTest::
247248
executeTest()
248249
{
250+
bool do_compute_owners_direct = options()->computeOwnersDirect();
251+
if (do_compute_owners_direct)
252+
_testComputeOwnersDirect();
253+
249254
bool do_sort_faces_and_edges = options()->testSortNodeFacesAndEdges();
250255
if (do_sort_faces_and_edges) {
251256
mesh()->nodeFamily()->properties()->setBool("sort-connected-faces-edges",true);
@@ -1796,6 +1801,19 @@ _testNodeNodeViaEdgeConnectivity()
17961801
/*---------------------------------------------------------------------------*/
17971802
/*---------------------------------------------------------------------------*/
17981803

1804+
void MeshUnitTest::
1805+
_testComputeOwnersDirect()
1806+
{
1807+
info() << "Test: _testComputeOwnersDirect()";
1808+
mesh()->modifier()->setDynamic(true);
1809+
mesh()->modifier()->updateGhostLayers();
1810+
mesh()->utilities()->computeAndSetOwnersForNodes();
1811+
mesh()->utilities()->computeAndSetOwnersForFaces();
1812+
}
1813+
1814+
/*---------------------------------------------------------------------------*/
1815+
/*---------------------------------------------------------------------------*/
1816+
17991817
} // End namespace ArcaneTest
18001818

18011819
/*---------------------------------------------------------------------------*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" ?>
2+
<cas codename="ArcaneTest" xml:lang="fr" codeversion="1.0">
3+
<arcane>
4+
<titre>Test Maillage 1</titre>
5+
<description>Test Maillage 1</description>
6+
<boucle-en-temps>UnitTest</boucle-en-temps>
7+
</arcane>
8+
9+
<maillage nb-ghostlayer='0' ghostlayer-builder-version="3">
10+
<fichier internal-partition="true">sod.vtk</fichier>
11+
</maillage>
12+
13+
<module-test-unitaire>
14+
<test name="MeshUnitTest">
15+
<compute-owners-direct>true</compute-owners-direct>
16+
</test>
17+
</module-test-unitaire>
18+
19+
</cas>

0 commit comments

Comments
 (0)