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