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