Arcane  v3.14.10.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 <>
61
62template <>
68
69template <>
75
76template <>
82
83
84template <class SourceFamily, class TargetFamily>
85class ARCANE_MESH_EXPORT LegacyConnectivity
86{
87public:
89};
90
91
93{
94 return String::concat(source_family->name(),target_family->name());
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
103 {
104 public:
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:
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())));
125 ConnectivityItemVector cell_nodes_connectivity(mesh->itemFamilyNetwork()->getConnectivity(m_cell_family,mesh->nodeFamily(), connectivityName(m_cell_family,mesh->nodeFamily())));
128 // Find which local_face
129 Integer face_index = -1;
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());
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();
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());
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 {
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/*---------------------------------------------------------------------------*/
180{
181public:
185
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
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
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
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
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",
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
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.
Maille d'un maillage.
Definition Item.h:1178
Gère la récupération des informations de connectivité.
Face d'une maille.
Definition Item.h:932
Interface d'une famille d'entités.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Interface du réseau de familles (familles connectées)
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é
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:40
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Informations locales sur une face d'une maille.
Infos sur un type d'entité du maillage.
Vue sur un vecteur d'entités.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
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.
Mutualisation pour les connectuvutés Face-Maille (Legacy ou New)
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)
Connectivité incrémentale item->item[].
IMesh * mesh() const override
Maillage associé
ItemInternalList itemsInternal() override
Tableau interne des entités.
Famille de noeuds.
Definition NodeFamily.h:37
Spécialisation de CompactItemItemInternalIndexT pour accéder aux noeuds.
Exception lorsqu'une erreur fatale est survenue.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
T * arcaneThrowIfNull(T *ptr, const char *ptr_name, const char *text)
Vérifie qu'un pointeur n'est pas nul.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
Int32 Integer
Type représentant un entier.