Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ConnectivityNewWithDependenciesTypes.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* ConnectivityNewWithDependenciesTypes.h (C) 2000-2022 */
9/* */
10/* Types utilisés dans le mode connectivités avec dépendances des familles */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_MESH_CONNECTIVITYNEWWITHDEPENDENCIESTYPES_H_
13#define ARCANE_MESH_CONNECTIVITYNEWWITHDEPENDENCIESTYPES_H_
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18
19#include "arcane/mesh/MeshGlobal.h"
20#include "arcane/mesh/FaceFamily.h"
21#include "arcane/mesh/CellFamily.h"
22#include "arcane/IMesh.h"
23#include "arcane/ItemInternal.h"
24#include "arcane/ItemTypeInfo.h"
25#include "arcane/MeshUtils.h"
26#include "arcane/ConnectivityItemVector.h"
27#include "arcane/IItemFamilyNetwork.h"
28#include "arcane/ItemPrinter.h"
29
30#include "arcane/mesh/IncrementalItemConnectivity.h"
31#include "arcane/mesh/CompactIncrementalItemConnectivity.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::mesh
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42typedef IncrementalItemConnectivity ConnectivityType; // standard connectivity type
43
44template <class SourceFamily, class TargetFamily>
45class ARCANE_MESH_EXPORT CustomConnectivity
46{
47public:
48 typedef ConnectivityType type;
49};
50
51template <class SourceFamily>
54
55template <>
57{
58public:
60};
61
62template <>
64{
65public:
67};
68
69template <>
71{
72public:
74};
75
76template <>
78{
79public:
81};
82
83
84template <class SourceFamily, class TargetFamily>
85class ARCANE_MESH_EXPORT LegacyConnectivity
86{
87public:
89};
90
91
92static String connectivityName(IItemFamily* source_family, IItemFamily* target_family)
93{
94 return String::concat(source_family->name(),target_family->name());
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
102 class FaceToCellConnectivity
103 {
104 public:
105 FaceToCellConnectivity(IItemFamily* source_family,IItemFamily* target_family)
106 : m_face_family(nullptr)
107 , m_cell_family(nullptr) {
108 if (source_family->itemKind() != IK_Face || target_family->itemKind()!= IK_Cell)
109 throw FatalErrorException("FaceToCellIncrementalConnectivity must be created with face family as source and cell family as target. Exiting.");
110 m_face_family = dynamic_cast<FaceFamily*>(source_family);
111 m_cell_family = dynamic_cast<CellFamily*>(target_family);
112 // todo supprimer le cast, le type concret n'est plus nécessaire
113 }
114
115 protected:
116 bool isFrontCell(ItemLocalId source_item,ItemLocalId target_item)
117 {
118 ItemInternal* face = m_face_family->itemsInternal()[source_item.localId()];
119 ItemInternal* cell = m_cell_family->itemsInternal()[target_item.localId()];
120 // Find if cell is front or back for given face
121 // get face and cell nodes
122 IMesh* mesh = m_face_family->mesh();
123 ConnectivityItemVector face_nodes_connectivity(mesh->itemFamilyNetwork()->getConnectivity(m_face_family,mesh->nodeFamily(), connectivityName(m_face_family,mesh->nodeFamily())));
124 ItemVectorView face_nodes = face_nodes_connectivity.connectedItems(Face(face));
125 ConnectivityItemVector cell_nodes_connectivity(mesh->itemFamilyNetwork()->getConnectivity(m_cell_family,mesh->nodeFamily(), connectivityName(m_cell_family,mesh->nodeFamily())));
126 ItemVectorView cell_nodes = cell_nodes_connectivity.connectedItems(Cell(cell));
127 ItemTypeInfo* cell_type_info = cell->typeInfo();
128 // Find which local_face
129 Integer face_index = -1;
130 Int64UniqueArray face_node_uids;
131 for (const auto& node : face_nodes)
132 face_node_uids.add(node.uniqueId().asInt64());
133 std::set<Int64> face_nodes_set(face_node_uids.begin(),face_node_uids.end());
134 Int64UniqueArray local_face_node_uids;
135 for (Integer local_face_index = 0; local_face_index < cell_type_info->nbLocalFace() && face_index == -1; ++local_face_index)
136 {
137 local_face_node_uids.clear();
138 ItemTypeInfo::LocalFace local_face = cell_type_info->localFace(local_face_index);
139 if (local_face.nbNode() != face_nodes.size()) continue;
140 for (Integer local_node_index = 0; local_node_index < local_face.nbNode() ; ++local_node_index) local_face_node_uids.add(cell_nodes[local_face.node(local_node_index)].uniqueId().asInt64());
141 std::set<Int64> local_face_nodes_set(local_face_node_uids.begin(),local_face_node_uids.end());
142 if (local_face_nodes_set == face_nodes_set) face_index = local_face_index; // we found the face in the cell
143 }
144 if (face_index == -1) throw FatalErrorException(String::format("Face {0} does not belong to Cell {1}. Cannot connect. Exiting."));
145 if (mesh->dimension() == 1) // 1d mesh : back cell is local face 0, front is local face 1
146 return (face_index == 1);
147 else
148 {
149 UniqueArray<Int64> ordered_face_node_ids(face_node_uids.size());
150 if (mesh_utils::reorderNodesOfFace(local_face_node_uids,ordered_face_node_ids)) return true;
151 else return false;
152 }
153}
154
155void _checkValidSourceTargetItems(ItemInternal* source,ItemInternal* target)
156{
157#ifdef ARCANE_CHECK
158 arcaneThrowIfNull(source,"source","Invalid null source item");
159 arcaneThrowIfNull(target,"target","Invalid null target item");
160#else
161 ARCANE_UNUSED(source);
162 ARCANE_UNUSED(target);
163#endif
164}
165
166 protected:
167 FaceFamily* m_face_family;
168 CellFamily* m_cell_family;
169
170 };
171
172/*---------------------------------------------------------------------------*/
173/*---------------------------------------------------------------------------*/
177class ARCANE_MESH_EXPORT FaceToCellIncrementalItemConnectivity
178: public FaceToCellConnectivity
179, public IncrementalItemConnectivity
180{
181public:
182 FaceToCellIncrementalItemConnectivity(IItemFamily* source_family,IItemFamily* target_family,const String& aname)
183 : FaceToCellConnectivity(source_family,target_family)
184 , IncrementalItemConnectivity(source_family,target_family,aname){}
185
186 virtual ~FaceToCellIncrementalItemConnectivity() {}
187
188// const String& name() const override {return m_item_connectivity.name();}
189// ConstArrayView<IItemFamily*> families() const override {return m_item_connectivity.families();}
190// IItemFamily* sourceFamily() const override {return m_item_connectivity.sourceFamily();}
191// IItemFamily* targetFamily() const override {return m_item_connectivity.targetFamily();}
192
193 void addConnectedItem(ItemLocalId source_item,ItemLocalId target_item) override
194 {
195
196 if (isFrontCell(source_item,target_item))
197 _addFrontCellToFace(m_face_family->itemsInternal()[source_item.localId()],m_cell_family->itemsInternal()[target_item.localId()]);
198 else
199 _addBackCellToFace(m_face_family->itemsInternal()[source_item.localId()],m_cell_family->itemsInternal()[target_item.localId()]);
200 }
201
202public :
203
204 void removeConnectedItem(ItemLocalId source_item,ItemLocalId target_item) override
205 {
206 _removeConnectedItem(m_face_family->itemsInternal()[source_item.localId()],target_item);
207 }
208
209
210private:
211
212
213 void _addFrontCellToFace(ItemInternal* face, ItemInternal* cell){
214 _checkValidSourceTargetItems(face,cell);
215
216 Integer nb_cell = nbConnectedItem(ItemLocalId(face));
217
218 // SDP: les tests suivants sont imcompatibles avec le raffinement
219 // par couches
220 // SDC: dans l'etat le check ne peut etre fait car les flags sont positionnes par la connectivite legacy.
221 // On peut donc avoir une front_cell qui n'est pas dans cette connectivite. C'est donc legal et de plus
222 // le check va planter puisque connectedItemLocalId(ItemLocalId(face),1) va retourner -1...
223 // Dans le nouveau mode les check devront etre faits via des proprietes.
224 const bool check_orientation = false; // SDC cf. ci-dessus
225 if (check_orientation){
226 if (face->flags() & ItemFlags::II_HasFrontCell){
227 ItemInternal* current_cell = m_cell_family->itemsInternal()[connectedItemLocalId(ItemLocalId(face),1)]; // FrontCell is the second connected cell
228 ARCANE_FATAL("Face already having a front cell."
229 " This is most probably due to the fact that the face"
230 " is connected to a reverse cell with a negative volume."
231 " Face={0}. new_cell={1} current_cell={2}",face->uniqueId().asInt64(),
232 cell->uniqueId().asInt64(),current_cell->uniqueId().asInt64()); // FullItemPrinter cannot be used here, the connectivities are not entirely set
233 }
234 }
235
236 if (nb_cell>=2)
237 ARCANE_FATAL("face '{0}' already has two cells",face->uniqueId().asInt64());// FullItemPrinter cannot be used here, the connectivities are not entirely set
238
239 // Si on a déjà une maille, il s'agit de la back cell.
240 Int32 iback_cell_lid = (nb_cell==1) ? face->cellId(0) : NULL_ITEM_LOCAL_ID;
241 ItemLocalId back_cell_lid(iback_cell_lid);
242 ItemLocalId front_cell_lid(cell->localId());
243 _setBackAndFrontCells(face,back_cell_lid,front_cell_lid);
244
245
246 }
247
248 void _addBackCellToFace(ItemInternal* face, ItemInternal* cell){
249 _checkValidSourceTargetItems(face,cell);
250
251 Integer nb_cell = nbConnectedItem(ItemLocalId(face));
252
253 // SDP: les tests suivants sont imcompatibles avec le raffinement
254 // par couches
255 // SDC: dans l'etat le check ne peut etre fait car les flags sont positionnes par la connectivite legacy.
256 // On peut donc avoir une back_cell qui n'est pas dans cette connectivite. C'est donc legal et de plus
257 // le check va planter puisque connectedItemLocalId(ItemLocalId(face),0) va retourner -1.
258 // Dans le nouveau mode les check devront etre faits via des proprietes.
259 const bool check_orientation = false; // SDC cf. ci-dessus
260 if (check_orientation){
261 if (face->flags() & ItemFlags::II_HasBackCell){
262 ItemInternal* current_cell = m_cell_family->itemsInternal()[connectedItemLocalId(ItemLocalId(face),0)]; // BackCell is the first connected cell
263 ARCANE_FATAL("Face already having a back cell."
264 " This is most probably due to the fact that the face"
265 " is connected to a reverse cell with a negative volume."
266 " Face={0}. new_cell={1} current_cell={2}",face->uniqueId().asInt64(),
267 cell->uniqueId().asInt64(),current_cell->uniqueId().asInt64()); // FullItemPrinter cannot be used here, the connectivities are not entirely set
268 }
269 }
270
271 if (nb_cell>=2)
272 ARCANE_FATAL("face '{0}' already has two cells",face->uniqueId().asInt64());// FullItemPrinter cannot be used here, the connectivities are not entirely set
273 // Si on a déjà une maille, il s'agit de la front cell.
274 Int32 ifront_cell_lid = (nb_cell==1) ? face->cellId(0) : NULL_ITEM_LOCAL_ID;
275
276 ItemLocalId back_cell_lid(cell->localId());
277 ItemLocalId front_cell_lid(ifront_cell_lid);
278 _setBackAndFrontCells(face,back_cell_lid,front_cell_lid);
279
280 }
281
282private:
283
284 void _setBackAndFrontCells(ItemInternal* face,ItemLocalId back_cell_lid,ItemLocalId front_cell_lid){
285 ItemLocalId face_lid(face->localId());
286 // Supprime toutes les mailles connectées => la méthode est mutualisée pour les ajouts ou suppressions
287 // TODO: optimiser en ne supprimant pas s'il n'y a pas besoin pour éviter
288 // des réallocations.
289 removeConnectedItems(face_lid);
290 Int32 mod_flags = 0;
291 if (front_cell_lid==NULL_ITEM_LOCAL_ID){
292 if (back_cell_lid!=NULL_ITEM_LOCAL_ID){
293 // Reste uniquement la back_cell
294 IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid); // add the class name for the case of Face to Cell connectivity. The class is overridden to handle family dependencies but the base method must be called here.
295 // add flags
296 mod_flags = (ItemFlags::II_Boundary | ItemFlags::II_HasBackCell | ItemFlags::II_BackCellIsFirst);
297 }
298 // Ici reste aucune maille mais comme on a tout supprimé il n'y a rien
299 // à faire
300 }
301 else if (back_cell_lid==NULL_ITEM_LOCAL_ID){
302 // Reste uniquement la front cell
303 IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
304 // add flags
305 mod_flags = (ItemFlags::II_Boundary | ItemFlags::II_HasFrontCell | ItemFlags::II_FrontCellIsFirst);
306 }
307 else{
308 // Il y a deux mailles connectées. La back_cell est toujours la première.
309 IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid);
310 IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
311 // add flags
312 mod_flags = (ItemFlags::II_HasFrontCell | ItemFlags::II_HasBackCell | ItemFlags::II_BackCellIsFirst);
313 }
314 Int32 face_flags = face->flags();
315 face_flags &= ~ItemFlags::II_InterfaceFlags;
316 face_flags |= mod_flags;
317 face->setFlags(face_flags);
318 }
319
320 void _removeConnectedItem(ItemInternal* face,ItemLocalId cell_to_remove_lid)
321 {
322 // Code taken from FaceFamily::removeCellFromFace where new and legacy are separated.
323 // Here only for new connectivity.
324 // This duplication allows to reach the specificity of Cell/Face connectivity through the unique interface removeConnectedItem (instead of removeCellFromFace)
325 _checkValidSourceTargetItems(face,m_cell_family->itemsInternal()[cell_to_remove_lid]);
326
327 Integer nb_cell = nbConnectedItem(ItemLocalId(face));
328
329#ifdef ARCANE_CHECK
330 if (face->isSuppressed())
331 ARCANE_FATAL("Can not remove cell from destroyed face={0}",ItemPrinter(face));
332 if (nb_cell==0)
333 ARCANE_FATAL("Can not remove cell lid={0} from face uid={1} with no cell connected",
334 cell_to_remove_lid, face->uniqueId());
335#endif /* ARCANE_CHECK */
336
337 Integer nb_cell_after = nb_cell-1;
338 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
339
341
342 // OFF AMR
343 if (nb_cell_after!=0){
344 Int32 cell0 = face->cellId(0);
345 Int32 cell1 = face->cellId(1);
346 // On avait obligatoirement deux mailles connectées avant,
347 // donc la back_cell est la maille 0, la front cell la maille 1
348 if (cell0==cell_to_remove_lid){
349 // Reste la front cell
350 _setBackAndFrontCells(face,ItemLocalId(null_cell_lid),ItemLocalId(cell1));
351 }
352 else{
353 // Reste la back cell
354 _setBackAndFrontCells(face,ItemLocalId(cell0),ItemLocalId(null_cell_lid));
355 }
356 }
357 else{
358 _setBackAndFrontCells(face,ItemLocalId(null_cell_lid),ItemLocalId(null_cell_lid));
359 }
360 }
361};
362
363template<>
364class ARCANE_MESH_EXPORT CustomConnectivity<FaceFamily,CellFamily>
365{
366public:
368};
369
370/*---------------------------------------------------------------------------*/
371/*---------------------------------------------------------------------------*/
372
373} // End namespace Arcane::mesh
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
378
379#endif /* ARCANE_CONNECTIVITYNEWWITHDEPENDENCIESTYPES_H_ */
Fichier de configuration d'Arcane.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Réordonne les noeuds d'une face.
Integer size() const
Nombre d'éléments du vecteur.
void clear()
Supprime les éléments du tableau.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Maille d'un maillage.
Definition Item.h:1191
Gère la récupération des informations de connectivité.
ItemVectorView connectedItems(ItemLocalId item)
Retourne les entités connectées à item.
Face d'une maille.
Definition Item.h:944
Exception lorsqu'une erreur fatale est survenue.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual String name() const =0
Nom de la famille.
virtual eItemKind itemKind() const =0
Genre des entités.
bool isSuppressed() const
Vrai si l'entité est supprimée.
ItemUniqueId uniqueId() const
Numéro unique de l'entité
Int32 flags() const
Flags de l'entité
ItemTypeInfo * typeInfo() const
Type de l'entité.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
@ II_HasFrontCell
L'entité a une maille devant.
Definition ItemFlags.h:44
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Informations locales sur une face d'une maille.
Integer node(Integer i) const
Indice locale dans la maille du i-ème noeud de la face.
Integer nbNode() const
Nombre de noeuds de la face.
Infos sur un type d'entité du maillage.
LocalFace localFace(Integer id) const
Connectivité locale de la i-ème face de la maille.
Integer nbLocalFace() const
Nombre de faces de l'entité
Vue sur un vecteur d'entités.
Int32 size() const
Nombre d'éléments du vecteur.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Famille de mailles.
Definition CellFamily.h:46
Spécialisation de CompactItemItemInternalConnectivityIndexT pour accéder aux mailles.
Famille d'arêtes.
Definition EdgeFamily.h:35
Spécialisation de CompactItemItemInternalConnectivityIndexT pour accéder aux arêtes.
Famille de faces.
Definition FaceFamily.h:53
Spécialisation de CompactItemItemInternalConnectivityIndexT pour accéder aux faces.
Surcharge du type IncrementalItemConnectivity pour gérer les connectivités Face -> BackCell et FrontC...
void addConnectedItem(ItemLocalId source_item, ItemLocalId target_item) override
Ajoute l'entité de localId() target_local_id à la connectivité de source_item.
void removeConnectedItem(ItemLocalId source_item, ItemLocalId target_item) override
Supprime l'entité de localId() target_local_id à la connectivité de source_item.
void _removeConnectedItem(ItemInternal *face, ItemLocalId cell_to_remove_lid)
Integer nbConnectedItem(ItemLocalId lid) const final
Nombre d'entité connectées à l'entité source de numéro local lid.
Connectivité incrémentale item->item[].
Famille de noeuds.
Definition NodeFamily.h:37
Spécialisation de CompactItemItemInternalIndexT pour accéder aux noeuds.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:426
Int32 Integer
Type représentant un entier.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
std::int32_t Int32
Type entier signé sur 32 bits.