Arcane  v4.1.4.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AMRZonePosition.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* AMRZonePosition.cc (C) 2000-2026 */
9/* */
10/* Definition d'une zone 2D ou 3D d'un maillage. */
11/*---------------------------------------------------------------------------*/
12
13#include "arcane/cartesianmesh/AMRZonePosition.h"
14
15#include "arcane/utils/FixedArray.h"
16#include "arcane/utils/ITraceMng.h"
17
18#include "arcane/core/IMesh.h"
19#include "arcane/core/MeshKind.h"
20#include "arcane/core/IParallelMng.h"
21
22#include "arcane/cartesianmesh/AMRPatchPosition.h"
23#include "arcane/cartesianmesh/ICartesianMesh.h"
24
25#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
37cellsInPatch(IMesh* mesh, UniqueArray<Int32>& cells_local_id) const
38{
39 VariableNodeReal3& nodes_coord = mesh->nodesCoordinates();
40 // Parcours les mailles actives et ajoute dans la liste des mailles
41 // à raffiner celles qui sont contenues dans la boîte englobante.
42 Real3 min_pos = m_position;
43 Real3 max_pos = min_pos + m_length;
44 //Int32 level = -10;
45 cells_local_id.clear();
46 ENUMERATE_ (Cell, icell, mesh->allActiveCells()) {
47 Cell cell = *icell;
48 Real3 center;
49 for (const Node node : cell.nodes())
50 center += nodes_coord[node];
51 center /= cell.nbNode();
52 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
53 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
54 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d;
55 if (is_inside_x && is_inside_y && is_inside_z) {
56 //if (level == -10) level = cell.level();
57 //else if (level != cell.level()) ARCANE_FATAL("Level pb"); // TODO plus clair.
58 cells_local_id.add(icell.itemLocalId());
59 }
60 }
61}
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
68{
69 if (mesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
70 cellsInPatch(mesh->mesh(), cells_local_id);
71 return;
72 }
73 auto numbering = mesh->_internalApi()->cartesianMeshNumberingMngInternal();
74
76 min_n_max[0] = INT32_MAX;
77 min_n_max[1] = INT32_MAX;
78 min_n_max[2] = INT32_MAX;
79 min_n_max[3] = -1;
80 min_n_max[4] = -1;
81 min_n_max[5] = -1;
82 ArrayView min(min_n_max.view().subView(0, 3));
83 ArrayView max(min_n_max.view().subView(3, 3));
84 Int64 nb_cells = 0;
85
86 VariableNodeReal3& nodes_coord = mesh->mesh()->nodesCoordinates();
87 // Parcours les mailles actives et ajoute dans la liste des mailles
88 // à raffiner celles qui sont contenues dans la boîte englobante.
89 Real3 min_pos = m_position;
90 Real3 max_pos = min_pos + m_length;
91 Int32 level = -1;
92 cells_local_id.clear();
93
94 // On ne peut pas utiliser allActiveCells() car on doit prendre en compte
95 // les mailles sous les mailles de recouvrement (et non les mailles de
96 // recouvrement).
97 ENUMERATE_ (Cell, icell, mesh->mesh()->allCells()) {
98 Cell cell = *icell;
100 continue;
101 }
102 if (cell.hasHChildren()) {
104 continue;
105 }
106 }
107 Real3 center;
108 for (const Node node : cell.nodes())
109 center += nodes_coord[node];
110 center /= cell.nbNode();
111 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
112 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
113 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d;
114 if (is_inside_x && is_inside_y && is_inside_z) {
115 if (level == -1)
116 level = cell.level();
117 else if (level != cell.level())
118 ARCANE_FATAL("Level pb -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, cell.level(), cell.uniqueId());
119 cells_local_id.add(icell.itemLocalId());
120
121 if (icell->isOwn())
122 nb_cells++;
123
124 CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
125 if (pos.x < min[MD_DirX])
126 min[MD_DirX] = pos.x;
127 if (pos.x > max[MD_DirX])
128 max[MD_DirX] = pos.x;
129
130 if (pos.y < min[MD_DirY])
131 min[MD_DirY] = pos.y;
132 if (pos.y > max[MD_DirY])
133 max[MD_DirY] = pos.y;
134
135 if (pos.z < min[MD_DirZ])
136 min[MD_DirZ] = pos.z;
137 if (pos.z > max[MD_DirZ])
138 max[MD_DirZ] = pos.z;
139 }
140 }
141 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min);
142 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max);
143 nb_cells = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells);
144 Int32 level_r = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level);
145
146 if (level != -1 && level != level_r) {
147 ARCANE_FATAL("Bad level reduced");
148 }
149
150 max[MD_DirX] += 1;
151 max[MD_DirY] += 1;
152 max[MD_DirZ] += 1;
153
154 {
155 Int64 nb_cells_patch = static_cast<Int64>(max[MD_DirX] - min[MD_DirX]) * (max[MD_DirY] - min[MD_DirY]) * (max[MD_DirZ] - min[MD_DirZ]);
156 if (nb_cells != nb_cells_patch) {
157 ARCANE_FATAL("Not regular patch");
158 }
159 }
160 position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] });
161 position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] });
162 position.setLevel(level_r);
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
170{
171 if (mesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
172 ARCANE_FATAL("Reserved to AMR type 3");
173 }
174
176 auto numbering = mesh->_internalApi()->cartesianMeshNumberingMngInternal();
177
178 FixedArray<CartCoord, 6> min_n_max;
179 min_n_max[0] = INT32_MAX;
180 min_n_max[1] = INT32_MAX;
181 min_n_max[2] = INT32_MAX;
182 min_n_max[3] = -1;
183 min_n_max[4] = -1;
184 min_n_max[5] = -1;
185 ArrayView min(min_n_max.view().subView(0, 3));
186 ArrayView max(min_n_max.view().subView(3, 3));
187 Int64 nb_cells = 0;
188
189 VariableNodeReal3& nodes_coord = mesh->mesh()->nodesCoordinates();
190 // Parcours les mailles actives et ajoute dans la liste des mailles
191 // à raffiner celles qui sont contenues dans la boîte englobante.
192 const Real3 min_pos = m_position;
193 const Real3 max_pos = min_pos + m_length;
194 Int32 level = -1;
195 Int64 d_cell_level = -1;
196
197 // On ne peut pas utiliser allActiveCells() car on doit prendre en compte
198 // les mailles sous les mailles de recouvrement (et non les mailles de
199 // recouvrement).
200 ENUMERATE_ (Cell, icell, mesh->mesh()->allCells()) {
201 Cell cell = *icell;
202 if (!cell.hasFlags(ItemFlags::II_InPatch)) {
203 continue;
204 }
205 if (cell.hasHChildren()) {
207 continue;
208 }
209 }
210 Real3 center;
211 for (const Node node : cell.nodes())
212 center += nodes_coord[node];
213 center /= cell.nbNode();
214 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
215 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
216 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d;
217 if (is_inside_x && is_inside_y && is_inside_z) {
218 if (level == -1) {
219 level = cell.level();
220 d_cell_level = cell.uniqueId();
221 }
222 else if (level != cell.level())
223 ARCANE_FATAL("Level pb -- Level recorded before : {0} -- CellUID before : {1} -- Cell Level : {2} -- CellUID : {3}", level, d_cell_level, cell.level(), cell.uniqueId());
224
225 if (icell->isOwn())
226 nb_cells++;
227
228 const CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
229 if (pos.x < min[MD_DirX])
230 min[MD_DirX] = pos.x;
231 if (pos.x > max[MD_DirX])
232 max[MD_DirX] = pos.x;
233
234 if (pos.y < min[MD_DirY])
235 min[MD_DirY] = pos.y;
236 if (pos.y > max[MD_DirY])
237 max[MD_DirY] = pos.y;
238
239 if (pos.z < min[MD_DirZ])
240 min[MD_DirZ] = pos.z;
241 if (pos.z > max[MD_DirZ])
242 max[MD_DirZ] = pos.z;
243 }
244 }
245 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min);
246 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max);
247 nb_cells = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells);
248 Int32 level_r = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level);
249
250 if (level != -1 && level != level_r) {
251 ARCANE_FATAL("Bad level reduced");
252 }
253
254 // Min inclus / Max exclu
255 max[MD_DirX] += 1;
256 max[MD_DirY] += 1;
257 max[MD_DirZ] += 1;
258
259 {
260 const Int64 nb_cells_patch = static_cast<Int64>(max[MD_DirX] - min[MD_DirX]) * (max[MD_DirY] - min[MD_DirY]) * (max[MD_DirZ] - min[MD_DirZ]);
261 if (nb_cells != nb_cells_patch) {
262 ARCANE_FATAL("Not regular patch");
263 }
264 }
265 position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] });
266 position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] });
267 position.setLevel(level_r);
268
269 // Attention : Pas assez d'infos pour mettre le bon overlapSize !
270
271 //mesh->traceMng()->info() << "Position test -- Min : " << position.minPoint() << " -- Max : " << position.maxPoint() << " -- Level : " << position.level();
272
273 return position;
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279} // End namespace Arcane
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Classe permettant de définir la position d'un patch dans le maillage cartésien.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Méthode permettant de retrouver les mailles incluses dans la zone.
Real3 position() const
Méthode permettant de retrouver la position de la zone.
AMRPatchPosition toAMRPatchPosition(ICartesianMesh *mesh) const
Méthode permettant de convertir ce AMRZonePosition en AMRPatchPosition.
Vue modifiable d'un tableau d'un type T.
void clear()
Supprime les éléments du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Maille d'un maillage.
Definition Item.h:1214
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1336
bool hasHChildren() const
Definition Item.h:1361
Int32 level() const
Definition Item.h:1368
constexpr __host__ __device__ ArrayView< T > view()
Vue modifiable sur le tableau.
Interface d'un maillage cartésien.
@ II_InPatch
[AMR Patch] L'entité est marqué comme étant dans un patch AMR.
Definition ItemFlags.h:92
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:794
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:788
constexpr bool hasFlags(Int32 flags) const
Retourne si les flags flags sont positionnées pour l'entité
Definition Item.h:338
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Noeud d'un maillage.
Definition Item.h:582
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
@ ReduceSum
Somme des valeurs.
@ ReduceMin
Minimum des valeurs.
@ ReduceMax
Maximum des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
@ MD_DirZ
Direction Z.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire)
Definition MeshKind.h:56
std::int32_t Int32
Type entier signé sur 32 bits.
Int32x3 CartCoord3
Représente les coordonnées 3D d'un élément dans la grille cartésienne {x, y, z}.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35