Arcane  v3.15.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
FaceReorienter.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/* FaceReorienter.cc (C) 2000-2025 */
9/* */
10/* Vérifie la bonne orientation d'une face et la réoriente le cas échéant. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/FaceReorienter.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18
20#include "arcane/core/ItemPrinter.h"
21#include "arcane/core/ItemInternal.h"
22#include "arcane/core/IMesh.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/IItemFamilyTopologyModifier.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
37: m_trace_mng(tm)
38, m_face_family(nullptr)
39{
40}
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
47: m_trace_mng(mesh->traceMng())
48, m_face_family(nullptr)
49{
50 m_face_family = mesh->faceFamily();
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
76{
77 if (!m_face_family)
78 m_face_family = face.itemFamily();
79 Int32 face_nb_node = face.nbNode();
81
82 m_nodes_unique_id.resize(face_nb_node);
83 m_nodes_local_id.resize(face_nb_node);
84
85 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
86 m_nodes_unique_id[i_node] = face.node(i_node).uniqueId();
87 m_nodes_local_id[i_node] = face.node(i_node).localId();
88 }
89
90 m_face_nodes_index.resize(face_nb_node);
91 mesh_utils::reorderNodesOfFace2(m_nodes_unique_id, m_face_nodes_index);
92
93 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
94 ItemLocalId node_lid(m_nodes_local_id[m_face_nodes_index[i_node]]);
95 face_topology_modifier->replaceNode(face, i_node, node_lid);
96 }
97
98 // On cherche le plus petit uid de la face
99 std::pair<Int64, Int64> face_smallest_node_uids = std::make_pair(face.node(0).uniqueId(),
100 face.node(1).uniqueId());
101 if (face.node(0).uniqueId() == face.node(1).uniqueId())
102 face_smallest_node_uids = std::make_pair(face.node(0).uniqueId(),
103 face.node(2).uniqueId());
104 Cell cell = face.cell(0);
105 Int32 cell0_lid = cell.localId();
106 Integer local_face_number = -1;
107 for (Integer i_face = 0; i_face < cell.nbFace(); ++i_face) {
108 if (cell.face(i_face) == face) {
109 // On a trouvé la bonne face
111 break;
112 }
113 }
114
115 if (local_face_number == (-1))
116 ARCANE_FATAL("Incoherent connectivity: Face {0} not connected to cell {1}",
117 face.uniqueId(), cell.uniqueId());
118
120 bool cell0_is_back_cell = false;
121
122 if (face_nb_node == 2) {
124 }
125 else {
126 for (Integer i_node = 0; i_node < local_face.nbNode(); ++i_node) {
127 if (cell.node(local_face.node(i_node)).uniqueId() == face_smallest_node_uids.first) {
128 if (cell.node(local_face.node((i_node + 1) % local_face.nbNode())).uniqueId() == cell.node(local_face.node(i_node)).uniqueId()) {
129 if (cell.node(local_face.node((i_node + 2) % local_face.nbNode())).uniqueId() == face_smallest_node_uids.second) {
130 cell0_is_back_cell = true;
131 break;
132 }
133 else {
134 cell0_is_back_cell = false;
135 break;
136 }
137 }
138 else {
139 if (cell.node(local_face.node((i_node + 1) % local_face.nbNode())).uniqueId() == face_smallest_node_uids.second) {
140 cell0_is_back_cell = true;
141 break;
142 }
143 else {
144 cell0_is_back_cell = false;
145 break;
146 }
147 }
148 }
149 }
150 }
151
152 Int32 cell1_lid = (face.nbCell() == 2) ? face.cell(1).localId() : NULL_ITEM_LOCAL_ID;
153 // Paire contenant la back_cell et front_cell de la face.
154 std::pair<Int32, Int32> face_cells(cell1_lid, cell0_lid);
155 if (cell0_is_back_cell) {
156 // Si on arrive ici c'est que la maille 0 est la back_cell
157 std::swap(face_cells.first, face_cells.second);
158 }
159 face_topology_modifier->setBackAndFrontCells(face, CellLocalId(face_cells.first), CellLocalId(face_cells.second));
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164//! AMR
167{
168 if (!m_face_family)
169 m_face_family = face.itemFamily();
171
172 m_nodes_unique_id.resize(face.nbNode());
173 m_nodes_local_id.resize(face.nbNode());
174
175 for (Integer i_node = 0; i_node < face.nbNode(); ++i_node) {
176 m_nodes_unique_id[i_node] = face.node(i_node).uniqueId();
177 m_nodes_local_id[i_node] = face.node(i_node).localId();
178 }
179
180 m_face_nodes_index.resize(face.nbNode());
181 mesh_utils::reorderNodesOfFace2(m_nodes_unique_id, m_face_nodes_index);
182
183 for (Integer i_node = 0; i_node < face.nbNode(); ++i_node) {
184 ItemLocalId node_lid(m_nodes_local_id[m_face_nodes_index[i_node]]);
185 face_topology_modifier->replaceNode(face, i_node, node_lid);
186 }
187
188 // On cherche le plus petit uid de la face
189 std::pair<Int64, Int64> face_smallest_node_uids = std::make_pair(face.node(0).uniqueId(),
190 face.node(1).uniqueId());
191
192 if (face.node(0).uniqueId() == face.node(1).uniqueId())
193 face_smallest_node_uids = std::make_pair(face.node(0).uniqueId(),
194 face.node(2).uniqueId());
195
196 //ItemInternal* cell = face->cell(0);
197 bool cell_0 = false;
198 bool cell_1 = false;
199 Cell cell;
200
201 if (face.nbCell() == 2) {
202 if (face.cell(0).level() >= face.cell(1).level()) {
203 cell = face.cell(0);
204 cell_0 = true;
205 }
206 else {
207 cell = face.cell(1);
208 cell_1 = true;
209 }
210 }
211 else {
212 cell = face.cell(0);
213 cell_0 = true;
214 if (cell.null()) {
215 ARCANE_FATAL("Face without cells cannot be possible -- Face uid: {0}", face.uniqueId());
216 }
217 }
218 Integer local_face_number = -1;
219 for (Integer i_face = 0; i_face < cell.nbFace(); ++i_face) {
220 if (cell.face(i_face) == face) {
221 // On a trouvé la bonne face
223 break;
224 }
225 }
226
227 if (local_face_number == (-1)) {
228 ARCANE_FATAL("Incoherent connectivity: Face {0} not connected to cell {1}",
229 face.uniqueId(), cell.uniqueId());
230 }
231
233
234 bool cell_is_back_cell = false;
235
236 if (face.nbNode() == 2) {
238 }
239 else {
240 for (Integer i_node = 0; i_node < local_face.nbNode(); ++i_node) {
241 if (cell.node(local_face.node(i_node)).uniqueId() == face_smallest_node_uids.first) {
242 if (cell.node(local_face.node((i_node + 1) % local_face.nbNode())).uniqueId() == cell.node(local_face.node(i_node)).uniqueId()) {
243 if (cell.node(local_face.node((i_node + 2) % local_face.nbNode())).uniqueId() == face_smallest_node_uids.second) {
244 cell_is_back_cell = true;
245 break;
246 }
247 else {
248 cell_is_back_cell = false;
249 break;
250 }
251 }
252 else {
253 if (cell.node(local_face.node((i_node + 1) % local_face.nbNode())).uniqueId() == face_smallest_node_uids.second) {
254 cell_is_back_cell = true;
255 break;
256 }
257 else {
258 cell_is_back_cell = false;
259 break;
260 }
261 }
262 }
263 }
264 }
265
266 // Paire contenant la back_cell et front_cell de la face.
267 std::pair<Int32, Int32> face_cells(NULL_ITEM_LOCAL_ID, NULL_ITEM_LOCAL_ID);
268 bool face_has_two_cell = (face.nbCell() == 2);
269
270 if (cell_0) {
271 Int32 cell1_lid = (face_has_two_cell) ? face.cell(1).localId() : NULL_ITEM_LOCAL_ID;
272 if (cell_is_back_cell) {
273 // Si on arrive ici, c'est que la maille 0 est la back_cell
274 // La front cell est toujours cell1_lid (qui peut être nulle).
275 face_cells = { face.cell(0).localId(), cell1_lid };
276 }
277 else {
278 // Si on arrive ici, c'est que la maille 0 est la front_cell
279 // La back cell est toujours cell1_lid (qui peut être nulle)
280 face_cells.first = cell1_lid;
281 face_cells.second = (face_has_two_cell) ? cell.localId() : face.cell(0).localId();
282 }
283 }
284 else if (cell_1) {
285 if (cell_is_back_cell) {
286 // Si on arrive ici, c'est que la maille 0 est la front_cell
287 // On met à jour les infos d'orientation
288 face_cells.second = face.cell(0).localId();
289 // GG Attention, si ici, cela signifie qu'il faut échanger la front cell
290 // et la back cell car la back cell doit toujours être la première
291 face_cells.first = (face_has_two_cell) ? cell.localId() : NULL_ITEM_LOCAL_ID;
292 }
293 else {
294 // Si on arrive ici, c'est que la maille 0 est la back_cell
295 // On met à jour les infos d'orientation
296 face_cells.first = face.cell(0).localId();
297 face_cells.second = (face_has_two_cell) ? face.cell(1).localId() : NULL_ITEM_LOCAL_ID;
298 }
299 }
300 face_topology_modifier->setBackAndFrontCells(face, CellLocalId(face_cells.first), CellLocalId(face_cells.second));
301}
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Maille d'un maillage.
Definition Item.h:1191
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1269
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1266
Int32 level() const
Definition Item.h:1342
ARCANE_DEPRECATED_260 void checkAndChangeOrientation(ItemInternal *face)
ARCANE_DEPRECATED_260 void checkAndChangeOrientationAMR(ItemInternal *face)
ARCANE_DEPRECATED_260 FaceReorienter(ITraceMng *tm)
Face d'une maille.
Definition Item.h:944
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1633
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1019
Interface de modification de la topologie des entités d'une famille.
virtual IItemFamilyTopologyModifier * _topologyModifier()=0
Interface du modificateur de topologie.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Informations locales sur une face d'une maille.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:779
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:776
const ItemTypeInfo * typeInfo() const
Infos sur le type de l'entité.
Definition Item.h:386
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
IItemFamily * itemFamily() const
Famille dont est issue l'entité
Definition Item.h:247
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Interface du gestionnaire de traces.
Référence à une instance.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-