Arcane  v4.1.1.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
NodesOfItemReorderer.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/* NodesOfItemReorderer.cc (C) 2000-2025 */
9/* */
10/* Classe utilitaire pour réordonner les noeuds d'une entité. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/NodesOfItemReorderer.h"
15
16#include "arcane/utils/NotImplementedException.h"
17
18#include "arcane/core/ItemTypeId.h"
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29// TODO: fusionner avec la version d'ordre 1
30// Seulement implémenté pour les arêtes
31bool NodesOfItemReorderer::
32_reorderOrder3(ConstArrayView<Int64> nodes_uid,
33 ArrayView<Int64> sorted_nodes_uid,
34 [[maybe_unused]] bool has_center_node)
35{
36 // \a true s'il faut réorienter les faces pour que leur orientation
37 // soit indépendante du partitionnement du maillage initial.
38
39 Int32 nb_node = nodes_uid.size();
40
41 // Traite uniquement le cas des arêtes d'ordre 3 qui ont donc 4 noeuds
42 if (nb_node != 4)
43 ARCANE_THROW(NotImplementedException, "Node reordering for 2D type of order 3 or more");
44
45 if (nodes_uid[0] < nodes_uid[1]) {
46 // Rien à faire
47 sorted_nodes_uid[0] = nodes_uid[0];
48 sorted_nodes_uid[1] = nodes_uid[1];
49 sorted_nodes_uid[2] = nodes_uid[2];
50 sorted_nodes_uid[3] = nodes_uid[3];
51 return false;
52 }
53 sorted_nodes_uid[0] = nodes_uid[1];
54 sorted_nodes_uid[1] = nodes_uid[0];
55 sorted_nodes_uid[2] = nodes_uid[3];
56 sorted_nodes_uid[3] = nodes_uid[2];
57 return true;
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62// TODO: fusionner avec la version d'ordre 1
63bool NodesOfItemReorderer::
64_reorderOrder2(ConstArrayView<Int64> nodes_uid,
65 ArrayView<Int64> sorted_nodes_uid, bool has_center_node)
66{
67 // \a true s'il faut réorienter les faces pour que leur orientation
68 // soit indépendante du partitionnement du maillage initial.
69 bool need_swap_orientation = false;
70 Int32 min_node_index = 0;
71
72 Int32 nb_node = nodes_uid.size();
73
74 // Traite directement le cas des arêtes d'ordre 2
75 if (nb_node == 3) {
76 if (nodes_uid[0] < nodes_uid[1]) {
77 sorted_nodes_uid[0] = nodes_uid[0];
78 sorted_nodes_uid[1] = nodes_uid[1];
79 sorted_nodes_uid[2] = nodes_uid[2];
80 return false;
81 }
82 sorted_nodes_uid[0] = nodes_uid[1];
83 sorted_nodes_uid[1] = nodes_uid[0];
84 sorted_nodes_uid[2] = nodes_uid[2];
85 return true;
86 }
87 // S'il y a un nœud central, c'est le dernier nœud de la liste
88 // et il ne faut pas le trier
89 // NOTE : Dans ce cas le nombre de noeuds de l'entité est impair.
90 if (has_center_node)
91 sorted_nodes_uid[nb_node - 1] = nodes_uid[nb_node - 1];
92
93 // A l'ordre 2, si on a N noeuds, il ne faut tester les N/2 premiers noeuds
94 // TODO: utiliser les informations de type.
95 nb_node = nb_node / 2;
96
97 // L'algorithme suivant oriente les faces en tenant compte uniquement
98 // de l'ordre de la numérotation de ces noeuds. Si cet ordre est
99 // conservé lors du partitionnement, alors l'orientation des faces
100 // sera aussi conservée.
101
102 // L'algorithme est le suivant:
103 // - Recherche le noeud n de plus petit indice.
104 // - Recherche n-1 et n+1 les indices de ses 2 noeuds voisins.
105 // - Si (n+1) est inférieur à (n-1), l'orientation n'est pas modifiée.
106 // - Si (n+1) est supérieur à (n-1), l'orientation est inversée.
107
108 // Recherche le noeud de plus petit indice
109
110 Int64 min_node = INT64_MAX;
111 for (Integer k = 0; k < nb_node; ++k) {
112 Int64 id = nodes_uid[k];
113 if (id < min_node) {
114 min_node = id;
115 min_node_index = k;
116 }
117 }
118 Int64 next_node = nodes_uid[(min_node_index + 1) % nb_node];
119 Int64 prev_node = nodes_uid[(min_node_index + (nb_node - 1)) % nb_node];
120 Integer incr = 0;
121 Integer incr2 = 0;
122 // Teste le cas où les noeuds précédents ou suivant
123 // sont les mêmes que le noeud de plus petit uniqueId().
124 // (dans ce cas l'entité est semi-dégénérée)
125 {
126 if (next_node == min_node) {
127 next_node = nodes_uid[(min_node_index + (nb_node + 2)) % nb_node];
128 incr = 1;
129 }
130 if (prev_node == min_node) {
131 prev_node = nodes_uid[(min_node_index + (nb_node - 2)) % nb_node];
132 incr2 = nb_node - 1;
133 }
134 }
135 if (next_node > prev_node)
136 need_swap_orientation = true;
137 if (need_swap_orientation) {
138 for (Integer k = 0; k < nb_node; ++k) {
139 Integer index = (nb_node - k + min_node_index + incr) % nb_node;
140 Int32 index2 = ((2*nb_node-1) + incr + min_node_index - k) % nb_node;
141 sorted_nodes_uid[k] = nodes_uid[index];
142 sorted_nodes_uid[k + nb_node] = nodes_uid[index2 + nb_node];
143 }
144 }
145 else {
146 for (Integer k = 0; k < nb_node; ++k) {
147 Integer index = (k + min_node_index + incr2) % nb_node;
148 sorted_nodes_uid[k] = nodes_uid[index];
149 sorted_nodes_uid[k + nb_node] = nodes_uid[index + nb_node];
150 }
151 }
152 return need_swap_orientation;
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158bool NodesOfItemReorderer::
159reorder(ItemTypeId type_id, ConstArrayView<Int64> nodes_uids)
160{
161 ItemTypeInfo* iti = m_item_type_mng->typeFromId(type_id);
162 Int32 order = iti->order();
163 Int32 nb_node = nodes_uids.size();
164 m_work_sorted_nodes.resize(nb_node);
165 if (order > 3)
166 ARCANE_THROW(NotImplementedException, "Node reordering for type of order 4 or more");
167 if (order == 3)
168 return _reorderOrder3(nodes_uids, m_work_sorted_nodes, iti->hasCenterNode());
169 if (order == 2)
170 return _reorderOrder2(nodes_uids, m_work_sorted_nodes, iti->hasCenterNode());
171 return MeshUtils::reorderNodesOfFace(nodes_uids, m_work_sorted_nodes);
172}
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
177} // End namespace Arcane
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
Fonctions utilitaires sur le maillage.
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
Type d'une entité (Item).
Definition ItemTypeId.h:32
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
std::int32_t Int32
Type entier signé sur 32 bits.