Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
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 of an AMR patch in a Cartesian mesh. */
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() = default;
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
70level() const
71{
72 return m_level;
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
80{
81 m_level = level;
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
88minPoint() const
89{
90 return m_min_point;
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
97setMinPoint(CartCoord3 min_point)
98{
99 m_min_point = min_point;
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
106maxPoint() const
107{
108 return m_max_point;
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
115setMaxPoint(CartCoord3 max_point)
116{
117 m_max_point = max_point;
118}
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
124overlapLayerSize() const
125{
126 return m_overlap_layer_size;
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
133setOverlapLayerSize(Int32 layer_size)
134{
135 m_overlap_layer_size = layer_size;
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
143{
144 return m_min_point - m_overlap_layer_size;
145}
146
147/*---------------------------------------------------------------------------*/
148/*---------------------------------------------------------------------------*/
149
152{
153 return m_max_point + m_overlap_layer_size;
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
160nbCells() const
161{
162 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);
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
168std::pair<AMRPatchPosition, AMRPatchPosition> AMRPatchPosition::
169cut(CartCoord cut_point, Integer dim) const
170{
171 CartCoord3 patch_max_cut = m_max_point;
172 CartCoord3 patch_min_cut = m_min_point;
173
174 if (dim == MD_DirX) {
175 patch_max_cut.x = cut_point;
176 patch_min_cut.x = cut_point;
177 }
178 else if (dim == MD_DirY) {
179 patch_max_cut.y = cut_point;
180 patch_min_cut.y = cut_point;
181 }
182 else {
183 patch_max_cut.z = cut_point;
184 patch_min_cut.z = cut_point;
185 }
186
187 AMRPatchPosition p0(*this);
188 p0.setMaxPoint(patch_max_cut);
189
190 AMRPatchPosition p1(*this);
191 p1.setMinPoint(patch_min_cut);
192
193 return { p0, p1 };
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
200canBeFusion(const AMRPatchPosition& other_patch) const
201{
202 const CartCoord3 min_point = other_patch.minPoint();
203 const CartCoord3 max_point = other_patch.maxPoint();
204 return m_level == other_patch.level() &&
205 (((m_min_point.x == max_point.x || m_max_point.x == min_point.x) &&
206 (m_min_point.y == min_point.y && m_max_point.y == max_point.y) &&
207 (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) ||
208
209 ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) &&
210 (m_min_point.y == max_point.y || m_max_point.y == min_point.y) &&
211 (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) ||
212
213 ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) &&
214 (m_min_point.y == min_point.y && m_max_point.y == max_point.y) &&
215 (m_min_point.z == max_point.z || m_max_point.z == min_point.z)));
216}
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
222fusion(AMRPatchPosition& other_patch)
223{
224 if (!canBeFusion(other_patch)) {
225 return false;
226 }
227
228 const CartCoord3 min_point = other_patch.minPoint();
229 const CartCoord3 max_point = other_patch.maxPoint();
230
231 if (m_min_point.x > min_point.x) {
232 m_min_point.x = min_point.x;
233 }
234 else if (m_max_point.x < max_point.x) {
235 m_max_point.x = max_point.x;
236 }
237
238 else if (m_min_point.y > min_point.y) {
239 m_min_point.y = min_point.y;
240 }
241 else if (m_max_point.y < max_point.y) {
242 m_max_point.y = max_point.y;
243 }
244
245 else if (m_min_point.z > min_point.z) {
246 m_min_point.z = min_point.z;
247 }
248 else if (m_max_point.z < max_point.z) {
249 m_max_point.z = max_point.z;
250 }
251
252 other_patch.setLevel(-2);
253
254 return true;
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
261isNull() const
262{
263 return m_level == -2;
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
270patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
271{
273 p.setLevel(m_level + 1);
274 p.setMinPoint(m_min_point * 2);
275 if (dim == 2) {
276 p.setMaxPoint({ m_max_point.x * 2, m_max_point.y * 2, 1 });
277 }
278 else {
279 p.setMaxPoint(m_max_point * 2);
280 }
281 p.computeOverlapLayerSize(higher_level, overlap_layer_size_top_level);
282 return p;
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
289patchDown(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
290{
292 p.setLevel(m_level - 1);
293 p.setMinPoint(m_min_point / 2);
294 if (dim == 2) {
295 p.setMaxPoint({ static_cast<CartCoord>(std::ceil(m_max_point.x / 2.)), static_cast<CartCoord>(std::ceil(m_max_point.y / 2.)), 1 });
296 }
297 else {
298 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.)) });
299 }
300 p.computeOverlapLayerSize(higher_level, overlap_layer_size_top_level);
301 return p;
302}
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
308length() const
309{
310 return m_max_point - m_min_point;
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
317isIn(CartCoord x, CartCoord y, CartCoord z) const
318{
319 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;
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
326isIn(CartCoord3 coord) const
327{
328 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;
329}
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
336{
337 const CartCoord3 min_point = minPointWithOverlap();
338 const CartCoord3 max_point = maxPointWithOverlap();
339 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;
340}
341
342/*---------------------------------------------------------------------------*/
343/*---------------------------------------------------------------------------*/
344
346isInWithOverlap(CartCoord3 coord) const
347{
348 const CartCoord3 min_point = minPointWithOverlap();
349 const CartCoord3 max_point = maxPointWithOverlap();
350 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;
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
358{
359 const CartCoord3 min_point = m_min_point - overlap;
360 const CartCoord3 max_point = m_max_point + overlap;
361 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;
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
368isInWithOverlap(CartCoord3 coord, Integer overlap) const
369{
370 const CartCoord3 min_point = m_min_point - overlap;
371 const CartCoord3 max_point = m_max_point + overlap;
372 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;
373}
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
379haveIntersection(const AMRPatchPosition& other) const
380{
381 return (
382 (other.level() == level()) &&
383 (other.maxPoint().x > minPoint().x && maxPoint().x > other.minPoint().x) &&
384 (other.maxPoint().y > minPoint().y && maxPoint().y > other.minPoint().y) &&
385 (other.maxPoint().z > minPoint().z && maxPoint().z > other.minPoint().z));
386}
387
388/*---------------------------------------------------------------------------*/
389/*---------------------------------------------------------------------------*/
390
399computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
400{
401 // If the top level is -1, overlap cells are disabled.
402 if (overlap_layer_size_top_level == -1) {
403 return 0;
404 }
405 // Level 0 never has layers.
406 if (level == 0) {
407 return 0;
408 }
409 if (level == higher_level) {
410 return overlap_layer_size_top_level;
411 }
412 if (level < 0 || level > higher_level) {
413 ARCANE_FATAL("Level {0} doesn't exist (higher_level={1})", level, higher_level);
414 }
415
416 Int32 nb_overlap_cells = overlap_layer_size_top_level;
417
418 // To avoid unnecessary loops.
419 if (nb_overlap_cells == 0) {
420 return 2;
421 }
422 if (nb_overlap_cells == 2) {
423 return 2;
424 }
425 for (Integer m = higher_level; m > level; --m) {
426 if (nb_overlap_cells == 4) {
427 return 4;
428 }
429 nb_overlap_cells = ((nb_overlap_cells / 4) + 1) * 2;
430 }
431
432 return nb_overlap_cells;
433}
434
435/*---------------------------------------------------------------------------*/
436/*---------------------------------------------------------------------------*/
437
439computeOverlapLayerSize(Int32 higher_level, Int32 overlap_layer_size_top_level)
440{
441 m_overlap_layer_size = computeOverlapLayerSize(m_level, higher_level, overlap_layer_size_top_level);
442}
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
447} // End namespace Arcane
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Declarations of Arcane's general types.
AMRPatchPosition patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Method to create an AMRPatchPosition for the higher level.
bool isInWithOverlap(CartCoord x, CartCoord y, CartCoord z) const
Method to know if a cell at position x,y,z is included in this patch with overlap layer.
CartCoord3 minPointWithOverlap() const
Method to retrieve the min position of the enclosing box including the overlap cell layer.
AMRPatchPosition patchDown(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Method to create an AMRPatchPosition for the lower level.
bool isIn(CartCoord x, CartCoord y, CartCoord z) const
Method to know if a cell at position x,y,z is included in this patch.
bool canBeFusion(const AMRPatchPosition &other_patch) const
Method to know if our patch can be merged with other_patch.
static Int32 computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
Method to calculate the number of overlap cell layers for a given level.
bool fusion(AMRPatchPosition &other_patch)
Method to merge other_patch with ours.
CartCoord3 minPoint() const
Method to retrieve the min position of the enclosing box.
void setMinPoint(CartCoord3 min_point)
Method to set the min position of the enclosing box.
CartCoord3 length() const
Method to know the size of the patch (in number of cells per direction).
AMRPatchPosition()
Constructor for a null position. A null position is defined by a level = -2.
void setLevel(Int32 level)
Method to set the patch level.
bool isNull() const
Method to know if the patch is null.
CartCoord3 maxPointWithOverlap() const
Method to retrieve the max position of the enclosing box including the overlap cell layer.
CartCoord3 maxPoint() const
Method to retrieve the max position of the enclosing box.
bool haveIntersection(const AMRPatchPosition &other) const
Method to know if our patch is in contact with other.
Int64 nbCells() const
Method to know the number of cells in the patch according to its position.
Int32 overlapLayerSize() const
Method to retrieve the number of overlap cell layers of the patch.
void setOverlapLayerSize(Int32 layer_size)
Method to set the number of overlap cell layers of the patch.
Int32 level() const
Method to retrieve the patch level.
std::pair< AMRPatchPosition, AMRPatchPosition > cut(CartCoord cut_point, Integer dim) const
Method to cut the patch into two patches according to a cut point.
void setMaxPoint(CartCoord3 max_point)
Method to set the max position of the enclosing box.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 CartCoord
Represents a coordinate of an element in the Cartesian grid (in X or Y or Z).
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
@ MD_DirY
Y Direction.
@ MD_DirX
X Direction.
std::int32_t Int32
Signed integer type of 32 bits.
Int32x3 CartCoord3
Represents the 3D coordinates of an element in the Cartesian grid {x, y, z}.