Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
EdgeFamily.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/* EdgeFamily.cc (C) 2000-2025 */
9/* */
10/* Edge family. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/EdgeFamily.h"
15
16#include "arcane/utils/FatalErrorException.h"
17
18#include "arcane/core/IMesh.h"
19
21#include "arcane/core/ItemPrinter.h"
22#include "arcane/core/Connectivity.h"
23#include "arcane/core/NodesOfItemReorderer.h"
24
25#include "arcane/mesh/NodeFamily.h"
26#include "arcane/mesh/CompactIncrementalItemConnectivity.h"
27#include "arcane/mesh/ItemConnectivitySelector.h"
28#include "arcane/mesh/AbstractItemFamilyTopologyModifier.h"
29#include "arcane/mesh/NewWithLegacyConnectivity.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::mesh
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41: public AbstractItemFamilyTopologyModifier
42{
43 public:
44
45 TopologyModifier(EdgeFamily* f)
46 : AbstractItemFamilyTopologyModifier(f)
47 , m_true_family(f)
48 {}
49
50 public:
51
52 void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
53 {
54 m_true_family->replaceNode(item_lid, index, new_lid);
55 }
56
57 private:
58
59 EdgeFamily* m_true_family;
60};
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65EdgeFamily::
66EdgeFamily(IMesh* mesh, const String& name)
67: ItemFamily(mesh, IK_Edge, name)
68{
69 _setTopologyModifier(new TopologyModifier(this));
70}
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75EdgeFamily::
76~EdgeFamily()
77{
78}
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
83void EdgeFamily::
84build()
85{
86 ItemFamily::build();
87 ItemTypeMng* itm = m_mesh->itemTypeMng();
88 m_edge_type = itm->typeFromId(IT_Line2);
89
90 m_node_family = ARCANE_CHECK_POINTER(dynamic_cast<NodeFamily*>(m_mesh->nodeFamily()));
91
92 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
93 {
94 m_node_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily, NodeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->nodeFamily(), connectivityName(this, mesh()->nodeFamily())));
95 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily, FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->faceFamily(), connectivityName(this, mesh()->faceFamily())));
96 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily, CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->cellFamily(), connectivityName(this, mesh()->cellFamily())));
97 }
98 else {
99 m_node_connectivity = new NodeConnectivity(this, mesh()->nodeFamily(), "EdgeNode");
100 m_face_connectivity = new FaceConnectivity(this, mesh()->faceFamily(), "EdgeFace");
101 m_cell_connectivity = new CellConnectivity(this, mesh()->cellFamily(), "EdgeCell");
102 }
103
104 _addConnectivitySelector(m_node_connectivity);
105 _addConnectivitySelector(m_face_connectivity);
106 _addConnectivitySelector(m_cell_connectivity);
107
108 _buildConnectivitySelectors();
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114inline void EdgeFamily::
115_createOne(ItemInternal* item, Int64 uid)
116{
117 m_item_internal_list->edges = _itemsInternal();
118 _allocateInfos(item, uid, m_edge_type);
119 auto nc = m_node_connectivity->trueCustomConnectivity();
120 if (nc)
121 nc->addConnectedItems(ItemLocalId(item), 2);
122}
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
133allocOne(Int64 uid, ItemTypeId type_id, MeshInfos& mesh_info)
134{
135 ARCANE_ASSERT((type_id == IT_Line2), (""));
136 ARCANE_UNUSED(type_id);
137 ++mesh_info.nbEdge();
138 return allocOne(uid);
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
147allocOne(Int64 uid)
148{
149 ItemInternal* item = _allocOne(uid);
150 _createOne(item, uid);
151 return item;
152}
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
167findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos& mesh_info, bool& is_alloc)
168{
169 ARCANE_ASSERT((type_id == IT_Line2), (""));
170 ARCANE_UNUSED(type_id);
171 auto edge = findOrAllocOne(uid, is_alloc);
172 if (is_alloc)
173 ++mesh_info.nbEdge();
174 return edge;
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
186findOrAllocOne(Int64 uid, bool& is_alloc)
187{
188 ItemInternal* item = _findOrAllocOne(uid, is_alloc);
189 if (is_alloc)
190 _createOne(item, uid);
191 return item;
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197void EdgeFamily::
198preAllocate(Integer nb_item)
199{
200 if (m_has_edge) {
201 this->_preAllocate(nb_item, true);
202 }
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
210{
211 debug() << "Creating the list of ghosts edges";
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
223{
224 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_EdgeToNode))
225 return;
226 m_node_connectivity->replaceItem(edge, index, node);
227}
228
229/*---------------------------------------------------------------------------*/
230/*---------------------------------------------------------------------------*/
231
233addCellToEdge(Edge edge, Cell new_cell)
234{
235 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_EdgeToCell))
236 return;
237 _checkValidSourceTargetItems(edge, new_cell);
238 m_cell_connectivity->addConnectedItem(ItemLocalId(edge), ItemLocalId(new_cell));
239}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
245addFaceToEdge(Edge edge, Face new_face)
246{
247 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_EdgeToFace))
248 return;
249 _checkValidSourceTargetItems(edge, new_face);
250 m_face_connectivity->addConnectedItem(ItemLocalId(edge), ItemLocalId(new_face));
251}
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256inline void EdgeFamily::
257_removeEdge(Edge edge)
258{
259 for (Node node : edge.nodes())
260 m_node_family->removeEdgeFromNode(node, edge);
261 _removeOne(edge);
262 // We do not delete the other relationships here (face->edge,cell->edge)
263 // Because the deletion order must always be cell, face, edge, node
264 // so node is last and everything is already done
265 // Furthermore, this avoids recursion problems
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
272removeCellFromEdge(Edge edge, ItemLocalId cell_to_remove_lid)
273{
274 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_EdgeToCell))
275 return;
276 _checkValidItem(edge);
277 m_cell_connectivity->removeConnectedItem(ItemLocalId(edge), cell_to_remove_lid);
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
284removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
285{
286 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_EdgeToFace))
287 return;
288 m_face_connectivity->removeConnectedItem(edge, face_to_remove);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
296{
297 _checkValidItem(edge);
298 if (!edge.itemBase().isSuppressed() && edge.nbCell() == 0) {
299 _removeEdge(edge);
300 }
301}
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
308{
309 m_mesh_connectivity = c;
310 m_has_edge = Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasEdge);
311 if (m_has_edge) {
312 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Edge, IK_Node);
313 m_face_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Edge, IK_Face);
314 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Edge, IK_Cell);
315 }
316 debug() << "Family " << name() << " prealloc "
317 << m_node_prealloc << " by node, "
318 << m_face_prealloc << " by face, "
319 << m_cell_prealloc << " by cell.";
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325void EdgeFamily::
326reorientEdgesIfNeeded()
327{
328 info() << "Reorient Edges family=" << fullName();
329 // Reorients the edges if necessary. This is the case, for example, if we
330 // have changed the numbering of node uniqueIds().
331 NodesOfItemReorderer reorderer(mesh()->itemTypeMng());
332 SmallArray<Int32> new_nodes_lid;
333 IncrementalItemConnectivity* true_connectivity = m_node_connectivity->trueCustomConnectivity();
334 ENUMERATE_ (Edge, iedge, allItems()) {
335 Edge edge = *iedge;
336 ItemTypeId edge_type = edge.itemTypeId();
337 Int32 nb_node = edge.nbNode();
338 // The first node must be the one with the smallest uniqueId().
339 // If the type is ITI_Line3, the third node does not change.
340 if (edge_type == ITI_Line2 || edge_type == ITI_Line3) {
341 new_nodes_lid.resize(nb_node);
342 for (Int32 i = 0; i < nb_node; ++i)
343 new_nodes_lid[i] = edge.nodeId(i);
344 Node node0 = edge.node(0);
345 Node node1 = edge.node(1);
346 if (node0.uniqueId() > node1.uniqueId()) {
347 std::swap(new_nodes_lid[0], new_nodes_lid[1]);
348 }
349 true_connectivity->replaceConnectedItems(edge, new_nodes_lid);
350 }
351 else
352 ARCANE_FATAL("Reorientation of edge of type '{0}' not yet supported", edge_type);
353 }
354 info() << "End Edge Reorientation";
355}
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360} // End namespace Arcane::mesh
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
Utility functions for the mesh.
void resize(Int64 s)
Changes the number of elements in the array to s.
Cell of a mesh.
Definition Item.h:1300
Edge of a cell.
Definition Item.h:875
Int32 nbNode() const
Number of vertices of the edge.
Definition Item.h:972
Int32 nbCell() const
Number of cells connected to the edge.
Definition Item.h:978
Face of a cell.
Definition Item.h:1032
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual ItemTypeMng * itemTypeMng() const =0
Associated entity type manager.
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Family network interface (connected families).
bool isSuppressed() const
True if the entity is suppressed.
Internal structure of a mesh entity.
Index of an Item in a variable.
Definition ItemLocalId.h:42
Type of an entity (Item).
Definition ItemTypeId.h:33
NodeLocalId nodeId(Int32 index) const
i-th node of the entity.
Definition Item.h:849
Node node(Int32 i) const
i-th node of the entity
Definition Item.h:840
NodeConnectedListViewType nodes() const
List of nodes of the entity.
Definition Item.h:843
Base class for a mesh element.
Definition Item.h:84
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
ItemTypeId itemTypeId() const
Entity type.
Definition Item.h:258
impl::ItemBase itemBase() const
Internal part of the entity.
Definition Item.h:383
Node of a mesh.
Definition Item.h:598
Utility class to reorder the nodes of an entity.
1D data array with pre-allocated stack buffer.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a node of an entity.
Definition EdgeFamily.cc:52
void removeCellFromEdge(Edge edge, ItemLocalId cell_to_remove_lid)
Removes a cell from an edge.
virtual void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
void removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
Removes a face from an edge.
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Retrieves or allocates a unique numbered edge uid and of type type.Generic item addition.
void setConnectivity(const Integer c)
Sets the active connectivity for the associated mesh.
NodeFamily * m_node_family
Node family associated with this family.
Definition EdgeFamily.h:98
void removeEdgeIfNotConnected(Edge edge)
Removes the edge if it is no longer connected.
void addFaceToEdge(Edge edge, Face new_face)
Adds a neighboring face to an edge.
void replaceNode(ItemLocalId edge, Integer index, ItemLocalId node)
Replaces the node at index index of the edge edge with * that of localId() node_lid.
Item allocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info) override
Version called in generic item addition.
void addCellToEdge(Edge edge, Cell new_cell)
Adds a neighboring cell to an edge.
void replaceConnectedItems(ItemLocalId source_item, Int32ConstArrayView target_local_ids) override
Replaces the entities of source_item with the entities with localId() target_local_ids.
IMesh * mesh() const override
Associated mesh.
String fullName() const override
Full family name (with the mesh's name).
Definition ItemFamily.h:141
ItemGroup allItems() const override
Group of all entities.
void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
String name() const override
Family name.
Definition ItemFamily.h:140
Class containing mesh information.
Definition MeshInfos.h:36
Integer & nbEdge()
Number of edges in the mesh.
Definition MeshInfos.h:61
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
@ 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.