Arcane  v4.1.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AMRPatchPosition.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/* AMRPatchPosition.cc (C) 2000-2026 */
9/* */
10/* Position d'un patch AMR d'un maillage cartésien. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/cartesianmesh/AMRPatchPosition.h"
15
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/Math.h"
19
20#include <cmath>
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
33: m_level(-2)
34, m_overlap_layer_size(0)
35{}
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41AMRPatchPosition(Int32 level, CartCoord3 min_point, CartCoord3 max_point, Int32 overlap_layer_size)
42: m_level(level)
43, m_min_point(min_point)
44, m_max_point(max_point)
45, m_overlap_layer_size(overlap_layer_size)
46{}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
53: m_level(src.level())
54, m_min_point(src.minPoint())
55, m_max_point(src.maxPoint())
56, m_overlap_layer_size(src.overlapLayerSize())
57{
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63AMRPatchPosition::
64~AMRPatchPosition()
65= default;
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
71level() const
72{
73 return m_level;
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
81{
82 m_level = level;
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
89minPoint() const
90{
91 return m_min_point;
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
98setMinPoint(CartCoord3 min_point)
99{
100 m_min_point = min_point;
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
107maxPoint() const
108{
109 return m_max_point;
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
116setMaxPoint(CartCoord3 max_point)
117{
118 m_max_point = max_point;
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125overlapLayerSize() const
126{
127 return m_overlap_layer_size;
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
134setOverlapLayerSize(Int32 layer_size)
135{
136 m_overlap_layer_size = layer_size;
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
144{
145 return m_min_point - m_overlap_layer_size;
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
153{
154 return m_max_point + m_overlap_layer_size;
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
161nbCells() const
162{
163 return static_cast<Int64>(m_max_point.x - m_min_point.x) * (m_max_point.y - m_min_point.y) * (m_max_point.z - m_min_point.z);
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
169std::pair<AMRPatchPosition, AMRPatchPosition> AMRPatchPosition::
170cut(CartCoord cut_point, Integer dim) const
171{
172 CartCoord3 patch_max_cut = m_max_point;
173 CartCoord3 patch_min_cut = m_min_point;
174
175 if (dim == MD_DirX) {
176 patch_max_cut.x = cut_point;
177 patch_min_cut.x = cut_point;
178 }
179 else if (dim == MD_DirY) {
180 patch_max_cut.y = cut_point;
181 patch_min_cut.y = cut_point;
182 }
183 else {
184 patch_max_cut.z = cut_point;
185 patch_min_cut.z = cut_point;
186 }
187
188 AMRPatchPosition p0(*this);
189 p0.setMaxPoint(patch_max_cut);
190
191 AMRPatchPosition p1(*this);
192 p1.setMinPoint(patch_min_cut);
193
194 return { p0, p1 };
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
201canBeFusion(const AMRPatchPosition& other_patch) const
202{
203 const CartCoord3 min_point = other_patch.minPoint();
204 const CartCoord3 max_point = other_patch.maxPoint();
205 return m_level == other_patch.level() &&
206 (((m_min_point.x == max_point.x || m_max_point.x == min_point.x) &&
207 (m_min_point.y == min_point.y && m_max_point.y == max_point.y) &&
208 (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) ||
209
210 ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) &&
211 (m_min_point.y == max_point.y || m_max_point.y == min_point.y) &&
212 (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) ||
213
214 ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) &&
215 (m_min_point.y == min_point.y && m_max_point.y == max_point.y) &&
216 (m_min_point.z == max_point.z || m_max_point.z == min_point.z)));
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
223fusion(AMRPatchPosition& other_patch)
224{
225 if (!canBeFusion(other_patch)) {
226 return false;
227 }
228
229 const CartCoord3 min_point = other_patch.minPoint();
230 const CartCoord3 max_point = other_patch.maxPoint();
231
232 if (m_min_point.x > min_point.x) {
233 m_min_point.x = min_point.x;
234 }
235 else if (m_max_point.x < max_point.x) {
236 m_max_point.x = max_point.x;
237 }
238
239 else if (m_min_point.y > min_point.y) {
240 m_min_point.y = min_point.y;
241 }
242 else if (m_max_point.y < max_point.y) {
243 m_max_point.y = max_point.y;
244 }
245
246 else if (m_min_point.z > min_point.z) {
247 m_min_point.z = min_point.z;
248 }
249 else if (m_max_point.z < max_point.z) {
250 m_max_point.z = max_point.z;
251 }
252
253 other_patch.setLevel(-2);
254
255 return true;
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
262isNull() const
263{
264 return m_level == -2;
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
271patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
272{
274 p.setLevel(m_level + 1);
275 p.setMinPoint(m_min_point * 2);
276 if (dim == 2) {
277 p.setMaxPoint({ m_max_point.x * 2, m_max_point.y * 2, 1 });
278 }
279 else {
280 p.setMaxPoint(m_max_point * 2);
281 }
282 p.computeOverlapLayerSize(higher_level, overlap_layer_size_top_level);
283 return p;
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
290patchDown(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
291{
293 p.setLevel(m_level - 1);
294 p.setMinPoint(m_min_point / 2);
295 if (dim == 2) {
296 p.setMaxPoint({ static_cast<CartCoord>(std::ceil(m_max_point.x / 2.)), static_cast<CartCoord>(std::ceil(m_max_point.y / 2.)), 1 });
297 }
298 else {
299 p.setMaxPoint({ static_cast<CartCoord>(std::ceil(m_max_point.x / 2.)), static_cast<CartCoord>(std::ceil(m_max_point.y / 2.)), static_cast<CartCoord>(std::ceil(m_max_point.z / 2.)) });
300 }
301 p.computeOverlapLayerSize(higher_level, overlap_layer_size_top_level);
302 return p;
303}
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
309length() const
310{
311 return m_max_point - m_min_point;
312}
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
316
318isIn(CartCoord x, CartCoord y, CartCoord z) const
319{
320 return x >= m_min_point.x && x < m_max_point.x && y >= m_min_point.y && y < m_max_point.y && z >= m_min_point.z && z < m_max_point.z;
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
327isIn(CartCoord3 coord) const
328{
329 return coord.x >= m_min_point.x && coord.x < m_max_point.x && coord.y >= m_min_point.y && coord.y < m_max_point.y && coord.z >= m_min_point.z && coord.z < m_max_point.z;
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
337{
338 const CartCoord3 min_point = minPointWithOverlap();
339 const CartCoord3 max_point = maxPointWithOverlap();
340 return x >= min_point.x && x < max_point.x && y >= min_point.y && y < max_point.y && z >= min_point.z && z < max_point.z;
341}
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
345
347isInWithOverlap(CartCoord3 coord) const
348{
349 const CartCoord3 min_point = minPointWithOverlap();
350 const CartCoord3 max_point = maxPointWithOverlap();
351 return coord.x >= min_point.x && coord.x < max_point.x && coord.y >= min_point.y && coord.y < max_point.y && coord.z >= min_point.z && coord.z < max_point.z;
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
359{
360 const CartCoord3 min_point = m_min_point - overlap;
361 const CartCoord3 max_point = m_max_point + overlap;
362 return x >= min_point.x && x < max_point.x && y >= min_point.y && y < max_point.y && z >= min_point.z && z < max_point.z;
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
369isInWithOverlap(CartCoord3 coord, Integer overlap) const
370{
371 const CartCoord3 min_point = m_min_point - overlap;
372 const CartCoord3 max_point = m_max_point + overlap;
373 return coord.x >= min_point.x && coord.x < max_point.x && coord.y >= min_point.y && coord.y < max_point.y && coord.z >= min_point.z && coord.z < max_point.z;
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
380haveIntersection(const AMRPatchPosition& other) const
381{
382 return (
383 (other.level() == level()) &&
384 (other.maxPoint().x > minPoint().x && maxPoint().x > other.minPoint().x) &&
385 (other.maxPoint().y > minPoint().y && maxPoint().y > other.minPoint().y) &&
386 (other.maxPoint().z > minPoint().z && maxPoint().z > other.minPoint().z));
387}
388
389/*---------------------------------------------------------------------------*/
390/*---------------------------------------------------------------------------*/
391
400computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
401{
402 // Si le top level est à -1, les mailles de recouvrement sont désactivées.
403 if (overlap_layer_size_top_level == -1) {
404 return 0;
405 }
406 // Le niveau 0 n'a jamais de couches.
407 if (level == 0) {
408 return 0;
409 }
410 if (level == higher_level) {
411 return overlap_layer_size_top_level;
412 }
413 if (level < 0 || level > higher_level) {
414 ARCANE_FATAL("Level {0} doesn't exist (higher_level={1})", level, higher_level);
415 }
416
417 Int32 nb_overlap_cells = overlap_layer_size_top_level;
418
419 // Pour éviter des tours de boucle inutiles.
420 if (nb_overlap_cells == 0) {
421 return 2;
422 }
423 if (nb_overlap_cells == 2) {
424 return 2;
425 }
426 for (Integer m = higher_level; m > level; --m) {
427 if (nb_overlap_cells == 4) {
428 return 4;
429 }
430 nb_overlap_cells = ((nb_overlap_cells / 4) + 1) * 2;
431 }
432
433 return nb_overlap_cells;
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
440computeOverlapLayerSize(Int32 higher_level, Int32 overlap_layer_size_top_level)
441{
442 m_overlap_layer_size = computeOverlapLayerSize(m_level, higher_level, overlap_layer_size_top_level);
443}
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
447
448} // End namespace Arcane
449
450/*---------------------------------------------------------------------------*/
451/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types généraux de Arcane.
AMRPatchPosition patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Méthode permettant de créer un AMRPatchPosition pour le niveau supérieur.
bool isInWithOverlap(CartCoord x, CartCoord y, CartCoord z) const
Méthode permettant de savoir si une maille de position x,y,z est incluse dans ce patch avec couche de...
CartCoord3 minPointWithOverlap() const
Méthode permettant de récupérer la position min de la boite englobante en incluant la couche de maill...
AMRPatchPosition patchDown(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Méthode permettant de créer un AMRPatchPosition pour le niveau inférieur.
bool isIn(CartCoord x, CartCoord y, CartCoord z) const
Méthode permettant de savoir si une maille de position x,y,z est incluse dans ce patch.
bool canBeFusion(const AMRPatchPosition &other_patch) const
Méthode permettant de savoir si notre patch peut être fusionné avec other_patch.
static Int32 computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
Méthode permettant de calculer le nombre de couches de mailles de recouvrement pour un niveau donné.
bool fusion(AMRPatchPosition &other_patch)
Méthode permettant de fusionner other_patch avec le nôtre.
CartCoord3 minPoint() const
Méthode permettant de récupérer la position min de la boite englobante.
void setMinPoint(CartCoord3 min_point)
Méthode permettant de définir la position min de la boite englobante.
CartCoord3 length() const
Méthode permettant de connaitre la taille du patch (en nombre de mailles par direction).
AMRPatchPosition()
Constructeur pour une position nulle. Une position nulle est définie par un level = -2.
void setLevel(Int32 level)
Méthode permettant de définir le niveau du patch.
bool isNull() const
Méthode permettant de savoir si la position du patch est nulle.
CartCoord3 maxPointWithOverlap() const
Méthode permettant de récupérer la position max de la boite englobante en incluant la couche de maill...
CartCoord3 maxPoint() const
Méthode permettant de récupérer la position max de la boite englobante.
bool haveIntersection(const AMRPatchPosition &other) const
Méthode permettant de savoir si notre patch est en contact avec le patch other.
Int64 nbCells() const
Méthode permettant de connaitre le nombre de mailles du patch selon sa position.
Int32 overlapLayerSize() const
Méthode permettant de récupérer le nombre de couches de mailles de recouvrement du patch.
void setOverlapLayerSize(Int32 layer_size)
Méthode permettant de définir le nombre de couches de mailles de recouvrement du patch.
Int32 level() const
Méthode permettant de récupérer le niveau du patch.
std::pair< AMRPatchPosition, AMRPatchPosition > cut(CartCoord cut_point, Integer dim) const
Méthode permettant de découper le patch en deux patchs selon un point de découpe.
void setMaxPoint(CartCoord3 max_point)
Méthode permettant de définir la position max de la boite englobante.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 CartCoord
Représente une coordonnée d'un élément dans la grille cartésienne (en X ou en Y ou en Z).
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.
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}.