Arcane  v3.14.10.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-2024 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-2024 */
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
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane::mesh
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
48{
49 public:
51 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
52 public:
53 void replaceEdge(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
54 {
55 m_true_family->replaceEdge(item_lid,index,new_lid);
56 }
57 void replaceFace(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
58 {
59 m_true_family->replaceFace(item_lid,index,new_lid);
60 }
61 void replaceCell(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
62 {
63 m_true_family->replaceCell(item_lid,index,new_lid);
64 }
65 private:
66 NodeFamily* m_true_family;
67};
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72NodeFamily::
73NodeFamily(IMesh* mesh,const String& name)
74: ItemFamily(mesh,IK_Node,name)
75{
76 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_SORT_FACE_AND_EDGE_OF_NODE", true)){
78 info() << "Set sort faces and edges of nodes v?=" << m_is_sort_connected_faces_and_edges;
79 }
80 _setTopologyModifier(new TopologyModifier(this));
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86NodeFamily::
87~NodeFamily()
88{
89 delete m_nodes_coords;
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95void NodeFamily::
96build()
97{
98 ItemFamily::build();
99
100 ItemTypeMng* itm = m_mesh->itemTypeMng();
101 m_node_type = itm->typeFromId(IT_Vertex);
102 if (m_parent_family)
103 m_nodes_coords = nullptr;
104 else
105 m_nodes_coords = new VariableNodeReal3(VariableBuildInfo(mesh(),"NodeCoord"));
106
107 m_face_family = ARCANE_CHECK_POINTER(dynamic_cast<FaceFamily*>(mesh()->faceFamily()));
108
109 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
110 {
111 m_edge_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,EdgeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->edgeFamily(),connectivityName(this,mesh()->edgeFamily())));
112 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,m_face_family,connectivityName(this,mesh()->faceFamily())));
113 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<NodeFamily,CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->cellFamily(),connectivityName(this,mesh()->cellFamily())));
114 }
115 else
116 {
117 m_edge_connectivity = new EdgeConnectivity(this,mesh()->edgeFamily(),"NodeEdge");
118 m_face_connectivity = new FaceConnectivity(this,m_face_family,"NodeFace");
119 m_cell_connectivity = new CellConnectivity(this,mesh()->cellFamily(),"NodeCell");
120 }
121 m_hparent_connectivity = new HParentConnectivity(this, this, "HParentNode");
122 m_hchild_connectivity = new HChildConnectivity(this, this, "HChildNode");
123
124 _addConnectivitySelector(m_edge_connectivity);
125 _addConnectivitySelector(m_face_connectivity);
126 _addConnectivitySelector(m_cell_connectivity);
127 _addConnectivitySelector(m_hparent_connectivity);
128 _addConnectivitySelector(m_hchild_connectivity);
129
130 _buildConnectivitySelectors();
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136void NodeFamily::
137preAllocate(Integer nb_item)
138{
139 this->_preAllocate(nb_item,true);
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145void NodeFamily::
146_endAllocate()
147{
148 if (m_nodes_coords)
149 m_nodes_coords->setUsed(true);
150 ItemFamily::_endAllocate();
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156void NodeFamily::
157addCellToNode(Node node,Cell new_cell)
158{
159 _checkValidSourceTargetItems(node,new_cell);
160 Int32 cell_lid = new_cell.localId();
161 m_cell_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(cell_lid));
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
167void NodeFamily::
168addFaceToNode(Node node,Face new_face)
169{
170 if (m_no_face_connectivity)
171 return;
172
173 _checkValidSourceTargetItems(node,new_face);
174 m_face_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(new_face));
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180void NodeFamily::
181addEdgeToNode(Node node,Edge new_edge)
182{
183 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
184 return;
185
186 _checkValidSourceTargetItems(node,new_edge);
187 m_edge_connectivity->addConnectedItem(ItemLocalId(node),ItemLocalId(new_edge));
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
193void NodeFamily::
194removeEdgeFromNode(ItemLocalId node,ItemLocalId edge_to_remove)
195{
196 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
197 return;
198 m_edge_connectivity->removeConnectedItem(node,edge_to_remove);
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204void NodeFamily::
205removeFaceFromNode(ItemLocalId node,ItemLocalId face_to_remove)
206{
207 if (m_no_face_connectivity)
208 return;
209
210 m_face_connectivity->removeConnectedItem(node,face_to_remove);
211}
212
213/*---------------------------------------------------------------------------*/
214/*---------------------------------------------------------------------------*/
215
216void NodeFamily::
217removeCellFromNode(Node node,ItemLocalId cell_to_remove_lid)
218{
219 _checkValidItem(node);
220 m_cell_connectivity->removeConnectedItem(ItemLocalId(node),cell_to_remove_lid);
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
228{
229 _checkValidItem(node);
230 if (!node.itemBase().isSuppressed()){
231 Integer nb_cell = node.nbCell();
232 if (nb_cell == 0)
233 _removeNode(node);
234 }
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
242{
243 debug() << "Creating the ghosts nodes list";
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250inline void NodeFamily::
251_removeNode(Node node)
252{
253 _removeOne(node);
254 // On ne supprime pas ici les autres relations (edge->node, face->node)
255 // Car l'ordre de suppression doit toujours être cell, face, edge, node
256 // donc node est en dernier et tout est déjà fait
257 // Par ailleurs, cela évite des problèmes de récursivité
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
267replaceCell(ItemLocalId node,Integer index,ItemLocalId cell)
268{
269 m_cell_connectivity->replaceItem(node,index,cell);
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
279replaceEdge(ItemLocalId node,Integer index,ItemLocalId edge)
280{
281 m_edge_connectivity->replaceItem(node,index,edge);
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
291replaceFace(ItemLocalId node,Integer index,ItemLocalId face)
292{
293 m_face_connectivity->replaceItem(node,index,face);
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
300setConnectivity(const Integer c)
301{
302 m_mesh_connectivity = c;
303 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
304 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Edge);
305 m_face_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Face);
306 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Node,IK_Cell);
307 m_face_connectivity->setPreAllocatedSize(m_face_prealloc);
308 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
309 debug() << "Family " << name() << " prealloc "
310 << m_edge_prealloc << " by edge, "
311 << m_face_prealloc << " by face, "
312 << m_cell_prealloc << " by cell.";
313 m_no_face_connectivity = !Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToFace);
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
320{
321 public:
322
323 explicit ItemCompare2(const ItemInfoListView& items)
324 : m_items(items)
325 {
326 }
327
328 public:
329
330 bool operator()(Int32 item1,Int32 item2) const
331 {
332 return m_items.uniqueId(item1) < m_items.uniqueId(item2);
333 }
334
335 private:
336
337 ItemInfoListView m_items;
338};
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
344{
345 public:
346 explicit ItemCompare3(ITraceMng* msg) : m_msg(msg) {}
347 public:
348 ITraceMng* m_msg;
349 ItemInternalArrayView m_items;
350 public:
351 bool operator()(Integer item1,Integer item2) const
352 {
353 m_msg->info() << "** Compare ptr=" << m_items.data()
354 << " i1=" << item1 << " i2=" << item2
355 << " i1=" << m_items[item1] << " i2=" << m_items[item2]
356 << " uid1=" << m_items[item1]->uniqueId()
357 << " uid2=" << m_items[item2]->uniqueId();
358 return m_items[item1]->uniqueId() < m_items[item2]->uniqueId();
359 }
360};
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365void NodeFamily::
366_sortConnectedItems(IItemFamily* family, IncrementalItemConnectivity* connectivity)
367{
368 if (!connectivity)
369 return;
370
371 // Trie les entités connectées aux noeuds par uniqueId() croissant.
372 // Cela est utile pour garantir un ordre de parcours de ces entités
373 // identique quel que soit le découpage et ainsi améliorer
374 // la reproductibilité.
378 ItemLocalId lid(iitem.itemLocalId());
379 Int32ArrayView conn_lids = connectivity->_connectedItemsLocalId(lid);
380 std::sort(std::begin(conn_lids),std::end(conn_lids),ic_items);
381 }
382}
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
387void NodeFamily::
388sortInternalReferences()
389{
390 // Trie les mailles connectées aux noeuds par uniqueId() croissant.
391 _sortConnectedItems(mesh()->cellFamily(),m_cell_connectivity->trueCustomConnectivity());
392
393 // Fait de même pour les faces et les arêtes.
394 // Pour des raisons historiques, cela n'est pas actif par défaut.
395 bool do_sort = properties()->getBoolWithDefault("sort-connected-faces-edges",m_is_sort_connected_faces_and_edges);
396 if (do_sort){
397 info(4) << "Sorting connected faces and edges family=" << fullName();
398 _sortConnectedItems(m_face_family,m_face_connectivity->trueCustomConnectivity());
399 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_NodeToEdge))
400 _sortConnectedItems(mesh()->edgeFamily(),m_edge_connectivity->trueCustomConnectivity());
401 }
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
409{
411 // Si les uniqueId() des noeuds changent, cela peut avoir une influence sur
412 // l'orientation des faces. Il faut donc renuméroter ces dernières
413 if (m_face_family)
414 m_face_family->reorientFacesIfNeeded();
415}
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
419
420void NodeFamily::
421_addParentNodeToNode(Node parent_node, Node child_node)
422{
423 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_node), ItemLocalId(parent_node));
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429void NodeFamily::
430_addChildNodeToNode(Node parent_node, Node child_node)
431{
432 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_node), ItemLocalId(child_node));
433}
434
435/*---------------------------------------------------------------------------*/
436/*---------------------------------------------------------------------------*/
437
438} // End namespace Arcane::mesh
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
#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.
Interface d'une famille d'entités.
virtual ItemInfoListView itemInfoListView()=0
Vue sur la liste d'informations sur les entités.
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.
Vue sur une liste pour obtenir des informations sur les entités.
Index d'un Item dans une variable.
Definition ItemLocalId.h:40
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Noeud d'un maillage.
Definition Dom.h:204
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Definition Item.h:643
bool getBoolWithDefault(const String &name, bool default_value) const
Valeur de la propriété de nom name.
Modification de la topologie des entités d'une famille.
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:126
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:263
String name() const override
Nom de la famille.
Definition ItemFamily.h:125
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une maille d'une entité.
Definition NodeFamily.cc:61
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une face d'une entité.
Definition NodeFamily.cc:57
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une arête d'une entité.
Definition NodeFamily.cc:53
Famille de noeuds.
Definition NodeFamily.h:37
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:163
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
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.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
@ 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.