Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MeshUtils2.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MeshUtils2.cc (C) 2000-2025 */
9/* */
10/* Various utility functions on the mesh. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
15
16#include "arcane/utils/SmallArray.h"
17#include "arcane/utils/HashTableMap2.h"
18#include "arcane/utils/CheckedConvert.h"
19
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IItemFamily.h"
22#include "arcane/core/Item.h"
24#include "arcane/core/ItemGroup.h"
25#include "arcane/core/IIndexedIncrementalItemConnectivityMng.h"
26#include "arcane/core/IIndexedIncrementalItemConnectivity.h"
27#include "arcane/core/IIncrementalItemConnectivity.h"
28#include "arcane/core/IParallelMng.h"
29
30#include <set>
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane
36{
37
38namespace
39{
40 class NodeNodeConnectivityHelper
41 {
42 public:
43
44 NodeNodeConnectivityHelper(IMesh* mesh, const String& connectivity_name)
45 : node_family(mesh->nodeFamily())
46 {
47 auto connectivity_mng = mesh->indexedConnectivityMng();
48 connectivity_ref = connectivity_mng->findOrCreateConnectivity(node_family, node_family, connectivity_name);
49 item_connectivity = connectivity_ref->connectivity();
50 }
51
52 public:
53
54 void addCurrentNodeSetToNode(NodeLocalId node_lid)
55 {
56 // Adds the entities to the node.
57 {
58 Int32 nb_node = CheckedConvert::toInt32(node_set.size());
59 if (nb_node == 0)
60 return;
61 connected_items_ids.resize(nb_node);
62 Int32 index = 0;
63 for (auto x : node_set) {
64 connected_items_ids[index] = x;
65 ++index;
66 }
67 item_connectivity->setConnectedItems(node_lid, connected_items_ids);
68 }
69 node_set.clear();
70 }
71
72 public:
73
74 IItemFamily* node_family = nullptr;
75 Ref<IIndexedIncrementalItemConnectivity> connectivity_ref;
76
77 // Set of nodes connected to a node
78 // We use a 'std::set' because we want to sort by increasing localId()
79 // to always have the same order.
80 std::set<Int32> node_set;
81
82 private:
83
84 //! Working array of nodes connected to another node
85 SmallArray<Int32> connected_items_ids;
86
87 IIncrementalItemConnectivity* item_connectivity = nullptr;
88 };
89} // namespace
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
95computeNodeNodeViaEdgeConnectivity(IMesh* mesh, const String& connectivity_name)
96{
98 NodeNodeConnectivityHelper helper(mesh, connectivity_name);
99
100 // To create the connectivity, iterate over all connected cells
101 // nodes and then the set of edges of this cell.
102 // If one of the two nodes of the edge is my node, add it
103 // to the connectivity.
104 ENUMERATE_ (Node, inode, helper.node_family->allItems()) {
105 Node node = *inode;
106 NodeLocalId node_lid(node.localId());
107 for (Cell cell : node.cells()) {
108 const ItemTypeInfo* t = cell.typeInfo();
109 for (Int32 i = 0, n = t->nbLocalEdge(); i < n; ++i) {
111 NodeLocalId node0_lid = cell.nodeId(e.beginNode());
112 NodeLocalId node1_lid = cell.nodeId(e.endNode());
113 if (node0_lid == node_lid)
114 helper.node_set.insert(node1_lid);
115 if (node1_lid == node_lid)
116 helper.node_set.insert(node0_lid);
117 }
118 }
119 // Adds the entities to the node.
120 helper.addCurrentNodeSetToNode(node_lid);
121 }
122
123 return helper.connectivity_ref;
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
130computeBoundaryNodeNodeViaEdgeConnectivity(IMesh* mesh, const String& connectivity_name)
131{
134 NodeNodeConnectivityHelper helper(mesh, connectivity_name);
135
137 Int32 my_rank = mesh->parallelMng()->commRank();
138 // First, add to boundary_node_map the list of nodes
139 // located on the boundary faces.
140 ENUMERATE_ (Face, iface, mesh->allFaces()) {
141 Face face = *iface;
142 Int32 nb_cell = face.nbCell();
143 if (nb_cell == 2) {
144 Int32 nb_own = 0;
145 // If two connected cells, only one of the owners
146 // of these two cells is mine (otherwise it is an internal face and thus we
147 // do not process it).
148 if (face.cell(0).owner() == my_rank)
149 ++nb_own;
150 if (face.cell(1).owner() == my_rank)
151 ++nb_own;
152 if (nb_own != 1)
153 continue;
154 }
155 // If only one cell, the face must belong to me.
156 if (!face.isOwn())
157 continue;
158 for (NodeLocalId node_id : face.nodeIds())
159 boundary_node_map.add(node_id, true);
160 }
161 // Now, iterate over the boundary nodes.
162 // For each one, iterate over the edges of the cells connected to this node
163 // and add the corresponding node if it is also on the boundary
164 // (in this case, it is also in boundary_node_map).
165 NodeLocalIdToNodeConverter nodes(helper.node_family);
166 for (auto [node_lid, _] : boundary_node_map) {
167 Node node = nodes[node_lid];
168 for (Cell cell : node.cells()) {
169 const ItemTypeInfo* t = cell.typeInfo();
170 for (Int32 i = 0, n = t->nbLocalEdge(); i < n; ++i) {
172 NodeLocalId node0_lid = cell.nodeId(e.beginNode());
173 NodeLocalId node1_lid = cell.nodeId(e.endNode());
174 Int32 other_node_lid = NULL_ITEM_LOCAL_ID;
175 if (node0_lid == node_lid)
176 other_node_lid = node1_lid;
177 if (node1_lid == node_lid)
178 other_node_lid = node0_lid;
179 if (other_node_lid != NULL_ITEM_LOCAL_ID && boundary_node_map.contains(other_node_lid))
180 helper.node_set.insert(other_node_lid);
181 }
182 }
183 helper.addCurrentNodeSetToNode(NodeLocalId(node_lid));
184 }
185 return helper.connectivity_ref;
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191} // namespace Arcane
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
Types and macros for iterating over mesh entities.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
Utility functions for the mesh.
Cell of a mesh.
Definition Item.h:1300
Face of a cell.
Definition Item.h:1032
Cell cell(Int32 i) const
i-th cell of the face
Definition Item.h:1793
Int32 nbCell() const
Number of cells of the face (1 or 2).
Definition Item.h:1129
Local information about a cell edge.
Integer endNode() const
Local index in the cell of the ending node of the edge.
Integer beginNode() const
Local index in the cell of the starting node of the edge.
Info on a mesh entity type.
LocalEdge localEdge(Integer id) const
Local connectivity of the i-th edge of the cell.
Integer nbLocalEdge() const
Number of edges of the entity.
NodeLocalIdView nodeIds() const
List of nodes of the entity.
Definition Item.h:846
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
Int32 owner() const
Owner subdomain number of the entity.
Definition Item.h:252
constexpr bool isOwn() const
true if the entity belongs to the subdomain
Definition Item.h:267
Class to convert a NodeLocalId to an edge.
Node of a mesh.
Definition Item.h:598
CellConnectedListViewType cells() const
List of cells of the node.
Definition Item.h:728
Reference to an instance.
Implementation of std::unordered_map.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int32_t Int32
Signed integer type of 32 bits.