14#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/Math.h"
21#include "arcane/core/IMesh.h"
22#include "arcane/core/IParallelMng.h"
24#include "arcane/core/ItemGroup.h"
26#include "arcane/cartesianmesh/ICartesianMesh.h"
28#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
29#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h"
40 constexpr Integer TARGET_SIZE = 8;
41 constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 1;
42 constexpr Integer MAX_NB_CUT = 6;
43 constexpr Real TARGET_EFFICACITY = 1.0;
49AMRPatchPositionSignature::
50AMRPatchPositionSignature()
58, m_all_patches(nullptr)
62AMRPatchPositionSignature::
63AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches)
69, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMngInternal().get())
72, m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0)
73, m_sig_y(patch.maxPoint().y - patch.minPoint().y, 0)
74, m_sig_z(patch.maxPoint().z - patch.minPoint().z, 0)
75, m_all_patches(all_patches)
78AMRPatchPositionSignature::
79AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches, Integer nb_cut)
85, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMngInternal().get())
88, m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0)
89, m_sig_y(patch.maxPoint().y - patch.minPoint().y, 0)
90, m_sig_z(patch.maxPoint().z - patch.minPoint().z, 0)
91, m_all_patches(all_patches)
97AMRPatchPositionSignature::
98~AMRPatchPositionSignature()
104void AMRPatchPositionSignature::
112 if (m_sig_x[0] == 0) {
113 for (; reduce_x_min < m_sig_x.size(); ++reduce_x_min) {
114 if (m_sig_x[reduce_x_min] != 0) {
120 if (m_sig_y[0] == 0) {
121 for (; reduce_y_min < m_sig_y.size(); ++reduce_y_min) {
122 if (m_sig_y[reduce_y_min] != 0) {
128 if (m_sig_z[0] == 0) {
129 for (; reduce_z_min < m_sig_z.size(); ++reduce_z_min) {
130 if (m_sig_z[reduce_z_min] != 0) {
136 Integer reduce_x_max = m_sig_x.size()-1;
137 if (m_sig_x[reduce_x_max] == 0) {
138 for (; reduce_x_max >= 0; --reduce_x_max) {
139 if (m_sig_x[reduce_x_max] != 0) {
144 Integer reduce_y_max = m_sig_y.size()-1;
145 if (m_sig_y[reduce_y_max] == 0) {
146 for (; reduce_y_max >= 0; --reduce_y_max) {
147 if (m_sig_y[reduce_y_max] != 0) {
152 Integer reduce_z_max = m_sig_z.size() - 1;
153 if (m_sig_z[reduce_z_max] == 0) {
154 for (; reduce_z_max >= 0; --reduce_z_max) {
155 if (m_sig_z[reduce_z_max] != 0) {
161 if (reduce_x_min != 0 || reduce_x_max != m_sig_x.size()-1) {
162 if (reduce_x_max < reduce_x_min) {
166 UniqueArray tmp = m_sig_x.subView(reduce_x_min, reduce_x_max - reduce_x_min);
168 Int64x3 patch_min = m_patch.minPoint();
169 Int64x3 patch_max = m_patch.maxPoint();
170 patch_min.x += reduce_x_min;
171 patch_max.x = patch_min.x + (reduce_x_max - reduce_x_min);
172 m_patch.setMinPoint(patch_min);
173 m_patch.setMaxPoint(patch_max);
175 if (reduce_y_min != 0 || reduce_y_max != m_sig_y.size()-1) {
176 if (reduce_y_max < reduce_y_min) {
180 UniqueArray tmp = m_sig_y.subView(reduce_y_min, reduce_y_max - reduce_y_min);
182 Int64x3 patch_min = m_patch.minPoint();
183 Int64x3 patch_max = m_patch.maxPoint();
184 patch_min.y += reduce_y_min;
185 patch_max.y = patch_min.y + (reduce_y_max - reduce_y_min);
186 m_patch.setMinPoint(patch_min);
187 m_patch.setMaxPoint(patch_max);
189 if (m_mesh->mesh()->dimension() == 3 && (reduce_z_min != 0 || reduce_z_max != m_sig_z.size() - 1)) {
190 if (reduce_z_max < reduce_z_min) {
194 UniqueArray tmp = m_sig_z.subView(reduce_z_min, reduce_z_max - reduce_z_min);
196 Int64x3 patch_min = m_patch.minPoint();
197 Int64x3 patch_max = m_patch.maxPoint();
198 patch_min.z += reduce_z_min;
199 patch_max.z = patch_min.z + (reduce_z_max - reduce_z_min);
200 m_patch.setMinPoint(patch_min);
201 m_patch.setMaxPoint(patch_max);
208void AMRPatchPositionSignature::
214 ENUMERATE_ (Cell, icell, m_mesh->mesh()->ownLevelCells(m_patch.level())) {
215 if (!icell->hasFlags(ItemFlags::II_Refine)) {
219 const Int64 pos_x = m_numbering->cellUniqueIdToCoordX(*icell);
220 const Int64 pos_y = m_numbering->cellUniqueIdToCoordY(*icell);
221 const Int64 pos_z = m_numbering->cellUniqueIdToCoordZ(*icell);
224 pos_x < m_patch.minPoint().x || pos_x >= m_patch.maxPoint().x ||
225 pos_y < m_patch.minPoint().y || pos_y >= m_patch.maxPoint().y ||
226 pos_z < m_patch.minPoint().z || pos_z >= m_patch.maxPoint().z) {
230 m_sig_x[pos_x - m_patch.minPoint().x]++;
231 m_sig_y[pos_y - m_patch.minPoint().y]++;
232 m_sig_z[pos_z - m_patch.minPoint().z]++;
235 m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_x);
236 m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_y);
237 m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_z);
239 if (m_all_patches->maxLevel() > m_patch.level()) {
243 for (
const auto& elem : m_all_patches->patches(m_patch.level() + 1)) {
244 AMRPatchPosition patch_down = elem.patchDown(m_mesh->mesh()->dimension());
245 if (!m_patch.haveIntersection(patch_down)) {
249 Int64x3
min = patch_down.minPoint() - m_patch.minPoint();
250 Int64x3
max = patch_down.maxPoint() - m_patch.minPoint();
255 begin.x = std::max(
min.
x,
static_cast<Int64
>(0));
256 end.x = std::min(
max.x,
static_cast<Int64
>(m_sig_x.size()));
258 begin.y = std::max(
min.
y,
static_cast<Int64
>(0));
259 end.y = std::min(
max.y,
static_cast<Int64
>(m_sig_y.size()));
261 if (m_mesh->mesh()->dimension() == 2) {
266 begin.z = std::max(
min.z,
static_cast<Int64
>(0));
267 end.z = std::min(
max.z,
static_cast<Int64
>(m_sig_z.size()));
270 for (Int64 k = begin.z; k < end.z; ++k) {
271 for (Int64 j = begin.y; j < end.y; ++j) {
272 for (Int64 i = begin.x; i < end.x; ++i) {
283 m_have_cells = m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, m_have_cells);
289bool AMRPatchPositionSignature::
295 if (m_sig_x.size() < MIN_SIZE || m_sig_y.size() < MIN_SIZE || (m_mesh->mesh()->dimension() == 3 && m_sig_z.size() < MIN_SIZE)) {
304bool AMRPatchPositionSignature::
307 m_mesh->traceMng()->info() <<
"canBeCut() -- m_sig_x.size : " << m_sig_x.size()
308 <<
" -- m_sig_y.size : " << m_sig_y.size()
309 <<
" -- m_sig_z.size : " << m_sig_z.size()
310 <<
" -- min = " << m_patch.minPoint()
311 <<
" -- max = " << m_patch.maxPoint()
312 <<
" -- length = " << m_patch.length()
313 <<
" -- isValid : " << isValid()
314 <<
" -- efficacity : " << efficacity() <<
" / " << TARGET_EFFICACITY
315 <<
" -- m_nb_cut : " << m_nb_cut <<
" / " << MAX_NB_CUT
316 <<
" -- m_stop_cut : " << m_stop_cut;
326 if (efficacity() > TARGET_EFFICACITY) {
329 if (MAX_NB_CUT != -1 && m_nb_cut >= MAX_NB_CUT) {
338void AMRPatchPositionSignature::
341 m_mesh->traceMng()->info() <<
"Compute() -- Patch before compute : min = " << m_patch.minPoint() <<
" -- max = " << m_patch.maxPoint() <<
" -- length = " << m_patch.length();
345 m_mesh->traceMng()->info() <<
"Compute() -- Compress : min = " << m_patch.minPoint() <<
" -- max = " << m_patch.maxPoint() <<
" -- x = " << m_sig_x <<
" -- y = " << m_sig_y <<
" -- z = " << m_sig_z;
346 m_mesh->traceMng()->info() <<
"Compute() -- Patch computed : min = " << m_patch.minPoint() <<
" -- max = " << m_patch.maxPoint() <<
" -- length = " << m_patch.length();
348 m_is_computed =
true;
354Real AMRPatchPositionSignature::
357 if (!m_is_computed) {
359 m_mesh->traceMng()->warning() <<
"Need to be computed";
362 for (
const Integer elem : m_sig_x) {
366 Real eff =
static_cast<Real
>(sum) / (m_sig_x.size() * m_sig_y.size() * m_sig_z.size());
368 if constexpr (TARGET_SIZE == -1 || TARGET_SIZE_WEIGHT_IN_EFFICACITY == 0) {
373 if (m_sig_x.size() <= TARGET_SIZE) {
374 eff_xy =
static_cast<Real
>(m_sig_x.size()) / TARGET_SIZE;
376 else if (m_sig_x.size() < TARGET_SIZE*2) {
377 Real size_x = math::abs(m_sig_x.size() - TARGET_SIZE*2);
378 eff_xy = size_x / TARGET_SIZE;
381 if (m_sig_y.size() <= TARGET_SIZE) {
382 eff_xy +=
static_cast<Real
>(m_sig_y.size()) / TARGET_SIZE;
384 else if (m_sig_y.size() < TARGET_SIZE * 2) {
385 Real size_y = math::abs(m_sig_y.size() - TARGET_SIZE * 2);
386 eff_xy += size_y / TARGET_SIZE;
389 if (m_mesh->mesh()->dimension() == 2) {
393 if (m_sig_z.size() <= TARGET_SIZE) {
394 eff_xy = (eff_xy + (
static_cast<Real
>(m_sig_z.size()) / TARGET_SIZE)) / 3;
396 else if (m_sig_z.size() < TARGET_SIZE * 2) {
397 Real size_z = math::abs(m_sig_z.size() - TARGET_SIZE * 2);
398 eff_xy = (eff_xy + (size_z / TARGET_SIZE)) / 3;
404 eff_xy *= TARGET_SIZE_WEIGHT_IN_EFFICACITY;
406 return (eff+eff_xy)/(1+TARGET_SIZE_WEIGHT_IN_EFFICACITY);
412std::pair<AMRPatchPositionSignature, AMRPatchPositionSignature> AMRPatchPositionSignature::
413cut(Integer dim, Integer cut_point)
const
415 auto [fst, snd] = m_patch.cut(cut_point, dim);
416 return {AMRPatchPositionSignature(fst, m_mesh, m_all_patches, m_nb_cut+1), AMRPatchPositionSignature(snd, m_mesh, m_all_patches, m_nb_cut+1)};
422bool AMRPatchPositionSignature::
423isIn(Integer x, Integer y, Integer z)
const
425 return m_patch.isIn(x, y, z);
427ConstArrayView<Integer> AMRPatchPositionSignature::sigX()
const
431ConstArrayView<Integer> AMRPatchPositionSignature::sigY()
const
435ConstArrayView<Integer> AMRPatchPositionSignature::sigZ()
const
439AMRPatchPosition AMRPatchPositionSignature::patch()
const
443ICartesianMesh* AMRPatchPositionSignature::mesh()
const
447bool AMRPatchPositionSignature::stopCut()
const
451void AMRPatchPositionSignature::setStopCut(
bool stop_cut)
453 m_stop_cut = stop_cut;
455bool AMRPatchPositionSignature::isComputed()
const
457 return m_is_computed;
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types généraux de Arcane.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
double Real
Type représentant un réel.
Real y
deuxième composante du couple
Real x
première composante du couple