Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
EdgeFamily.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* Famille d'arêtes. */
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 TopologyModifier(EdgeFamily* f)
45 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
46 public:
47 void replaceNode(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
48 {
49 m_true_family->replaceNode(item_lid,index,new_lid);
50 }
51 private:
52 EdgeFamily* m_true_family;
53};
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58EdgeFamily::
59EdgeFamily(IMesh* mesh,const String& name)
61{
62 _setTopologyModifier(new TopologyModifier(this));
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68EdgeFamily::
69~EdgeFamily()
70{
71}
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76void EdgeFamily::
77build()
78{
79 ItemFamily::build();
80 ItemTypeMng* itm = m_mesh->itemTypeMng();
81 m_edge_type = itm->typeFromId(IT_Line2);
82
83 m_node_family = ARCANE_CHECK_POINTER(dynamic_cast<NodeFamily*>(m_mesh->nodeFamily()));
84
85 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
86 {
87 m_node_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily,NodeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->nodeFamily(),connectivityName(this,mesh()->nodeFamily())));
88 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily,FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->faceFamily(),connectivityName(this,mesh()->faceFamily())));
89 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<EdgeFamily,CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->cellFamily(),connectivityName(this,mesh()->cellFamily())));
90 }
91 else
92 {
93 m_node_connectivity = new NodeConnectivity(this,mesh()->nodeFamily(),"EdgeNode");
94 m_face_connectivity = new FaceConnectivity(this,mesh()->faceFamily(),"EdgeFace");
95 m_cell_connectivity = new CellConnectivity(this,mesh()->cellFamily(),"EdgeCell");
96 }
97
98 _addConnectivitySelector(m_node_connectivity);
99 _addConnectivitySelector(m_face_connectivity);
100 _addConnectivitySelector(m_cell_connectivity);
101
102 _buildConnectivitySelectors();
103}
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108inline void EdgeFamily::
109_createOne(ItemInternal* item,Int64 uid)
110{
111 m_item_internal_list->edges = _itemsInternal();
112 _allocateInfos(item,uid,m_edge_type);
113 auto nc = m_node_connectivity->trueCustomConnectivity();
114 if (nc)
115 nc->addConnectedItems(ItemLocalId(item),2);
116}
117
118/*---------------------------------------------------------------------------*/
119/*---------------------------------------------------------------------------*/
127allocOne(Int64 uid,ItemTypeId type_id, MeshInfos& mesh_info)
128{
129 ARCANE_ASSERT((type_id == IT_Line2),(""));
130 ARCANE_UNUSED(type_id);
131 ++mesh_info.nbEdge();
132 return allocOne(uid);
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
141allocOne(Int64 uid)
142{
143 ItemInternal* item = _allocOne(uid);
144 _createOne(item,uid);
145 return item;
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
161findOrAllocOne(Int64 uid,ItemTypeId type_id,MeshInfos& mesh_info, bool& is_alloc)
162{
163 ARCANE_ASSERT((type_id == IT_Line2),(""));
164 ARCANE_UNUSED(type_id);
165 auto edge = findOrAllocOne(uid,is_alloc);
166 if (is_alloc)
167 ++mesh_info.nbEdge();
168 return edge;
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
180findOrAllocOne(Int64 uid,bool& is_alloc)
181{
182 ItemInternal* item = _findOrAllocOne(uid,is_alloc);
183 if (is_alloc)
184 _createOne(item,uid);
185 return item;
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191void EdgeFamily::
192preAllocate(Integer nb_item)
193{
194 if (m_has_edge) {
195 this->_preAllocate(nb_item,true);
196 }
197}
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201
204{
205 debug() << "Creating the list of ghosts edges";
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
217{
218 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_EdgeToNode))
219 return;
220 m_node_connectivity->replaceItem(edge,index,node);
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
227addCellToEdge(Edge edge,Cell new_cell)
228{
229 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_EdgeToCell))
230 return;
231 _checkValidSourceTargetItems(edge,new_cell);
232 m_cell_connectivity->addConnectedItem(ItemLocalId(edge),ItemLocalId(new_cell));
233}
234
235/*---------------------------------------------------------------------------*/
236/*---------------------------------------------------------------------------*/
237
239addFaceToEdge(Edge edge,Face new_face)
240{
241 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_EdgeToFace))
242 return;
243 _checkValidSourceTargetItems(edge,new_face);
244 m_face_connectivity->addConnectedItem(ItemLocalId(edge),ItemLocalId(new_face));
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250inline void EdgeFamily::
251_removeEdge(Edge edge)
252{
253 for( Node node : edge.nodes() )
254 m_node_family->removeEdgeFromNode(node,edge);
255 _removeOne(edge);
256 // On ne supprime pas ici les autres relations (face->edge,cell->edge)
257 // Car l'ordre de suppression doit toujours être cell, face, edge, node
258 // donc node est en dernier et tout est déjà fait
259 // Par ailleurs, cela évite des problèmes de récursivité
260}
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
264
266removeCellFromEdge(Edge edge,ItemLocalId cell_to_remove_lid)
267{
268 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_EdgeToCell))
269 return;
270 _checkValidItem(edge);
271 m_cell_connectivity->removeConnectedItem(ItemLocalId(edge),cell_to_remove_lid);
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
278removeFaceFromEdge(ItemLocalId edge,ItemLocalId face_to_remove)
279{
280 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_EdgeToFace))
281 return;
282 m_face_connectivity->removeConnectedItem(edge,face_to_remove);
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
290{
291 _checkValidItem(edge);
292 if (!edge.itemBase().isSuppressed() && edge.nbCell()==0){
293 _removeEdge(edge);
294 }
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
301setConnectivity(const Integer c)
302{
303 m_mesh_connectivity = c;
304 m_has_edge = Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge);
305 if (m_has_edge) {
306 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Edge,IK_Node);
307 m_face_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Edge,IK_Face);
308 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Edge,IK_Cell);
309 }
310 debug() << "Family " << name() << " prealloc "
311 << m_node_prealloc << " by node, "
312 << m_face_prealloc << " by face, "
313 << m_cell_prealloc << " by cell.";
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319void EdgeFamily::
320reorientEdgesIfNeeded()
321{
322 info() << "Reorient Edges family=" << fullName();
323 // Réoriente les arêtes si nécessaire. Cela est le cas par exemple si on
324 // a changé la numérotation des uniqueId() des noeuds.
325 NodesOfItemReorderer reorderer(mesh()->itemTypeMng());
326 SmallArray<Int32> new_nodes_lid;
327 IncrementalItemConnectivity* true_connectivity = m_node_connectivity->trueCustomConnectivity();
328 ENUMERATE_ (Edge, iedge, allItems()) {
329 Edge edge = *iedge;
330 ItemTypeId edge_type = edge.itemTypeId();
331 Int32 nb_node = edge.nbNode();
332 // Il faut que le premier noeud soit celui de plus petit uniqueId().
333 // Si le type est ITI_Line3, le troisième noeud ne change pas.
334 if (edge_type == ITI_Line2 || edge_type == ITI_Line3) {
335 new_nodes_lid.resize(nb_node);
336 for (Int32 i = 0; i < nb_node; ++i)
337 new_nodes_lid[i] = edge.nodeId(i);
338 Node node0 = edge.node(0);
339 Node node1 = edge.node(1);
340 if (node0.uniqueId() > node1.uniqueId()) {
341 std::swap(new_nodes_lid[0], new_nodes_lid[1]);
342 }
343 true_connectivity->replaceConnectedItems(edge, new_nodes_lid);
344 }
345 else
346 ARCANE_FATAL("Reorientation of edge of type '{0}' not yet supported", edge_type);
347 }
348 info() << "End Edge Reorientation";
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
354} // End namespace Arcane::mesh
355
356/*---------------------------------------------------------------------------*/
357/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Fonctions utilitaires sur le maillage.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Maille d'un maillage.
Definition Item.h:1214
Arête d'une maille.
Definition Item.h:826
Int32 nbNode() const
Nombre de sommets de l'arête.
Definition Item.h:904
Int32 nbCell() const
Nombre de mailles connectées à l'arête.
Definition Item.h:910
Face d'une maille.
Definition Item.h:964
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual ItemTypeMng * itemTypeMng() const =0
Gestionnaire de types d'entités associé
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Interface du réseau de familles (familles connectées)
bool isSuppressed() const
Vrai si l'entité est supprimée.
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Type d'une entité (Item).
Definition ItemTypeId.h:32
NodeLocalId nodeId(Int32 index) const
i-ème noeud de l'entité.
Definition Item.h:800
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:791
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:794
Classe de base d'un élément de maillage.
Definition Item.h:83
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
ItemTypeId itemTypeId() const
Type de l'entité
Definition Item.h:244
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:369
Noeud d'un maillage.
Definition Item.h:582
Classe utilitaire pour réordonner les noeuds d'une entité.
Tableau 1D de données avec buffer pré-alloué sur la pile.
Chaîne de caractères unicode.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace un noeud d'une entité.
Definition EdgeFamily.cc:47
void removeCellFromEdge(Edge edge, ItemLocalId cell_to_remove_lid)
Supprime une maille d'une arête.
virtual void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
void removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
Supprime une maille d'une arête.
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Récupère ou alloue une arête de numéro unique uid et de type type.Ajout générique d'item.
void setConnectivity(const Integer c)
Définit la connectivité active pour le maillage associé
NodeFamily * m_node_family
Famille des noeuds associée à cette famille.
Definition EdgeFamily.h:98
void removeEdgeIfNotConnected(Edge edge)
Supprime l'arête si elle n'est plus connectée.
void addFaceToEdge(Edge edge, Face new_face)
Ajoute une maille voisine à une arête.
void replaceNode(ItemLocalId edge, Integer index, ItemLocalId node)
Remplace le noeud d'index index de l'arête edge avec celui de localId() node_lid.
Item allocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info) override
Version appelées dans l'ajout générique d'item.
void addCellToEdge(Edge edge, Cell new_cell)
Ajoute une maille voisine à une arête.
Connectivité incrémentale item->item[].
void replaceConnectedItems(ItemLocalId source_item, Int32ConstArrayView target_local_ids) override
Remplace les entités de source_item par les entités de localId() target_local_ids.
Famille d'entités.
Definition ItemFamily.h:76
IMesh * mesh() const override
Maillage associé
String fullName() const override
Nom complet de la famille (avec celui du maillage)
Definition ItemFamily.h:131
ItemGroup allItems() const override
Groupe de toutes les entités.
void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
String name() const override
Nom de la famille.
Definition ItemFamily.h:130
Classe factorisant des informations sur le maillage.
Definition MeshInfos.h:36
Integer & nbEdge()
Nombre d'arêtes dans le maillage.
Definition MeshInfos.h:60
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
@ 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.
std::int32_t Int32
Type entier signé sur 32 bits.