Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
NodeFamily.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/* NodeFamily.cc (C) 2000-2025 */
9/* */
10/* Famille de noeuds. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/NodeFamily.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/ValueConvert.h"
20
21#include "arcane/core/ISubDomain.h"
22#include "arcane/core/ItemPrinter.h"
23#include "arcane/core/VariableTypes.h"
24#include "arcane/core/IMesh.h"
26#include "arcane/core/Connectivity.h"
27#include "arcane/core/ConnectivityItemVector.h"
28#include "arcane/core/Properties.h"
29
30#include "arcane/mesh/IncrementalItemConnectivity.h"
31#include "arcane/mesh/CompactIncrementalItemConnectivity.h"
32#include "arcane/mesh/ItemConnectivitySelector.h"
33#include "arcane/mesh/AbstractItemFamilyTopologyModifier.h"
34#include "arcane/mesh/NewWithLegacyConnectivity.h"
35#include "arcane/mesh/FaceFamily.h"
36#include "arcane/mesh/EdgeFamily.h"
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41namespace Arcane::mesh
42{
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
48: public AbstractItemFamilyTopologyModifier
49{
50 public:
51 TopologyModifier(NodeFamily* f)
52 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
53 public:
54 void replaceEdge(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
55 {
56 m_true_family->replaceEdge(item_lid,index,new_lid);
57 }
58 void replaceFace(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
59 {
60 m_true_family->replaceFace(item_lid,index,new_lid);
61 }
62 void replaceCell(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
63 {
64 m_true_family->replaceCell(item_lid,index,new_lid);
65 }
66 private:
67 NodeFamily* m_true_family;
68};
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73NodeFamily::
74NodeFamily(IMesh* mesh,const String& name)
76{
77 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_SORT_FACE_AND_EDGE_OF_NODE", true)){
79 info() << "Set sort faces and edges of nodes v?=" << m_is_sort_connected_faces_and_edges;
80 }
81 _setTopologyModifier(new TopologyModifier(this));
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87NodeFamily::
88~NodeFamily()
89{
90 delete m_nodes_coords;
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96void NodeFamily::
97build()
98{
99 ItemFamily::build();
100
101 ItemTypeMng* itm = m_mesh->itemTypeMng();
102 m_node_type = itm->typeFromId(IT_Vertex);
103 if (m_parent_family)
104 m_nodes_coords = nullptr;
105 else
106 m_nodes_coords = new VariableNodeReal3(VariableBuildInfo(mesh(),"NodeCoord"));
107
108 m_face_family = ARCANE_CHECK_POINTER(dynamic_cast<FaceFamily*>(mesh()->faceFamily()));
109 m_edge_family = ARCANE_CHECK_POINTER(dynamic_cast<EdgeFamily*>(mesh()->edgeFamily()));
110
111 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
112 {
113 m_edge_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,EdgeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->edgeFamily(),connectivityName(this,mesh()->edgeFamily())));
114 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,m_face_family,connectivityName(this,mesh()->faceFamily())));
115 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->cellFamily(),connectivityName(this,mesh()->cellFamily())));
116 }
117 else
118 {
119 m_edge_connectivity = new EdgeConnectivity(this,mesh()->edgeFamily(),"NodeEdge");
120 m_face_connectivity = new FaceConnectivity(this,m_face_family,"NodeFace");
121 m_cell_connectivity = new CellConnectivity(this,mesh()->cellFamily(),"NodeCell");
122 }
123 m_hparent_connectivity = new HParentConnectivity(this, this, "HParentNode");
124 m_hchild_connectivity = new HChildConnectivity(this, this, "HChildNode");
125
126 _addConnectivitySelector(m_edge_connectivity);
127 _addConnectivitySelector(m_face_connectivity);
128 _addConnectivitySelector(m_cell_connectivity);
129 _addConnectivitySelector(m_hparent_connectivity);
130 _addConnectivitySelector(m_hchild_connectivity);
131
132 _buildConnectivitySelectors();
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
138void NodeFamily::
139preAllocate(Integer nb_item)
140{
141 this->_preAllocate(nb_item,true);
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
147void NodeFamily::
148_endAllocate()
149{
150 if (m_nodes_coords)
151 m_nodes_coords->setUsed(true);
152 ItemFamily::_endAllocate();
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158void NodeFamily::
159addCellToNode(Node node,Cell new_cell)
160{
161 _checkValidSourceTargetItems(node,new_cell);
162 Int32 cell_lid = new_cell.localId();
163 m_cell_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(cell_lid));
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
169void NodeFamily::
170addFaceToNode(Node node,Face new_face)
171{
172 if (m_no_face_connectivity)
173 return;
174
175 _checkValidSourceTargetItems(node,new_face);
176 m_face_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(new_face));
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
182void NodeFamily::
183addEdgeToNode(Node node,Edge new_edge)
184{
185 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
186 return;
187
188 _checkValidSourceTargetItems(node,new_edge);
189 m_edge_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(new_edge));
190}
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
195void NodeFamily::
196removeEdgeFromNode(ItemLocalId node,ItemLocalId edge_to_remove)
197{
198 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
199 return;
200 m_edge_connectivity->removeConnectedItem(node,edge_to_remove);
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
206void NodeFamily::
207removeFaceFromNode(ItemLocalId node,ItemLocalId face_to_remove)
208{
209 if (m_no_face_connectivity)
210 return;
211
212 m_face_connectivity->removeConnectedItem(node,face_to_remove);
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218void NodeFamily::
219removeCellFromNode(Node node,ItemLocalId cell_to_remove_lid)
220{
221 _checkValidItem(node);
222 m_cell_connectivity->removeConnectedItem(ItemLocalId(node),cell_to_remove_lid);
223}
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
230{
231 _checkValidItem(node);
232 if (!node.itemBase().isSuppressed()){
233 Integer nb_cell = node.nbCell();
234 if (nb_cell == 0)
235 _removeNode(node);
236 }
237}
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
241
244{
245 debug() << "Creating the ghosts nodes list";
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252inline void NodeFamily::
253_removeNode(Node node)
254{
255 _removeOne(node);
256 // On ne supprime pas ici les autres relations (edge->node, face->node)
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/*---------------------------------------------------------------------------*/
270{
271 m_cell_connectivity->replaceItem(node,index,cell);
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
282{
283 m_edge_connectivity->replaceItem(node,index,edge);
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
294{
295 m_face_connectivity->replaceItem(node,index,face);
296}
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
300
302setConnectivity(const Integer c)
303{
304 m_mesh_connectivity = c;
305 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
306 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Edge);
307 m_face_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Face);
308 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Cell);
309 m_face_connectivity->setPreAllocatedSize(m_face_prealloc);
310 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
311 debug() << "Family " << name() << " prealloc "
312 << m_edge_prealloc << " by edge, "
313 << m_face_prealloc << " by face, "
314 << m_cell_prealloc << " by cell.";
315 m_no_face_connectivity = !Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToFace);
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
322{
323 public:
324
325 explicit ItemCompare2(const ItemInfoListView& items)
326 : m_items(items)
327 {
328 }
329
330 public:
331
332 bool operator()(Int32 item1,Int32 item2) const
333 {
334 return m_items.uniqueId(item1) < m_items.uniqueId(item2);
335 }
336
337 private:
338
339 ItemInfoListView m_items;
340};
341
342/*---------------------------------------------------------------------------*/
343/*---------------------------------------------------------------------------*/
344
346{
347 public:
348 explicit ItemCompare3(ITraceMng* msg) : m_msg(msg) {}
349 public:
350 ITraceMng* m_msg;
351 ItemInternalArrayView m_items;
352 public:
353 bool operator()(Integer item1,Integer item2) const
354 {
355 m_msg->info() << "** Compare ptr=" << m_items.data()
356 << " i1=" << item1 << " i2=" << item2
357 << " i1=" << m_items[item1] << " i2=" << m_items[item2]
358 << " uid1=" << m_items[item1]->uniqueId()
359 << " uid2=" << m_items[item2]->uniqueId();
360 return m_items[item1]->uniqueId() < m_items[item2]->uniqueId();
361 }
362};
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
367void NodeFamily::
368_sortConnectedItems(IItemFamily* family, IncrementalItemConnectivity* connectivity)
369{
370 if (!connectivity)
371 return;
372
373 // Trie les entités connectées aux noeuds par uniqueId() croissant.
374 // Cela est utile pour garantir un ordre de parcours de ces entités
375 // identique quel que soit le découpage et ainsi améliorer
376 // la reproductibilité.
377 ItemInfoListView items_infos(family->itemInfoListView());
378 ItemCompare2 ic_items(items_infos);
379 ENUMERATE_ITEM(iitem,allItems()){
380 ItemLocalId lid(iitem.itemLocalId());
381 Int32ArrayView conn_lids = connectivity->_connectedItemsLocalId(lid);
382 std::sort(std::begin(conn_lids),std::end(conn_lids),ic_items);
383 }
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389void NodeFamily::
390sortInternalReferences()
391{
392 // Trie les mailles connectées aux noeuds par uniqueId() croissant.
393 _sortConnectedItems(mesh()->cellFamily(),m_cell_connectivity->trueCustomConnectivity());
394
395 // Fait de même pour les faces et les arêtes.
396 // Pour des raisons historiques, cela n'est pas actif par défaut.
397 bool do_sort = properties()->getBoolWithDefault("sort-connected-faces-edges",m_is_sort_connected_faces_and_edges);
398 if (do_sort){
399 info(4) << "Sorting connected faces and edges family=" << fullName();
400 _sortConnectedItems(m_face_family,m_face_connectivity->trueCustomConnectivity());
401 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
402 _sortConnectedItems(mesh()->edgeFamily(),m_edge_connectivity->trueCustomConnectivity());
403 }
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
411{
413 // Si les uniqueId() des noeuds changent, cela peut avoir une influence sur
414 // l'orientation des faces et des arêtes. Il faut donc renuméroter ces dernières
415 m_face_family->reorientFacesIfNeeded();
416 m_edge_family->reorientEdgesIfNeeded();
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422void NodeFamily::
423_addParentNodeToNode(Node parent_node, Node child_node)
424{
425 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_node), ItemLocalId(parent_node));
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431void NodeFamily::
432_addChildNodeToNode(Node parent_node, Node child_node)
433{
434 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_node), ItemLocalId(child_node));
435}
436
437/*---------------------------------------------------------------------------*/
438/*---------------------------------------------------------------------------*/
439
440} // End namespace Arcane::mesh
441
442/*---------------------------------------------------------------------------*/
443/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
Classe template pour convertir un type.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
bool isSuppressed() const
Vrai si l'entité est supprimée.
Vue sur une liste pour obtenir des informations sur les entités.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:369
Noeud d'un maillage.
Definition Item.h:582
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Definition Item.h:665
bool getBoolWithDefault(const String &name, bool default_value) const
Valeur de la propriété de nom name.
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.
Connectivité incrémentale item->item[].
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 notifyItemsUniqueIdChanged() override
Notifie que les numéros uniques des entités ont été modifiées.
void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
Properties * properties() override
Propriétés associées à cette famille.
Definition ItemFamily.h:275
String name() const override
Nom de la famille.
Definition ItemFamily.h:130
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une maille d'une entité.
Definition NodeFamily.cc:62
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une face d'une entité.
Definition NodeFamily.cc:58
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une arête d'une entité.
Definition NodeFamily.cc:54
void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
void replaceCell(ItemLocalId node, Integer index, ItemLocalId cell)
Remplace la maille d'index index du noeud node avec celle de localId() node_lid.
void removeNodeIfNotConnected(Node node)
Supprime le noeud siln'est plus connecté
void replaceFace(ItemLocalId node, Integer index, ItemLocalId face)
Remplace la face d'index index du noeud node avec celle de localId() face_lid.
void notifyItemsUniqueIdChanged() override
Notifie que les numéros uniques des entités ont été modifiées.
void setConnectivity(const Integer c)
Définit la connectivité active pour le maillage associé
void replaceEdge(ItemLocalId node, Integer index, ItemLocalId edge)
Remplace l'arête d'index index du noeud node avec celle de localId() face_lid.
ItemTypeInfo * m_node_type
Instance contenant le type des noeuds.
Definition NodeFamily.h:148
bool m_is_sort_connected_faces_and_edges
Indique si on trie les faces et arêtes connectées aux noeuds.
Definition NodeFamily.h:164
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
Int32 Integer
Type représentant un entier.
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:469
@ 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.
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
std::int32_t Int32
Type entier signé sur 32 bits.