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