Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
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 of a 2D or 3D zone of a mesh. */
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 // Iterates over active cells and adds to the list of cells
41 // to refine those contained in the bounding box.
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 // Iterates over active cells and adds to the list of cells
88 // to refine those contained in the bounding box.
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 // We cannot use allActiveCells() because we must take into account
95 // the cells under the overlap cells (and not the overlap cells themselves).
96 ENUMERATE_ (Cell, icell, mesh->mesh()->allCells()) {
97 Cell cell = *icell;
99 continue;
100 }
101 if (cell.hasHChildren()) {
103 continue;
104 }
105 }
106 Real3 center;
107 for (const Node node : cell.nodes())
108 center += nodes_coord[node];
109 center /= cell.nbNode();
110 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
111 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
112 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d;
113 if (is_inside_x && is_inside_y && is_inside_z) {
114 if (level == -1)
115 level = cell.level();
116 else if (level != cell.level())
117 ARCANE_FATAL("Level pb -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, cell.level(), cell.uniqueId());
118 cells_local_id.add(icell.itemLocalId());
119
120 if (icell->isOwn())
121 nb_cells++;
122
123 CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
124 if (pos.x < min[MD_DirX])
125 min[MD_DirX] = pos.x;
126 if (pos.x > max[MD_DirX])
127 max[MD_DirX] = pos.x;
128
129 if (pos.y < min[MD_DirY])
130 min[MD_DirY] = pos.y;
131 if (pos.y > max[MD_DirY])
132 max[MD_DirY] = pos.y;
133
134 if (pos.z < min[MD_DirZ])
135 min[MD_DirZ] = pos.z;
136 if (pos.z > max[MD_DirZ])
137 max[MD_DirZ] = pos.z;
138 }
139 }
140 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min);
141 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max);
142 nb_cells = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells);
143 Int32 level_r = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level);
144
145 if (level != -1 && level != level_r) {
146 ARCANE_FATAL("Bad level reduced");
147 }
148
149 max[MD_DirX] += 1;
150 max[MD_DirY] += 1;
151 max[MD_DirZ] += 1;
152
153 {
154 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]);
155 if (nb_cells != nb_cells_patch) {
156 ARCANE_FATAL("Not regular patch");
157 }
158 }
159 position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] });
160 position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] });
161 position.setLevel(level_r);
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
169{
170 if (mesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
171 ARCANE_FATAL("Reserved to AMR type 3");
172 }
173
175 auto numbering = mesh->_internalApi()->cartesianMeshNumberingMngInternal();
176
177 FixedArray<CartCoord, 6> min_n_max;
178 min_n_max[0] = INT32_MAX;
179 min_n_max[1] = INT32_MAX;
180 min_n_max[2] = INT32_MAX;
181 min_n_max[3] = -1;
182 min_n_max[4] = -1;
183 min_n_max[5] = -1;
184 ArrayView min(min_n_max.view().subView(0, 3));
185 ArrayView max(min_n_max.view().subView(3, 3));
186 Int64 nb_cells = 0;
187
188 VariableNodeReal3& nodes_coord = mesh->mesh()->nodesCoordinates();
189 // Iterates over active cells and adds to the list of cells
190 // to refine those contained in the bounding box.
191 const Real3 min_pos = m_position;
192 const Real3 max_pos = min_pos + m_length;
193 Int32 level = -1;
194 Int64 d_cell_level = -1;
195
196 // We cannot use allActiveCells() because we must take into account
197 // the cells under the overlap cells (and not the overlap cells themselves).
198 ENUMERATE_ (Cell, icell, mesh->mesh()->allCells()) {
199 Cell cell = *icell;
200 if (!cell.hasFlags(ItemFlags::II_InPatch)) {
201 continue;
202 }
203 if (cell.hasHChildren()) {
205 continue;
206 }
207 }
208 Real3 center;
209 for (const Node node : cell.nodes())
210 center += nodes_coord[node];
211 center /= cell.nbNode();
212 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
213 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
214 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d;
215 if (is_inside_x && is_inside_y && is_inside_z) {
216 if (level == -1) {
217 level = cell.level();
218 d_cell_level = cell.uniqueId();
219 }
220 else if (level != cell.level())
221 ARCANE_FATAL("Level pb -- Level recorded before : {0} -- CellUID before : {1} -- Cell Level : {2} -- CellUID : {3}", level, d_cell_level, cell.level(), cell.uniqueId());
222
223 if (icell->isOwn())
224 nb_cells++;
225
226 const CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
227 if (pos.x < min[MD_DirX])
228 min[MD_DirX] = pos.x;
229 if (pos.x > max[MD_DirX])
230 max[MD_DirX] = pos.x;
231
232 if (pos.y < min[MD_DirY])
233 min[MD_DirY] = pos.y;
234 if (pos.y > max[MD_DirY])
235 max[MD_DirY] = pos.y;
236
237 if (pos.z < min[MD_DirZ])
238 min[MD_DirZ] = pos.z;
239 if (pos.z > max[MD_DirZ])
240 max[MD_DirZ] = pos.z;
241 }
242 }
243 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min);
244 mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max);
245 nb_cells = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells);
246 Int32 level_r = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level);
247
248 if (level != -1 && level != level_r) {
249 ARCANE_FATAL("Bad level reduced");
250 }
251
252 // Min inclusive / Max exclusive
253 max[MD_DirX] += 1;
254 max[MD_DirY] += 1;
255 max[MD_DirZ] += 1;
256
257 {
258 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]);
259 if (nb_cells != nb_cells_patch) {
260 ARCANE_FATAL("Not regular patch");
261 }
262 }
263 position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] });
264 position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] });
265 position.setLevel(level_r);
266
267 // Warning: Not enough information to set the correct overlapSize!
268
269 //mesh->traceMng()->info() << "Position test -- Min : " << position.minPoint() << " -- Max : " << position.maxPoint() << " -- Level : " << position.level();
270
271 return position;
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
277} // End namespace Arcane
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
Class allowing the definition of a patch position in the Cartesian mesh.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Method allowing retrieval of the cells included in the zone.
Real3 position() const
Method allowing retrieval of the zone's position.
AMRPatchPosition toAMRPatchPosition(ICartesianMesh *mesh) const
Method allowing conversion of this AMRZonePosition into AMRPatchPosition.
Modifiable view of an array of type T.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Cell of a mesh.
Definition Item.h:1300
Cell hChild(Int32 i) const
i-th AMR child
Definition Item.h:1441
bool hasHChildren() const
Definition Item.h:1466
Int32 level() const
Definition Item.h:1473
constexpr __host__ __device__ ArrayView< T > view()
Modifiable view of the array.
@ II_InPatch
[AMR Patch] The entity is marked as being in an AMR patch.
Definition ItemFlags.h:92
NodeConnectedListViewType nodes() const
List of nodes of the entity.
Definition Item.h:843
Int32 nbNode() const
Number of nodes of the entity.
Definition Item.h:837
constexpr bool hasFlags(Int32 flags) const
Returns if the flags are set for the entity.
Definition Item.h:352
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
Node of a mesh.
Definition Item.h:598
Class managing a 3-dimensional real vector.
Definition Real3.h:132
1D data vector with value semantics (STL style).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
@ ReduceMin
Minimum of values.
@ ReduceMax
Maximum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
@ MD_DirZ
Z Direction.
@ MD_DirY
Y Direction.
@ MD_DirX
X Direction.
@ PatchCartesianMeshOnly
The mesh is AMR by Cartesian patch (rectangular).
Definition MeshKind.h:57
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}.
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35