From 1313d43de69f3332e213ad5e36ad9acd66053ce6 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Wed, 22 Oct 2025 16:37:57 +0200 Subject: [PATCH 01/19] [arcane:cartesianmesh] Add AMRPatchPosition class to represent position of patch in the cartesian mesh And : - Add methods to split patches to ensure that patches are always regular after coarseZone() call. --- .../tests/AMRCartesianMeshTesterModule.cc | 10 + .../arcane/cartesianmesh/AMRPatchPosition.cc | 216 +++++++ .../arcane/cartesianmesh/AMRPatchPosition.h | 67 ++ .../arcane/cartesianmesh/AMRZonePosition.cc | 102 ++- .../arcane/cartesianmesh/AMRZonePosition.h | 7 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 55 +- .../cartesianmesh/CartesianMeshAMRPatchMng.cc | 5 +- .../cartesianmesh/CartesianMeshPatch.cc | 2 - .../cartesianmesh/CartesianMeshUtils.cc | 9 + .../arcane/cartesianmesh/CartesianMeshUtils.h | 7 + .../arcane/cartesianmesh/CartesianPatch.cc | 10 + .../src/arcane/cartesianmesh/CartesianPatch.h | 8 +- .../cartesianmesh/CartesianPatchGroup.cc | 605 ++++++++++++++++-- .../cartesianmesh/CartesianPatchGroup.h | 18 +- .../cartesianmesh/ICartesianMeshPatch.h | 6 +- .../internal/CartesianMeshPatch.h | 16 +- arcane/src/arcane/cartesianmesh/srcs.cmake | 2 + 17 files changed, 1021 insertions(+), 124 deletions(-) create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPosition.h diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 24d5cebc53..67f631cd2d 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -603,6 +603,16 @@ void AMRCartesianMeshTesterModule:: compute() { _compute1(); + info() << "NbPatch : " << m_cartesian_mesh->nbPatch(); + info() << "NbPatch : " << m_cartesian_mesh->patches().size(); + + for (Integer i = 0; i < m_cartesian_mesh->patches().size(); ++i) { + auto patch = m_cartesian_mesh->amrPatch(i); + info() << "Patch #" << i; + info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); + info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); + info() << "\tLevel : " << patch.patchInterface()->position().level(); + } } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc new file mode 100644 index 0000000000..36a0714d1f --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -0,0 +1,216 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPosition.cc (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPosition.h" + +#include "arcane/core/ArcaneTypes.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPosition:: +AMRPatchPosition() +: m_level(-2) +{ + +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPosition:: +~AMRPatchPosition() += default; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer AMRPatchPosition:: +level() const +{ + return m_level; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPosition:: +setLevel(Integer level) +{ + m_level = level; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +minPoint() const +{ + return m_min_point; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPosition:: +setMinPoint(Int64x3 min_point) +{ + m_min_point = min_point; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +maxPoint() const +{ + return m_max_point; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPosition:: +setMaxPoint(Int64x3 max_point) +{ + m_max_point = max_point; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +isIn(Int64 x, Int64 y, Int64 z) const +{ + 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; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 AMRPatchPosition:: +nbCells() const +{ + return (m_max_point.x - m_min_point.x) * (m_max_point.y - m_min_point.y) * (m_max_point.z - m_min_point.z); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +std::pair AMRPatchPosition:: +cut(Int64 cut_point, Integer dim) const +{ + Int64x3 patch_max_cut = m_max_point; + Int64x3 patch_min_cut = m_min_point; + + if (dim == MD_DirX) { + patch_max_cut.x = cut_point; + patch_min_cut.x = cut_point; + } + else if (dim == MD_DirY) { + patch_max_cut.y = cut_point; + patch_min_cut.y = cut_point; + } + else { + patch_max_cut.z = cut_point; + patch_min_cut.z = cut_point; + } + + AMRPatchPosition p0; + p0.setLevel(m_level); + p0.setMinPoint(m_min_point); + p0.setMaxPoint(patch_max_cut); + + AMRPatchPosition p1; + p1.setLevel(m_level); + p1.setMinPoint(patch_min_cut); + p1.setMaxPoint(m_max_point); + + return { p0, p1 }; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +canBeFusion(const AMRPatchPosition& other_patch) const +{ + const Int64x3 min_point = other_patch.minPoint(); + const Int64x3 max_point = other_patch.maxPoint(); + return m_level == other_patch.level() && + (((m_min_point.x == max_point.x || m_max_point.x == min_point.x) && + (m_min_point.y == min_point.y && m_max_point.y == max_point.y) && + (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) || + + ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) && + (m_min_point.y == max_point.y || m_max_point.y == min_point.y) && + (m_min_point.z == min_point.z && m_max_point.z == max_point.z)) || + + ((m_min_point.x == min_point.x && m_max_point.x == max_point.x) && + (m_min_point.y == min_point.y && m_max_point.y == max_point.y) && + (m_min_point.z == max_point.z || m_max_point.z == min_point.z))); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPosition:: +fusion(const AMRPatchPosition& other_patch) +{ + const Int64x3 min_point = other_patch.minPoint(); + const Int64x3 max_point = other_patch.maxPoint(); + + if (m_min_point.x > min_point.x) { + m_min_point.x = min_point.x; + } + else if (m_max_point.x < max_point.x) { + m_max_point.x = max_point.x; + } + + else if (m_min_point.y > min_point.y) { + m_min_point.y = min_point.y; + } + else if (m_max_point.y < max_point.y) { + m_max_point.y = max_point.y; + } + + else if (m_min_point.z > min_point.z) { + m_min_point.z = min_point.z; + } + else if (m_max_point.z < max_point.z) { + m_max_point.z = max_point.z; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +isNull() const +{ + return m_level == -2; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h new file mode 100644 index 0000000000..7b1257f273 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -0,0 +1,67 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPosition.h (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITION_H +#define ARCANE_CARTESIANMESH_AMRPATCHPOSITION_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/utils/Vector3.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition +{ + public: + AMRPatchPosition(); + ~AMRPatchPosition(); + public: + + Integer level() const; + void setLevel(Integer level); + + Int64x3 minPoint() const; + void setMinPoint(Int64x3 min_point); + Int64x3 maxPoint() const; + void setMaxPoint(Int64x3 max_point); + + bool isIn(Int64 x, Int64 y, Int64 z) const; + + Int64 nbCells() const; + std::pair cut(Int64 cut_point, Integer dim) const; + bool canBeFusion(const AMRPatchPosition& other_patch) const; + void fusion(const AMRPatchPosition& other_patch); + bool isNull() const; + + private: + Integer m_level; + Int64x3 m_min_point; + Int64x3 m_max_point; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif + diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc index a5d8f047d3..1be25f6fb0 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc @@ -11,7 +11,14 @@ /*---------------------------------------------------------------------------*/ #include "arcane/cartesianmesh/AMRZonePosition.h" + +#include "ICartesianMesh.h" #include "arcane/core/IMesh.h" +#include "arcane/core/MeshKind.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" +#include "arcane/core/IParallelMng.h" +#include "arcane/utils/FixedArray.h" +#include "arcane/utils/ITraceMng.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -23,7 +30,7 @@ namespace Arcane /*---------------------------------------------------------------------------*/ void AMRZonePosition:: -cellsInPatch(IMesh* mesh, SharedArray cells_local_id) const +cellsInPatch(IMesh* mesh, UniqueArray& cells_local_id) const { VariableNodeReal3& nodes_coord = mesh->nodesCoordinates(); // Parcours les mailles actives et ajoute dans la liste des mailles @@ -52,6 +59,99 @@ cellsInPatch(IMesh* mesh, SharedArray cells_local_id) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void AMRZonePosition:: +cellsInPatch(ICartesianMesh* mesh, UniqueArray& cells_local_id, AMRPatchPosition& position) const +{ + if (mesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + cellsInPatch(mesh->mesh(), cells_local_id); + return; + } + auto numbering = mesh->_internalApi()->cartesianMeshNumberingMng(); + + FixedArray min_n_max; + min_n_max[0] = INT64_MAX; + min_n_max[1] = INT64_MAX; + min_n_max[2] = INT64_MAX; + min_n_max[3] = -1; + min_n_max[4] = -1; + min_n_max[5] = -1; + ArrayView min(min_n_max.view().subView(0, 3)); + ArrayView max(min_n_max.view().subView(3, 3)); + Int64 nb_cells = 0; + + VariableNodeReal3& nodes_coord = mesh->mesh()->nodesCoordinates(); + // Parcours les mailles actives et ajoute dans la liste des mailles + // à raffiner celles qui sont contenues dans la boîte englobante. + Real3 min_pos = m_position; + Real3 max_pos = min_pos + m_length; + Int32 level = -1; + cells_local_id.clear(); + ENUMERATE_ (Cell, icell, mesh->mesh()->allActiveCells()) { + Cell cell = *icell; + Real3 center; + for (const Node node : cell.nodes()) + center += nodes_coord[node]; + center /= cell.nbNode(); + bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x; + bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y; + bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d; + if (is_inside_x && is_inside_y && is_inside_z) { + mesh->mesh()->traceMng()->info() << "CellUID : " << cell.uniqueId() << " -- Level : " << cell.level(); + if (level == -1) + level = cell.level(); + else if (level != cell.level()) + ARCANE_FATAL("Level pb -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, cell.level(), cell.uniqueId()); + cells_local_id.add(icell.itemLocalId()); + + if (icell->isOwn()) + nb_cells++; + + Int64 pos_x = numbering->cellUniqueIdToCoordX(cell); + if (pos_x < min[MD_DirX]) + min[MD_DirX] = pos_x; + if (pos_x > max[MD_DirX]) + max[MD_DirX] = pos_x; + + Int64 pos_y = numbering->cellUniqueIdToCoordY(cell); + if (pos_y < min[MD_DirY]) + min[MD_DirY] = pos_y; + if (pos_y > max[MD_DirY]) + max[MD_DirY] = pos_y; + + Int64 pos_z = numbering->cellUniqueIdToCoordZ(cell); + if (pos_z < min[MD_DirZ]) + min[MD_DirZ] = pos_z; + if (pos_z > max[MD_DirZ]) + max[MD_DirZ] = pos_z; + } + } + mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min); + mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max); + nb_cells = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells); + Integer level_r = mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level); + + if (level != -1 && level != level_r) { + ARCANE_FATAL("Bad level reduced"); + } + + max[MD_DirX] += 1; + max[MD_DirY] += 1; + max[MD_DirZ] += 1; + + { + Int64 nb_cells_patch = (max[MD_DirX] - min[MD_DirX]) * (max[MD_DirY] - min[MD_DirY]) * (max[MD_DirZ] - min[MD_DirZ]); + if (nb_cells != nb_cells_patch) { + ARCANE_FATAL("Not regular patch"); + } + } + position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] }); + position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); + position.setLevel(level_r); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h index 32ac562c58..71c18228b9 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h @@ -14,6 +14,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +#include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/utils/Real3.h" #include "arcane/core/VariableTypes.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" @@ -24,8 +25,6 @@ namespace Arcane { -class ICartesianMesh; - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -93,7 +92,9 @@ class ARCANE_CARTESIANMESH_EXPORT AMRZonePosition * \param cells_local_id Le tableau qui contiendra les localIds des mailles de la zone. * Attention : le tableau sera d'abord effacé. */ - void cellsInPatch(IMesh* mesh, SharedArray cells_local_id) const; + void cellsInPatch(IMesh* mesh, UniqueArray& cells_local_id) const; + + void cellsInPatch(ICartesianMesh* mesh, UniqueArray& cells_local_id, AMRPatchPosition& position) const; private: Real3 m_position; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index c2a299c78d..e95d6a378e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -239,8 +239,7 @@ class CartesianMeshImpl VariableFaceReal3& faces_center,CellGroup all_cells, NodeGroup all_nodes); void _applyRefine(const AMRZonePosition &position); - void _removeCellsInPatches(ConstArrayView const_array_view); - void _applyCoarse(const AMRZonePosition &position); + void _applyCoarse(const AMRZonePosition& zone_position); void _addPatch(const CellGroup& parent_cells); void _saveInfosInProperties(); @@ -889,6 +888,8 @@ reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) void CartesianMeshImpl:: _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id) { + m_patch_group.updateLevelsBeforeAddGroundPatch(); + IItemFamily* cell_family = m_mesh->cellFamily(); Integer index = m_patch_group.nextIndexForNewPatch(); String parent_group_name = String("CartesianMeshPatchParentCells")+index; @@ -925,38 +926,10 @@ _addPatch(const CellGroup& parent_cells) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -void CartesianMeshImpl:: -_removeCellsInPatches(ConstArrayView const_array_view) -{ - if (m_amr_type == eMeshAMRKind::Cell) { - m_patch_group.removeCellsInAllPatches(const_array_view); - m_patch_group.applyPatchEdit(true); - } - else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_patch_group.removeCellsInAllPatches(const_array_view); - // SharedArray altered_patches; - // m_patch_group.removeCellsInAllPatches(const_array_view, altered_patches); - // info() << "altered_patches : " << altered_patches; - // for (Integer index : altered_patches) { - // m_patch_group.repairPatch(index, _internalApi()->cartesianMeshNumberingMng().get()); - // } - m_patch_group.applyPatchEdit(true); - } - else if (m_amr_type == eMeshAMRKind::Patch) { - ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)"); - } - else { - ARCANE_FATAL("AMR is not enabled"); - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - void CartesianMeshImpl:: _applyRefine(const AMRZonePosition& position) { - SharedArray cells_local_id; + UniqueArray cells_local_id; position.cellsInPatch(mesh(), cells_local_id); IItemFamily* cell_family = m_mesh->cellFamily(); @@ -1001,10 +974,16 @@ _applyRefine(const AMRZonePosition& position) /*---------------------------------------------------------------------------*/ void CartesianMeshImpl:: -_applyCoarse(const AMRZonePosition& position) +_applyCoarse(const AMRZonePosition& zone_position) { - SharedArray cells_local_id; - position.cellsInPatch(mesh(), cells_local_id); + UniqueArray cells_local_id; + AMRPatchPosition patch_position; + if (m_amr_type == eMeshAMRKind::Cell) { + zone_position.cellsInPatch(mesh(), cells_local_id); + } + else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + zone_position.cellsInPatch(this, cells_local_id, patch_position); + } Integer nb_cell = cells_local_id.size(); info(4) << "Local_NbCellToCoarsen = " << nb_cell; @@ -1015,15 +994,19 @@ _applyCoarse(const AMRZonePosition& position) if (total_nb_cell == 0) return; - _removeCellsInPatches(cells_local_id); - if (m_amr_type == eMeshAMRKind::Cell) { debug() << "Coarse with modifier() (for all mesh types)"; + m_patch_group.removeCellsInAllPatches(cells_local_id); + m_patch_group.applyPatchEdit(true); + m_mesh->modifier()->flagCellToCoarsen(cells_local_id); m_mesh->modifier()->coarsenItemsV2(true); } else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { debug() << "Coarsen with specific coarser (for cartesian mesh only)"; + m_patch_group.removeCellsInAllPatches(cells_local_id, patch_position); + m_patch_group.applyPatchEdit(true); + computeDirections(); m_internal_api.cartesianMeshAMRPatchMng()->flagCellToCoarsen(cells_local_id, true); m_internal_api.cartesianMeshAMRPatchMng()->coarsen(true); diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc index b7e1f069b7..eb114b3263 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc @@ -2002,7 +2002,10 @@ createSubLevel() else { // Ça peut arriver si le partitionnement n'est pas adapté. if (around_parent_cells_uid_to_owner[parent_uid] != cell.owner()) { - ARCANE_FATAL("Pb owner"); + ARCANE_FATAL("Pb owner -- Two+ children, two+ different owners, same parent\n" + "The ground patch size in x, y (and z if 3D) must be a multiple of four (need partitionner update to support multiple of two)\n" + "CellUID : {0} -- CellOwner : {1} -- OtherChildOwner : {2}", + cell.uniqueId(), cell.owner(), around_parent_cells_uid_to_owner[parent_uid]); } } diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc index 2d76a0c20b..23188142fc 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc @@ -34,8 +34,6 @@ CartesianMeshPatch:: CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index) : TraceAccessor(cmesh->traceMng()) , m_mesh(cmesh) -, m_amr_patch_index(patch_index) -, m_level(0) { Integer nb_dir = cmesh->mesh()->dimension(); for( Integer i=0; i_internalApi()->cartesianMeshAMRPatchMng(); } +/*! + * TODO + */ +Ref CartesianMeshUtils:: +cartesianMeshNumberingMng(ICartesianMesh* cm) +{ + return cm->_internalApi()->cartesianMeshNumberingMng(); +} + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h index dca212b929..c56acf5ece 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h @@ -18,6 +18,7 @@ #include "arcane/cartesianmesh/CartesianMeshGlobal.h" #include "arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h" +#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -44,6 +45,12 @@ createCartesianMeshCoarsening2(ICartesianMesh* cm); extern "C++" ARCANE_CARTESIANMESH_EXPORT Ref cartesianMeshAMRPatchMng(ICartesianMesh* cm); +/*! + * TODO + */ +extern "C++" ARCANE_CARTESIANMESH_EXPORT Ref +cartesianMeshNumberingMng(ICartesianMesh* cm); + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc index f3d8a5d276..1f125686cd 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc @@ -34,6 +34,16 @@ cells() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +Integer CartesianPatch:: +index() const +{ + ARCANE_CHECK_POINTER(m_patch); + return m_patch->index(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.h b/arcane/src/arcane/cartesianmesh/CartesianPatch.h index d0399349f8..ebb7e28daa 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.h @@ -54,15 +54,11 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch //! Groupe de mailles du patch CellGroup cells(); - Integer index() const - { - ARCANE_CHECK_POINTER(m_patch); - return m_patch->index(); - } + Integer index() const; Integer level() const { ARCANE_CHECK_POINTER(m_patch); - return m_patch->level(); + return m_patch->position().level(); } //! Liste des mailles dans la direction \a dir diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index 6453006a55..baa8844a00 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -12,12 +12,18 @@ #include "arcane/cartesianmesh/CartesianPatchGroup.h" -#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h" +#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" + +#include "arcane/utils/ITraceMng.h" +#include "arcane/utils/FixedArray.h" +#include "arcane/utils/Vector3.h" + #include "arcane/core/IMesh.h" #include "arcane/core/IParallelMng.h" -#include "arccore/trace/ITraceMng.h" +#include "arcane/core/MeshKind.h" -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -28,6 +34,22 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +// Le patch 0 est un patch spécial "ground". Il ne possède pas de cell_group +// dans le tableau "m_amr_patch_cell_groups". +// Pour les index, on utilise toujours celui des tableaux m_amr_patches_pointer +// et m_amr_patches. + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CartesianPatchGroup::CartesianPatchGroup(ICartesianMesh* cmesh) +: m_cmesh(cmesh) +, m_index_new_patches(0) +{} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Ref CartesianPatchGroup:: groundPatch() { @@ -35,22 +57,97 @@ groundPatch() return patch(0); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: addPatch(CellGroup cell_group) { _createGroundPatch(); - if (cell_group.null()) ARCANE_FATAL("Null cell group"); - auto* cdi = new CartesianMeshPatch(m_cmesh, nextIndexForNewPatch()+1); // +1 pour reproduire l'ancien comportement. + if (cell_group.null()) + ARCANE_FATAL("Null cell group"); + Integer index = nextIndexForNewPatch(); + auto* cdi = new CartesianMeshPatch(m_cmesh, index); m_amr_patch_cell_groups.add(cell_group); _addPatchInstance(makeRef(cdi)); m_cmesh->traceMng()->info() << "m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() - << " -- m_amr_patches : " << m_amr_patches.size() - << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() - << " -- cell_group name : " << m_amr_patch_cell_groups[nextIndexForNewPatch()-1].name() - << " -- index : " << nextIndexForNewPatch()-1 - ; + << " -- m_amr_patches : " << m_amr_patches.size() + << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() + << " -- index : " << index - 1 + << " -- cell_group name : " << m_amr_patch_cell_groups[index - 1].name(); // m_index_new_patches commence par 1, pas le tableau m_amr_patch_cell_groups + + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + FixedArray min_n_max; + min_n_max[0] = INT64_MAX; + min_n_max[1] = INT64_MAX; + min_n_max[2] = INT64_MAX; + min_n_max[3] = -1; + min_n_max[4] = -1; + min_n_max[5] = -1; + ArrayView min(min_n_max.view().subView(0, 3)); + ArrayView max(min_n_max.view().subView(3, 3)); + Int64 nb_cells = 0; + Integer level = -1; + ENUMERATE_ (Cell, icell, cell_group) { + if (icell->isOwn()) + nb_cells++; + if (level == -1) { + level = icell->level(); + } + if (level != icell->level()) { + ARCANE_FATAL("Level pb -- Zone with cells to different levels -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, icell->level(), icell->uniqueId()); + } + Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); + if (pos_x < min[MD_DirX]) + min[MD_DirX] = pos_x; + if (pos_x > max[MD_DirX]) + max[MD_DirX] = pos_x; + + Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); + if (pos_y < min[MD_DirY]) + min[MD_DirY] = pos_y; + if (pos_y > max[MD_DirY]) + max[MD_DirY] = pos_y; + + Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); + if (pos_z < min[MD_DirZ]) + min[MD_DirZ] = pos_z; + if (pos_z > max[MD_DirZ]) + max[MD_DirZ] = pos_z; + } + m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min); + m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max); + nb_cells = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells); + Integer level_r = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level); + + if (level != -1 && level != level_r) { + ARCANE_FATAL("Bad level reduced"); + } + + max[MD_DirX] += 1; + max[MD_DirY] += 1; + max[MD_DirZ] += 1; + + { + Int64 nb_cells_patch = (max[MD_DirX] - min[MD_DirX]) * (max[MD_DirY] - min[MD_DirY]) * (max[MD_DirZ] - min[MD_DirZ]); + if (nb_cells != nb_cells_patch) { + ARCANE_FATAL("Not regular patch"); + } + } + + cdi->position().setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] }); + cdi->position().setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); + cdi->position().setLevel(level_r); + } + m_cmesh->traceMng()->info() << "Min Point : " << cdi->position().minPoint(); + m_cmesh->traceMng()->info() << "Max Point : " << cdi->position().maxPoint(); + m_cmesh->traceMng()->info() << "Level : " << cdi->position().level(); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + // Attention : avant _createGroundPatch() = 0, après _createGroundPatch(); = 1 Integer CartesianPatchGroup:: nbPatch() const @@ -58,27 +155,39 @@ nbPatch() const return m_amr_patches.size(); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Ref CartesianPatchGroup:: patch(const Integer index) const { return m_amr_patches[index]; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CartesianMeshPatchListView CartesianPatchGroup:: patchListView() const { - return CartesianMeshPatchListView{m_amr_patches_pointer}; + return CartesianMeshPatchListView{ m_amr_patches_pointer }; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CellGroup CartesianPatchGroup:: cells(const Integer index) { if (index == 0) { ARCANE_FATAL("You cannot get cells of ground patch with this method"); } - return m_amr_patch_cell_groups[index-1]; + return m_amr_patch_cell_groups[index - 1]; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + // Attention : efface aussi le ground patch. Nécessaire de le récupérer après coup. void CartesianPatchGroup:: clear() @@ -89,6 +198,9 @@ clear() _createGroundPatch(); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: removePatch(const Integer index) { @@ -98,13 +210,16 @@ removePatch(const Integer index) if (index == 0) { ARCANE_FATAL("You cannot remove ground patch"); } - if (index < 1 || index >= m_amr_patch_cell_groups.size()) { + if (index < 1 || index >= m_amr_patches.size()) { ARCANE_FATAL("Invalid index"); } m_patches_to_delete.add(index); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: removeCellsInAllPatches(ConstArrayView cells_local_id) { @@ -113,36 +228,40 @@ removeCellsInAllPatches(ConstArrayView cells_local_id) } } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: -removeCellsInAllPatches(ConstArrayView cells_local_id, SharedArray altered_patches) +removeCellsInAllPatches(ConstArrayView cells_local_id, const AMRPatchPosition& patch_position) { - UniqueArray size_of_patches_before(m_amr_patch_cell_groups.size()); - for (Integer i = 0; i < m_amr_patch_cell_groups.size(); ++i) { - size_of_patches_before[i] = m_amr_patch_cell_groups[i].size(); - } - m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches_before); - - for (CellGroup cells : m_amr_patch_cell_groups) { - cells.removeItems(cells_local_id); - } + // Pas de foreach : _splitPatch() ajoute des patchs. + // Attention si suppression de la suppression en deux étapes : _splitPatch() supprime aussi des patchs. + // i = 1 car on ne peut pas déraffjner le patch ground. + Integer nb_patchs = m_amr_patches_pointer.size(); + for (Integer i = 1; i < nb_patchs; ++i) { + ICartesianMeshPatch* patch = m_amr_patches_pointer[i]; + m_cmesh->mesh()->traceMng()->info() << "I : " << i + << " -- Compare Patch (min : " << patch->position().minPoint() + << ", max : " << patch->position().maxPoint() + << ", level : " << patch->position().level() + << ") and Zone (min : " << patch_position.minPoint() + << ", max : " << patch_position.maxPoint() + << ", level : " << patch_position.level() << ")"; - UniqueArray size_of_patches_after(m_amr_patch_cell_groups.size()); - for (Integer i = 0; i < m_amr_patch_cell_groups.size(); ++i) { - size_of_patches_after[i] = m_amr_patch_cell_groups[i].size(); - } - m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches_after); - - altered_patches.clear(); - for (Integer i = 0; i < size_of_patches_after.size(); ++i) { - if (size_of_patches_before[i] != size_of_patches_after[i]) { - altered_patches.add(i+1); + if (_isPatchInContact(patch->position(), patch_position)) { + //m_amr_patch_cell_groups[i - 1].removeItems(cells_local_id); // TODO : toujours utile ? Le patch sera supprimé. + _splitPatch(i, patch_position); } } } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: applyPatchEdit(bool remove_empty_patches) { + m_cmesh->mesh()->traceMng()->info() << "applyPatchEdit() -- Remove nb patch : " << m_patches_to_delete.size(); _removeMultiplePatches(m_patches_to_delete); m_patches_to_delete.clear(); @@ -154,7 +273,7 @@ applyPatchEdit(bool remove_empty_patches) m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches); for (Integer i = 0; i < size_of_patches.size(); ++i) { if (size_of_patches[i] == 0) { - m_patches_to_delete.add(i+1); + m_patches_to_delete.add(i + 1); } } _removeMultiplePatches(m_patches_to_delete); @@ -162,49 +281,76 @@ applyPatchEdit(bool remove_empty_patches) } } -// void CartesianPatchGroup:: -// repairPatch(Integer index, ICartesianMeshNumberingMng* numbering_mng) -// { -// UniqueArray size_of_line; -// UniqueArray begin_of_line; -// -// ENUMERATE_ () -// CellDirectionMng cells = m_amr_patches_pointer[index]->cellDirection(eMeshDirection::MD_DirX); -// cells.cell() -// -// // Localement, découper le old_patch en patch X. -// // Echange pour avoir la taille réel des patchs X. -// // Fusion des patchs X ayant le même originX et lenghtX (entre Y et Y+1). -// // (3D) Fusion des patchs XY ayant le même originXY et lenghtXY (entre Z et Z+1). -// } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void CartesianPatchGroup:: -updateLevelsBeforeCoarsen() +updateLevelsBeforeAddGroundPatch() { - for (ICartesianMeshPatch* patch : m_amr_patches_pointer) { - patch->setLevel(patch->level() + 1); + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + for (ICartesianMeshPatch* patch : m_amr_patches_pointer) { + Integer level = patch->position().level(); + // Si le niveau est 0, c'est le patch spécial 0 donc on ne modifie que le max, le niveau reste à 0. + if (level == 0) { + Int64x3 max_point = patch->position().maxPoint(); + if (m_cmesh->mesh()->dimension() == 2) { + patch->position().setMaxPoint({ + numbering->offsetLevelToLevel(max_point.x, level, level - 1), + numbering->offsetLevelToLevel(max_point.y, level, level - 1), + 1, + }); + } + else { + patch->position().setMaxPoint({ + numbering->offsetLevelToLevel(max_point.x, level, level - 1), + numbering->offsetLevelToLevel(max_point.y, level, level - 1), + numbering->offsetLevelToLevel(max_point.z, level, level - 1), + }); + } + } + // Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1" + else { + patch->position().setLevel(level + 1); + } + } } } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Integer CartesianPatchGroup:: -nextIndexForNewPatch(){ - return m_amr_patch_cell_groups.size(); +nextIndexForNewPatch() +{ + return m_index_new_patches; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _addPatchInstance(Ref v) { m_amr_patches.add(v); m_amr_patches_pointer.add(v.get()); + m_index_new_patches++; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _removeOnePatch(Integer index) { - m_amr_patch_cell_groups.remove(index-1); + m_amr_patch_cell_groups.remove(index - 1); m_amr_patches_pointer.remove(index); m_amr_patches.remove(index); } + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _removeMultiplePatches(ConstArrayView indexes) { @@ -215,11 +361,356 @@ _removeMultiplePatches(ConstArrayView indexes) } } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _createGroundPatch() { - if (!m_amr_patches.empty()) return; - _addPatchInstance(makeRef(new CartesianMeshPatch(m_cmesh, -1))); + if (!m_amr_patches.empty()) + return; + auto patch = makeRef(new CartesianMeshPatch(m_cmesh, -1)); + _addPatchInstance(patch); + + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + patch->position().setMinPoint({ 0, 0, 0 }); + patch->position().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) }); + patch->position().setLevel(0); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool CartesianPatchGroup:: +_isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPosition& patch_position1) +{ + return ( + (patch_position0.level() == patch_position1.level()) && + (patch_position0.maxPoint().x > patch_position1.minPoint().x && patch_position1.maxPoint().x > patch_position0.minPoint().x) && + (patch_position0.maxPoint().y > patch_position1.minPoint().y && patch_position1.maxPoint().y > patch_position0.minPoint().y) && + (m_cmesh->mesh()->dimension() == 2 || (patch_position0.maxPoint().z > patch_position1.minPoint().z && patch_position1.maxPoint().z > patch_position0.minPoint().z))); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianPatchGroup:: +_splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) +{ + // Il est nécessaire que le patch source et le patch part_to_remove soient + // en contact pour que cette méthode fonctionne. + + m_cmesh->mesh()->traceMng()->info() << "Coarse Zone" + << " -- Min point : " << part_to_remove.minPoint() + << " -- Max point : " << part_to_remove.maxPoint() + << " -- Level : " << part_to_remove.level(); + + // p1 est le bout de patch qu'il faut retirer de p0. + // On a donc uniquement quatre cas à traiter (sachant que p0 et p1 sont + // forcément en contact en x et/ou y et/ou z). + // + // Cas 1 : + // p0 |-----| + // p1 |---------| + // r = {-1, -1} + // + // Cas 2 : + // p0 |-----| + // p1 |-----| + // r = {p1_min, -1} + // + // Cas 3 : + // p0 |-----| + // p1 |-----| + // r = {-1, p1_max} + // + // Cas 4 : + // p0 |-----| + // p1 |---| + // r = {p1_min, p1_max} + auto cut_points_p0 = [](Int64 p0_min, Int64 p0_max, Int64 p1_min, Int64 p1_max) -> std::pair { + std::pair to_return{ -1, -1 }; + if (p1_min > p0_min && p1_min < p0_max) { + to_return.first = p1_min; + } + if (p1_max > p0_min && p1_max < p0_max) { + to_return.second = p1_max; + } + return to_return; + }; + + ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch]; + AMRPatchPosition patch_position = patch->position(); + + UniqueArray new_patch_out; + + Int64x3 min_point_of_patch_to_exclude(-1, -1, -1); + + // Partie découpe du patch autour de la zone à exclure. + { + UniqueArray new_patch_in; + + // On coupe le patch en x. + { + auto cut_point_x = cut_points_p0(patch_position.minPoint().x, patch_position.maxPoint().x, part_to_remove.minPoint().x, part_to_remove.maxPoint().x); + + // p0 |-----| + // p1 |---------| + if (cut_point_x.first == -1 && cut_point_x.second == -1) { + min_point_of_patch_to_exclude.x = patch_position.minPoint().x; + new_patch_out.add(patch_position); + } + // p0 |-----| + // p1 |-----| + else if (cut_point_x.second == -1) { + min_point_of_patch_to_exclude.x = cut_point_x.first; + auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + // p0 |-----| + // p1 |-----| + else if (cut_point_x.first == -1) { + min_point_of_patch_to_exclude.x = patch_position.minPoint().x; + auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + // p0 |-----| + // p1 |---| + else { + min_point_of_patch_to_exclude.x = cut_point_x.first; + auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX); + new_patch_out.add(fst); + auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX); + new_patch_out.add(snd); + new_patch_out.add(thr); + } + } + + // On coupe le patch en y. + { + std::swap(new_patch_out, new_patch_in); + + auto cut_point_y = cut_points_p0(patch_position.minPoint().y, patch_position.maxPoint().y, part_to_remove.minPoint().y, part_to_remove.maxPoint().y); + + // p0 |-----| + // p1 |---------| + if (cut_point_y.first == -1 && cut_point_y.second == -1) { + for (const AMRPatchPosition& patch_x : new_patch_in) { + min_point_of_patch_to_exclude.y = patch_x.minPoint().y; + new_patch_out.add(patch_x); + } + } + // p0 |-----| + // p1 |-----| + else if (cut_point_y.second == -1) { + min_point_of_patch_to_exclude.y = cut_point_y.first; + for (const AMRPatchPosition& patch_x : new_patch_in) { + auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + } + // p0 |-----| + // p1 |-----| + else if (cut_point_y.first == -1) { + for (const AMRPatchPosition& patch_x : new_patch_in) { + min_point_of_patch_to_exclude.y = patch_x.minPoint().y; + auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + } + // p0 |-----| + // p1 |---| + else { + min_point_of_patch_to_exclude.y = cut_point_y.first; + for (const AMRPatchPosition& patch_x : new_patch_in) { + auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY); + new_patch_out.add(fst); + auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY); + new_patch_out.add(snd); + new_patch_out.add(thr); + } + } + } + + // On coupe le patch en z. + if (m_cmesh->mesh()->dimension() == 3) { + std::swap(new_patch_out, new_patch_in); + new_patch_out.clear(); + + std::pair cut_point_z = cut_points_p0(patch_position.minPoint().z, patch_position.maxPoint().z, part_to_remove.minPoint().z, part_to_remove.maxPoint().z); + + // p0 |-----| + // p1 |---------| + if (cut_point_z.first == -1 && cut_point_z.second == -1) { + for (const AMRPatchPosition& patch_y : new_patch_in) { + min_point_of_patch_to_exclude.z = patch_y.minPoint().z; + new_patch_out.add(patch_y); + } + } + // p0 |-----| + // p1 |-----| + else if (cut_point_z.second == -1) { + for (const AMRPatchPosition& patch_y : new_patch_in) { + min_point_of_patch_to_exclude.z = cut_point_z.first; + auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + } + // p0 |-----| + // p1 |-----| + else if (cut_point_z.first == -1) { + for (const AMRPatchPosition& patch_y : new_patch_in) { + min_point_of_patch_to_exclude.z = patch_y.minPoint().z; + auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ); + new_patch_out.add(fst); + new_patch_out.add(snd); + } + } + // p0 |-----| + // p1 |---| + else { + for (const AMRPatchPosition& patch_y : new_patch_in) { + min_point_of_patch_to_exclude.z = cut_point_z.first; + auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ); + new_patch_out.add(fst); + auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ); + new_patch_out.add(snd); + new_patch_out.add(thr); + } + } + } + } + + // Partie fusion et ajout. + { + if (m_cmesh->mesh()->dimension() == 2) { + min_point_of_patch_to_exclude.z = 0; + } + m_cmesh->mesh()->traceMng()->info() << "Nb of new patch before fusion : " << new_patch_out.size(); + m_cmesh->mesh()->traceMng()->info() << "min_point_of_patch_to_exclude : " << min_point_of_patch_to_exclude; + + // On met à null le patch représentant le bout de patch à retirer. + for (AMRPatchPosition& new_patch : new_patch_out) { + if (new_patch.minPoint() == min_point_of_patch_to_exclude) { + new_patch.setLevel(-2); // Devient null. + } + } + + // Algo de fusion. + // D'abord, on trie les patchs du plus petit nb de mailles au plus grand nb de mailles (optionnel). + // Ensuite, pour chaque patch, on regarde si l'on peut le fusionner avec un autre. + // Si on arrive à faire une fusion, on recommence l'algo jusqu'à ne plus pouvoir fusionner. + bool fusion = true; + while (fusion) { + fusion = false; + + std::sort(new_patch_out.begin(), new_patch_out.end(), + [](const AMRPatchPosition& a, const AMRPatchPosition& b) { + return a.nbCells() < b.nbCells(); + }); + + for (Integer p0 = 0; p0 < new_patch_out.size(); ++p0) { + AMRPatchPosition& patch_fusion_0 = new_patch_out[p0]; + if (patch_fusion_0.isNull()) + continue; + + // Si une fusion a déjà eu lieu, on doit alors regarder les patchs avant "p0" + // (vu qu'il y en a au moins un qui a été modifié). + // (une "optimisation" pourrait être de récupérer la position du premier + // patch fusionné mais bon, moins lisible + pas beaucoup de patchs). + Integer p1 = (fusion ? 0 : p0 + 1); + for (; p1 < new_patch_out.size(); ++p1) { + if (p1 == p0) + continue; + + AMRPatchPosition& patch_fusion_1 = new_patch_out[p1]; + + if (patch_fusion_1.isNull()) + continue; + + m_cmesh->mesh()->traceMng()->info() << "\tCheck fusion" + << " -- 0 Min point : " << patch_fusion_0.minPoint() + << " -- 0 Max point : " << patch_fusion_0.maxPoint() + << " -- 0 Level : " << patch_fusion_0.level() + << " -- 1 Min point : " << patch_fusion_1.minPoint() + << " -- 1 Max point : " << patch_fusion_1.maxPoint() + << " -- 1 Level : " << patch_fusion_1.level(); + if (patch_fusion_0.canBeFusion(patch_fusion_1)) { + m_cmesh->mesh()->traceMng()->info() << "Fusion OK"; + patch_fusion_0.fusion(patch_fusion_1); + patch_fusion_1.setLevel(-2); // Devient null. + fusion = true; + break; + } + } + } + } + + // On ajoute les nouveaux patchs dans la liste des patchs. + Integer d_nb_patch_final = 0; + for (const auto& new_patch : new_patch_out) { + if (!new_patch.isNull()) { + // m_cmesh->mesh()->traceMng()->info() << "\tNew cut patch" + // << " -- Min point : " << new_patch.minPoint() + // << " -- Max point : " << new_patch.maxPoint() + // << " -- Level : " << new_patch.level(); + _addCutPatch(new_patch, m_amr_patch_cell_groups[index_patch - 1]); + d_nb_patch_final++; + } + } + m_cmesh->mesh()->traceMng()->info() << "Nb of new patch after fusion : " << d_nb_patch_final; + } + + removePatch(index_patch); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianPatchGroup:: +_addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group) +{ + if (parent_patch_cell_group.null()) + ARCANE_FATAL("Null cell group"); + + // TODO : Le nextIndexForNewPatch() actuel ne fonctionnera pas si on s'amuse à créer, détruire et recréer des patchs ! + // TODO : Attribut que l'on incrémente de 1 lors de la création d'un patch. + IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); + Integer index = nextIndexForNewPatch(); + String parent_group_name = String("CartesianMeshPatchParentCells") + index; + + auto* cdi = new CartesianMeshPatch(m_cmesh, index + 1); + + _addPatchInstance(makeRef(cdi)); + + UniqueArray cells_local_id; + + cdi->position().setLevel(new_patch_position.level()); + cdi->position().setMinPoint(new_patch_position.minPoint()); + cdi->position().setMaxPoint(new_patch_position.maxPoint()); + + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + ENUMERATE_ (Cell, icell, parent_patch_cell_group) { + Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); + Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); + Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); + if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { + cells_local_id.add(icell.localId()); + } + } + + CellGroup parent_cells = cell_family->createGroup(parent_group_name, cells_local_id, true); + m_amr_patch_cell_groups.add(parent_cells); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h index 35f2805d2e..5d268cbc72 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h @@ -34,9 +34,10 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup { public: - explicit CartesianPatchGroup(ICartesianMesh* cmesh) : m_cmesh(cmesh){} + explicit CartesianPatchGroup(ICartesianMesh* cmesh); public: + Ref groundPatch(); void addPatch(CellGroup cell_group); @@ -55,23 +56,26 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void removeCellsInAllPatches(ConstArrayView cells_local_id); - void removeCellsInAllPatches(ConstArrayView cells_local_id, SharedArray altered_patches); + void removeCellsInAllPatches(ConstArrayView cells_local_id, const AMRPatchPosition& patch_position); void applyPatchEdit(bool remove_empty_patches); - // void repairPatch(Integer index, ICartesianMeshNumberingMng* numbering_mng); - - void updateLevelsBeforeCoarsen(); + void updateLevelsBeforeAddGroundPatch(); Integer nextIndexForNewPatch(); private: + void _addPatchInstance(Ref v); void _removeOnePatch(Integer index); void _removeMultiplePatches(ConstArrayView indexes); void _createGroundPatch(); + bool _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPosition& patch_position1); + void _splitPatch(Integer index_patch, const AMRPatchPosition& patch_position); + void _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group); + private: UniqueArray m_amr_patch_cell_groups; @@ -79,6 +83,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup UniqueArray> m_amr_patches; ICartesianMesh* m_cmesh; UniqueArray m_patches_to_delete; + Int32 m_index_new_patches; }; /*---------------------------------------------------------------------------*/ @@ -89,5 +94,4 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif - +#endif diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h index 7b578666ef..4ff6bae792 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h @@ -14,6 +14,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +#include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/ItemTypes.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" @@ -25,6 +26,7 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + /*! * \ingroup ArcaneCartesianMesh * \brief Interface d'un patch AMR d'un maillage cartésien. @@ -40,8 +42,6 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatch //! TODO virtual Integer index() = 0; - virtual Integer level() = 0; - virtual void setLevel(Integer level) = 0; //! Liste des mailles dans la direction \a dir virtual CellDirectionMng& cellDirection(eMeshDirection dir) =0; @@ -63,6 +63,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatch //! Effectue des vérifications sur la validité de l'instance. virtual void checkValid() const =0; + + virtual AMRPatchPosition& position() = 0; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h index b927cf9491..897b9d7ec2 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h @@ -54,14 +54,6 @@ class CartesianMeshPatch { return m_amr_patch_index; } - Integer level() override - { - return m_level; - } - void setLevel(Integer level) override - { - m_level = level; - } CellDirectionMng& cellDirection(eMeshDirection dir) override { return m_cell_directions[dir]; @@ -92,17 +84,23 @@ class CartesianMeshPatch return m_node_directions[idir]; } void checkValid() const override; + + AMRPatchPosition& position() override + { + return m_position; + } + private: void _internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); void _computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); void _computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); private: ICartesianMesh* m_mesh; + AMRPatchPosition m_position; CellDirectionMng m_cell_directions[3]; FaceDirectionMng m_face_directions[3]; NodeDirectionMng m_node_directions[3]; Integer m_amr_patch_index; - Integer m_level; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/srcs.cmake b/arcane/src/arcane/cartesianmesh/srcs.cmake index 7ad14c4751..eb84e54a49 100644 --- a/arcane/src/arcane/cartesianmesh/srcs.cmake +++ b/arcane/src/arcane/cartesianmesh/srcs.cmake @@ -49,4 +49,6 @@ set(ARCANE_SOURCES CartesianMeshNumberingMng.h AMRZonePosition.cc AMRZonePosition.h + AMRPatchPosition.h + AMRPatchPosition.cc ) From c4116a86476332a9cc68d2304c2e26dd659ad365 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Mon, 27 Oct 2025 16:09:40 +0100 Subject: [PATCH 02/19] [arcane:cartesianmesh] Add a method to merge patches (amr-type=3 only) --- .../arcane/tests/AMRCartesianMeshTester.axl | 7 + .../tests/AMRCartesianMeshTesterModule.cc | 20 +- .../arcane/cartesianmesh/AMRZonePosition.cc | 1 - .../src/arcane/cartesianmesh/CartesianMesh.cc | 16 +- .../cartesianmesh/CartesianPatchGroup.cc | 200 +++++++++++++----- .../cartesianmesh/CartesianPatchGroup.h | 4 +- .../src/arcane/cartesianmesh/ICartesianMesh.h | 2 + 7 files changed, 190 insertions(+), 60 deletions(-) diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTester.axl b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTester.axl index 8f532c8e24..36ba7b0427 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTester.axl +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTester.axl @@ -38,6 +38,13 @@ > Si présent, total sur tous les sous-domaines du nombre de mailles fantôme que doit avoir chaque patch + + + Indique si on souhaite fusionner les patchs après raffinement/déraffinement. + Permet de réduire le nombre de patchs s'ils ont côte-à-côte. + Fonctionne uniquement avec amr-type=3. + + diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 67f631cd2d..191d17b73d 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -98,6 +98,7 @@ class AMRCartesianMeshTesterModule Ref m_utils; UniqueArray m_cell_patch_variables; Int32 m_nb_expected_patch = 0; + bool m_merge_patches = true; private: @@ -105,6 +106,7 @@ class AMRCartesianMeshTesterModule void _compute2(); void _initAMR(); void _coarseZone(); + void _mergePatches(); void _reduceNbGhostLayers(); void _computeSubCellDensity(Cell cell); void _computeCenters(); @@ -258,9 +260,14 @@ init() m_cartesian_mesh = ICartesianMesh::getReference(mesh); m_utils = makeRef(new CartesianMeshTestUtils(m_cartesian_mesh,acceleratorMng())); + m_merge_patches = options()->mergePatches(); + if (!subDomain()->isContinue()) { _initAMR(); _coarseZone(); + if (m_merge_patches) { + _mergePatches(); + } _reduceNbGhostLayers(); } @@ -379,10 +386,11 @@ _processPatches() // à computeDirections() n'ajoutent pas de patchs. // Cette vérification ne s'applique que s'il n'y a pas de zone de dé-raffinement. // En effet, dé-raffiner un patch complet le supprime de la liste des patchs. + // Elle est aussi désactivée s'il y a fusion possible des patchs. Integer nb_expected_patch = m_nb_expected_patch; Integer nb_patch = m_cartesian_mesh->nbPatch(); - if (without_coarse_zone && nb_expected_patch != nb_patch) + if (without_coarse_zone && nb_expected_patch != nb_patch && !m_merge_patches) ARCANE_FATAL("Bad number of patchs expected={0} value={1}",nb_expected_patch,nb_patch); IParallelMng* pm = parallelMng(); @@ -583,6 +591,16 @@ _coarseZone() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void AMRCartesianMeshTesterModule:: +_mergePatches() +{ + m_cartesian_mesh->mergePatches(); + m_cartesian_mesh->computeDirections(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void AMRCartesianMeshTesterModule:: _reduceNbGhostLayers() { diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc index 1be25f6fb0..b27b1cdfa6 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc @@ -96,7 +96,6 @@ cellsInPatch(ICartesianMesh* mesh, UniqueArray& cells_local_id, AMRPatchP bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y; bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !m_is_3d; if (is_inside_x && is_inside_y && is_inside_z) { - mesh->mesh()->traceMng()->info() << "CellUID : " << cell.uniqueId() << " -- Level : " << cell.level(); if (level == -1) level = cell.level(); else if (level != cell.level()) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index e95d6a378e..fa496170b9 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -195,6 +195,8 @@ class CartesianMeshImpl Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override; + void mergePatches() override; + void renumberItemsUniqueId(const CartesianMeshRenumberingInfo& v) override; void checkValid() const override; @@ -885,6 +887,18 @@ reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshImpl:: +mergePatches() +{ + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_patch_group.mergePatches(); + m_patch_group.applyPatchEdit(false); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshImpl:: _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id) { @@ -1004,7 +1018,7 @@ _applyCoarse(const AMRZonePosition& zone_position) } else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { debug() << "Coarsen with specific coarser (for cartesian mesh only)"; - m_patch_group.removeCellsInAllPatches(cells_local_id, patch_position); + m_patch_group.removeCellsInAllPatches(patch_position); m_patch_group.applyPatchEdit(true); computeDirections(); diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index baa8844a00..8fd64ec196 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -195,6 +195,7 @@ clear() m_amr_patch_cell_groups.clear(); m_amr_patches_pointer.clear(); m_amr_patches.clear(); + m_index_new_patches = 0; _createGroundPatch(); } @@ -232,25 +233,23 @@ removeCellsInAllPatches(ConstArrayView cells_local_id) /*---------------------------------------------------------------------------*/ void CartesianPatchGroup:: -removeCellsInAllPatches(ConstArrayView cells_local_id, const AMRPatchPosition& patch_position) +removeCellsInAllPatches(const AMRPatchPosition& zone_to_delete) { - // Pas de foreach : _splitPatch() ajoute des patchs. // Attention si suppression de la suppression en deux étapes : _splitPatch() supprime aussi des patchs. // i = 1 car on ne peut pas déraffjner le patch ground. - Integer nb_patchs = m_amr_patches_pointer.size(); + const Integer nb_patchs = m_amr_patches_pointer.size(); for (Integer i = 1; i < nb_patchs; ++i) { ICartesianMeshPatch* patch = m_amr_patches_pointer[i]; - m_cmesh->mesh()->traceMng()->info() << "I : " << i - << " -- Compare Patch (min : " << patch->position().minPoint() - << ", max : " << patch->position().maxPoint() - << ", level : " << patch->position().level() - << ") and Zone (min : " << patch_position.minPoint() - << ", max : " << patch_position.maxPoint() - << ", level : " << patch_position.level() << ")"; - - if (_isPatchInContact(patch->position(), patch_position)) { - //m_amr_patch_cell_groups[i - 1].removeItems(cells_local_id); // TODO : toujours utile ? Le patch sera supprimé. - _splitPatch(i, patch_position); + // m_cmesh->traceMng()->info() << "I : " << i + // << " -- Compare Patch (min : " << patch->position().minPoint() + // << ", max : " << patch->position().maxPoint() + // << ", level : " << patch->position().level() + // << ") and Zone (min : " << zone_to_delete.minPoint() + // << ", max : " << zone_to_delete.maxPoint() + // << ", level : " << zone_to_delete.level() << ")"; + + if (_isPatchInContact(patch->position(), zone_to_delete)) { + _splitPatch(i, zone_to_delete); } } } @@ -262,6 +261,12 @@ void CartesianPatchGroup:: applyPatchEdit(bool remove_empty_patches) { m_cmesh->mesh()->traceMng()->info() << "applyPatchEdit() -- Remove nb patch : " << m_patches_to_delete.size(); + + std::sort(m_patches_to_delete.begin(), m_patches_to_delete.end(), + [](const Integer a, const Integer b) { + return a < b; + }); + _removeMultiplePatches(m_patches_to_delete); m_patches_to_delete.clear(); @@ -287,33 +292,34 @@ applyPatchEdit(bool remove_empty_patches) void CartesianPatchGroup:: updateLevelsBeforeAddGroundPatch() { - if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); - for (ICartesianMeshPatch* patch : m_amr_patches_pointer) { - Integer level = patch->position().level(); - // Si le niveau est 0, c'est le patch spécial 0 donc on ne modifie que le max, le niveau reste à 0. - if (level == 0) { - Int64x3 max_point = patch->position().maxPoint(); - if (m_cmesh->mesh()->dimension() == 2) { - patch->position().setMaxPoint({ - numbering->offsetLevelToLevel(max_point.x, level, level - 1), - numbering->offsetLevelToLevel(max_point.y, level, level - 1), - 1, - }); - } - else { - patch->position().setMaxPoint({ - numbering->offsetLevelToLevel(max_point.x, level, level - 1), - numbering->offsetLevelToLevel(max_point.y, level, level - 1), - numbering->offsetLevelToLevel(max_point.z, level, level - 1), - }); - } + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + return; + } + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + for (ICartesianMeshPatch* patch : m_amr_patches_pointer) { + Integer level = patch->position().level(); + // Si le niveau est 0, c'est le patch spécial 0 donc on ne modifie que le max, le niveau reste à 0. + if (level == 0) { + Int64x3 max_point = patch->position().maxPoint(); + if (m_cmesh->mesh()->dimension() == 2) { + patch->position().setMaxPoint({ + numbering->offsetLevelToLevel(max_point.x, level, level - 1), + numbering->offsetLevelToLevel(max_point.y, level, level - 1), + 1, + }); } - // Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1" else { - patch->position().setLevel(level + 1); + patch->position().setMaxPoint({ + numbering->offsetLevelToLevel(max_point.x, level, level - 1), + numbering->offsetLevelToLevel(max_point.y, level, level - 1), + numbering->offsetLevelToLevel(max_point.z, level, level - 1), + }); } } + // Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1" + else { + patch->position().setLevel(level + 1); + } } } @@ -329,6 +335,88 @@ nextIndexForNewPatch() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +mergePatches() +{ + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + return; + } + // m_cmesh->traceMng()->info() << "Global fusion"; + UniqueArray> index_n_nb_cells; + { + Integer index = 0; + for (auto patch : m_amr_patches_pointer) { + index_n_nb_cells.add({ index++, patch->position().nbCells() }); + } + } + + // Algo de fusion. + // D'abord, on trie les patchs du plus petit nb de mailles au plus grand nb de mailles (optionnel). + // Ensuite, pour chaque patch, on regarde si l'on peut le fusionner avec un autre. + // Si on arrive à faire une fusion, on recommence l'algo jusqu'à ne plus pouvoir fusionner. + bool fusion = true; + while (fusion) { + fusion = false; + + std::sort(index_n_nb_cells.begin(), index_n_nb_cells.end(), + [](const std::pair& a, const std::pair& b) { + return a.second < b.second; + }); + + for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) { + auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0]; + + AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->position(); + if (patch_fusion_0.isNull()) + continue; + + // Si une fusion a déjà eu lieu, on doit alors regarder les patchs avant "p0" + // (vu qu'il y en a au moins un qui a été modifié). + // (une "optimisation" pourrait être de récupérer la position du premier + // patch fusionné mais bon, moins lisible + pas beaucoup de patchs). + Integer p1 = (fusion ? 0 : p0 + 1); + for (; p1 < m_amr_patches_pointer.size(); ++p1) { + if (p1 == p0) + continue; + auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1]; + + AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->position(); + + if (patch_fusion_1.isNull()) + continue; + + // m_cmesh->traceMng()->info() << "\tCheck fusion" + // << " -- 0 Min point : " << patch_fusion_0.minPoint() + // << " -- 0 Max point : " << patch_fusion_0.maxPoint() + // << " -- 0 Level : " << patch_fusion_0.level() + // << " -- 1 Min point : " << patch_fusion_1.minPoint() + // << " -- 1 Max point : " << patch_fusion_1.maxPoint() + // << " -- 1 Level : " << patch_fusion_1.level(); + + if (patch_fusion_0.canBeFusion(patch_fusion_1)) { + // m_cmesh->traceMng()->info() << "Fusion OK"; + patch_fusion_0.fusion(patch_fusion_1); + patch_fusion_1.setLevel(-2); // Devient null. + index_n_nb_cells[p0].second = patch_fusion_0.nbCells(); + + UniqueArray local_ids; + cells(index_p1).view().fillLocalIds(local_ids); + cells(index_p0).addItems(local_ids, false); + + m_cmesh->traceMng()->info() << "Remove patch : " << index_p1; + removePatch(index_p1); + + fusion = true; + break; + } + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _addPatchInstance(Ref v) { @@ -351,6 +439,7 @@ _removeOnePatch(Integer index) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +// Le tableau doit être trié. void CartesianPatchGroup:: _removeMultiplePatches(ConstArrayView indexes) { @@ -399,16 +488,15 @@ _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPositio /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +// Il est nécessaire que le patch source et le patch part_to_remove soient +// en contact pour que cette méthode fonctionne. void CartesianPatchGroup:: _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) { - // Il est nécessaire que le patch source et le patch part_to_remove soient - // en contact pour que cette méthode fonctionne. - - m_cmesh->mesh()->traceMng()->info() << "Coarse Zone" - << " -- Min point : " << part_to_remove.minPoint() - << " -- Max point : " << part_to_remove.maxPoint() - << " -- Level : " << part_to_remove.level(); + m_cmesh->traceMng()->info() << "Coarse Zone" + << " -- Min point : " << part_to_remove.minPoint() + << " -- Max point : " << part_to_remove.maxPoint() + << " -- Level : " << part_to_remove.level(); // p1 est le bout de patch qu'il faut retirer de p0. // On a donc uniquement quatre cas à traiter (sachant que p0 et p1 sont @@ -596,8 +684,8 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) if (m_cmesh->mesh()->dimension() == 2) { min_point_of_patch_to_exclude.z = 0; } - m_cmesh->mesh()->traceMng()->info() << "Nb of new patch before fusion : " << new_patch_out.size(); - m_cmesh->mesh()->traceMng()->info() << "min_point_of_patch_to_exclude : " << min_point_of_patch_to_exclude; + m_cmesh->traceMng()->info() << "Nb of new patch before fusion : " << new_patch_out.size(); + m_cmesh->traceMng()->info() << "min_point_of_patch_to_exclude : " << min_point_of_patch_to_exclude; // On met à null le patch représentant le bout de patch à retirer. for (AMRPatchPosition& new_patch : new_patch_out) { @@ -638,15 +726,15 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) if (patch_fusion_1.isNull()) continue; - m_cmesh->mesh()->traceMng()->info() << "\tCheck fusion" - << " -- 0 Min point : " << patch_fusion_0.minPoint() - << " -- 0 Max point : " << patch_fusion_0.maxPoint() - << " -- 0 Level : " << patch_fusion_0.level() - << " -- 1 Min point : " << patch_fusion_1.minPoint() - << " -- 1 Max point : " << patch_fusion_1.maxPoint() - << " -- 1 Level : " << patch_fusion_1.level(); + // m_cmesh->traceMng()->info() << "\tCheck fusion" + // << " -- 0 Min point : " << patch_fusion_0.minPoint() + // << " -- 0 Max point : " << patch_fusion_0.maxPoint() + // << " -- 0 Level : " << patch_fusion_0.level() + // << " -- 1 Min point : " << patch_fusion_1.minPoint() + // << " -- 1 Max point : " << patch_fusion_1.maxPoint() + // << " -- 1 Level : " << patch_fusion_1.level(); if (patch_fusion_0.canBeFusion(patch_fusion_1)) { - m_cmesh->mesh()->traceMng()->info() << "Fusion OK"; + // m_cmesh->traceMng()->info() << "Fusion OK"; patch_fusion_0.fusion(patch_fusion_1); patch_fusion_1.setLevel(-2); // Devient null. fusion = true; @@ -660,7 +748,7 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) Integer d_nb_patch_final = 0; for (const auto& new_patch : new_patch_out) { if (!new_patch.isNull()) { - // m_cmesh->mesh()->traceMng()->info() << "\tNew cut patch" + // m_cmesh->traceMng()->info() << "\tNew cut patch" // << " -- Min point : " << new_patch.minPoint() // << " -- Max point : " << new_patch.maxPoint() // << " -- Level : " << new_patch.level(); @@ -668,7 +756,7 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) d_nb_patch_final++; } } - m_cmesh->mesh()->traceMng()->info() << "Nb of new patch after fusion : " << d_nb_patch_final; + m_cmesh->traceMng()->info() << "Nb of new patch after fusion : " << d_nb_patch_final; } removePatch(index_patch); diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h index 5d268cbc72..c11b17c5d3 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h @@ -56,7 +56,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void removeCellsInAllPatches(ConstArrayView cells_local_id); - void removeCellsInAllPatches(ConstArrayView cells_local_id, const AMRPatchPosition& patch_position); + void removeCellsInAllPatches(const AMRPatchPosition& zone_to_delete); void applyPatchEdit(bool remove_empty_patches); @@ -64,6 +64,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup Integer nextIndexForNewPatch(); + void mergePatches(); + private: void _addPatchInstance(Ref v); diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h index d6333e2602..a93a469926 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h @@ -251,6 +251,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh */ virtual Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) = 0; + virtual void mergePatches() = 0; + /*! * \brief Renumérote les uniqueId() des entités. * From 79b8f567ba426e725e617878db81cd66de65046d Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Mon, 27 Oct 2025 16:10:39 +0100 Subject: [PATCH 03/19] [arcane:cartesianmesh] Introduce properties in CartesianMeshNumberingMng to support checkpoints --- .../src/arcane/cartesianmesh/CartesianMesh.cc | 11 +++ .../CartesianMeshNumberingMng.cc | 72 +++++++++++++++++++ .../cartesianmesh/CartesianMeshNumberingMng.h | 6 ++ .../ICartesianMeshNumberingMng.h | 6 +- 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index fa496170b9..5924312fec 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -290,6 +290,9 @@ void CartesianMeshImpl:: build() { m_properties = new Properties(*(mesh()->properties()),"CartesianMesh"); + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_internal_api.cartesianMeshNumberingMng()->_build(); + } } namespace @@ -325,6 +328,10 @@ _saveInfosInProperties() patch_group_names.add(m_patch_group.cells(i).name()); } m_properties->set("PatchGroupNames",patch_group_names); + + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_internal_api.cartesianMeshNumberingMng()->_saveInfosInProperties(); + } } /*---------------------------------------------------------------------------*/ @@ -335,6 +342,10 @@ recreateFromDump() { info() << "Creating 'CartesianMesh' infos from dump"; + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_internal_api.cartesianMeshNumberingMng()->_recreateFromDump(); + } + // Sauve le numéro de version pour être sur que c'est OK en reprise Int32 v = m_properties->getInt32("Version"); if (v!=SERIALIZE_VERSION) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index dc598dc002..070b90ac7b 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -20,6 +20,7 @@ #include "arcane/core/IParallelMng.h" #include "arcane/core/VariableTypes.h" #include "arcane/core/ICartesianMeshGenerationInfo.h" +#include "arcane/core/Properties.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -91,6 +92,77 @@ CartesianMeshNumberingMng(IMesh* mesh) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshNumberingMng:: +_build() +{ + m_properties = makeRef(new Properties(*(m_mesh->properties()), "CartesianMeshNumberingMng")); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +_saveInfosInProperties() +{ + m_properties->set("Version", 1); + m_properties->set("FirstCellUIDByLevel", m_first_cell_uid_level); + + // Voir pour le recalculer à la reprise. + m_properties->set("FirstNodeUIDByLevel", m_first_node_uid_level); + m_properties->set("FirstFaceUIDByLevel", m_first_face_uid_level); + + m_properties->set("PositionToLevel", m_p_to_l_level); // Tableau à supprimer. + + m_properties->set("OriginalGroundLevel", m_ori_level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +_recreateFromDump() +{ + Int32 v = m_properties->getInt32("Version"); + if (v != 1) + ARCANE_FATAL("Bad numbering mng version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1); + + m_properties->get("FirstCellUIDByLevel", m_first_cell_uid_level); + m_properties->get("FirstNodeUIDByLevel", m_first_node_uid_level); + m_properties->get("FirstFaceUIDByLevel", m_first_face_uid_level); + + m_properties->get("PositionToLevel", m_p_to_l_level); + + m_nb_cell = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) }; + + m_properties->get("OriginalGroundLevel", m_ori_level); + + m_max_level = m_first_cell_uid_level.size() - 1; + + m_latest_cell_uid = m_first_cell_uid_level[m_max_level] + nbCellInLevel(m_max_level); + m_latest_node_uid = m_first_node_uid_level[m_max_level] + nbNodeInLevel(m_max_level); + m_latest_face_uid = m_first_face_uid_level[m_max_level] + nbFaceInLevel(m_max_level); + + // À activer lorsqu'on retirera m_p_to_l_level. + // { + // Integer pos = 0; + // Int64 max = 0; + // Integer iter = 0; + // for (const Int64 elem : m_first_cell_uid_level) { + // if (elem > max) { + // max = elem; + // pos = iter; + // } + // iter++; + // } + // m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos); + // m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos); + // m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos); + // } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshNumberingMng:: prepareLevel(Int32 level) { diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h index db61da992b..d4b830c9e0 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h @@ -46,6 +46,10 @@ class CartesianMeshNumberingMng public: + void _build() override; + void _saveInfosInProperties() override; + void _recreateFromDump() override; + void prepareLevel(Int32 level) override; void updateFirstLevel() override; @@ -173,6 +177,8 @@ class CartesianMeshNumberingMng IMesh* m_mesh; + Ref m_properties; + Integer m_dimension; Integer m_pattern; diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h index 510588a583..6760ff3ac0 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h @@ -39,6 +39,10 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng public: + virtual void _build() = 0; + virtual void _saveInfosInProperties() = 0; + virtual void _recreateFromDump() = 0; + /*! * \brief Méthode permettant de préparer un nouveau niveau. * @@ -52,7 +56,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng * * \param level Le nouveau niveau à préparer. */ - virtual void prepareLevel(Int32 level) =0; + virtual void prepareLevel(Int32 level) = 0; /*! * \brief Méthode permettant de mettre à jour le premier niveau. From 92aba547470b155e02aca4456654bf9a9d722455 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Tue, 28 Oct 2025 12:12:53 +0100 Subject: [PATCH 04/19] [arcane:cartesianmesh] In CartesianMeshNumberingMng, remove 'PositionToLevel' array And : - Add a method to write status of the object, - Fix an error in updateFirstLevel() (cmgi part), - Add a method to renumber faces of level 0 (to optimize and support mesh repartitioner) --- .../src/arcane/cartesianmesh/CartesianMesh.cc | 1 + .../CartesianMeshNumberingMng.cc | 286 +++++++++++------- .../cartesianmesh/CartesianMeshNumberingMng.h | 16 +- .../cartesianmesh/CartesianPatchGroup.cc | 2 +- .../ICartesianMeshNumberingMng.h | 33 +- 5 files changed, 221 insertions(+), 117 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 5924312fec..8b6379fdd1 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -344,6 +344,7 @@ recreateFromDump() if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.cartesianMeshNumberingMng()->_recreateFromDump(); + m_internal_api.cartesianMeshNumberingMng()->printStatus(); } // Sauve le numéro de version pour être sur que c'est OK en reprise diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index 070b90ac7b..3324daff44 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -15,11 +15,13 @@ #include "CartesianMeshNumberingMng.h" #include "arcane/utils/Vector2.h" +#include "arcane/utils/ITraceMng.h" #include "arcane/core/IMesh.h" #include "arcane/core/IParallelMng.h" #include "arcane/core/VariableTypes.h" #include "arcane/core/ICartesianMeshGenerationInfo.h" +#include "arcane/core/IItemFamily.h" #include "arcane/core/Properties.h" /*---------------------------------------------------------------------------*/ @@ -45,28 +47,26 @@ CartesianMeshNumberingMng(IMesh* mesh) const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); - m_nb_cell.x = global_nb_cells_by_direction[MD_DirX]; - m_nb_cell.y = global_nb_cells_by_direction[MD_DirY]; - m_nb_cell.z = ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ]); + m_nb_cell_ground.x = global_nb_cells_by_direction[MD_DirX]; + m_nb_cell_ground.y = global_nb_cells_by_direction[MD_DirY]; + m_nb_cell_ground.z = ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ]); - if (m_nb_cell.x <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", m_nb_cell.x); - if (m_nb_cell.y <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", m_nb_cell.y); - if (m_nb_cell.z <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", m_nb_cell.z); - - m_p_to_l_level.add(0); + if (m_nb_cell_ground.x <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", m_nb_cell_ground.x); + if (m_nb_cell_ground.y <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", m_nb_cell_ground.y); + if (m_nb_cell_ground.z <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", m_nb_cell_ground.z); if (m_dimension == 2) { - m_latest_cell_uid = m_nb_cell.x * m_nb_cell.y; - m_latest_node_uid = (m_nb_cell.x + 1) * (m_nb_cell.y + 1); - m_latest_face_uid = (m_nb_cell.x * m_nb_cell.y) * 2 + m_nb_cell.x * 2 + m_nb_cell.y; + m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y; + m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1); + m_latest_face_uid = (m_nb_cell_ground.x * m_nb_cell_ground.y) * 2 + m_nb_cell_ground.x * 2 + m_nb_cell_ground.y; } else { - m_latest_cell_uid = m_nb_cell.x * m_nb_cell.y * m_nb_cell.z; - m_latest_node_uid = (m_nb_cell.x + 1) * (m_nb_cell.y + 1) * (m_nb_cell.z + 1); - m_latest_face_uid = (m_nb_cell.z + 1) * m_nb_cell.x * m_nb_cell.y + (m_nb_cell.x + 1) * m_nb_cell.y * m_nb_cell.z + (m_nb_cell.y + 1) * m_nb_cell.z * m_nb_cell.x; + m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y * m_nb_cell_ground.z; + m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1) * (m_nb_cell_ground.z + 1); + m_latest_face_uid = (m_nb_cell_ground.z + 1) * m_nb_cell_ground.x * m_nb_cell_ground.y + (m_nb_cell_ground.x + 1) * m_nb_cell_ground.y * m_nb_cell_ground.z + (m_nb_cell_ground.y + 1) * m_nb_cell_ground.z * m_nb_cell_ground.x; } m_first_cell_uid_level.add(0); @@ -111,9 +111,7 @@ _saveInfosInProperties() m_properties->set("FirstNodeUIDByLevel", m_first_node_uid_level); m_properties->set("FirstFaceUIDByLevel", m_first_face_uid_level); - m_properties->set("PositionToLevel", m_p_to_l_level); // Tableau à supprimer. - - m_properties->set("OriginalGroundLevel", m_ori_level); + m_properties->set("OriginalGroundLevelForConverting", m_ori_level); } /*---------------------------------------------------------------------------*/ @@ -130,34 +128,104 @@ _recreateFromDump() m_properties->get("FirstNodeUIDByLevel", m_first_node_uid_level); m_properties->get("FirstFaceUIDByLevel", m_first_face_uid_level); - m_properties->get("PositionToLevel", m_p_to_l_level); - - m_nb_cell = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) }; + m_properties->get("OriginalGroundLevelForConverting", m_ori_level); + if (m_ori_level == -1) { + m_converting_numbering_face = false; + m_face_ori_numbering_to_new.clear(); + m_face_new_numbering_to_ori.clear(); + } - m_properties->get("OriginalGroundLevel", m_ori_level); + m_nb_cell_ground = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) }; m_max_level = m_first_cell_uid_level.size() - 1; - m_latest_cell_uid = m_first_cell_uid_level[m_max_level] + nbCellInLevel(m_max_level); - m_latest_node_uid = m_first_node_uid_level[m_max_level] + nbNodeInLevel(m_max_level); - m_latest_face_uid = m_first_face_uid_level[m_max_level] + nbFaceInLevel(m_max_level); + { + Integer pos = 0; + Int64 max = 0; + Integer iter = 0; + for (const Int64 elem : m_first_cell_uid_level) { + if (elem > max) { + max = elem; + pos = iter; + } + iter++; + } + m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos); + m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos); + m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +renumberingFacesLevel0FromOriginalArcaneNumbering() +{ + if (!m_converting_numbering_face) + return; + + UniqueArray face_uid(nbFaceByCell()); + ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(m_ori_level)) { + cellFaceUniqueIds(face_uid, m_ori_level, icell->uniqueId()); + for (Integer i = 0; i < nbFaceByCell(); ++i) { + // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i]; + icell->face(i).mutableItemBase().setUniqueId(face_uid[i]); + } + } + m_mesh->faceFamily()->notifyItemsUniqueIdChanged(); + m_mesh->checkValidMesh(); - // À activer lorsqu'on retirera m_p_to_l_level. - // { - // Integer pos = 0; - // Int64 max = 0; - // Integer iter = 0; - // for (const Int64 elem : m_first_cell_uid_level) { - // if (elem > max) { - // max = elem; - // pos = iter; - // } - // iter++; - // } - // m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos); - // m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos); - // m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos); - // } + m_converting_numbering_face = false; + m_ori_level = -1; + m_face_ori_numbering_to_new.clear(); + m_face_new_numbering_to_ori.clear(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +printStatus() +{ + ITraceMng* tm = m_mesh->traceMng(); + Trace::Setter _(tm, "CartesianMeshNumberingMng"); + + tm->info() << "CartesianMeshNumberingMng status :"; + + // tm->info() << "FirstCellUIDByLevel : " << m_first_cell_uid_level; + // tm->info() << "FirstNodeUIDByLevel : " << m_first_node_uid_level; + // tm->info() << "FirstFaceUIDByLevel : " << m_first_face_uid_level; + + tm->info() << "LatestCellUID : " << m_latest_cell_uid; + tm->info() << "LatestNodeUID : " << m_latest_node_uid; + tm->info() << "LatestFaceUID : " << m_latest_face_uid; + + tm->info() << "MinLevel : " << m_min_level; + tm->info() << "MaxLevel : " << m_max_level; + + tm->info() << "GroundLevelNbCells : " << m_nb_cell_ground; + + if (m_ori_level == -1) { + tm->info() << "Ground Level is renumbered"; + } + else { + tm->info() << "Ground Level is not renumbered -- OriginalGroundLevel : " << m_ori_level; + } + + for (Integer i = m_min_level; i <= m_max_level; ++i) { + tm->info() << "Level " << i << " : "; + tm->info() << "\tUID Cells : [" << firstCellUniqueId(i) << ", " << (firstCellUniqueId(i) + nbCellInLevel(i)) << "["; + tm->info() << "\tUID Nodes : [" << firstNodeUniqueId(i) << ", " << (firstNodeUniqueId(i) + nbNodeInLevel(i)) << "["; + tm->info() << "\tUID Faces : [" << firstFaceUniqueId(i) << ", " << (firstFaceUniqueId(i) + nbFaceInLevel(i)) << "["; + } + + const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); + + Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); + tm->info() << "global_nb_cells_by_direction.x : " << global_nb_cells_by_direction[MD_DirX]; + tm->info() << "global_nb_cells_by_direction.y : " << global_nb_cells_by_direction[MD_DirY]; + tm->info() << "global_nb_cells_by_direction.z : " << global_nb_cells_by_direction[MD_DirZ]; } /*---------------------------------------------------------------------------*/ @@ -170,18 +238,19 @@ prepareLevel(Int32 level) return; if (level == m_max_level + 1) { m_max_level++; + m_first_cell_uid_level.add(m_latest_cell_uid); + m_first_node_uid_level.add(m_latest_node_uid); + m_first_face_uid_level.add(m_latest_face_uid); } else if (level == m_min_level - 1) { m_min_level--; + _pushFront(m_first_cell_uid_level, m_latest_cell_uid); + _pushFront(m_first_node_uid_level, m_latest_node_uid); + _pushFront(m_first_face_uid_level, m_latest_face_uid); } else { ARCANE_FATAL("Level error : {0}", level); } - m_p_to_l_level.add(level); - - m_first_cell_uid_level.add(m_latest_cell_uid); - m_first_node_uid_level.add(m_latest_node_uid); - m_first_face_uid_level.add(m_latest_face_uid); m_latest_cell_uid += nbCellInLevel(level); m_latest_node_uid += nbNodeInLevel(level); @@ -194,7 +263,7 @@ prepareLevel(Int32 level) void CartesianMeshNumberingMng:: updateFirstLevel() { - Int32 nb_levels_to_add = -m_min_level; + const Int32 nb_levels_to_add = -m_min_level; m_ori_level += nb_levels_to_add; if (nb_levels_to_add == 0) { @@ -204,11 +273,8 @@ updateFirstLevel() m_max_level += nb_levels_to_add; m_min_level += nb_levels_to_add; - for (Int32& i : m_p_to_l_level) { - i += nb_levels_to_add; - } - - m_nb_cell /= (m_pattern * nb_levels_to_add); + const Integer to_div = m_pattern * nb_levels_to_add; + m_nb_cell_ground /= to_div; // ---------- // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() @@ -219,15 +285,15 @@ updateFirstLevel() { ConstArrayView v = cmgi->ownCellOffsets(); - cmgi->setOwnCellOffsets(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern); + cmgi->setOwnCellOffsets(v[0] / to_div, v[1] / to_div, v[2] / to_div); } { ConstArrayView v = cmgi->globalNbCells(); - cmgi->setGlobalNbCells(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern); + cmgi->setGlobalNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); } { ConstArrayView v = cmgi->ownNbCells(); - cmgi->setOwnNbCells(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern); + cmgi->setOwnNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); } cmgi->setFirstOwnCellUniqueId(firstCellUniqueId(0)); // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() @@ -238,45 +304,27 @@ updateFirstLevel() /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -firstCellUniqueId(Integer level) +firstCellUniqueId(Integer level) const { - auto pos = m_p_to_l_level.span().findFirst(level); - if (pos.has_value()) { - return m_first_cell_uid_level[pos.value()]; - } - else { - ARCANE_FATAL("Bad level : {0}", level); - } + return m_first_cell_uid_level[level - m_min_level]; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -firstNodeUniqueId(Integer level) +firstNodeUniqueId(Integer level) const { - auto pos = m_p_to_l_level.span().findFirst(level); - if (pos.has_value()) { - return m_first_node_uid_level[pos.value()]; - } - else { - ARCANE_FATAL("Bad level : {0}", level); - } + return m_first_node_uid_level[level - m_min_level]; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -firstFaceUniqueId(Integer level) +firstFaceUniqueId(Integer level) const { - auto pos = m_p_to_l_level.span().findFirst(level); - if (pos.has_value()) { - return m_first_face_uid_level[pos.value()]; - } - else { - ARCANE_FATAL("Bad level : {0}", level); - } + return m_first_face_uid_level[level - m_min_level]; } /*---------------------------------------------------------------------------*/ @@ -285,7 +333,7 @@ firstFaceUniqueId(Integer level) Int64 CartesianMeshNumberingMng:: globalNbCellsX(Integer level) const { - return static_cast(static_cast(m_nb_cell.x) * std::pow(m_pattern, level)); + return static_cast(static_cast(m_nb_cell_ground.x) * std::pow(m_pattern, level)); } /*---------------------------------------------------------------------------*/ @@ -294,7 +342,7 @@ globalNbCellsX(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbCellsY(Integer level) const { - return static_cast(static_cast(m_nb_cell.y) * std::pow(m_pattern, level)); + return static_cast(static_cast(m_nb_cell_ground.y) * std::pow(m_pattern, level)); } /*---------------------------------------------------------------------------*/ @@ -303,7 +351,7 @@ globalNbCellsY(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbCellsZ(Integer level) const { - return static_cast(static_cast(m_nb_cell.z) * std::pow(m_pattern, level)); + return static_cast(static_cast(m_nb_cell_ground.z) * std::pow(m_pattern, level)); } /*---------------------------------------------------------------------------*/ @@ -447,14 +495,17 @@ pattern() const Int32 CartesianMeshNumberingMng:: cellLevel(Int64 uid) const { - Integer pos = 0; + Integer pos = -1; + Int64 max = 0; - while (pos < m_first_cell_uid_level.size() && m_first_cell_uid_level[pos] <= uid) { - pos++; + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstCellUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } } - pos--; - - return m_p_to_l_level[pos]; + return pos; } /*---------------------------------------------------------------------------*/ @@ -463,14 +514,17 @@ cellLevel(Int64 uid) const Int32 CartesianMeshNumberingMng:: nodeLevel(Int64 uid) const { - Integer pos = 0; + Integer pos = -1; + Int64 max = 0; - while (pos < m_first_node_uid_level.size() && m_first_node_uid_level[pos] <= uid) { - pos++; + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstNodeUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } } - pos--; - - return m_p_to_l_level[pos]; + return pos; } /*---------------------------------------------------------------------------*/ @@ -479,14 +533,17 @@ nodeLevel(Int64 uid) const Int32 CartesianMeshNumberingMng:: faceLevel(Int64 uid) const { - Integer pos = 0; + Integer pos = -1; + Int64 max = 0; - while (pos < m_first_face_uid_level.size() && m_first_face_uid_level[pos] <= uid) { - pos++; + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstFaceUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } } - pos--; - - return m_p_to_l_level[pos]; + return pos; } /*---------------------------------------------------------------------------*/ @@ -766,7 +823,7 @@ faceUniqueIdToCoordX(Int64 uid, Integer level) uid -= first_face_uid; - Int64x3 three_parts_numbering = face3DNumberingThreeParts(level); + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 @@ -896,7 +953,7 @@ faceUniqueIdToCoordY(Int64 uid, Integer level) uid -= first_face_uid; - Int64x3 three_parts_numbering = face3DNumberingThreeParts(level); + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 @@ -1002,7 +1059,7 @@ faceUniqueIdToCoordZ(Int64 uid, Integer level) uid -= first_face_uid; - Int64x3 three_parts_numbering = face3DNumberingThreeParts(level); + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 @@ -1149,7 +1206,7 @@ faceUniqueId(Integer level, Int64x3 face_coord) const Int64 nb_cell_x = globalNbCellsX(level); const Int64 nb_cell_y = globalNbCellsY(level); - Int64x3 three_parts_numbering = face3DNumberingThreeParts(level); + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); Int64 uid = firstFaceUniqueId(level); // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : @@ -2149,7 +2206,7 @@ childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) Int64 child_x = child_index_in_parent % m_pattern; Int64 child_y = child_index_in_parent / m_pattern; - Int64x3 three_parts_numbering = face3DNumberingThreeParts(level); + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); if (uid < three_parts_numbering.x) { first_child_coord_x += child_x * 2; @@ -2186,7 +2243,7 @@ childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) /*---------------------------------------------------------------------------*/ Int64x3 CartesianMeshNumberingMng:: -face3DNumberingThreeParts(Integer level) const +_face3DNumberingThreeParts(Integer level) const { const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); return { (nb_cell.z + 1) * nb_cell.x * nb_cell.y, (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x }; @@ -2195,6 +2252,19 @@ face3DNumberingThreeParts(Integer level) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshNumberingMng:: +_pushFront(UniqueArray& array, const Int64 elem) +{ + array.resize(array.size() + 1); + array.back() = elem; + for (Integer i = array.size() - 2; i >= 0; --i) { + std::swap(array[i], array[i + 1]); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h index d4b830c9e0..41b231c6b2 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h @@ -50,12 +50,16 @@ class CartesianMeshNumberingMng void _saveInfosInProperties() override; void _recreateFromDump() override; + void renumberingFacesLevel0FromOriginalArcaneNumbering() override; + + void printStatus() override; + void prepareLevel(Int32 level) override; void updateFirstLevel() override; - Int64 firstCellUniqueId(Integer level) override; - Int64 firstNodeUniqueId(Integer level) override; - Int64 firstFaceUniqueId(Integer level) override; + Int64 firstCellUniqueId(Integer level) const override; + Int64 firstNodeUniqueId(Integer level) const override; + Int64 firstFaceUniqueId(Integer level) const override; Int64 globalNbCellsX(Integer level) const override; Int64 globalNbCellsY(Integer level) const override; @@ -171,7 +175,9 @@ class CartesianMeshNumberingMng * \param level Le niveau de la numérotation. * \return Le nombre de faces {xy, yz, zx}. */ - Int64x3 face3DNumberingThreeParts(Integer level) const; + Int64x3 _face3DNumberingThreeParts(Integer level) const; + + static void _pushFront(UniqueArray& array, Int64 elem); private: @@ -195,7 +201,7 @@ class CartesianMeshNumberingMng Int64 m_latest_face_uid; UniqueArray m_first_face_uid_level; - Int64x3 m_nb_cell; + Int64x3 m_nb_cell_ground; // Partie conversion numérotation d'origine <-> nouvelle numérotation (face). bool m_converting_numbering_face; diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index 8fd64ec196..c27ab90e0b 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -132,7 +132,7 @@ addPatch(CellGroup cell_group) { Int64 nb_cells_patch = (max[MD_DirX] - min[MD_DirX]) * (max[MD_DirY] - min[MD_DirY]) * (max[MD_DirZ] - min[MD_DirZ]); if (nb_cells != nb_cells_patch) { - ARCANE_FATAL("Not regular patch"); + ARCANE_FATAL("Not regular patch -- NbCellsInGroup : {0} -- NbCellsInPatch : {1}", nb_cells, nb_cells_patch); } } diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h index 6760ff3ac0..a7ef26fd71 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h @@ -31,6 +31,16 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +/*! + * \brief Interface de gestionnaire de numérotation pour maillage cartesian. + * + * Dans ces gestionnaires, on considère que l'on a un intervalle d'uniqueids + * attribué à chaque niveau du maillage. + * + * \warning Le maillage ne doit pas être renuméroté si une implémentation de + * cette interface est utilisée (ou alors, il ne faut plus l'utiliser après + * renumérotation (attention aux protections/reprises)). + */ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng { public: @@ -43,6 +53,23 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng virtual void _saveInfosInProperties() = 0; virtual void _recreateFromDump() = 0; + /*! + * \brief Méthode permettant de renuméroter les faces du niveau 0. + * + * Cela permet de ne plus faire de conversions de uniqueIds lors de + * certaines opérations sur les faces et donc de libérer les structures + * faisant la correspondance entre les deux numérotations. + * + * Ces structures n'étant pas partagées entre sous-domaines, renuméroter + * permet de repartitionner le maillage sans problème. + */ + virtual void renumberingFacesLevel0FromOriginalArcaneNumbering() = 0; + + /*! + * \brief Méthode permettant de décrire l'état de l'objet. + */ + virtual void printStatus() = 0; + /*! * \brief Méthode permettant de préparer un nouveau niveau. * @@ -75,7 +102,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng * \param level Le niveau. * \return Le premier uid des mailles du niveau. */ - virtual Int64 firstCellUniqueId(Integer level) = 0; + virtual Int64 firstCellUniqueId(Integer level) const = 0; /*! * \brief Méthode permettant de récupérer le premier unique id utilisé par les noeuds d'un niveau. @@ -85,7 +112,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng * \param level Le niveau. * \return Le premier uid des noeuds du niveau. */ - virtual Int64 firstNodeUniqueId(Integer level) = 0; + virtual Int64 firstNodeUniqueId(Integer level) const = 0; /*! * \brief Méthode permettant de récupérer le premier unique id utilisé par les faces d'un niveau. @@ -95,7 +122,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng * \param level Le niveau. * \return Le premier uid des faces du niveau. */ - virtual Int64 firstFaceUniqueId(Integer level) = 0; + virtual Int64 firstFaceUniqueId(Integer level) const = 0; /*! * \brief Méthode permettant de récupérer le nombre de mailles global en X d'un niveau. From 81263814e79b6104a363d544321a4ad449e3cb29 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Tue, 28 Oct 2025 13:15:42 +0100 Subject: [PATCH 05/19] [arcane:cartesianmesh,tests] Update tests arc --- arcane/ceapart/tests/CMakeLists.txt | 20 ---- ...rtesianMesh2D-PatchCartesianMeshOnly-2.arc | 1 + ...rtesianMesh2D-PatchCartesianMeshOnly-3.arc | 11 +- ...2D-PatchCartesianMeshOnly-CoarseZone-1.arc | 19 ++-- ...2D-PatchCartesianMeshOnly-CoarseZone-2.arc | 19 ++-- ...2D-PatchCartesianMeshOnly-CoarseZone-3.arc | 77 ------------- ...2D-PatchCartesianMeshOnly-CoarseZone-4.arc | 90 --------------- ...InitialCoarse-PatchCartesianMeshOnly-7.arc | 14 +-- ...se-PatchCartesianMeshOnly-CoarseZone-1.arc | 9 +- ...rtesianMesh3D-PatchCartesianMeshOnly-2.arc | 1 + ...rtesianMesh3D-PatchCartesianMeshOnly-3.arc | 9 +- ...3D-PatchCartesianMeshOnly-CoarseZone-1.arc | 13 ++- ...3D-PatchCartesianMeshOnly-CoarseZone-2.arc | 13 ++- ...3D-PatchCartesianMeshOnly-CoarseZone-3.arc | 13 ++- ...3D-PatchCartesianMeshOnly-CoarseZone-4.arc | 13 ++- ...3D-PatchCartesianMeshOnly-CoarseZone-5.arc | 79 ------------- ...3D-PatchCartesianMeshOnly-CoarseZone-6.arc | 107 ------------------ ...3D-PatchCartesianMeshOnly-CoarseZone-7.arc | 78 ------------- ...3D-PatchCartesianMeshOnly-CoarseZone-8.arc | 107 ------------------ ...se-PatchCartesianMeshOnly-CoarseZone-1.arc | 9 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 2 + 21 files changed, 80 insertions(+), 624 deletions(-) delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc delete mode 100644 arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc diff --git a/arcane/ceapart/tests/CMakeLists.txt b/arcane/ceapart/tests/CMakeLists.txt index 25c58cd746..aae33641ed 100644 --- a/arcane/ceapart/tests/CMakeLists.txt +++ b/arcane/ceapart/tests/CMakeLists.txt @@ -291,12 +291,8 @@ arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-cell-coarse-zone- arcane_add_test(amr-cartesian2D-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc "-m 20") arcane_add_test(amr-cartesian2D-patch-cartesian-mesh-only-coarse-zone-2 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc "-m 20") -arcane_add_test(amr-cartesian2D-patch-cartesian-mesh-only-coarse-zone-3 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc "-m 20") -arcane_add_test(amr-cartesian2D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc "-m 20") arcane_add_test_checkpoint(amr-checkpoint-cartesian2D-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc 3 5) arcane_add_test_checkpoint(amr-checkpoint-cartesian2D-patch-cartesian-mesh-only-coarse-zone-2 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc 3 5) -arcane_add_test_checkpoint(amr-checkpoint-cartesian2D-patch-cartesian-mesh-only-coarse-zone-3 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc 3 5) -arcane_add_test_checkpoint(amr-checkpoint-cartesian2D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc 3 5) arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc "-m 20") @@ -307,14 +303,6 @@ arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-3 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc 8 "-m 20") arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc "-m 20") arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc 8 "-m 20") -arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-5 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc "-m 20") -arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-5 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc 8 "-m 20") -arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-6 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc "-m 20") -arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-6 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc 8 "-m 20") -arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-7 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc "-m 20") -arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-7 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc 8 "-m 20") -arcane_add_test_sequential(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-8 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc "-m 20") -arcane_add_test_parallel(amr-cartesian3D-patch-cartesian-mesh-only-coarse-zone-8 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc 8 "-m 20") arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc 3 5) arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc 8 3 5) arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-2 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc 3 5) @@ -323,14 +311,6 @@ arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-3 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc 8 3 5) arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc 3 5) arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-4 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc 8 3 5) -arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-5 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc 3 5) -arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-5 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc 8 3 5) -arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-6 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc 3 5) -arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-6 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc 8 3 5) -arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-7 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc 3 5) -arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-7 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc 8 3 5) -arcane_add_test_checkpoint_sequential(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-8 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc 3 5) -arcane_add_test_checkpoint_parallel(amr-checkpoint-cartesian3D-patch-cartesian-mesh-only-coarse-zone-8 testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc 8 3 5) arcane_add_test(amr-cartesian2D-coarse-patch-cartesian-mesh-only-coarse-zone-1 testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc "-m 20") diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc index 37b9352d6b..c40fcebdca 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc @@ -56,6 +56,7 @@ 2.0 0.0 2.0 2.0 + false 4 4 4 4 4 12 12 12 12 12 c162b8092f50639d0e8d83ef6439043e diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc index a08daa3394..7ca2131653 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc @@ -56,14 +56,15 @@ 0.0 2.0 2.0 2.0 - 4 4 4 4 4 - 12 12 12 12 12 + true + 4 16 + 12 48 c162b8092f50639d0e8d83ef6439043e a4b9d143dabca55819722e363022c00c b1a1189e7febabd5c2b0e3d0f1e91c57 - 15bcbeededc9fb9bfbf6b5347cfece0d - d03cc496dfc49a02aafcc4a01b1add9e - 329c56f1ccba78ce502cfc2001e0e716 + 05ec4fa803a51eedc91a383a777602ae + a48051badfc0eeca42d4a6b05c00600a + 86af3e90b283a6565742f0c7db1f33f3 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc index 253043fc54..f8d4d2e290 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 2D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -42,7 +42,7 @@ - 1 + 0 1.0 1.0 @@ -62,13 +62,14 @@ 1.0 1.0 - 25 32 - b85cb78ab44742ca5ae8d1440a38739d - f21c0a9a3f794391796fced1db892419 - 77ff9dc6c92dc78592a5a0f522422acb - 278dd927e27f254e9dd6e03788fe10ca - 639237c778c0ccbb6d41e2da46f42e4d - 88908c6b1166b61acb92923029042140 + + 25 4 8 8 12 + 228ccabec148d8994007ec68e78ff7d4 + 2a641fe98a56f0938992201e96d1cee8 + f3b6adc61a780f25ff6580c7c9f39142 + 86c7ad69500971e5d3c70b5235d729bb + 67cd454129841abf8dd3b9cc55d6ab4a + 22e4d56a6bae8ba70e2e387b00111330 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc index 23e35f7393..19f9880dc6 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 2D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -42,7 +42,7 @@ - 1 + 0 1.0 1.0 @@ -75,13 +75,14 @@ 3.0 3.0 - 100 220 - adbff87895b55d9ce55b60fcab95c542 - 2a8a808d2c4ac5f760812c9b5b16c3f0 - 9b275bfdff8e4485ab746bab360d02d3 - 3169601d3311a9bbd3f02dfe47ce263c - c017f7f8020fab9ae8a749a05540cffc - a7698709767a059c1670beac54f1c8c3 + + 100 36 48 64 72 + bc4723a3ae6b84325bb17509f94d624b + 1d4aba023756b0548b078f7915e2001e + 8874beeeeb07e91d1d49868bcce26b21 + 37f20b21b2eb8c41d589128e9f7c2ab1 + 9976902a8decf9d761d200c3d4b135e7 + 5f9f718794bdc870ba496d14f4b7bd33 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc deleted file mode 100644 index d6fcc45f83..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-3.arc +++ /dev/null @@ -1,77 +0,0 @@ - - - - Test CartesianMesh 2D PatchCartesianMeshOnly Coarse Zone (Variant 3) - - - Test du raffinement d'un maillage cartesian 2D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 - 0.0 0.0 - 5.0 - 5.0 - - - - - - 0 - - - 1.0 1.0 - 3.0 3.0 - - - 2.0 2.0 - 1.0 1.0 - - - - 2.0 2.0 - 1.0 1.0 - - - 2.0 2.0 - 1.0 1.0 - - - 25 32 - 228ccabec148d8994007ec68e78ff7d4 - 2a641fe98a56f0938992201e96d1cee8 - f3b6adc61a780f25ff6580c7c9f39142 - c9a52b9949dc01d2f96eef356ffdd8c6 - 66f244a79b230df70dec93aa16ea622f - 9729d1bc9dd344ca1632b0d4ead1418c - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc deleted file mode 100644 index ae3e90d7da..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-4.arc +++ /dev/null @@ -1,90 +0,0 @@ - - - - Test CartesianMesh 2D PatchCartesianMeshOnly Coarse Zone (Variant 4) - - - Test du raffinement d'un maillage cartesian 2D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 - 0.0 0.0 - 10.0 - 10.0 - - - - - - 0 - - - 1.0 1.0 - 8.0 8.0 - - - 3.0 3.0 - 4.0 4.0 - - - - 3.0 3.0 - 2.0 2.0 - - - 5.0 5.0 - 2.0 2.0 - - - 3.0 5.0 - 2.0 2.0 - - - 5.0 3.0 - 2.0 2.0 - - - - 3.0 3.0 - 3.0 3.0 - - - 100 220 - bc4723a3ae6b84325bb17509f94d624b - 1d4aba023756b0548b078f7915e2001e - 8874beeeeb07e91d1d49868bcce26b21 - e2a8b311b668f6c7374b7339ccfeaf40 - 7e3271c244da2ebf50ab4abbcd870c67 - adf4c70f22ce75695fcf9e85eddcdc2c - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc index 2150c8ce82..3d21da44fa 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc @@ -40,7 +40,7 @@ 0 true - 1 + 0 true 0.0 0.0 @@ -49,12 +49,12 @@ 1600 6400 484 516 2064 0 - be945c17467f6ba7bbf41ee1baf19c8c - c92d0e52cea7b406b449d57521f42124 - 19dd0b9269462bd111611a5f0adac601 - e5c557100202662f5b0f896186988899 - 8199a4db6ae7b59a3cd7e8dd5dddc1df - 0c31d9305b33eda7aa50f222f7395693 + d908f0b0fb7d7b8f5191444cee921518 + 7a55f9bbcd8ffe328455b774c619bb34 + cfa32d74b8f1ba19ab55eae6e84ce87a + 04f730c075fc1e636790583d4e8b8646 + ff5f7573b0107d492962605201ce6499 + bcd8f765aa2599913658588408bd995b diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc index d52b06b965..23ab648942 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -60,13 +60,14 @@ 4.0 2.0 - 16 56 48 + + 16 48 8 16 16 16 bc99948909b1c4499d164c6da40dcad9 f4914df7549e82882fc28849b89c8b5f 6e75535e29f9cb664058906a6e54c0a6 - 5e18f929f56e0edbabb140483a8f89bd - e8dfa7dff4817150ea2250834667d8c3 - 48966f7b215624d47a310508bcaf28b5 + aadacb309fd2f436af0c8fd4959af8e7 + 9897ea6879fa40978a487931568562cf + 4d240366d0b76e05b254e0da4ead19ef diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc index c46bbe3f1b..f97cafe7b0 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc @@ -73,6 +73,7 @@ 2.0 2.0 0.0 2.0 2.0 2.0 + false 8 8 8 8 8 8 8 8 8 bfa069f213eef90d389efa5c3ca0745d 5b12ac3a6d9ed116b024074cdef808c6 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc index 6c1427491e..1a8da306f6 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc @@ -73,13 +73,14 @@ 2.0 2.0 2.0 2.0 2.0 2.0 - 8 8 8 8 8 8 8 8 8 + true + 8 64 bfa069f213eef90d389efa5c3ca0745d 5b12ac3a6d9ed116b024074cdef808c6 1ee6fc646290a97f10cef6795ac106f0 - 4715458eab6ac128fb08dacf80aacd37 - 01ddcaf0e0590ac4c56d3ddb98098c8a - e974c5f17047b2eb7253bff0c937e99a + 4744835ec9bc87f441a87f90bd9ab316 + 60ef888dde8214f6e7e96ea17f7cbb29 + 5985ba24d611bfac8b708c2d30f0a821 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc index 07709aff4a..e0d33f3346 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -43,7 +43,7 @@ - 1 + 0 1.0 1.0 1.0 @@ -64,13 +64,14 @@ - 125 208 + + 125 8 16 16 16 32 48 72 df3786d49d37ad67e721c927500d6fd1 b0a24dbeeea1bba8b887155109d5a312 0e51a40d9d1a79d115f4bb5ddeefd827 - 80a730336092726dfd8f878cc97a403e - a4a2370619cd30637fec8a9baea03b9b - 9df145d5cd32ba170267fd6044210e03 + 7b972b16de85388414d158e1d0d0f934 + d566487c11780b6e9801c0457b560542 + f5756692579d9efafeade38c72812304 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc index bad671ccff..3d690add71 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -43,7 +43,7 @@ - 1 + 0 1.0 1.0 1.0 @@ -92,13 +92,14 @@ 3.0 3.0 3.0 - 1000 3880 + + 1000 216 432 576 768 864 1024 194910d2bfdfb101b23a3ce372f4e60d 145355f865846e248eea6a3458cb5cd9 b025a6b3ac6545c730498d9967a65511 - 1f7be582f64304e490f0f49beeef8bda - f3073821e092607d071025c60b5881d7 - abb09d4f40fc4b799a19c46339118f2e + f6963e475c46948814d514eb1b26d8fa + 2e30a9808bbf5e4e873bae8f9607a975 + 286822b809191f89a85623e3a95bd9f6 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc index 7e97d5698f..05514e55a0 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -43,7 +43,7 @@ - 1 + 0 0.0 1.0 1.0 @@ -63,13 +63,14 @@ 1.0 1.0 1.0 - 125 208 + + 125 16 16 24 24 32 48 48 549c906b4835458793357c764e285d6c 2408a4cfc18f1c81c1238708ee7a7219 67073338e696ff7e73e429ed9965fd28 - ccdf163df5ca9a60fac41ed1ac72f017 - b0da47342026988b44055852a68da914 - 2dda186b82f5335e506f0c04ed0d7b9f + cfe748e9a5ab3902c1fb7fee89f916b4 + 07d5c9133b3756c85a285a3caabdacad + 8edd0c2fa02d38971e90684f90b01e40 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc index 6460f2389e..b93b60caa0 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc @@ -5,7 +5,7 @@ Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (avec renumérotation version 1) + puis du dé-raffinement de certaines zones (sans renumérotation) AMRCartesianMeshTestLoop @@ -43,7 +43,7 @@ - 1 + 0 0.0 1.0 1.0 @@ -92,13 +92,14 @@ 3.0 3.0 3.0 - 1000 3880 + + 1000 360 432 576 720 768 1024 38ce8a131e14a4ef3db4e9ac0b1b40e6 dab2908cc09b1572c08793666b2ebe10 5148e6e7af0ae779041a8bb42a7ca637 - efb30f7b6c5d39a18d8c40272a04ef51 - fbdc6e058df75c4e0b7f5508111a9826 - 1b83ea2ac7d60e6b4723162d6c09da68 + 7853a0e71c60141f5ce3ef1611ed0ce8 + 19b26d1b513014c1c568ba812dc0c23f + 5f291689ed9db06199bfec171a2dee95 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc deleted file mode 100644 index c761f99d4b..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-5.arc +++ /dev/null @@ -1,79 +0,0 @@ - - - - Test CartesianMesh 3D PatchCartesianMeshOnly Coarse Zone (Variant 5) - - - Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 2 - 0.0 0.0 0.0 - 5.0 - 5.0 - 5.0 - - - - - - 0 - - - 1.0 1.0 1.0 - 3.0 3.0 3.0 - - - 2.0 2.0 2.0 - 1.0 1.0 1.0 - - - - 2.0 2.0 2.0 - 1.0 1.0 1.0 - - - 2.0 2.0 2.0 - 1.0 1.0 1.0 - - - - 125 208 - df3786d49d37ad67e721c927500d6fd1 - b0a24dbeeea1bba8b887155109d5a312 - 0e51a40d9d1a79d115f4bb5ddeefd827 - 80a730336092726dfd8f878cc97a403e - a4a2370619cd30637fec8a9baea03b9b - 9df145d5cd32ba170267fd6044210e03 - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc deleted file mode 100644 index dc53cbd2bd..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-6.arc +++ /dev/null @@ -1,107 +0,0 @@ - - - - Test CartesianMesh 3D PatchCartesianMeshOnly Coarse Zone (Variant 6) - - - Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 2 - 0.0 0.0 0.0 - 10.0 - 10.0 - 10.0 - - - - - - 0 - - - 1.0 1.0 1.0 - 8.0 8.0 8.0 - - - 3.0 3.0 3.0 - 4.0 4.0 4.0 - - - - 3.0 3.0 3.0 - 2.0 2.0 2.0 - - - 3.0 3.0 5.0 - 2.0 2.0 2.0 - - - 3.0 5.0 3.0 - 2.0 2.0 2.0 - - - 3.0 5.0 5.0 - 2.0 2.0 2.0 - - - 5.0 3.0 3.0 - 2.0 2.0 2.0 - - - 5.0 3.0 5.0 - 2.0 2.0 2.0 - - - 5.0 5.0 3.0 - 2.0 2.0 2.0 - - - 5.0 5.0 5.0 - 2.0 2.0 2.0 - - - - 3.0 3.0 3.0 - 3.0 3.0 3.0 - - - 1000 3880 - 194910d2bfdfb101b23a3ce372f4e60d - 145355f865846e248eea6a3458cb5cd9 - b025a6b3ac6545c730498d9967a65511 - 1f7be582f64304e490f0f49beeef8bda - f3073821e092607d071025c60b5881d7 - abb09d4f40fc4b799a19c46339118f2e - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc deleted file mode 100644 index af6ae3a311..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-7.arc +++ /dev/null @@ -1,78 +0,0 @@ - - - - Test CartesianMesh 3D PatchCartesianMeshOnly Coarse Zone (Variant 7) - - - Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 2 - 0.0 0.0 0.0 - 5.0 - 5.0 - 5.0 - - - - - - 0 - - - 0.0 1.0 1.0 - 3.0 3.0 3.0 - - - 0.0 2.0 2.0 - 1.0 1.0 1.0 - - - - 0.0 2.0 2.0 - 1.0 1.0 1.0 - - - 0.0 2.0 2.0 - 1.0 1.0 1.0 - - - 125 208 - 549c906b4835458793357c764e285d6c - 2408a4cfc18f1c81c1238708ee7a7219 - 67073338e696ff7e73e429ed9965fd28 - ccdf163df5ca9a60fac41ed1ac72f017 - b0da47342026988b44055852a68da914 - 2dda186b82f5335e506f0c04ed0d7b9f - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc deleted file mode 100644 index b4e4ffbacf..0000000000 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-8.arc +++ /dev/null @@ -1,107 +0,0 @@ - - - - Test CartesianMesh 3D PatchCartesianMeshOnly Coarse Zone (Variant 8) - - - Test du raffinement d'un maillage cartesian 3D avec le type d'AMR PatchCartesianMeshOnly - puis du dé-raffinement de certaines zones (sans renumérotation) - - - AMRCartesianMeshTestLoop - - - - - - - - - - 1 - - Density - NodeDensity - AllCells - AllNodes - AllFacesDirection0 - AllFacesDirection1 - - - - - - - - 2 2 2 - 0.0 0.0 0.0 - 10.0 - 10.0 - 10.0 - - - - - - 0 - - - 0.0 1.0 1.0 - 8.0 8.0 8.0 - - - 0.0 3.0 3.0 - 4.0 4.0 4.0 - - - - 0.0 3.0 3.0 - 2.0 2.0 2.0 - - - 0.0 3.0 5.0 - 2.0 2.0 2.0 - - - 0.0 5.0 3.0 - 2.0 2.0 2.0 - - - 0.0 5.0 5.0 - 2.0 2.0 2.0 - - - 2.0 3.0 3.0 - 2.0 2.0 2.0 - - - 2.0 3.0 5.0 - 2.0 2.0 2.0 - - - 2.0 5.0 3.0 - 2.0 2.0 2.0 - - - 2.0 5.0 5.0 - 2.0 2.0 2.0 - - - - 0.0 3.0 3.0 - 3.0 3.0 3.0 - - - 1000 3880 - 38ce8a131e14a4ef3db4e9ac0b1b40e6 - dab2908cc09b1572c08793666b2ebe10 - 5148e6e7af0ae779041a8bb42a7ca637 - efb30f7b6c5d39a18d8c40272a04ef51 - fbdc6e058df75c4e0b7f5508111a9826 - 1b83ea2ac7d60e6b4723162d6c09da68 - - - - - - diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc index 8cacb7d86d..f594e97d62 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -61,13 +61,14 @@ 4.0 2.0 2.0 - 64 496 960 + + 64 384 576 32 48 64 96 128 128 f1eedebec73b1051ef2b7a77ed815702 0b1bba1f8971df16968f9648112dcbb1 85f1a6bff5d48797f358c0145fb9127c - c1888f691c5b6a89d432b2a8bc08f502 - 8182eec5342cbcd876589f9fd8528826 - 2d8191a235e17346e88953e650358309 + a362e7707f0455ec1fdc7e787488bc36 + acf1ed66f073090ef1254410deb54fdb + 0a299b23e95a42809e3e7b1156b78039 diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 8b6379fdd1..a6045af60e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -279,6 +279,8 @@ CartesianMeshImpl(IMesh* mesh) if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.initCartesianMeshNumberingMng(); m_internal_api.initCartesianMeshAMRPatchMng(); + // TODO : Voir où mettre la renumérotation. + //m_internal_api.cartesianMeshNumberingMng()->renumberingFacesLevel0FromOriginalArcaneNumbering(); } m_all_items_direction_info = m_patch_group.groundPatch(); } From 86b895749c65a2ba53e219fc4404095eb4bc5bd5 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Tue, 28 Oct 2025 15:46:13 +0100 Subject: [PATCH 06/19] [arcane:cartesianmesh] Add methods of the proto "amr_proto" And use the new methods in CartesianPatchGroup. --- .../arcane/cartesianmesh/AMRPatchPosition.cc | 182 +++++++ .../arcane/cartesianmesh/AMRPatchPosition.h | 16 + .../AMRPatchPositionLevelGroup.cc | 75 +++ .../AMRPatchPositionLevelGroup.h | 58 +++ .../AMRPatchPositionSignature.cc | 446 ++++++++++++++++++ .../cartesianmesh/AMRPatchPositionSignature.h | 92 ++++ .../AMRPatchPositionSignatureCut.cc | 425 +++++++++++++++++ .../AMRPatchPositionSignatureCut.h | 56 +++ .../src/arcane/cartesianmesh/CartesianMesh.cc | 18 + .../CartesianMeshNumberingMng.cc | 9 +- .../cartesianmesh/CartesianPatchGroup.cc | 256 +++++++++- .../cartesianmesh/CartesianPatchGroup.h | 3 + .../src/arcane/cartesianmesh/ICartesianMesh.h | 2 + arcane/src/arcane/cartesianmesh/srcs.cmake | 6 + 14 files changed, 1641 insertions(+), 3 deletions(-) create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc create mode 100644 arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc index 36a0714d1f..61ff01f540 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -14,6 +14,10 @@ #include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/core/ArcaneTypes.h" +#include "arcane/utils/FatalErrorException.h" +#include "arcane/utils/Math.h" + +#include /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -210,6 +214,184 @@ isNull() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +AMRPatchPosition AMRPatchPosition:: +patchUp() const +{ + AMRPatchPosition p; + p.setLevel(m_level + 1); + p.setMinPoint(m_min_point * 2); + p.setMaxPoint(m_max_point * 2); + return p; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +length() const +{ + return m_max_point - m_min_point; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +min(Integer level) const +{ + if (level == m_level) { + return m_min_point; + } + if (level == m_level + 1) { + return m_min_point * 2; + } + if (level == m_level - 1) { + return m_min_point / 2; + } + if (level < m_level) { + Int32 dif = static_cast(math::pow(2., static_cast(m_level - level))); + return m_min_point / dif; + } + + Int32 dif = static_cast(math::pow(2., static_cast(level - m_level))); + return m_min_point * dif; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +minWithMargin(Integer level) const +{ + if (level == m_level) { + return m_min_point - 1; + } + if (level == m_level - 1) { + return (m_min_point - 1) / 2; + } + ARCANE_FATAL("Pas utile"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +minWithMarginEven(Integer level) const +{ + if (level == m_level) { + Int64x3 with_margin = m_min_point - 1; + with_margin.x -= with_margin.x % 2; + with_margin.y -= with_margin.y % 2; + with_margin.z -= with_margin.z % 2; + return with_margin; + } + if (level == m_level - 1) { + Int64x3 with_margin = (m_min_point - 1) / 2; + with_margin.x -= with_margin.x % 2; + with_margin.y -= with_margin.y % 2; + with_margin.z -= with_margin.z % 2; + return with_margin; + } + ARCANE_FATAL("Pas utile"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +max(Integer level) const +{ + if (level == m_level) { + return m_max_point; + } + if (level == m_level + 1) { + return m_max_point * 2; + } + if (level == m_level - 1) { + return { static_cast(std::ceil(m_max_point.x / 2.)), static_cast(std::ceil(m_max_point.y / 2.)), static_cast(std::ceil(m_max_point.z / 2.)) }; + } + if (level < m_level) { + Int64 dif = static_cast(math::pow(2., static_cast(level - m_level))); + return { static_cast(std::ceil(m_max_point.x / dif)), static_cast(std::ceil(m_max_point.y / dif)), static_cast(std::ceil(m_max_point.z / dif)) }; + } + Int64 dif = static_cast(math::pow(2., static_cast(level - m_level))); + return m_max_point * dif; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +maxWithMargin(Integer level) const +{ + if (level == m_level) { + return m_max_point + 1; + } + if (level == m_level - 1) { + Int64x3 max = m_max_point + 1; + return { static_cast(std::ceil(max.x / 2.)), static_cast(std::ceil(max.y / 2.)), static_cast(std::ceil(max.z / 2.)) }; + } + ARCANE_FATAL("Pas utile"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +maxWithMarginEven(Integer level) const +{ + if (level == m_level) { + Int64x3 with_margin = m_max_point + 1; + with_margin.x += with_margin.x % 2; + with_margin.y += with_margin.y % 2; + with_margin.z += with_margin.z % 2; + return with_margin; + } + if (level == m_level - 1) { + Int64x3 max = m_max_point + 1; + Int64x3 with_margin = { static_cast(std::ceil(max.x / 2.)), static_cast(std::ceil(max.y / 2.)), static_cast(std::ceil(max.z / 2.)) }; + with_margin.x += with_margin.x % 2; + with_margin.y += with_margin.y % 2; + with_margin.z += with_margin.z % 2; + return with_margin; + } + ARCANE_FATAL("Pas utile"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +isIn(Integer x, Integer y, Integer z) const +{ + 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; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +isInWithMargin(Integer level, Integer x, Integer y, Integer z) const +{ + Int64x3 level_min = minWithMargin(level); + Int64x3 level_max = maxWithMargin(level); + return x >= level_min.x && x < level_max.x && y >= level_min.y && y < level_max.y && z >= level_min.z && z < level_max.z; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPosition:: +isInWithMarginEven(Integer level, Integer x, Integer y, Integer z) const +{ + Int64x3 level_min = minWithMarginEven(level); + Int64x3 level_max = maxWithMarginEven(level); + return x >= level_min.x && x < level_max.x && y >= level_min.y && y < level_max.y && z >= level_min.z && z < level_max.z; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index 7b1257f273..a50a5e7565 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -49,6 +49,22 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition void fusion(const AMRPatchPosition& other_patch); bool isNull() const; + AMRPatchPosition patchUp() const; + + Int64x3 length() const; + + Int64x3 min(Integer level) const; + Int64x3 minWithMargin(Integer level) const; + Int64x3 minWithMarginEven(Integer level) const; + + Int64x3 max(Integer level) const; + Int64x3 maxWithMargin(Integer level) const; + Int64x3 maxWithMarginEven(Integer level) const; + + bool isIn(Integer x, Integer y, Integer z) const; + bool isInWithMargin(Integer level, Integer x, Integer y, Integer z) const; + bool isInWithMarginEven(Integer level, Integer x, Integer y, Integer z) const; + private: Integer m_level; Int64x3 m_min_point; diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc new file mode 100644 index 0000000000..33529d8300 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc @@ -0,0 +1,75 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionLevelGroup.cc (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPositionLevelGroup.h" + +#include "arcane/core/ArcaneTypes.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionLevelGroup:: +AMRPatchPositionLevelGroup(Integer max_level) +: m_max_level(max_level) +, m_patches(max_level+1) +{ + +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionLevelGroup:: +~AMRPatchPositionLevelGroup() += default; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer AMRPatchPositionLevelGroup:: +maxLevel() +{ + return m_max_level; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ConstArrayView AMRPatchPositionLevelGroup:: +patches(Integer level) +{ + return m_patches[level]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPositionLevelGroup:: +addPatch(AMRPatchPosition patch) +{ + m_patches[patch.level()].add(patch); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h new file mode 100644 index 0000000000..23b339e711 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h @@ -0,0 +1,58 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionLevelGroup.h (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONLEVELGROUP_H +#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONLEVELGROUP_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +#include "arcane/utils/Vector3.h" +#include "arcane/utils/UniqueArray.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class AMRPatchPositionLevelGroup +{ + public: + AMRPatchPositionLevelGroup(Integer max_level); + ~AMRPatchPositionLevelGroup(); + + public: + + Integer maxLevel(); + ConstArrayView patches(Integer level); + void addPatch(AMRPatchPosition patch); + + private: + Integer m_max_level; + UniqueArray> m_patches; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif + diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc new file mode 100644 index 0000000000..fe69e9c6e7 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc @@ -0,0 +1,446 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionSignature.cc (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPositionSignature.h" + +#include "ICartesianMesh.h" +#include "arcane/core/ArcaneTypes.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/IParallelMng.h" +#include "arcane/core/ItemEnumerator.h" +#include "arcane/utils/FatalErrorException.h" +#include "arccore/trace/ITraceMng.h" +#include "internal/ICartesianMeshInternal.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +namespace +{ +constexpr Integer MIN_SIZE = 4; +constexpr Integer TARGET_SIZE = 8; +constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 0.5; +constexpr Integer MAX_NB_CUT = 5; +constexpr Real TARGET_EFFICACITY = 0.90; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionSignature:: +AMRPatchPositionSignature() +: m_is_null(true) +, m_mesh(nullptr) +, m_nb_cut(0) +, m_stop_cut(false) +, m_numbering(nullptr) +, m_have_cells(false) +, m_is_computed(false) +, m_all_patches(nullptr) +{ +} + +AMRPatchPositionSignature:: +AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches) +: m_is_null(false) +, m_patch(patch) +, m_mesh(cmesh) +, m_nb_cut(0) +, m_stop_cut(false) +, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMng().get()) +, m_have_cells(false) +, m_is_computed(false) +, m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0) +, m_sig_y(patch.maxPoint().y - patch.minPoint().y, 0) +, m_sig_z(patch.maxPoint().z - patch.minPoint().z, 0) +, m_all_patches(all_patches) +{} + +AMRPatchPositionSignature:: +AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches, Integer nb_cut) +: m_is_null(false) +, m_patch(patch) +, m_mesh(cmesh) +, m_nb_cut(nb_cut) +, m_stop_cut(false) +, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMng().get()) +, m_have_cells(false) +, m_is_computed(false) +, m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0) +, m_sig_y(patch.maxPoint().y - patch.minPoint().y, 0) +, m_sig_z(patch.maxPoint().z - patch.minPoint().z, 0) +, m_all_patches(all_patches) +{} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionSignature:: +~AMRPatchPositionSignature() += default; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPositionSignature:: +compress() +{ + if (!m_have_cells) { + return; + } + + Integer reduce_x_min = 0; + if (m_sig_x[0] == 0) { + for (; reduce_x_min < m_sig_x.size(); ++reduce_x_min) { + if (m_sig_x[reduce_x_min] != 0) { + break; + } + } + } + Integer reduce_y_min = 0; + if (m_sig_y[0] == 0) { + for (; reduce_y_min < m_sig_y.size(); ++reduce_y_min) { + if (m_sig_y[reduce_y_min] != 0) { + break; + } + } + } + Integer reduce_z_min = 0; + if (m_sig_z[0] == 0) { + for (; reduce_z_min < m_sig_z.size(); ++reduce_z_min) { + if (m_sig_z[reduce_z_min] != 0) { + break; + } + } + } + + Integer reduce_x_max = m_sig_x.size()-1; + if (m_sig_x[reduce_x_max] == 0) { + for (; reduce_x_max >= 0; --reduce_x_max) { + if (m_sig_x[reduce_x_max] != 0) { + break; + } + } + } + Integer reduce_y_max = m_sig_y.size()-1; + if (m_sig_y[reduce_y_max] == 0) { + for (; reduce_y_max >= 0; --reduce_y_max) { + if (m_sig_y[reduce_y_max] != 0) { + break; + } + } + } + Integer reduce_z_max = m_sig_z.size() - 1; + if (m_sig_z[reduce_z_max] == 0) { + for (; reduce_z_max >= 0; --reduce_z_max) { + if (m_sig_z[reduce_z_max] != 0) { + break; + } + } + } + + if (reduce_x_min != 0 || reduce_x_max != m_sig_x.size()-1) { + if (reduce_x_max < reduce_x_min) { + ARCANE_FATAL("Bad patch X : no refine cell"); + } + reduce_x_max++; + UniqueArray tmp = m_sig_x.subView(reduce_x_min, reduce_x_max - reduce_x_min); + m_sig_x = tmp; + Int64x3 patch_min = m_patch.minPoint(); + Int64x3 patch_max = m_patch.maxPoint(); + patch_min.x += reduce_x_min; + patch_max.x = patch_min.x + (reduce_x_max - reduce_x_min); + m_patch.setMinPoint(patch_min); + m_patch.setMaxPoint(patch_max); + } + if (reduce_y_min != 0 || reduce_y_max != m_sig_y.size()-1) { + if (reduce_y_max < reduce_y_min) { + ARCANE_FATAL("Bad patch Y : no refine cell"); + } + reduce_y_max++; + UniqueArray tmp = m_sig_y.subView(reduce_y_min, reduce_y_max - reduce_y_min); + m_sig_y = tmp; + Int64x3 patch_min = m_patch.minPoint(); + Int64x3 patch_max = m_patch.maxPoint(); + patch_min.y += reduce_y_min; + patch_max.y = patch_min.y + (reduce_y_max - reduce_y_min); + m_patch.setMinPoint(patch_min); + m_patch.setMaxPoint(patch_max); + } + if (m_mesh->mesh()->dimension() == 3 && (reduce_z_min != 0 || reduce_z_max != m_sig_z.size() - 1)) { + if (reduce_z_max < reduce_z_min) { + ARCANE_FATAL("Bad patch Z : no refine cell"); + } + reduce_z_max++; + UniqueArray tmp = m_sig_z.subView(reduce_z_min, reduce_z_max - reduce_z_min); + m_sig_z = tmp; + Int64x3 patch_min = m_patch.minPoint(); + Int64x3 patch_max = m_patch.maxPoint(); + patch_min.z += reduce_z_min; + patch_max.z = patch_min.z + (reduce_z_max - reduce_z_min); + m_patch.setMinPoint(patch_min); + m_patch.setMaxPoint(patch_max); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPositionSignature:: +fillSig() +{ + m_sig_x.fill(0); + m_sig_y.fill(0); + m_sig_z.fill(0); + ENUMERATE_ (Cell, icell, m_mesh->mesh()->ownLevelCells(m_patch.level())) { + if (!icell->hasFlags(ItemFlags::II_Refine)) { + continue; + } + + Integer pos_x = m_numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = m_numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = m_numbering->cellUniqueIdToCoordZ(*icell); + + if ( + pos_x < m_patch.minPoint().x || pos_x >= m_patch.maxPoint().x || + pos_y < m_patch.minPoint().y || pos_y >= m_patch.maxPoint().y || + pos_z < m_patch.minPoint().z || pos_z >= m_patch.maxPoint().z) { + continue; + } + m_have_cells = true; + m_sig_x[pos_x - m_patch.minPoint().x]++; + m_sig_y[pos_y - m_patch.minPoint().y]++; + m_sig_z[pos_z - m_patch.minPoint().z]++; + } + + if (m_all_patches->maxLevel() > m_patch.level()) { + Int64x3 min = m_patch.minPoint(); + Integer nb_proc = m_mesh->mesh()->parallelMng()->commSize(); + Integer my_proc = m_mesh->mesh()->parallelMng()->commRank(); + + Integer base = m_sig_x.size() / nb_proc; + Integer reste = m_sig_x.size() % nb_proc; + Integer size = base + (my_proc < reste ? 1 : 0); + Integer begin = my_proc * base + std::min(my_proc, reste); + Integer end = begin + size; + + for (Integer k = 0; k < m_sig_z.size(); ++k) { + Integer pos_z = min.z + k; + for (Integer j = 0; j < m_sig_y.size(); ++j) { + Integer pos_y = min.y + j; + for (Integer i = begin; i < end; ++i) { + Integer pos_x = min.x + i; + for (auto elem : m_all_patches->patches(m_patch.level() + 1)) { + if (elem.isInWithMargin(m_patch.level(), pos_x, pos_y, pos_z)) { + m_have_cells = true; + m_sig_x[i]++; + m_sig_y[j]++; + m_sig_z[k]++; + break; + } + } + } + } + } + } + + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_x); + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_y); + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_z); + m_have_cells = m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, m_have_cells); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPositionSignature:: +isValid() const +{ + if (m_is_null) { + return false; + } + if (m_sig_x.size() < MIN_SIZE || m_sig_y.size() < MIN_SIZE || (m_mesh->mesh()->dimension() == 3 && m_sig_z.size() < MIN_SIZE)) { + return false; + } + return true; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPositionSignature:: +canBeCut() const +{ + m_mesh->traceMng()->info() << "canBeCut() -- m_sig_x.size : " << m_sig_x.size() + << " -- m_sig_y.size : " << m_sig_y.size() + << " -- m_sig_z.size : " << m_sig_z.size() + << " -- min = " << m_patch.minPoint() + << " -- max = " << m_patch.maxPoint() + << " -- length = " << m_patch.length() + << " -- isValid : " << isValid() + << " -- efficacity : " << efficacity() << " / " << TARGET_EFFICACITY + << " -- m_nb_cut : " << m_nb_cut << " / " << MAX_NB_CUT + << " -- m_stop_cut : " << m_stop_cut; + + if (!isValid()) { + return false; + } + + if (m_stop_cut) { + return false; + } + + if (efficacity() > TARGET_EFFICACITY) { + return false; + } + if (MAX_NB_CUT != -1 && m_nb_cut >= MAX_NB_CUT) { + return false; + } + return true; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPositionSignature:: +compute() +{ + m_mesh->traceMng()->info() << "Compute() -- Patch before compute : min = " << m_patch.minPoint() << " -- max = " << m_patch.maxPoint() << " -- length = " << m_patch.length(); + fillSig(); + //m_mesh->traceMng()->info() << "Compute() -- Signature : x = " << m_sig_x << " -- y = " << m_sig_y ; + compress(); + 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; + m_mesh->traceMng()->info() << "Compute() -- Patch computed : min = " << m_patch.minPoint() << " -- max = " << m_patch.maxPoint() << " -- length = " << m_patch.length(); + + m_is_computed = true; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Real AMRPatchPositionSignature:: +efficacity() const +{ + if (!m_is_computed) { + // Sans compression, pas terrible. + m_mesh->traceMng()->warning() << "Need to be computed"; + } + Integer sum = 0; + for (const Integer elem : m_sig_x) { + sum += elem; + } + + Real eff = static_cast(sum) / (m_sig_x.size() * m_sig_y.size() * m_sig_z.size()); + + if constexpr (TARGET_SIZE == -1 || TARGET_SIZE_WEIGHT_IN_EFFICACITY == 0) { + return eff; + } + + Real eff_xy = 0; + if (m_sig_x.size() <= TARGET_SIZE) { + eff_xy = static_cast(m_sig_x.size()) / TARGET_SIZE; + } + else if (m_sig_x.size() < TARGET_SIZE*2) { + Real size_x = math::abs(m_sig_x.size() - TARGET_SIZE*2); + eff_xy = size_x / TARGET_SIZE; + } + + if (m_sig_y.size() <= TARGET_SIZE) { + eff_xy += static_cast(m_sig_y.size()) / TARGET_SIZE; + } + else if (m_sig_y.size() < TARGET_SIZE * 2) { + Real size_y = math::abs(m_sig_y.size() - TARGET_SIZE * 2); + eff_xy += size_y / TARGET_SIZE; + } + + if (m_mesh->mesh()->dimension() == 2) { + eff_xy /= 2; + } + else { + if (m_sig_z.size() <= TARGET_SIZE) { + eff_xy = (eff_xy + (static_cast(m_sig_z.size()) / TARGET_SIZE)) / 3; + } + else if (m_sig_z.size() < TARGET_SIZE * 2) { + Real size_z = math::abs(m_sig_z.size() - TARGET_SIZE * 2); + eff_xy = (eff_xy + (size_z / TARGET_SIZE)) / 3; + } + else { + eff_xy /= 3; + } + } + eff_xy *= TARGET_SIZE_WEIGHT_IN_EFFICACITY; + + return (eff+eff_xy)/(1+TARGET_SIZE_WEIGHT_IN_EFFICACITY); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +std::pair AMRPatchPositionSignature:: +cut(Integer dim, Integer cut_point) const +{ + auto [fst, snd] = m_patch.cut(cut_point, dim); + return {AMRPatchPositionSignature(fst, m_mesh, m_all_patches, m_nb_cut+1), AMRPatchPositionSignature(snd, m_mesh, m_all_patches, m_nb_cut+1)}; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +bool AMRPatchPositionSignature:: +isIn(Integer x, Integer y, Integer z) const +{ + return m_patch.isIn(x, y, z); +} +ConstArrayView AMRPatchPositionSignature::sigX() const +{ + return m_sig_x; +} +ConstArrayView AMRPatchPositionSignature::sigY() const +{ + return m_sig_y; +} +ConstArrayView AMRPatchPositionSignature::sigZ() const +{ + return m_sig_z; +} +AMRPatchPosition AMRPatchPositionSignature::patch() const +{ + return m_patch; +} +ICartesianMesh* AMRPatchPositionSignature::mesh() const +{ + return m_mesh; +} +bool AMRPatchPositionSignature::stopCut() const +{ + return m_stop_cut; +} +void AMRPatchPositionSignature::setStopCut(bool stop_cut) +{ + m_stop_cut = stop_cut; +} +bool AMRPatchPositionSignature::isComputed() const +{ + return m_is_computed; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h new file mode 100644 index 0000000000..dcef338e89 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h @@ -0,0 +1,92 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionSignature.h (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURE_H +#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURE_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "AMRPatchPositionLevelGroup.h" +#include "ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +#include "arcane/utils/Vector3.h" +#include "arcane/utils/UniqueArray.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class AMRPatchPositionSignature +{ + public: + AMRPatchPositionSignature(); + AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches); + AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches, Integer nb_cut); + ~AMRPatchPositionSignature(); + + public: + void compress(); + void fillSig(); + bool isValid() const; + bool canBeCut() const; + void compute(); + Real efficacity() const; + std::pair cut(Integer dim, Integer cut_point) const; + bool isIn(Integer x, Integer y, Integer z) const; + + ConstArrayView sigX()const; + ConstArrayView sigY()const; + ConstArrayView sigZ() const; + AMRPatchPosition patch()const; + ICartesianMesh* mesh() const; + bool stopCut()const; + void setStopCut(bool stop_cut); + bool isComputed()const; + + + private: + + bool m_is_null; + AMRPatchPosition m_patch; + ICartesianMesh* m_mesh; + Integer m_nb_cut; + bool m_stop_cut; + + ICartesianMeshNumberingMng* m_numbering; + + + bool m_have_cells; + bool m_is_computed; + + UniqueArray m_sig_x; + UniqueArray m_sig_y; + UniqueArray m_sig_z; + + AMRPatchPositionLevelGroup* m_all_patches; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif + diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc new file mode 100644 index 0000000000..3828b21fae --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc @@ -0,0 +1,425 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionSignatureCut.cc (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPositionSignatureCut.h" + +#include "ICartesianMesh.h" +#include "arcane/core/ArcaneTypes.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/IParallelMng.h" +#include "arcane/core/ItemEnumerator.h" +#include "arcane/utils/FatalErrorException.h" +#include "arccore/trace/ITraceMng.h" +#include "internal/ICartesianMeshInternal.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +namespace +{ + constexpr Integer MIN_SIZE = 4; + constexpr Integer TARGET_SIZE = 8; + constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 0.5; + constexpr Integer MAX_NB_CUT = 5; + constexpr Real TARGET_EFFICACITY = 0.90; +} // namespace + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionSignatureCut:: +AMRPatchPositionSignatureCut() +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +AMRPatchPositionSignatureCut:: +~AMRPatchPositionSignatureCut() = default; + +Integer AMRPatchPositionSignatureCut:: +_cutDim(ConstArrayView sig) +{ + if (sig.size() < MIN_SIZE * 2) { + return -1; + } + + Integer cut_point = -1; + Integer mid = sig.size() / 2; + + { + for (Integer i = 0; i < sig.size(); ++i) { + if (sig[i] == 0) { + cut_point = i; + break; + } + } + + if (cut_point == 0) { + ARCANE_FATAL("Call compress before"); + } + if (cut_point != -1 && cut_point >= MIN_SIZE && sig.size() - cut_point >= MIN_SIZE) { + return cut_point; + } + } + + { + UniqueArray dsec_sig(sig.size(), 0); + + Integer max = -1; + for (Integer i = 1; i < dsec_sig.size() - 1; ++i) { + dsec_sig[i] = sig[i + 1] - 2 * sig[i] + sig[i - 1]; + Integer dif = math::abs(dsec_sig[i - 1] - dsec_sig[i]); + if (dif > max) { + cut_point = i; + max = dif; + } + else if (dif == max && math::abs(cut_point - mid) > math::abs(i - mid)) { + cut_point = i; + } + } + + if (cut_point != -1 && cut_point >= MIN_SIZE && sig.size() - cut_point >= MIN_SIZE) { + return cut_point; + } + } + + { + cut_point = mid; + + if (cut_point != -1 && cut_point >= MIN_SIZE && sig.size() - cut_point >= MIN_SIZE) { + return cut_point; + } + } + + return -1; +} + +std::pair AMRPatchPositionSignatureCut:: +cut(const AMRPatchPositionSignature& sig) +{ + Integer cut_point_x = _cutDim(sig.sigX()); + Integer cut_point_y = _cutDim(sig.sigY()); + Integer cut_point_z = (sig.mesh()->mesh()->dimension() == 2 ? -1 : _cutDim(sig.sigZ())); + + if (cut_point_x == -1 && cut_point_y == -1 && cut_point_z == -1) { + return {}; + } + if (cut_point_x != -1) { + cut_point_x += sig.patch().minPoint().x; + } + if (cut_point_y != -1) { + cut_point_y += sig.patch().minPoint().y; + } + if (cut_point_z != -1) { + cut_point_z += sig.patch().minPoint().z; + } + + if (cut_point_x != -1 && cut_point_y != -1 && cut_point_z != -1) { + Real x_efficacity = 0; + auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); + { + sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + + fst_x.compute(); + snd_x.compute(); + if (fst_x.isValid() && snd_x.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" + << " -- min = " << fst_x.patch().minPoint() + << " -- max = " << fst_x.patch().maxPoint() + << " -- efficacity : " << fst_x.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" + << " -- min = " << snd_x.patch().minPoint() + << " -- max = " << snd_x.patch().maxPoint() + << " -- efficacity : " << snd_x.efficacity(); + + x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + } + } + + Real y_efficacity = 0; + auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); + { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + + fst_y.compute(); + snd_y.compute(); + if (fst_y.isValid() && snd_y.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" + << " -- min = " << fst_y.patch().minPoint() + << " -- max = " << fst_y.patch().maxPoint() + << " -- efficacity : " << fst_y.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" + << " -- min = " << snd_y.patch().minPoint() + << " -- max = " << snd_y.patch().maxPoint() + << " -- efficacity : " << snd_y.efficacity(); + + y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + } + } + + Real z_efficacity = 0; + auto [fst_z, snd_z] = sig.cut(MD_DirZ, cut_point_z); + { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; + + fst_z.compute(); + snd_z.compute(); + if (fst_z.isValid() && snd_z.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- Z.fst_z" + << " -- min = " << fst_z.patch().minPoint() + << " -- max = " << fst_z.patch().maxPoint() + << " -- efficacity : " << fst_z.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- Z.snd_z" + << " -- min = " << snd_z.patch().minPoint() + << " -- max = " << snd_z.patch().maxPoint() + << " -- efficacity : " << snd_z.efficacity(); + + z_efficacity = (fst_z.efficacity() + snd_z.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + } + } + + if (sig.efficacity() > x_efficacity && sig.efficacity() > y_efficacity && sig.efficacity() > z_efficacity) { + return {}; + } + + if (x_efficacity >= y_efficacity && x_efficacity >= z_efficacity && x_efficacity != 0) { + return { fst_x, snd_x }; + } + if (y_efficacity >= x_efficacity && y_efficacity >= z_efficacity && y_efficacity != 0) { + return { fst_y, snd_y }; + } + if (z_efficacity == 0) { + ARCANE_FATAL("Invalid cut"); + } + return { fst_z, snd_z }; + } + + if (cut_point_x != -1 && cut_point_y != -1) { + Real x_efficacity = 0; + auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); + { + sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + + fst_x.compute(); + snd_x.compute(); + if (fst_x.isValid() && snd_x.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" + << " -- min = " << fst_x.patch().minPoint() + << " -- max = " << fst_x.patch().maxPoint() + << " -- efficacity : " << fst_x.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" + << " -- min = " << snd_x.patch().minPoint() + << " -- max = " << snd_x.patch().maxPoint() + << " -- efficacity : " << snd_x.efficacity(); + + x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + } + } + + Real y_efficacity = 0; + auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); + { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + + fst_y.compute(); + snd_y.compute(); + if (fst_y.isValid() && snd_y.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" + << " -- min = " << fst_y.patch().minPoint() + << " -- max = " << fst_y.patch().maxPoint() + << " -- efficacity : " << fst_y.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" + << " -- min = " << snd_y.patch().minPoint() + << " -- max = " << snd_y.patch().maxPoint() + << " -- efficacity : " << snd_y.efficacity(); + + y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + } + } + + if (sig.efficacity() > x_efficacity && sig.efficacity() > y_efficacity) { + return {}; + } + + if (x_efficacity >= y_efficacity && x_efficacity != 0) { + return { fst_x, snd_x }; + } + if (y_efficacity == 0) { + ARCANE_FATAL("Invalid cut"); + } + return { fst_y, snd_y }; + } + + if (cut_point_x != -1) { + Real x_efficacity = 0; + auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); + + sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + + fst_x.compute(); + snd_x.compute(); + if (fst_x.isValid() && snd_x.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.fst_x : " << fst_x.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.snd_x : " << snd_x.efficacity(); + x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + } + if (sig.efficacity() > x_efficacity) { + return {}; + } + return { fst_x, snd_x }; + } + + if (cut_point_y != -1) { + Real y_efficacity = 0; + auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); + + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + + fst_y.compute(); + snd_y.compute(); + if (fst_y.isValid() && snd_y.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.fst_y : " << fst_y.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.snd_y : " << snd_y.efficacity(); + y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + } + if (sig.efficacity() > y_efficacity) { + return {}; + } + return { fst_y, snd_y }; + } + if (cut_point_z != -1) { + Real z_efficacity = 0; + auto [fst_z, snd_z] = sig.cut(MD_DirZ, cut_point_z); + + sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; + + fst_z.compute(); + snd_z.compute(); + if (fst_z.isValid() && snd_z.isValid()) { + + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.fst_z : " << fst_z.efficacity(); + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.snd_z : " << snd_z.efficacity(); + z_efficacity = (fst_z.efficacity() + snd_z.efficacity()) / 2; + sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; + } + else { + sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + } + if (sig.efficacity() > z_efficacity) { + return {}; + } + return { fst_z, snd_z }; + } +} + +void AMRPatchPositionSignatureCut:: +cut(UniqueArray& sig_array_a) +{ + UniqueArray sig_array_b; + bool a_a_b_b = false; + bool need_cut = true; + + while (need_cut) { + need_cut = false; + a_a_b_b = !a_a_b_b; + + UniqueArray& array_in = a_a_b_b ? sig_array_a : sig_array_b; + UniqueArray& array_out = a_a_b_b ? sig_array_b : sig_array_a; + + for (Integer i = 0; i < array_in.size(); ++i) { + AMRPatchPositionSignature sig = array_in[i]; + sig.mesh()->traceMng()->info() << "Cut() -- i : " << i; + + if (!sig.stopCut()) { + if (!sig.isComputed()) { + sig.compute(); + } + if (sig.canBeCut()) { + auto [fst, snd] = cut(sig); + + if (fst.isValid()) { + need_cut = true; + array_out.add(fst); + array_out.add(snd); + sig.mesh()->traceMng()->info() << "First Signature :"; + sig.mesh()->traceMng()->info() << "\tmin = " << fst.patch().minPoint() << " -- max = " << fst.patch().maxPoint() << " -- length = " << fst.patch().length(); + sig.mesh()->traceMng()->info() << "Second Signature :"; + sig.mesh()->traceMng()->info() << "\tmin = " << snd.patch().minPoint() << " -- max = " << snd.patch().maxPoint() << " -- length = " << snd.patch().length(); + continue; + } + sig.mesh()->traceMng()->info() << "Invalid Signature"; + sig.setStopCut(true); + } + else { + sig.setStopCut(true); + } + } + sig.mesh()->traceMng()->info() << "No Update"; + sig.mesh()->traceMng()->info() << "\tmin = " << sig.patch().minPoint() << " -- max = " << sig.patch().maxPoint(); + array_out.add(sig); + } + array_in.clear(); + } + if (a_a_b_b) { + sig_array_a.clear(); + sig_array_a = sig_array_b; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h new file mode 100644 index 0000000000..6319d112d0 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h @@ -0,0 +1,56 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* AMRPatchPositionSignatureCut.h (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURECUT_H +#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURECUT_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "AMRPatchPositionLevelGroup.h" +#include "AMRPatchPositionSignature.h" +#include "ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +#include "arcane/utils/Vector3.h" +#include "arcane/utils/UniqueArray.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class AMRPatchPositionSignatureCut +{ + public: + AMRPatchPositionSignatureCut(); + ~AMRPatchPositionSignatureCut(); + + public: + static Integer _cutDim(ConstArrayView sig); + static std::pair cut(const AMRPatchPositionSignature& sig); + static void cut(UniqueArray& sig_array_a); +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif + diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index a6045af60e..95ea83177d 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -193,6 +193,8 @@ class CartesianMeshImpl void coarseZone3D(Real3 position, Real3 length) override; void coarseZone(const AMRZonePosition& position) override; + void refine() override; + Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override; void mergePatches() override; @@ -333,6 +335,7 @@ _saveInfosInProperties() if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.cartesianMeshNumberingMng()->_saveInfosInProperties(); + m_internal_api.cartesianMeshNumberingMng()->printStatus(); } } @@ -744,6 +747,17 @@ coarseZone(const AMRZonePosition& position) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshImpl:: +refine() +{ + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_patch_group.refine(); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Integer CartesianMeshImpl:: reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) { @@ -1082,6 +1096,10 @@ renumberItemsUniqueId(const CartesianMeshRenumberingInfo& v) if (face_method==1) ARCANE_THROW(NotImplementedException,"Method 1 for face renumbering"); + if (face_method != 0 && m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Face renumbering is not compatible with this type of AMR"); + } + // Regarde ensuite les patchs si demandé. Int32 patch_method = v.renumberPatchMethod(); if (patch_method < 0 || patch_method > 4) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index 3324daff44..f9a2d80de1 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -274,7 +274,14 @@ updateFirstLevel() m_min_level += nb_levels_to_add; const Integer to_div = m_pattern * nb_levels_to_add; - m_nb_cell_ground /= to_div; + if (m_dimension == 2) { + m_nb_cell_ground.x /= to_div; + m_nb_cell_ground.y /= to_div; + // z reste à 1. + } + else { + m_nb_cell_ground /= to_div; + } // ---------- // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index c27ab90e0b..2df9c33b4b 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -12,6 +12,9 @@ #include "arcane/cartesianmesh/CartesianPatchGroup.h" +#include "AMRPatchPositionLevelGroup.h" +#include "AMRPatchPositionSignature.h" +#include "AMRPatchPositionSignatureCut.h" #include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" #include "arcane/utils/ITraceMng.h" @@ -24,6 +27,7 @@ #include "arcane/cartesianmesh/internal/CartesianMeshPatch.h" #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" +#include "arccore/base/StringBuilder.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -417,6 +421,219 @@ mergePatches() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +refine() +{ + Integer min_level = 0; + Integer max_level = -1; + + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { + if (icell->hasFlags(ItemFlags::II_Refine)) { + Integer level = icell->level(); + if (level > max_level) + max_level = level; + } + } + max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max_level); + + m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << max_level; + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + + AMRPatchPositionLevelGroup all_patches(max_level); + + for (Integer level = max_level; level >= min_level; --level) { + if (level != max_level) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { + if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) { + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + for (auto patch : all_patches.patches(level)) { + if (patch.isInWithMargin(level, pos_x, pos_y, pos_z)) { + icell->mutableItemBase().removeFlags(ItemFlags::II_Refine); + } + } + } + } + m_cmesh->traceMng()->info() << "All patch level+1 with margin (can be overlap) : "; + for (auto& elem : all_patches.patches(level + 1)) { + m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.minWithMargin(level) << " -- max = " << elem.maxWithMargin(level); + } + } + + AMRPatchPosition all_level; + all_level.setLevel(level); + all_level.setMinPoint({ 0, 0, 0 }); + all_level.setMaxPoint({ static_cast(numbering->globalNbCellsX(level)), static_cast(numbering->globalNbCellsY(level)), static_cast(numbering->globalNbCellsZ(level)) }); + + AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches); + UniqueArray sig_array; + sig_array.add(sig); + + AMRPatchPositionSignatureCut::cut(sig_array); + + for (const auto& elem : sig_array) { + all_patches.addPatch(elem.patch()); + } + + Real global_efficacity = 0; + m_cmesh->traceMng()->info() << "All patch : "; + for (auto& elem : sig_array) { + m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.patch().minPoint() << " -- max = " << elem.patch().maxPoint() << " -- Efficacité : " << elem.efficacity(); + global_efficacity += elem.efficacity(); + } + global_efficacity /= sig_array.size(); + m_cmesh->traceMng()->info() << "Global efficacity : " << global_efficacity; + + StringBuilder str = ""; + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { + if (icell->level() != level) + continue; + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + Integer patch = -1; + for (Integer i = 0; i < sig_array.size(); ++i) { + const AMRPatchPositionSignature& elem = sig_array[i]; + if (elem.isIn(pos_x, pos_y, pos_z)) { + if (patch != -1) { + ARCANE_FATAL("ABCDEFG -- old : {0} -- new : {1}", patch, i); + } + patch = i; + } + } + if (patch == -1 && icell->hasFlags(ItemFlags::II_Refine)) { + ARCANE_FATAL("Bad Patch"); + } + + if (pos_x == 0) { + str += "\n"; + } + if (patch != -1) { + str += "["; + if (patch < 10) { + str += " "; + } + str += patch; + str += "]"; + } + else { + str += "[..]"; + } + } + m_cmesh->traceMng()->info() << str; + } + + auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng(); + + { + constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine | + ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined | + ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { + icell->mutableItemBase().removeFlags(flags_to_remove); + } + } + + for (Integer i = 1; i < m_amr_patches.size(); ++i) { + _removeOnePatch(i); + } + applyPatchEdit(false); + + for (Integer level = min_level; level <= max_level; ++level) { + + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { + if (!icell->hasHChildren()) { + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + for (const AMRPatchPosition& patch : all_patches.patches(level)) { + if (patch.isIn(pos_x, pos_y, pos_z)) { + icell->mutableItemBase().addFlags(ItemFlags::II_Refine); + } + } + } + } + + Integer nb_cell_x = numbering->globalNbCellsX(level); + + StringBuilder str = "Level "; + str += level; + str += "\n"; + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level)) { + if (icell->uniqueId().asInt32() % nb_cell_x == 0) { + str += "\n"; + } + if (icell->hasFlags(ItemFlags::II_Refine)) { + str += "[++]"; + } + else { + str += "[..]"; + } + } + m_cmesh->traceMng()->info() << str; + + amr->refine(); + + for (const AMRPatchPosition& patch : all_patches.patches(level)) { + _addPatch(patch.patchUp()); + } + } + + for (Integer level = max_level; level > min_level; --level) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + bool is_in = false; + for (auto patch : all_patches.patches(level)) { + if (patch.isInWithMarginEven(level, pos_x, pos_y, pos_z)) { + is_in = true; + break; + } + } + if (!is_in) { + icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen); + } + } + + Integer nb_cell_x = numbering->globalNbCellsX(level); + + StringBuilder str = "Level "; + str += level; + str += "\n"; + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level)) { + if (icell->uniqueId().asInt32() % nb_cell_x == 0) { + str += "\n"; + } + if (icell->hasFlags(ItemFlags::II_Coarsen)) { + str += "[--]"; + } + else { + str += "[..]"; + } + } + m_cmesh->traceMng()->info() << str; + + amr->coarsen(true); + } + m_cmesh->computeDirections(); + + m_cmesh->traceMng()->info() << "NbPatch : " << m_cmesh->patches().size(); + + for (Integer i = 0; i < m_cmesh->patches().size(); ++i) { + auto patch = m_cmesh->amrPatch(i); + m_cmesh->traceMng()->info() << "Patch #" << i; + m_cmesh->traceMng()->info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); + m_cmesh->traceMng()->info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); + m_cmesh->traceMng()->info() << "\tLevel : " << patch.patchInterface()->position().level(); + m_cmesh->traceMng()->info() << "\tNbCells : " << patch.patchInterface()->cells().size(); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _addPatchInstance(Ref v) { @@ -771,8 +988,6 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ if (parent_patch_cell_group.null()) ARCANE_FATAL("Null cell group"); - // TODO : Le nextIndexForNewPatch() actuel ne fonctionnera pas si on s'amuse à créer, détruire et recréer des patchs ! - // TODO : Attribut que l'on incrémente de 1 lors de la création d'un patch. IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); Integer index = nextIndexForNewPatch(); String parent_group_name = String("CartesianMeshPatchParentCells") + index; @@ -804,6 +1019,43 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +_addPatch(const AMRPatchPosition& new_patch_position) +{ + UniqueArray cells_local_id; + + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) { + Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); + Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); + Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); + if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { + cells_local_id.add(icell.localId()); + } + } + + if (cells_local_id.empty()) { + return; + } + + IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); + Integer index = nextIndexForNewPatch(); + String parent_group_name = String("CartesianMeshPatchParentCells") + index; + + auto* cdi = new CartesianMeshPatch(m_cmesh, index + 1); + cdi->position().setLevel(new_patch_position.level()); + cdi->position().setMinPoint(new_patch_position.minPoint()); + cdi->position().setMaxPoint(new_patch_position.maxPoint()); + + _addPatchInstance(makeRef(cdi)); + + CellGroup parent_cells = cell_family->createGroup(parent_group_name, cells_local_id, true); + m_amr_patch_cell_groups.add(parent_cells); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h index c11b17c5d3..558a5cf86c 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h @@ -66,6 +66,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void mergePatches(); + void refine(); + private: void _addPatchInstance(Ref v); @@ -77,6 +79,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup bool _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPosition& patch_position1); void _splitPatch(Integer index_patch, const AMRPatchPosition& patch_position); void _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group); + void _addPatch(const AMRPatchPosition& new_patch_position); private: diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h index a93a469926..5f6871856e 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h @@ -233,6 +233,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh */ virtual void coarseZone(const AMRZonePosition& position) = 0; + virtual void refine() = 0; + /*! * \brief Méthode permettant de supprimer une ou plusieurs couches * de mailles fantômes sur un niveau de raffinement défini. diff --git a/arcane/src/arcane/cartesianmesh/srcs.cmake b/arcane/src/arcane/cartesianmesh/srcs.cmake index eb84e54a49..24db47c9e4 100644 --- a/arcane/src/arcane/cartesianmesh/srcs.cmake +++ b/arcane/src/arcane/cartesianmesh/srcs.cmake @@ -51,4 +51,10 @@ set(ARCANE_SOURCES AMRZonePosition.h AMRPatchPosition.h AMRPatchPosition.cc + AMRPatchPositionLevelGroup.h + AMRPatchPositionLevelGroup.cc + AMRPatchPositionSignature.h + AMRPatchPositionSignature.cc + AMRPatchPositionSignatureCut.h + AMRPatchPositionSignatureCut.cc ) From d472862c4d9815c7df2800b986e4b52963edd605 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Thu, 13 Nov 2025 16:12:58 +0100 Subject: [PATCH 07/19] [arcane:cartesianmesh] Reuse old patches groups to build new patches --- .../AMRPatchPositionSignature.cc | 12 +- .../AMRPatchPositionSignatureCut.cc | 8 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 47 +++--- .../cartesianmesh/CartesianMeshPatch.cc | 1 + .../cartesianmesh/CartesianPatchGroup.cc | 148 +++++++++++++++--- .../cartesianmesh/CartesianPatchGroup.h | 14 +- 6 files changed, 171 insertions(+), 59 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc index fe69e9c6e7..b13b8d4456 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc @@ -30,12 +30,12 @@ namespace Arcane namespace { -constexpr Integer MIN_SIZE = 4; -constexpr Integer TARGET_SIZE = 8; -constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 0.5; -constexpr Integer MAX_NB_CUT = 5; -constexpr Real TARGET_EFFICACITY = 0.90; -} +constexpr Integer MIN_SIZE = 1; + constexpr Integer TARGET_SIZE = 8; + constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 1; + constexpr Integer MAX_NB_CUT = 6; + constexpr Real TARGET_EFFICACITY = 1.0; +} // namespace /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc index 3828b21fae..98ff90f6ce 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc @@ -30,11 +30,11 @@ namespace Arcane namespace { - constexpr Integer MIN_SIZE = 4; + constexpr Integer MIN_SIZE = 1; constexpr Integer TARGET_SIZE = 8; - constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 0.5; - constexpr Integer MAX_NB_CUT = 5; - constexpr Real TARGET_EFFICACITY = 0.90; + constexpr Real TARGET_SIZE_WEIGHT_IN_EFFICACITY = 1; + constexpr Integer MAX_NB_CUT = 6; + constexpr Real TARGET_EFFICACITY = 1.0; } // namespace /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 95ea83177d..da5d68ed60 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -244,7 +244,7 @@ class CartesianMeshImpl NodeGroup all_nodes); void _applyRefine(const AMRZonePosition &position); void _applyCoarse(const AMRZonePosition& zone_position); - void _addPatch(const CellGroup& parent_cells); + void _addPatch(ConstArrayView parent_cells); void _saveInfosInProperties(); std::tuple @@ -333,6 +333,13 @@ _saveInfosInProperties() } m_properties->set("PatchGroupNames",patch_group_names); + // TODO : Trouver une autre façon de gérer ça. + // Dans le cas d'une protection reprise, le tableau m_available_index + // ne peut pas être correctement recalculé à cause des éléments après + // le "index max" des "index actif". Ces éléments "en trop" ne + // peuvent pas être retrouvés sans plus d'infos. + m_properties->set("PatchGroupNamesAvailable", m_patch_group.availableGroupIndex()); + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.cartesianMeshNumberingMng()->_saveInfosInProperties(); m_internal_api.cartesianMeshNumberingMng()->printStatus(); @@ -365,12 +372,15 @@ recreateFromDump() m_patch_group.clear(); m_all_items_direction_info = m_patch_group.groundPatch(); IItemFamily* cell_family = m_mesh->cellFamily(); - for( const String& x : patch_group_names ){ + for (const String& x : patch_group_names) { CellGroup group = cell_family->findGroup(x); if (group.null()) ARCANE_FATAL("Can not find cell group '{0}'",x); - m_patch_group.addPatch(group); + m_patch_group.addPatchAfterRestore(group); } + UniqueArray available_index; + m_properties->get("PatchGroupNamesAvailable", available_index); + m_patch_group.rebuildAvailableGroupIndex(available_index); computeDirections(); } @@ -931,12 +941,7 @@ void CartesianMeshImpl:: _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id) { m_patch_group.updateLevelsBeforeAddGroundPatch(); - - IItemFamily* cell_family = m_mesh->cellFamily(); - Integer index = m_patch_group.nextIndexForNewPatch(); - String parent_group_name = String("CartesianMeshPatchParentCells")+index; - CellGroup parent_cells = cell_family->createGroup(parent_group_name,parent_cells_local_id,true); - _addPatch(parent_cells); + _addPatch(parent_cells_local_id); } /*---------------------------------------------------------------------------*/ @@ -945,24 +950,22 @@ _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id) * \brief Créé un patch avec tous les enfants du groupe \a parent_cells. */ void CartesianMeshImpl:: -_addPatch(const CellGroup& parent_cells) +_addPatch(ConstArrayView parent_cells) { - Integer index = m_patch_group.nextIndexForNewPatch(); - info() << "Add patch index : " << index; // Créé le groupe contenant les mailles AMR // Il s'agit des mailles filles de \a parent_cells - String children_group_name = String("CartesianMeshPatchCells")+index; + UniqueArray children_local_id; - ENUMERATE_(Cell,icell,parent_cells){ - Cell c = *icell; - for(Integer k=0; kcellFamily()); + for (Int32 cell_local_id : parent_cells) { + Cell c = cells[cell_local_id]; + for (Integer k = 0; k < c.nbHChildren(); ++k) { Cell child = c.hChild(k); children_local_id.add(child.localId()); } } - IItemFamily* cell_family = m_mesh->cellFamily(); - CellGroup children_cells = cell_family->createGroup(children_group_name, children_local_id, true); - m_patch_group.addPatch(children_cells); + + m_patch_group.addPatch(children_local_id); } /*---------------------------------------------------------------------------*/ @@ -974,12 +977,8 @@ _applyRefine(const AMRZonePosition& position) UniqueArray cells_local_id; position.cellsInPatch(mesh(), cells_local_id); - IItemFamily* cell_family = m_mesh->cellFamily(); Integer nb_cell = cells_local_id.size(); info(4) << "Local_NbCellToRefine = " << nb_cell; - Integer index = m_patch_group.nextIndexForNewPatch(); - String parent_group_name = String("CartesianMeshPatchParentCells")+index; - CellGroup parent_cells = cell_family->createGroup(parent_group_name,cells_local_id,true); IParallelMng* pm = m_mesh->parallelMng(); Int64 total_nb_cell = pm->reduce(Parallel::ReduceSum,nb_cell); @@ -1009,7 +1008,7 @@ _applyRefine(const AMRZonePosition& position) MeshStats ms(traceMng(),m_mesh,m_mesh->parallelMng()); ms.dumpStats(); } - _addPatch(parent_cells); + _addPatch(cells_local_id); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc index 23188142fc..1d987cecd5 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc @@ -34,6 +34,7 @@ CartesianMeshPatch:: CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index) : TraceAccessor(cmesh->traceMng()) , m_mesh(cmesh) +, m_amr_patch_index(patch_index) { Integer nb_dir = cmesh->mesh()->dimension(); for( Integer i=0; i cells_local_id) +{ + Integer index = _nextIndexForNewPatch(); + String children_group_name = String("CartesianMeshPatchCells") + index; + IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); + CellGroup children_cells = cell_family->createGroup(children_group_name, cells_local_id, true); + addPatch(children_cells, index); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +// Il faut appeler rebuildAvailableIndex() après les appels à cette méthode. +Integer CartesianPatchGroup:: +addPatchAfterRestore(CellGroup cell_group) +{ + const String& name = cell_group.name(); + Integer group_index = -1; + if (name.startsWith("CartesianMeshPatchCells")) { + String index_str = name.substring(23); + group_index = std::stoi(index_str.localstr()); + } + // Ancien checkpoint. + else if (name.startsWith("CartesianMeshPatchParentCells")) { + String index_str = name.substring(29); + group_index = std::stoi(index_str.localstr()); + } + else { + ARCANE_FATAL("Invalid group"); + } + + addPatch(cell_group, group_index); + return group_index; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianPatchGroup:: +addPatch(CellGroup cell_group, Integer group_index) { _createGroundPatch(); if (cell_group.null()) ARCANE_FATAL("Null cell group"); - Integer index = nextIndexForNewPatch(); - auto* cdi = new CartesianMeshPatch(m_cmesh, index); + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); m_amr_patch_cell_groups.add(cell_group); _addPatchInstance(makeRef(cdi)); - m_cmesh->traceMng()->info() << "m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + m_cmesh->traceMng()->info() << "addPatch()" + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() << " -- m_amr_patches : " << m_amr_patches.size() << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() - << " -- index : " << index - 1 - << " -- cell_group name : " << m_amr_patch_cell_groups[index - 1].name(); // m_index_new_patches commence par 1, pas le tableau m_amr_patch_cell_groups + << " -- group_index : " << group_index + << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); @@ -199,7 +238,7 @@ clear() m_amr_patch_cell_groups.clear(); m_amr_patches_pointer.clear(); m_amr_patches.clear(); - m_index_new_patches = 0; + m_index_new_patches = 1; _createGroundPatch(); } @@ -331,9 +370,14 @@ updateLevelsBeforeAddGroundPatch() /*---------------------------------------------------------------------------*/ Integer CartesianPatchGroup:: -nextIndexForNewPatch() +_nextIndexForNewPatch() { - return m_index_new_patches; + if (!m_available_group_index.empty()) { + const Integer elem = m_available_group_index.back(); + m_available_group_index.popBack(); + return elem; + } + return m_index_new_patches++; } /*---------------------------------------------------------------------------*/ @@ -535,9 +579,10 @@ refine() } } - for (Integer i = 1; i < m_amr_patches.size(); ++i) { - _removeOnePatch(i); - } + // for (Integer i = 1; i < m_amr_patches.size(); ++i) { + // _removeOnePatch(i); + // } + _removeAllPatches(); applyPatchEdit(false); for (Integer level = min_level; level <= max_level; ++level) { @@ -619,6 +664,13 @@ refine() } m_cmesh->computeDirections(); + { + constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { + icell->mutableItemBase().removeFlags(flags_to_remove); + } + } + m_cmesh->traceMng()->info() << "NbPatch : " << m_cmesh->patches().size(); for (Integer i = 0; i < m_cmesh->patches().size(); ++i) { @@ -634,12 +686,29 @@ refine() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +rebuildAvailableGroupIndex(ConstArrayView available_group_index) +{ + m_available_group_index = available_group_index; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +ConstArrayView CartesianPatchGroup:: +availableGroupIndex() +{ + return m_available_group_index; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _addPatchInstance(Ref v) { m_amr_patches.add(v); m_amr_patches_pointer.add(v.get()); - m_index_new_patches++; } /*---------------------------------------------------------------------------*/ @@ -648,6 +717,10 @@ _addPatchInstance(Ref v) void CartesianPatchGroup:: _removeOnePatch(Integer index) { + m_available_group_index.add(m_amr_patches[index]->index()); + m_cmesh->traceMng()->info() << "_removeOnePatch() -- Save group_index : " << m_available_group_index.back(); + + m_amr_patch_cell_groups[index - 1].clear(); m_amr_patch_cell_groups.remove(index - 1); m_amr_patches_pointer.remove(index); m_amr_patches.remove(index); @@ -670,6 +743,25 @@ _removeMultiplePatches(ConstArrayView indexes) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +_removeAllPatches() +{ + Ref ground_patch = m_amr_patches.front(); + + m_amr_patch_cell_groups.clear(); + m_amr_patches_pointer.clear(); + m_amr_patches.clear(); + m_available_group_index.clear(); + m_patches_to_delete.clear(); + m_index_new_patches = 1; + + m_amr_patches.add(ground_patch); + m_amr_patches_pointer.add(ground_patch.get()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _createGroundPatch() { @@ -989,10 +1081,10 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ ARCANE_FATAL("Null cell group"); IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); - Integer index = nextIndexForNewPatch(); - String parent_group_name = String("CartesianMeshPatchParentCells") + index; + Integer group_index = _nextIndexForNewPatch(); + String patch_group_name = String("CartesianMeshPatchCells") + group_index; - auto* cdi = new CartesianMeshPatch(m_cmesh, index + 1); + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); _addPatchInstance(makeRef(cdi)); @@ -1012,8 +1104,14 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ } } - CellGroup parent_cells = cell_family->createGroup(parent_group_name, cells_local_id, true); + CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); m_amr_patch_cell_groups.add(parent_cells); + + m_cmesh->traceMng()->info() << "_addCutPatch()" + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patches : " << m_amr_patches.size() + << " -- group_index : " << group_index + << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); } /*---------------------------------------------------------------------------*/ @@ -1039,18 +1137,24 @@ _addPatch(const AMRPatchPosition& new_patch_position) } IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); - Integer index = nextIndexForNewPatch(); - String parent_group_name = String("CartesianMeshPatchParentCells") + index; + Integer group_index = _nextIndexForNewPatch(); + String patch_group_name = String("CartesianMeshPatchCells") + group_index; - auto* cdi = new CartesianMeshPatch(m_cmesh, index + 1); + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); cdi->position().setLevel(new_patch_position.level()); cdi->position().setMinPoint(new_patch_position.minPoint()); cdi->position().setMaxPoint(new_patch_position.maxPoint()); _addPatchInstance(makeRef(cdi)); - CellGroup parent_cells = cell_family->createGroup(parent_group_name, cells_local_id, true); + CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); m_amr_patch_cell_groups.add(parent_cells); + + m_cmesh->traceMng()->info() << "_addPatch()" + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patches : " << m_amr_patches.size() + << " -- group_index : " << group_index + << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h index 558a5cf86c..22b140c7f5 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h @@ -40,7 +40,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup Ref groundPatch(); - void addPatch(CellGroup cell_group); + void addPatch(ConstArrayView cells_local_id); + Integer addPatchAfterRestore(CellGroup cell_group); + void addPatch(CellGroup cell_group, Integer group_index); Integer nbPatch() const; @@ -62,18 +64,23 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void updateLevelsBeforeAddGroundPatch(); - Integer nextIndexForNewPatch(); - void mergePatches(); void refine(); + void rebuildAvailableGroupIndex(ConstArrayView available_group_index); + + ConstArrayView availableGroupIndex(); + private: + Integer _nextIndexForNewPatch(); + void _addPatchInstance(Ref v); void _removeOnePatch(Integer index); void _removeMultiplePatches(ConstArrayView indexes); + void _removeAllPatches(); void _createGroundPatch(); bool _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPosition& patch_position1); @@ -89,6 +96,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup ICartesianMesh* m_cmesh; UniqueArray m_patches_to_delete; Int32 m_index_new_patches; + UniqueArray m_available_group_index; }; /*---------------------------------------------------------------------------*/ From 57ce48d0cb9d64ebf317b6eac68c2854205dcd15 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Fri, 14 Nov 2025 12:23:43 +0100 Subject: [PATCH 08/19] [arcane:cartesianmesh] Move merge method in AMRPatchPositionLevelGroup --- .../AMRPatchPositionLevelGroup.cc | 74 +++++++++++++++++++ .../AMRPatchPositionLevelGroup.h | 2 + .../cartesianmesh/CartesianPatchGroup.cc | 51 +------------ 3 files changed, 78 insertions(+), 49 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc index 33529d8300..5874a8730c 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc @@ -69,6 +69,80 @@ addPatch(AMRPatchPosition patch) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void AMRPatchPositionLevelGroup:: +fusionPatches(Integer level) +{ + fusionPatches(m_patches[level], true); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPositionLevelGroup:: +fusionPatches(UniqueArray& patch_position, bool remove_null) +{ + // Algo de fusion. + // D'abord, on trie les patchs du plus petit nb de mailles au plus grand nb de mailles (optionnel). + // Ensuite, pour chaque patch, on regarde si l'on peut le fusionner avec un autre. + // Si on arrive à faire une fusion, on recommence l'algo jusqu'à ne plus pouvoir fusionner. + bool fusion = true; + while (fusion) { + fusion = false; + + std::sort(patch_position.begin(), patch_position.end(), + [](const AMRPatchPosition& a, const AMRPatchPosition& b) { + return a.nbCells() < b.nbCells(); + }); + + for (Integer p0 = 0; p0 < patch_position.size(); ++p0) { + AMRPatchPosition& patch_fusion_0 = patch_position[p0]; + if (patch_fusion_0.isNull()) + continue; + + // Si une fusion a déjà eu lieu, on doit alors regarder les patchs avant "p0" + // (vu qu'il y en a au moins un qui a été modifié). + // (une "optimisation" pourrait être de récupérer la position du premier + // patch fusionné mais bon, moins lisible + pas beaucoup de patchs). + Integer p1 = (fusion ? 0 : p0 + 1); + for (; p1 < patch_position.size(); ++p1) { + if (p1 == p0) + continue; + + AMRPatchPosition& patch_fusion_1 = patch_position[p1]; + + if (patch_fusion_1.isNull()) + continue; + + // m_cmesh->traceMng()->info() << "\tCheck fusion" + // << " -- 0 Min point : " << patch_fusion_0.minPoint() + // << " -- 0 Max point : " << patch_fusion_0.maxPoint() + // << " -- 0 Level : " << patch_fusion_0.level() + // << " -- 1 Min point : " << patch_fusion_1.minPoint() + // << " -- 1 Max point : " << patch_fusion_1.maxPoint() + // << " -- 1 Level : " << patch_fusion_1.level(); + if (patch_fusion_0.canBeFusion(patch_fusion_1)) { + // m_cmesh->traceMng()->info() << "Fusion OK"; + patch_fusion_0.fusion(patch_fusion_1); + patch_fusion_1.setLevel(-2); // Devient null. + fusion = true; + break; + } + } + } + } + if (remove_null) { + for (Integer i = 0; i < patch_position.size(); ++i) { + if (patch_position[i].isNull()) { + patch_position.remove(i); + i--; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h index 23b339e711..11a78c82f6 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h @@ -40,6 +40,8 @@ class AMRPatchPositionLevelGroup Integer maxLevel(); ConstArrayView patches(Integer level); void addPatch(AMRPatchPosition patch); + void fusionPatches(Integer level); + static void fusionPatches(UniqueArray& patch_position, bool remove_null); private: Integer m_max_level; diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index 8e7a59731a..cceebdaa7c 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -586,6 +586,7 @@ refine() applyPatchEdit(false); for (Integer level = min_level; level <= max_level; ++level) { + all_patches.fusionPatches(level); ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { if (!icell->hasHChildren()) { @@ -1003,55 +1004,7 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) } } - // Algo de fusion. - // D'abord, on trie les patchs du plus petit nb de mailles au plus grand nb de mailles (optionnel). - // Ensuite, pour chaque patch, on regarde si l'on peut le fusionner avec un autre. - // Si on arrive à faire une fusion, on recommence l'algo jusqu'à ne plus pouvoir fusionner. - bool fusion = true; - while (fusion) { - fusion = false; - - std::sort(new_patch_out.begin(), new_patch_out.end(), - [](const AMRPatchPosition& a, const AMRPatchPosition& b) { - return a.nbCells() < b.nbCells(); - }); - - for (Integer p0 = 0; p0 < new_patch_out.size(); ++p0) { - AMRPatchPosition& patch_fusion_0 = new_patch_out[p0]; - if (patch_fusion_0.isNull()) - continue; - - // Si une fusion a déjà eu lieu, on doit alors regarder les patchs avant "p0" - // (vu qu'il y en a au moins un qui a été modifié). - // (une "optimisation" pourrait être de récupérer la position du premier - // patch fusionné mais bon, moins lisible + pas beaucoup de patchs). - Integer p1 = (fusion ? 0 : p0 + 1); - for (; p1 < new_patch_out.size(); ++p1) { - if (p1 == p0) - continue; - - AMRPatchPosition& patch_fusion_1 = new_patch_out[p1]; - - if (patch_fusion_1.isNull()) - continue; - - // m_cmesh->traceMng()->info() << "\tCheck fusion" - // << " -- 0 Min point : " << patch_fusion_0.minPoint() - // << " -- 0 Max point : " << patch_fusion_0.maxPoint() - // << " -- 0 Level : " << patch_fusion_0.level() - // << " -- 1 Min point : " << patch_fusion_1.minPoint() - // << " -- 1 Max point : " << patch_fusion_1.maxPoint() - // << " -- 1 Level : " << patch_fusion_1.level(); - if (patch_fusion_0.canBeFusion(patch_fusion_1)) { - // m_cmesh->traceMng()->info() << "Fusion OK"; - patch_fusion_0.fusion(patch_fusion_1); - patch_fusion_1.setLevel(-2); // Devient null. - fusion = true; - break; - } - } - } - } + AMRPatchPositionLevelGroup::fusionPatches(new_patch_out, false); // On ajoute les nouveaux patchs dans la liste des patchs. Integer d_nb_patch_final = 0; From cfba9755e28168f7b6b0b942c67ce66a4272d017 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Mon, 17 Nov 2025 15:12:12 +0100 Subject: [PATCH 09/19] [arcane:cartesianmesh] Add overlap cells layer around patches And fix 2D patchUp() method - Managing overlap node and face --- .../arcane/cartesianmesh/AMRPatchPosition.cc | 207 +++++----------- .../arcane/cartesianmesh/AMRPatchPosition.h | 26 +- .../AMRPatchPositionSignature.cc | 8 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 47 ++-- .../cartesianmesh/CartesianMeshPatch.cc | 8 + .../arcane/cartesianmesh/CartesianPatch.cc | 6 + .../src/arcane/cartesianmesh/CartesianPatch.h | 1 + .../cartesianmesh/CartesianPatchGroup.cc | 229 +++++++++++++++--- .../cartesianmesh/CartesianPatchGroup.h | 22 ++ .../arcane/cartesianmesh/CellDirectionMng.cc | 29 ++- .../arcane/cartesianmesh/CellDirectionMng.h | 2 +- .../arcane/cartesianmesh/FaceDirectionMng.cc | 42 ++-- .../cartesianmesh/ICartesianMeshPatch.h | 1 + .../arcane/cartesianmesh/NodeDirectionMng.cc | 31 ++- .../internal/CartesianMeshPatch.h | 1 + 15 files changed, 418 insertions(+), 242 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc index 61ff01f540..a966346e57 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -31,8 +31,20 @@ namespace Arcane AMRPatchPosition:: AMRPatchPosition() : m_level(-2) +, m_overlap_layer_size(0) { +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +AMRPatchPosition:: +AMRPatchPosition(const AMRPatchPosition& src) +: m_level(src.level()) +, m_min_point(src.minPoint()) +, m_max_point(src.maxPoint()) +, m_overlap_layer_size(src.overlapLayerSize()) +{ } /*---------------------------------------------------------------------------*/ @@ -99,6 +111,42 @@ setMaxPoint(Int64x3 max_point) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +Integer AMRPatchPosition:: +overlapLayerSize() const +{ + return m_overlap_layer_size; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void AMRPatchPosition:: +setOverlapLayerSize(Integer layer_size) +{ + m_overlap_layer_size = layer_size; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +minPointWithOverlap() const +{ + return m_min_point - m_overlap_layer_size; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 AMRPatchPosition:: +maxPointWithOverlap() const +{ + return m_max_point + m_overlap_layer_size; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + bool AMRPatchPosition:: isIn(Int64 x, Int64 y, Int64 z) const { @@ -136,15 +184,11 @@ cut(Int64 cut_point, Integer dim) const patch_min_cut.z = cut_point; } - AMRPatchPosition p0; - p0.setLevel(m_level); - p0.setMinPoint(m_min_point); + AMRPatchPosition p0(*this); p0.setMaxPoint(patch_max_cut); - AMRPatchPosition p1; - p1.setLevel(m_level); + AMRPatchPosition p1(*this); p1.setMinPoint(patch_min_cut); - p1.setMaxPoint(m_max_point); return { p0, p1 }; } @@ -215,12 +259,18 @@ isNull() const /*---------------------------------------------------------------------------*/ AMRPatchPosition AMRPatchPosition:: -patchUp() const +patchUp(Integer dim) const { AMRPatchPosition p; p.setLevel(m_level + 1); p.setMinPoint(m_min_point * 2); - p.setMaxPoint(m_max_point * 2); + if (dim == 2) { + p.setMaxPoint({ m_max_point.x * 2, m_max_point.y * 2, 1 }); + } + else { + p.setMaxPoint(m_max_point * 2); + } + p.setOverlapLayerSize(m_overlap_layer_size * 2); return p; } @@ -236,131 +286,6 @@ length() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -Int64x3 AMRPatchPosition:: -min(Integer level) const -{ - if (level == m_level) { - return m_min_point; - } - if (level == m_level + 1) { - return m_min_point * 2; - } - if (level == m_level - 1) { - return m_min_point / 2; - } - if (level < m_level) { - Int32 dif = static_cast(math::pow(2., static_cast(m_level - level))); - return m_min_point / dif; - } - - Int32 dif = static_cast(math::pow(2., static_cast(level - m_level))); - return m_min_point * dif; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -Int64x3 AMRPatchPosition:: -minWithMargin(Integer level) const -{ - if (level == m_level) { - return m_min_point - 1; - } - if (level == m_level - 1) { - return (m_min_point - 1) / 2; - } - ARCANE_FATAL("Pas utile"); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -Int64x3 AMRPatchPosition:: -minWithMarginEven(Integer level) const -{ - if (level == m_level) { - Int64x3 with_margin = m_min_point - 1; - with_margin.x -= with_margin.x % 2; - with_margin.y -= with_margin.y % 2; - with_margin.z -= with_margin.z % 2; - return with_margin; - } - if (level == m_level - 1) { - Int64x3 with_margin = (m_min_point - 1) / 2; - with_margin.x -= with_margin.x % 2; - with_margin.y -= with_margin.y % 2; - with_margin.z -= with_margin.z % 2; - return with_margin; - } - ARCANE_FATAL("Pas utile"); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -Int64x3 AMRPatchPosition:: -max(Integer level) const -{ - if (level == m_level) { - return m_max_point; - } - if (level == m_level + 1) { - return m_max_point * 2; - } - if (level == m_level - 1) { - return { static_cast(std::ceil(m_max_point.x / 2.)), static_cast(std::ceil(m_max_point.y / 2.)), static_cast(std::ceil(m_max_point.z / 2.)) }; - } - if (level < m_level) { - Int64 dif = static_cast(math::pow(2., static_cast(level - m_level))); - return { static_cast(std::ceil(m_max_point.x / dif)), static_cast(std::ceil(m_max_point.y / dif)), static_cast(std::ceil(m_max_point.z / dif)) }; - } - Int64 dif = static_cast(math::pow(2., static_cast(level - m_level))); - return m_max_point * dif; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -Int64x3 AMRPatchPosition:: -maxWithMargin(Integer level) const -{ - if (level == m_level) { - return m_max_point + 1; - } - if (level == m_level - 1) { - Int64x3 max = m_max_point + 1; - return { static_cast(std::ceil(max.x / 2.)), static_cast(std::ceil(max.y / 2.)), static_cast(std::ceil(max.z / 2.)) }; - } - ARCANE_FATAL("Pas utile"); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -Int64x3 AMRPatchPosition:: -maxWithMarginEven(Integer level) const -{ - if (level == m_level) { - Int64x3 with_margin = m_max_point + 1; - with_margin.x += with_margin.x % 2; - with_margin.y += with_margin.y % 2; - with_margin.z += with_margin.z % 2; - return with_margin; - } - if (level == m_level - 1) { - Int64x3 max = m_max_point + 1; - Int64x3 with_margin = { static_cast(std::ceil(max.x / 2.)), static_cast(std::ceil(max.y / 2.)), static_cast(std::ceil(max.z / 2.)) }; - with_margin.x += with_margin.x % 2; - with_margin.y += with_margin.y % 2; - with_margin.z += with_margin.z % 2; - return with_margin; - } - ARCANE_FATAL("Pas utile"); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - bool AMRPatchPosition:: isIn(Integer x, Integer y, Integer z) const { @@ -371,22 +296,22 @@ isIn(Integer x, Integer y, Integer z) const /*---------------------------------------------------------------------------*/ bool AMRPatchPosition:: -isInWithMargin(Integer level, Integer x, Integer y, Integer z) const +isInWithOverlap(Integer x, Integer y, Integer z) const { - Int64x3 level_min = minWithMargin(level); - Int64x3 level_max = maxWithMargin(level); - return x >= level_min.x && x < level_max.x && y >= level_min.y && y < level_max.y && z >= level_min.z && z < level_max.z; + const Int64x3 min_point = minPointWithOverlap(); + const Int64x3 max_point = maxPointWithOverlap(); + 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; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ bool AMRPatchPosition:: -isInWithMarginEven(Integer level, Integer x, Integer y, Integer z) const +isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const { - Int64x3 level_min = minWithMarginEven(level); - Int64x3 level_max = maxWithMarginEven(level); - return x >= level_min.x && x < level_max.x && y >= level_min.y && y < level_max.y && z >= level_min.z && z < level_max.z; + const Int64x3 min_point = m_min_point - overlap; + const Int64x3 max_point = m_max_point + overlap; + 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; } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index a50a5e7565..3d356974e0 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -29,8 +29,12 @@ namespace Arcane class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition { public: + AMRPatchPosition(); + AMRPatchPosition(const AMRPatchPosition& src); + ~AMRPatchPosition(); + public: Integer level() const; @@ -41,6 +45,12 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition Int64x3 maxPoint() const; void setMaxPoint(Int64x3 max_point); + Integer overlapLayerSize() const; + void setOverlapLayerSize(Integer layer_size); + + Int64x3 minPointWithOverlap() const; + Int64x3 maxPointWithOverlap() const; + bool isIn(Int64 x, Int64 y, Int64 z) const; Int64 nbCells() const; @@ -49,26 +59,20 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition void fusion(const AMRPatchPosition& other_patch); bool isNull() const; - AMRPatchPosition patchUp() const; + AMRPatchPosition patchUp(Integer dim) const; Int64x3 length() const; - Int64x3 min(Integer level) const; - Int64x3 minWithMargin(Integer level) const; - Int64x3 minWithMarginEven(Integer level) const; - - Int64x3 max(Integer level) const; - Int64x3 maxWithMargin(Integer level) const; - Int64x3 maxWithMarginEven(Integer level) const; - bool isIn(Integer x, Integer y, Integer z) const; - bool isInWithMargin(Integer level, Integer x, Integer y, Integer z) const; - bool isInWithMarginEven(Integer level, Integer x, Integer y, Integer z) const; + bool isInWithOverlap(Integer x, Integer y, Integer z) const; + bool isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const; private: + Integer m_level; Int64x3 m_min_point; Int64x3 m_max_point; + Integer m_overlap_layer_size; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc index b13b8d4456..227b40bc97 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc @@ -238,13 +238,13 @@ fillSig() Integer end = begin + size; for (Integer k = 0; k < m_sig_z.size(); ++k) { - Integer pos_z = min.z + k; + Integer pos_z = m_numbering->offsetLevelToLevel(min.z + k, m_patch.level(), m_patch.level() + 1); for (Integer j = 0; j < m_sig_y.size(); ++j) { - Integer pos_y = min.y + j; + Integer pos_y = m_numbering->offsetLevelToLevel(min.y + j, m_patch.level(), m_patch.level() + 1); for (Integer i = begin; i < end; ++i) { - Integer pos_x = min.x + i; + Integer pos_x = m_numbering->offsetLevelToLevel(min.x + i, m_patch.level(), m_patch.level() + 1); for (auto elem : m_all_patches->patches(m_patch.level() + 1)) { - if (elem.isInWithMargin(m_patch.level(), pos_x, pos_y, pos_z)) { + if (elem.isIn(pos_x, pos_y, pos_z)) { m_have_cells = true; m_sig_x[i]++; m_sig_y[j]++; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index da5d68ed60..f3129e2c42 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -241,7 +241,7 @@ class CartesianMeshImpl void _computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir, VariableCellReal3& cells_center, VariableFaceReal3& faces_center,CellGroup all_cells, - NodeGroup all_nodes); + NodeGroup all_nodes, CellGroup own_cells); void _applyRefine(const AMRZonePosition &position); void _applyCoarse(const AMRZonePosition& zone_position); void _addPatch(ConstArrayView parent_cells); @@ -547,15 +547,15 @@ computeDirections() if (next_face_x!=(-1)){ m_local_face_direction[MD_DirX] = next_face_x; - _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirX,cells_center,faces_center,all_cells,all_nodes); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, cells_center, faces_center, all_cells, all_nodes, all_cells); } if (next_face_y!=(-1)){ m_local_face_direction[MD_DirY] = next_face_y; - _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirY,cells_center,faces_center,all_cells,all_nodes); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, cells_center, faces_center, all_cells, all_nodes, all_cells); } if (next_face_z != (-1)) { m_local_face_direction[MD_DirZ] = next_face_z; - _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirZ,cells_center,faces_center,all_cells,all_nodes); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, cells_center, faces_center, all_cells, all_nodes, all_cells); } // Positionne les informations par direction @@ -582,10 +582,10 @@ computeDirections() info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch(); patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord); auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); - _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes); - _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes); + _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); if (is_3d) - _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes); + _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); } if (arcaneIsCheck()) @@ -628,8 +628,8 @@ _buildPatchGroups(const CellGroup& cells,Integer patch_level) /*---------------------------------------------------------------------------*/ void CartesianMeshImpl:: -_computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir,VariableCellReal3& cells_center, - VariableFaceReal3& faces_center,CellGroup all_cells,NodeGroup all_nodes) +_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center, + VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes, CellGroup own_cells) { IItemFamily* cell_family = m_mesh->cellFamily(); IItemFamily* face_family = m_mesh->faceFamily(); @@ -671,25 +671,35 @@ _computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir,VariableCellRea // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles // soient de même niveau - ENUMERATE_CELL(icell,all_cells){ + ENUMERATE_CELL (icell, all_cells) { Cell cell = *icell; Int32 my_level = cell.level(); Face next_face = cell.face(next_local_face); Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell(); - if (cells_set.find(next_cell.localId())==cells_set.end()) - next_cell = Cell(); - else if (next_cell.level()!=my_level) + if (cells_set.find(next_cell.localId()) == cells_set.end()) { + if (next_cell.level() != my_level) { + next_cell = Cell(); + } + } + else if (next_cell.level() != my_level) { next_cell = Cell(); + } Face prev_face = cell.face(prev_local_face); Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell(); - if (cells_set.find(prev_cell.localId())==cells_set.end()) - prev_cell = Cell(); - else if (prev_cell.level()!=my_level) + + if (cells_set.find(prev_cell.localId()) == cells_set.end()) { + if (prev_cell.level() != my_level) { + prev_cell = Cell(); + } + } + else if (prev_cell.level() != my_level) { prev_cell = Cell(); - cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell,prev_cell); + } + + cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell); } - cell_dm._internalComputeInnerAndOuterItems(all_cells); + cell_dm._internalComputeInnerAndOuterItems(all_cells, own_cells); face_dm._internalComputeInfos(cell_dm,cells_center,faces_center); node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center); } @@ -1071,6 +1081,7 @@ _applyCoarse(const AMRZonePosition& zone_position) void CartesianMeshImpl:: checkValid() const { + return; // TODO : Modification des outers à prendre en compte. info(4) << "Check valid CartesianMesh"; Integer nb_patch = nbPatch(); for( Integer i=0; icells(); } +CellGroup CartesianPatch:: +ownCells() +{ + ARCANE_CHECK_POINTER(m_patch); + return m_patch->ownCells(); +} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.h b/arcane/src/arcane/cartesianmesh/CartesianPatch.h index ebb7e28daa..2c74fb1461 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.h @@ -53,6 +53,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch //! Groupe de mailles du patch CellGroup cells(); + CellGroup ownCells(); Integer index() const; Integer level() const diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index cceebdaa7c..2f0c2cdcfe 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -38,6 +38,57 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +OverlapItemGroupComputeFunctor:: +OverlapItemGroupComputeFunctor(Ref numbering, const AMRPatchPosition& patch_position) +: m_numbering(numbering) +, m_patch_position(patch_position) +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +OverlapItemGroupComputeFunctor:: +~OverlapItemGroupComputeFunctor() = default; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void OverlapItemGroupComputeFunctor:: +executeFunctor() +{ + ITraceMng* trace = m_group->mesh()->traceMng(); + ItemGroup parent(m_group->parent()); + + m_group->beginTransaction(); + Int32UniqueArray items_lid; + + // Ne fonctionne que pour les cells pour l'instant. + ENUMERATE_ITEM (iitem, parent) { + Cell cell = iitem->toCell(); + + Int64 pos_x = m_numbering->cellUniqueIdToCoordX(cell); + Int64 pos_y = m_numbering->cellUniqueIdToCoordY(cell); + Int64 pos_z = m_numbering->cellUniqueIdToCoordZ(cell); + + if (m_patch_position.isIn(pos_x, pos_y, pos_z)) { + items_lid.add(cell.localId()); + } + } + m_group->setItems(items_lid); + m_group->endTransaction(); + + trace->debug() << "OverlapItemGroupComputeFunctor::execute()" + << " this=" << m_group + << " parent_name=" << parent.name() + << " name=" << m_group->name() + << " parent_count=" << parent.size() + << " mysize=" << m_group->size(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + // Le patch 0 est un patch spécial "ground". Il ne possède pas de cell_group // dans le tableau "m_amr_patch_cell_groups". // Pour les index, on utilise toujours celui des tableaux m_amr_patches_pointer @@ -110,14 +161,7 @@ addPatch(CellGroup cell_group, Integer group_index) if (cell_group.null()) ARCANE_FATAL("Null cell group"); auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); - m_amr_patch_cell_groups.add(cell_group); _addPatchInstance(makeRef(cdi)); - m_cmesh->traceMng()->info() << "addPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() - << " -- m_amr_patches : " << m_amr_patches.size() - << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() - << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); @@ -183,6 +227,34 @@ addPatch(CellGroup cell_group, Integer group_index) cdi->position().setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); cdi->position().setLevel(level_r); } + else { + Integer level = -1; + ENUMERATE_ (Cell, icell, cell_group) { + if (level == -1) { + level = icell->level(); + } + if (level != icell->level()) { + ARCANE_FATAL("Level pb -- Zone with cells to different levels -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, icell->level(), icell->uniqueId()); + } + } + + Integer level_r = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level); + + if (level != -1 && level != level_r) { + ARCANE_FATAL("Bad level reduced"); + } + + cdi->position().setLevel(level_r); + } + _addCellGroup(cell_group, cdi); + + m_cmesh->traceMng()->info() << "addPatch()" + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patches : " << m_amr_patches.size() + << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() + << " -- group_index : " << group_index + << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); + m_cmesh->traceMng()->info() << "Min Point : " << cdi->position().minPoint(); m_cmesh->traceMng()->info() << "Max Point : " << cdi->position().maxPoint(); m_cmesh->traceMng()->info() << "Level : " << cdi->position().level(); @@ -231,14 +303,23 @@ cells(const Integer index) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +CellGroup CartesianPatchGroup:: +ownCells(Integer index) +{ + if (index == 0) { + ARCANE_FATAL("You cannot get cells of ground patch with this method"); + } + return m_amr_patch_cell_groups_own[index - 1]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + // Attention : efface aussi le ground patch. Nécessaire de le récupérer après coup. void CartesianPatchGroup:: clear() { - m_amr_patch_cell_groups.clear(); - m_amr_patches_pointer.clear(); - m_amr_patches.clear(); - m_index_new_patches = 1; + _removeAllPatches(); _createGroundPatch(); } @@ -270,6 +351,9 @@ removeCellsInAllPatches(ConstArrayView cells_local_id) for (CellGroup cells : m_amr_patch_cell_groups) { cells.removeItems(cells_local_id); } + for (CellGroup cells : m_amr_patch_cell_groups_own) { + cells.removeItems(cells_local_id); + } } /*---------------------------------------------------------------------------*/ @@ -314,6 +398,7 @@ applyPatchEdit(bool remove_empty_patches) m_patches_to_delete.clear(); if (remove_empty_patches) { + // TODO : Pas vraiment compatible avec les mailles overlap. UniqueArray size_of_patches(m_amr_patch_cell_groups.size()); for (Integer i = 0; i < m_amr_patch_cell_groups.size(); ++i) { size_of_patches[i] = m_amr_patch_cell_groups[i].size(); @@ -468,6 +553,8 @@ mergePatches() void CartesianPatchGroup:: refine() { + Integer dimension = m_cmesh->mesh()->dimension(); + Integer nb_overlap_cells = 1; Integer min_level = 0; Integer max_level = -1; @@ -489,11 +576,12 @@ refine() if (level != max_level) { ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) { - Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); - Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); - Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + Integer pos_x = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordX(*icell), level, level + 1); + Integer pos_y = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordY(*icell), level, level + 1); + Integer pos_z = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordZ(*icell), level, level + 1); + for (auto patch : all_patches.patches(level)) { - if (patch.isInWithMargin(level, pos_x, pos_y, pos_z)) { + if (patch.isInWithOverlap(pos_x, pos_y, pos_z, patch.overlapLayerSize() + 1)) { icell->mutableItemBase().removeFlags(ItemFlags::II_Refine); } } @@ -501,7 +589,7 @@ refine() } m_cmesh->traceMng()->info() << "All patch level+1 with margin (can be overlap) : "; for (auto& elem : all_patches.patches(level + 1)) { - m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.minWithMargin(level) << " -- max = " << elem.maxWithMargin(level); + m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.minPointWithOverlap() << " -- max = " << elem.maxPointWithOverlap(); } } @@ -509,6 +597,7 @@ refine() all_level.setLevel(level); all_level.setMinPoint({ 0, 0, 0 }); all_level.setMaxPoint({ static_cast(numbering->globalNbCellsX(level)), static_cast(numbering->globalNbCellsY(level)), static_cast(numbering->globalNbCellsZ(level)) }); + all_level.setOverlapLayerSize(nb_overlap_cells); AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches); UniqueArray sig_array; @@ -519,6 +608,10 @@ refine() for (const auto& elem : sig_array) { all_patches.addPatch(elem.patch()); } + nb_overlap_cells /= 2; + nb_overlap_cells += 1; + + ///////// Real global_efficacity = 0; m_cmesh->traceMng()->info() << "All patch : "; @@ -562,10 +655,12 @@ refine() str += "]"; } else { - str += "[..]"; + str += "[ ]"; } } m_cmesh->traceMng()->info() << str; + + //////////// } auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng(); @@ -594,7 +689,7 @@ refine() Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); for (const AMRPatchPosition& patch : all_patches.patches(level)) { - if (patch.isIn(pos_x, pos_y, pos_z)) { + if (patch.isInWithOverlap(pos_x, pos_y, pos_z)) { icell->mutableItemBase().addFlags(ItemFlags::II_Refine); } } @@ -614,26 +709,36 @@ refine() str += "[++]"; } else { - str += "[..]"; + str += "[ ]"; } } m_cmesh->traceMng()->info() << str; amr->refine(); + // // Pour debug, forcer le else de la methode addPatch(AV). + // UniqueArray d_cell_ids; + // ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level + 1)) { + // d_cell_ids.add(icell.localId()); + // } + // addPatch(d_cell_ids); + for (const AMRPatchPosition& patch : all_patches.patches(level)) { - _addPatch(patch.patchUp()); + _addPatch(patch.patchUp(dimension)); } } - for (Integer level = max_level; level > min_level; --level) { + m_cmesh->traceMng()->info() << "max_level : " << max_level << " -- min_level : " << min_level; + + for (Integer level = max_level + 1; level > min_level; --level) { ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + bool is_in = false; - for (auto patch : all_patches.patches(level)) { - if (patch.isInWithMarginEven(level, pos_x, pos_y, pos_z)) { + for (const AMRPatchPosition& patch : all_patches.patches(level - 1)) { + if (patch.patchUp(dimension).isInWithOverlap(pos_x, pos_y, pos_z)) { is_in = true; break; } @@ -643,20 +748,25 @@ refine() } } - Integer nb_cell_x = numbering->globalNbCellsX(level); + Integer nb_cell_x = numbering->globalNbCellsX(level - 1); StringBuilder str = "Level "; str += level; str += "\n"; - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level)) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level - 1)) { if (icell->uniqueId().asInt32() % nb_cell_x == 0) { str += "\n"; } - if (icell->hasFlags(ItemFlags::II_Coarsen)) { - str += "[--]"; + if (icell->hasHChildren()) { + if (icell->hChild(0).hasFlags(ItemFlags::II_Coarsen)) { + str += "[--]"; + } + else { + str += "[XX]"; + } } else { - str += "[..]"; + str += "[ ]"; } } m_cmesh->traceMng()->info() << str; @@ -681,6 +791,7 @@ refine() m_cmesh->traceMng()->info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); m_cmesh->traceMng()->info() << "\tLevel : " << patch.patchInterface()->position().level(); m_cmesh->traceMng()->info() << "\tNbCells : " << patch.patchInterface()->cells().size(); + m_cmesh->traceMng()->info() << "\tIndex : " << patch.patchInterface()->index(); } } @@ -723,6 +834,9 @@ _removeOnePatch(Integer index) m_amr_patch_cell_groups[index - 1].clear(); m_amr_patch_cell_groups.remove(index - 1); + m_amr_patch_cell_groups_own[index - 1].clear(); + m_amr_patch_cell_groups_own.remove(index - 1); + m_amr_patches_pointer.remove(index); m_amr_patches.remove(index); } @@ -749,7 +863,14 @@ _removeAllPatches() { Ref ground_patch = m_amr_patches.front(); + for (CellGroup cell_group : m_amr_patch_cell_groups) { + cell_group.clear(); + } + for (CellGroup cell_group : m_amr_patch_cell_groups_own) { + cell_group.clear(); + } m_amr_patch_cell_groups.clear(); + m_amr_patch_cell_groups_own.clear(); m_amr_patches_pointer.clear(); m_amr_patches.clear(); m_available_group_index.clear(); @@ -782,6 +903,41 @@ _createGroundPatch() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch) +{ + m_amr_patch_cell_groups.add(cell_group); + + if (patch->position().isNull()) { + // Patch non-régulier. + m_amr_patch_cell_groups_own.add(cell_group); + return; + } + + AMRPatchPosition patch_position = patch->position(); + Ref numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + + UniqueArray items_lid; + + ENUMERATE_ (Cell, icell, cell_group) { + Cell cell = *icell; + + Int64 pos_x = numbering->cellUniqueIdToCoordX(cell); + Int64 pos_y = numbering->cellUniqueIdToCoordY(cell); + Int64 pos_z = numbering->cellUniqueIdToCoordZ(cell); + + if (patch_position.isIn(pos_x, pos_y, pos_z)) { + items_lid.add(cell.localId()); + } + } + + CellGroup own = m_cmesh->mesh()->cellFamily()->createGroup(cell_group.name().clone() + "_Own", items_lid, true); + m_amr_patch_cell_groups_own.add(own); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -1043,22 +1199,20 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ UniqueArray cells_local_id; - cdi->position().setLevel(new_patch_position.level()); - cdi->position().setMinPoint(new_patch_position.minPoint()); - cdi->position().setMaxPoint(new_patch_position.maxPoint()); + cdi->position() = new_patch_position; auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); ENUMERATE_ (Cell, icell, parent_patch_cell_group) { Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); - if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { + if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { // TODO : Ajouter overlap dans .arc cells_local_id.add(icell.localId()); } } CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); - m_amr_patch_cell_groups.add(parent_cells); + _addCellGroup(parent_cells, cdi); m_cmesh->traceMng()->info() << "_addCutPatch()" << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() @@ -1080,7 +1234,7 @@ _addPatch(const AMRPatchPosition& new_patch_position) Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); - if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { + if (new_patch_position.isInWithOverlap(pos_x, pos_y, pos_z)) { cells_local_id.add(icell.localId()); } } @@ -1094,14 +1248,11 @@ _addPatch(const AMRPatchPosition& new_patch_position) String patch_group_name = String("CartesianMeshPatchCells") + group_index; auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); - cdi->position().setLevel(new_patch_position.level()); - cdi->position().setMinPoint(new_patch_position.minPoint()); - cdi->position().setMaxPoint(new_patch_position.maxPoint()); + cdi->position() = new_patch_position; _addPatchInstance(makeRef(cdi)); - CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); - m_amr_patch_cell_groups.add(parent_cells); + _addCellGroup(parent_cells, cdi); m_cmesh->traceMng()->info() << "_addPatch()" << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h index 22b140c7f5..c39a9977b6 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h @@ -18,18 +18,36 @@ #include "arcane/cartesianmesh/ICartesianMeshPatch.h" #include "arcane/cartesianmesh/CartesianMeshPatchListView.h" #include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/core/ItemGroupComputeFunctor.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ namespace Arcane { +class ICartesianMeshNumberingMng; class CartesianMeshPatch; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +class OverlapItemGroupComputeFunctor +: public ItemGroupComputeFunctor +{ + public: + + OverlapItemGroupComputeFunctor(Ref numbering, const AMRPatchPosition& patch_position); + ~OverlapItemGroupComputeFunctor(); + + void executeFunctor() override; + + private: + + Ref m_numbering; + AMRPatchPosition m_patch_position; +}; + class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup { public: @@ -51,6 +69,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup CartesianMeshPatchListView patchListView() const; CellGroup cells(Integer index); + CellGroup ownCells(Integer index); void clear(); @@ -83,6 +102,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void _removeAllPatches(); void _createGroundPatch(); + void _addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch); + bool _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPosition& patch_position1); void _splitPatch(Integer index_patch, const AMRPatchPosition& patch_position); void _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group); @@ -91,6 +112,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup private: UniqueArray m_amr_patch_cell_groups; + UniqueArray m_amr_patch_cell_groups_own; UniqueArray m_amr_patches_pointer; UniqueArray> m_amr_patches; ICartesianMesh* m_cmesh; diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc index a2065cecb9..676cee37bb 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc @@ -104,19 +104,34 @@ _internalResizeInfos(Int32 new_size) /*---------------------------------------------------------------------------*/ void CellDirectionMng:: -_internalComputeInnerAndOuterItems(const ItemGroup& items) +_internalComputeInnerAndOuterItems(const ItemGroup& items, const ItemGroup& own_items) { Int32UniqueArray inner_lids; Int32UniqueArray outer_lids; IItemFamily* family = items.itemFamily(); ENUMERATE_ITEM(iitem,items){ Int32 lid = iitem.itemLocalId(); - Int32 i1 = m_infos_view[lid].m_next_lid; - Int32 i2 = m_infos_view[lid].m_previous_lid; - if (i1==NULL_ITEM_LOCAL_ID || i2==NULL_ITEM_LOCAL_ID) - outer_lids.add(lid); - else - inner_lids.add(lid); + // Int32 i1 = m_infos_view[lid].m_next_lid; + // Int32 i2 = m_infos_view[lid].m_previous_lid; + // bool b1 = m_infos_view[lid].m_next_own; + // bool b2 = m_infos_view[lid].m_previous_own; + // if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID || !b1 || !b2) + // if (i1==NULL_ITEM_LOCAL_ID || i2==NULL_ITEM_LOCAL_ID) + outer_lids.add(lid); + // else + // inner_lids.add(lid); + } + ENUMERATE_ITEM (iitem, own_items) { + Int32 lid = iitem.itemLocalId(); + // Int32 i1 = m_infos_view[lid].m_next_lid; + // Int32 i2 = m_infos_view[lid].m_previous_lid; + // bool b1 = m_infos_view[lid].m_next_own; + // bool b2 = m_infos_view[lid].m_previous_own; + // if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID || !b1 || !b2) + // if (i1==NULL_ITEM_LOCAL_ID || i2==NULL_ITEM_LOCAL_ID) + // outer_lids.add(lid); + // else + inner_lids.add(lid); } int dir = (int)m_direction; String base_group_name = String("Direction")+dir; diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h index a591ade3c9..eb344e4019 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h @@ -565,7 +565,7 @@ class ARCANE_CARTESIANMESH_EXPORT CellDirectionMng * \brief Usage interne à Arcane. Calcul les entités internes et externes. * Suppose que init() a été appelé. */ - void _internalComputeInnerAndOuterItems(const ItemGroup& items); + void _internalComputeInnerAndOuterItems(const ItemGroup& items, const ItemGroup& own_items); /*! * \internal diff --git a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc index 4015bfc618..10839e297c 100644 --- a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc @@ -140,16 +140,30 @@ _internalComputeInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& c FaceGroup all_faces = face_family->createGroup(String("AllFaces")+base_group_name,Int32ConstArrayView(),true); all_faces.setItems(faces_lid,true); + UniqueArray inner_cells_lid; + cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); + UniqueArray inner_lids; UniqueArray outer_lids; - ENUMERATE_FACE(iitem,all_faces){ - Int32 lid = iitem.itemLocalId(); - Face face = *iitem; + ENUMERATE_ (Face, iface, all_faces) { + Int32 lid = iface.itemLocalId(); + Face face = *iface; // TODO: ne pas utiser nbCell() mais faire cela via le std::set utilisé précédemment - if (face.nbCell()==1) + if (face.nbCell() == 1) { outer_lids.add(lid); - else - inner_lids.add(lid); + } + else { + bool c0_inner_cell = inner_cells_lid.contains(face.cell(0).localId()); + bool c1_inner_cell = inner_cells_lid.contains(face.cell(1).localId()); + // Si au moins une des mailles est interne, alors la face est interne. + // TODO : Gérer les faces communes. + if (c0_inner_cell || c1_inner_cell) { + inner_lids.add(lid); + } + else { + outer_lids.add(lid); + } + } } m_p->m_inner_all_items = face_family->createGroup(String("AllInner")+base_group_name,inner_lids,true); m_p->m_outer_all_items = face_family->createGroup(String("AllOuter")+base_group_name,outer_lids,true); @@ -202,12 +216,12 @@ _computeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells Cell back_cell = face.backCell(); // Vérifie que les mailles sont dans notre patch. - if (!front_cell.null()) - if (patch_cells_set.find(front_cell.localId())==patch_cells_set.end()) - front_cell = Cell(); - if (!back_cell.null()) - if (patch_cells_set.find(back_cell.localId())==patch_cells_set.end()) - back_cell = Cell(); + // if (!front_cell.null()) + // if (patch_cells_set.find(front_cell.localId())==patch_cells_set.end()) + // front_cell = Cell(); + // if (!back_cell.null()) + // if (patch_cells_set.find(back_cell.localId())==patch_cells_set.end()) + // back_cell = Cell(); bool is_inverse = false; if (!front_cell.null()){ @@ -257,9 +271,9 @@ _computeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells } } if (is_inverse) - m_infos_view[face_lid] = ItemDirectionInfo(back_cell,front_cell); + m_infos_view[face_lid] = ItemDirectionInfo(back_cell, front_cell); else - m_infos_view[face_lid] = ItemDirectionInfo(front_cell,back_cell); + m_infos_view[face_lid] = ItemDirectionInfo(front_cell, back_cell); } } diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h index 4ff6bae792..46f369f519 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h @@ -39,6 +39,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatch //! Groupe de mailles du patch virtual CellGroup cells() =0; + virtual CellGroup ownCells() = 0; //! TODO virtual Integer index() = 0; diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc index bde9e4ad95..809a221aca 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc @@ -148,17 +148,34 @@ _internalComputeInfos(const CellDirectionMng& cell_dm,const NodeGroup& all_nodes } } - Int32UniqueArray inner_lids; - Int32UniqueArray outer_lids; + UniqueArray inner_cells_lid; + cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); + + UniqueArray inner_lids; + UniqueArray outer_lids; IItemFamily* family = all_nodes.itemFamily(); - ENUMERATE_ITEM(iitem,all_nodes){ - Int32 lid = iitem.itemLocalId(); + ENUMERATE_ (Node, inode, all_nodes) { + Int32 lid = inode.itemLocalId(); Int32 i1 = m_infos_view[lid].m_next_lid; Int32 i2 = m_infos_view[lid].m_previous_lid; - if (i1==NULL_ITEM_LOCAL_ID || i2==NULL_ITEM_LOCAL_ID) + if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID) { outer_lids.add(lid); - else - inner_lids.add(lid); + } + else { + // Si au moins une des mailles est interne, alors le noeud est interne. + // TODO : Gérer les noeuds communs peut-être une autre méthode plus performante. + bool is_outer = true; + for (Cell cell : inode->cells()) { + if (inner_cells_lid.contains(cell.localId())) { + inner_lids.add(lid); + is_outer = false; + break; + } + } + if (is_outer) { + outer_lids.add(lid); + } + } } int dir = (int)m_direction; String base_group_name = String("Direction")+dir; diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h index 897b9d7ec2..98643b28e1 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h @@ -50,6 +50,7 @@ class CartesianMeshPatch ~CartesianMeshPatch() override; public: CellGroup cells() override; + CellGroup ownCells() override; Integer index() override { return m_amr_patch_index; From b9e30af118df3ccdd2baeaf3f9f8d32f30555fbb Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Fri, 21 Nov 2025 15:26:33 +0100 Subject: [PATCH 10/19] [arcane:core,cartesianmesh] Fixes for multi-level refinement and parallel execution --- .../arcane/cartesianmesh/AMRPatchPosition.cc | 31 +++ .../arcane/cartesianmesh/AMRPatchPosition.h | 3 + .../AMRPatchPositionSignature.cc | 68 +++--- .../cartesianmesh/CartesianMeshAMRPatchMng.h | 2 +- .../cartesianmesh/CartesianPatchGroup.cc | 219 +++++++++++------- .../cartesianmesh/ICartesianMeshAMRPatchMng.h | 1 + arcane/src/arcane/mesh/DynamicMesh.cc | 6 +- 7 files changed, 222 insertions(+), 108 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc index a966346e57..7e273eb6f8 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -277,6 +277,25 @@ patchUp(Integer dim) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +AMRPatchPosition AMRPatchPosition:: +patchDown(Integer dim) const +{ + AMRPatchPosition p; + p.setLevel(m_level - 1); + p.setMinPoint(m_min_point / 2); + if (dim == 2) { + p.setMaxPoint({ static_cast(std::ceil(m_max_point.x / 2.)), static_cast(std::ceil(m_max_point.y / 2.)), 1 }); + } + else { + p.setMaxPoint({ static_cast(std::ceil(m_max_point.x / 2.)), static_cast(std::ceil(m_max_point.y / 2.)), static_cast(std::ceil(m_max_point.z / 2.)) }); + } + p.setOverlapLayerSize((m_overlap_layer_size / 2) + 1); + return p; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Int64x3 AMRPatchPosition:: length() const { @@ -317,6 +336,18 @@ isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +bool AMRPatchPosition:: +haveIntersection(const AMRPatchPosition& other) const +{ + return ( + (other.maxPoint().x > minPoint().x && maxPoint().x > other.minPoint().x) && + (other.maxPoint().y > minPoint().y && maxPoint().y > other.minPoint().y) && + (other.maxPoint().z > minPoint().z && maxPoint().z > other.minPoint().z)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index 3d356974e0..a52a76a087 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -60,6 +60,7 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition bool isNull() const; AMRPatchPosition patchUp(Integer dim) const; + AMRPatchPosition patchDown(Integer dim) const; Int64x3 length() const; @@ -67,6 +68,8 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition bool isInWithOverlap(Integer x, Integer y, Integer z) const; bool isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const; + bool haveIntersection(const AMRPatchPosition& other) const; + private: Integer m_level; diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc index 227b40bc97..d4951dca47 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc @@ -226,40 +226,54 @@ fillSig() m_sig_z[pos_z - m_patch.minPoint().z]++; } + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_x); + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_y); + m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_z); + if (m_all_patches->maxLevel() > m_patch.level()) { - Int64x3 min = m_patch.minPoint(); - Integer nb_proc = m_mesh->mesh()->parallelMng()->commSize(); - Integer my_proc = m_mesh->mesh()->parallelMng()->commRank(); - - Integer base = m_sig_x.size() / nb_proc; - Integer reste = m_sig_x.size() % nb_proc; - Integer size = base + (my_proc < reste ? 1 : 0); - Integer begin = my_proc * base + std::min(my_proc, reste); - Integer end = begin + size; - - for (Integer k = 0; k < m_sig_z.size(); ++k) { - Integer pos_z = m_numbering->offsetLevelToLevel(min.z + k, m_patch.level(), m_patch.level() + 1); - for (Integer j = 0; j < m_sig_y.size(); ++j) { - Integer pos_y = m_numbering->offsetLevelToLevel(min.y + j, m_patch.level(), m_patch.level() + 1); - for (Integer i = begin; i < end; ++i) { - Integer pos_x = m_numbering->offsetLevelToLevel(min.x + i, m_patch.level(), m_patch.level() + 1); - for (auto elem : m_all_patches->patches(m_patch.level() + 1)) { - if (elem.isIn(pos_x, pos_y, pos_z)) { - m_have_cells = true; - m_sig_x[i]++; - m_sig_y[j]++; - m_sig_z[k]++; - break; - } + + // Pour que la signature soit valide, il ne faut pas que les patchs de m_all_patches + // s'intersectent entre eux (pour un même niveau). + for (const auto& elem : m_all_patches->patches(m_patch.level() + 1)) { + AMRPatchPosition patch_down = elem.patchDown(m_mesh->mesh()->dimension()); + if (!m_patch.haveIntersection(patch_down)) { + continue; + } + + Int64x3 min = patch_down.minPoint() - m_patch.minPoint(); + Int64x3 max = patch_down.maxPoint() - m_patch.minPoint(); + + Int64x3 begin; + Int64x3 end; + + begin.x = std::max(min.x, 0l); + end.x = std::min(max.x, m_sig_x.size() + 0l); + + begin.y = std::max(min.y, 0l); + end.y = std::min(max.y, m_sig_y.size() + 0l); + + if (m_mesh->mesh()->dimension() == 2) { + begin.z = 0; + end.z = 1; + } + else { + begin.z = std::max(min.z, 0l); + end.z = std::min(max.z, m_sig_z.size() + 0l); + } + + for (Integer k = begin.z; k < end.z; ++k) { + for (Integer j = begin.y; j < end.y; ++j) { + for (Integer i = begin.x; i < end.x; ++i) { + m_sig_x[i]++; + m_sig_y[j]++; + m_sig_z[k]++; + m_have_cells = true; } } } } } - m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_x); - m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_y); - m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, m_sig_z); m_have_cells = m_mesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, m_have_cells); } diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h index 97ff489b5d..ce82cd8fbd 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h @@ -48,10 +48,10 @@ class CartesianMeshAMRPatchMng void refine() override; void createSubLevel() override; void coarsen(bool update_parent_flag) override; + void _syncFlagCell() const override; private: - void _syncFlagCell() const; void _shareInfosOfCellsAroundPatch(ConstArrayView patch_cells, std::unordered_map& around_cells_uid_to_owner, std::unordered_map& around_cells_uid_to_flags, Int32 useful_flags) const; private: diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc index 2f0c2cdcfe..74bcc60ec4 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc @@ -556,25 +556,33 @@ refine() Integer dimension = m_cmesh->mesh()->dimension(); Integer nb_overlap_cells = 1; Integer min_level = 0; - Integer max_level = -1; + Integer future_max_level = -1; // Désigne le niveau max qui aura des enfants, donc le futur level max +1. + Integer old_max_level = -1; // Mais s'il reste des mailles à des niveaux plus haut, il faut les retirer. + auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng(); + + amr->_syncFlagCell(); - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { + Integer level = icell->level(); if (icell->hasFlags(ItemFlags::II_Refine)) { - Integer level = icell->level(); - if (level > max_level) - max_level = level; + if (level > future_max_level) + future_max_level = level; } + if (level > old_max_level) + old_max_level = level; } - max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max_level); + future_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, future_max_level); + old_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, old_max_level); - m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << max_level; + m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << future_max_level; auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); - AMRPatchPositionLevelGroup all_patches(max_level); + AMRPatchPositionLevelGroup all_patches(future_max_level); - for (Integer level = max_level; level >= min_level; --level) { - if (level != max_level) { - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { + for (Integer level = future_max_level; level >= min_level; --level) { + m_cmesh->traceMng()->info() << "Refine Level " << level << " with " << nb_overlap_cells << " layers of overlap cells"; + if (level != future_max_level) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) { Integer pos_x = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordX(*icell), level, level + 1); Integer pos_y = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordY(*icell), level, level + 1); @@ -621,49 +629,59 @@ refine() } global_efficacity /= sig_array.size(); m_cmesh->traceMng()->info() << "Global efficacity : " << global_efficacity; - - StringBuilder str = ""; - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownCells()) { - if (icell->level() != level) - continue; - Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); - Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); - Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); - Integer patch = -1; - for (Integer i = 0; i < sig_array.size(); ++i) { - const AMRPatchPositionSignature& elem = sig_array[i]; - if (elem.isIn(pos_x, pos_y, pos_z)) { - if (patch != -1) { - ARCANE_FATAL("ABCDEFG -- old : {0} -- new : {1}", patch, i); + { + UniqueArray out(numbering->globalNbCellsY(level) * numbering->globalNbCellsX(level), -1); + Array2View av_out(out.data(), numbering->globalNbCellsY(level), numbering->globalNbCellsX(level)); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { + if (icell->level() != level) + continue; + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + Integer patch = -1; + for (Integer i = 0; i < sig_array.size(); ++i) { + const AMRPatchPositionSignature& elem = sig_array[i]; + if (elem.patch().isInWithOverlap(pos_x, pos_y, pos_z)) { + patch = -2; + } + if (elem.isIn(pos_x, pos_y, pos_z)) { + if (patch >= 0) { + ARCANE_FATAL("ABCDEFG -- old : {0} -- new : {1}", patch, i); + } + patch = i; } - patch = i; } - } - if (patch == -1 && icell->hasFlags(ItemFlags::II_Refine)) { - ARCANE_FATAL("Bad Patch"); + if (patch == -1 && icell->hasFlags(ItemFlags::II_Refine)) { + ARCANE_FATAL("Bad Patch"); + } + av_out(pos_y, pos_x) = patch; } - if (pos_x == 0) { + StringBuilder str = ""; + for (Integer i = 0; i < numbering->globalNbCellsX(level); ++i) { str += "\n"; - } - if (patch != -1) { - str += "["; - if (patch < 10) { - str += " "; + for (Integer j = 0; j < numbering->globalNbCellsY(level); ++j) { + Integer c = av_out(i, j); + if (c >= 0) { + str += "["; + if (c < 10) + str += " "; + str += c; + str += "]"; + } + else if (c == -2) { + str += "[RE]"; + } + else + str += "[ ]"; } - str += patch; - str += "]"; - } - else { - str += "[ ]"; } + m_cmesh->traceMng()->info() << str; } - m_cmesh->traceMng()->info() << str; //////////// } - auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng(); { constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine | @@ -680,7 +698,7 @@ refine() _removeAllPatches(); applyPatchEdit(false); - for (Integer level = min_level; level <= max_level; ++level) { + for (Integer level = min_level; level <= future_max_level; ++level) { all_patches.fusionPatches(level); ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { @@ -696,23 +714,39 @@ refine() } } - Integer nb_cell_x = numbering->globalNbCellsX(level); + { + UniqueArray out(numbering->globalNbCellsY(level) * numbering->globalNbCellsX(level), -1); + Array2View av_out(out.data(), numbering->globalNbCellsY(level), numbering->globalNbCellsX(level)); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + if (icell->hasHChildren()) { + av_out(pos_y, pos_x) = 0; + } + if (icell->hasFlags(ItemFlags::II_Refine)) { + av_out(pos_y, pos_x) = 1; + } + if (icell->hasHChildren() && icell->hasFlags(ItemFlags::II_Refine)) { + ARCANE_FATAL("Bad refine cell"); + } + } - StringBuilder str = "Level "; - str += level; - str += "\n"; - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level)) { - if (icell->uniqueId().asInt32() % nb_cell_x == 0) { + StringBuilder str = ""; + for (Integer i = 0; i < numbering->globalNbCellsX(level); ++i) { str += "\n"; + for (Integer j = 0; j < numbering->globalNbCellsY(level); ++j) { + Integer c = av_out(i, j); + if (c == 1) + str += "[++]"; + else if (c == 0) + str += "[XX]"; + else + str += "[ ]"; + } } - if (icell->hasFlags(ItemFlags::II_Refine)) { - str += "[++]"; - } - else { - str += "[ ]"; - } + m_cmesh->traceMng()->info() << str; } - m_cmesh->traceMng()->info() << str; amr->refine(); @@ -728,9 +762,27 @@ refine() } } - m_cmesh->traceMng()->info() << "max_level : " << max_level << " -- min_level : " << min_level; + m_cmesh->traceMng()->info() << "max_level : " << future_max_level << " -- min_level : " << min_level; + + // On retire les mailles qui n'auront plus de parent. + // Exemple : + // À l'itération précédente, on a mis des flags II_Refine sur des mailles de niveau 0 et 1, + // le niveau max était 2. + // Alors, dans cette itération, old_max_level = 2. + // À cette itération, on a mis des flags II_Refine uniquement sur des mailles de niveau 0. + // Alors, future_max_level = 0. + // + // On doit retirer toutes les mailles de niveau 2 pour éviter les mailles orphelines. + { + for (Integer level = old_max_level; level > future_max_level + 1; --level) { + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { + icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen); + } + amr->coarsen(true); + } + } - for (Integer level = max_level + 1; level > min_level; --level) { + for (Integer level = future_max_level + 1; level > min_level; --level) { ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) { Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); @@ -748,28 +800,38 @@ refine() } } - Integer nb_cell_x = numbering->globalNbCellsX(level - 1); + { + UniqueArray out(numbering->globalNbCellsY(level - 1) * numbering->globalNbCellsX(level - 1), -1); + Array2View av_out(out.data(), numbering->globalNbCellsY(level - 1), numbering->globalNbCellsX(level - 1)); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level - 1)) { + Integer pos_x = numbering->cellUniqueIdToCoordX(*icell); + Integer pos_y = numbering->cellUniqueIdToCoordY(*icell); + Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell); + if (icell->hasHChildren()) { + if (icell->hChild(0).hasFlags(ItemFlags::II_Coarsen)) { + av_out(pos_y, pos_x) = 1; + } + else { + av_out(pos_y, pos_x) = 0; + } + } + } - StringBuilder str = "Level "; - str += level; - str += "\n"; - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->ownLevelCells(level - 1)) { - if (icell->uniqueId().asInt32() % nb_cell_x == 0) { + StringBuilder str = ""; + for (Integer i = 0; i < numbering->globalNbCellsX(level - 1); ++i) { str += "\n"; - } - if (icell->hasHChildren()) { - if (icell->hChild(0).hasFlags(ItemFlags::II_Coarsen)) { - str += "[--]"; + for (Integer j = 0; j < numbering->globalNbCellsY(level - 1); ++j) { + Integer c = av_out(i, j); + if (c == 1) + str += "[--]"; + else if (c == 0) + str += "[XX]"; + else + str += "[ ]"; } - else { - str += "[XX]"; - } - } - else { - str += "[ ]"; } + m_cmesh->traceMng()->info() << str; } - m_cmesh->traceMng()->info() << str; amr->coarsen(true); } @@ -921,6 +983,9 @@ _addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch) ENUMERATE_ (Cell, icell, cell_group) { Cell cell = *icell; + if (!cell.isOwn()) { + continue; + } Int64 pos_x = numbering->cellUniqueIdToCoordX(cell); Int64 pos_y = numbering->cellUniqueIdToCoordY(cell); @@ -1239,10 +1304,6 @@ _addPatch(const AMRPatchPosition& new_patch_position) } } - if (cells_local_id.empty()) { - return; - } - IItemFamily* cell_family = m_cmesh->mesh()->cellFamily(); Integer group_index = _nextIndexForNewPatch(); String patch_group_name = String("CartesianMeshPatchCells") + group_index; diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h index 80c93a555f..930870722b 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h @@ -77,6 +77,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshAMRPatchMng * mis à jour. Cela inclut l'activation des mailles parentes. */ virtual void coarsen(bool update_parent_flag) = 0; + virtual void _syncFlagCell() const = 0; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/mesh/DynamicMesh.cc b/arcane/src/arcane/mesh/DynamicMesh.cc index d4ec5b648b..332bff91ca 100644 --- a/arcane/src/arcane/mesh/DynamicMesh.cc +++ b/arcane/src/arcane/mesh/DynamicMesh.cc @@ -441,9 +441,13 @@ build() else if(m_amr_type == eMeshAMRKind::Patch){ ARCANE_FATAL("Patch AMR type is not implemented."); } - else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly){ + else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { // L'AMR PatchCartesianMeshOnly n'est pas géré par MeshRefinement(). // Voir dans CartesianMesh.cc. + // TODO : CartesianMeshAMRPatchMng en a besoin pour les mailles fantômes. + // Voir pour retirer ou remplacer l'appel à la methode + // updateGhostLayerFromParent(). + m_mesh_refinement = new MeshRefinement(this); } } } From bfabee8e8a391d56af8959434c0d4d605a614505 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Wed, 26 Nov 2025 15:06:25 +0100 Subject: [PATCH 11/19] [arcane:cartesianmesh] Move some files in internal folder --- .../tests/AMRCartesianMeshTesterModule.cc | 23 +- .../arcane/cartesianmesh/AMRPatchPosition.h | 1 + .../arcane/cartesianmesh/AMRZonePosition.cc | 4 +- .../arcane/cartesianmesh/AMRZonePosition.h | 12 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 27 +- .../cartesianmesh/CartesianMeshAMRMng.cc | 140 + .../cartesianmesh/CartesianMeshAMRMng.h | 69 + .../CartesianMeshNumberingMng.cc | 1832 +------------ .../cartesianmesh/CartesianMeshNumberingMng.h | 222 +- .../cartesianmesh/CartesianMeshPatch.cc | 21 +- .../cartesianmesh/CartesianMeshUtils.cc | 19 - .../arcane/cartesianmesh/CartesianMeshUtils.h | 15 - .../src/arcane/cartesianmesh/CartesianPatch.h | 6 + .../cartesianmesh/ICartesianMeshPatch.h | 9 +- .../AMRPatchPositionLevelGroup.cc | 4 +- .../AMRPatchPositionLevelGroup.h | 1 - .../AMRPatchPositionSignature.cc | 12 +- .../AMRPatchPositionSignature.h | 7 +- .../AMRPatchPositionSignatureCut.cc | 10 +- .../AMRPatchPositionSignatureCut.h | 8 +- .../CartesianMeshAMRPatchMng.cc | 4 +- .../{ => internal}/CartesianMeshAMRPatchMng.h | 8 +- .../CartesianMeshNumberingMngInternal.cc | 2278 +++++++++++++++++ .../CartesianMeshNumberingMngInternal.h | 221 ++ .../internal/CartesianMeshPatch.h | 36 +- .../{ => internal}/CartesianPatchGroup.cc | 119 +- .../{ => internal}/CartesianPatchGroup.h | 20 +- .../ICartesianMeshAMRPatchMng.h | 0 .../internal/ICartesianMeshInternal.h | 8 +- .../ICartesianMeshNumberingMngInternal.h} | 12 +- .../internal/ICartesianMeshPatchInternal.h | 51 + arcane/src/arcane/cartesianmesh/srcs.cmake | 38 +- 32 files changed, 3175 insertions(+), 2062 deletions(-) create mode 100644 arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc create mode 100644 arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionLevelGroup.cc (98%) rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionLevelGroup.h (98%) rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionSignature.cc (97%) rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionSignature.h (94%) rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionSignatureCut.cc (98%) rename arcane/src/arcane/cartesianmesh/{ => internal}/AMRPatchPositionSignatureCut.h (91%) rename arcane/src/arcane/cartesianmesh/{ => internal}/CartesianMeshAMRPatchMng.cc (99%) rename arcane/src/arcane/cartesianmesh/{ => internal}/CartesianMeshAMRPatchMng.h (92%) create mode 100644 arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc create mode 100644 arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h rename arcane/src/arcane/cartesianmesh/{ => internal}/CartesianPatchGroup.cc (93%) rename arcane/src/arcane/cartesianmesh/{ => internal}/CartesianPatchGroup.h (91%) rename arcane/src/arcane/cartesianmesh/{ => internal}/ICartesianMeshAMRPatchMng.h (100%) rename arcane/src/arcane/cartesianmesh/{ICartesianMeshNumberingMng.h => internal/ICartesianMeshNumberingMngInternal.h} (98%) create mode 100644 arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 191d17b73d..4daba5d9ec 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -46,6 +46,7 @@ #include "arcane/cartesianmesh/FaceDirectionMng.h" #include "arcane/cartesianmesh/NodeDirectionMng.h" #include "arcane/cartesianmesh/CartesianConnectivity.h" +#include "arcane/cartesianmesh/CartesianMeshAMRMng.h" #include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h" #include "arcane/cartesianmesh/ICartesianMeshPatch.h" #include "arcane/cartesianmesh/CartesianMeshUtils.h" @@ -516,16 +517,18 @@ _initAMR() m_cartesian_mesh->computeDirections(); info() << "Doint initial coarsening"; - - if (m_cartesian_mesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { - debug() << "Coarse with specific coarser (for cartesian mesh only)"; - Ref coarser = CartesianMeshUtils::cartesianMeshAMRPatchMng(m_cartesian_mesh); - coarser->createSubLevel(); - } - else { - Ref coarser = CartesianMeshUtils::createCartesianMeshCoarsening2(m_cartesian_mesh); - coarser->createCoarseCells(); - } + // + // if (m_cartesian_mesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + // debug() << "Coarse with specific coarser (for cartesian mesh only)"; + // Ref coarser = CartesianMeshUtils::cartesianMeshAMRPatchMng(m_cartesian_mesh); + // coarser->createSubLevel(); + // } + // else { + // Ref coarser = CartesianMeshUtils::createCartesianMeshCoarsening2(m_cartesian_mesh); + // coarser->createCoarseCells(); + // } + CartesianMeshAMRMng amr_mng(m_cartesian_mesh); + amr_mng.createSubLevel(); CartesianMeshPatchListView patches = m_cartesian_mesh->patches(); Int32 nb_patch = patches.size(); diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index a52a76a087..e0152533ca 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -31,6 +31,7 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition public: AMRPatchPosition(); + // TODO Faire operator= AMRPatchPosition(const AMRPatchPosition& src); ~AMRPatchPosition(); diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc index b27b1cdfa6..6776c86f96 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc @@ -12,7 +12,7 @@ #include "arcane/cartesianmesh/AMRZonePosition.h" -#include "ICartesianMesh.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/core/IMesh.h" #include "arcane/core/MeshKind.h" #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" @@ -66,7 +66,7 @@ cellsInPatch(ICartesianMesh* mesh, UniqueArray& cells_local_id, AMRPatchP cellsInPatch(mesh->mesh(), cells_local_id); return; } - auto numbering = mesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = mesh->_internalApi()->cartesianMeshNumberingMngInternal(); FixedArray min_n_max; min_n_max[0] = INT64_MAX; diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h index 71c18228b9..b7da5d2517 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h @@ -94,9 +94,18 @@ class ARCANE_CARTESIANMESH_EXPORT AMRZonePosition */ void cellsInPatch(IMesh* mesh, UniqueArray& cells_local_id) const; + /*! + * \brief Méthode permettant de retrouver les mailles incluses dans la zone. + * Un objet AMRPatchPosition désignant la position du patch est aussi rempli. + * \param mesh Le maillage. + * \param cells_local_id Le tableau qui contiendra les localIds des mailles de la zone. + * Attention : le tableau sera d'abord effacé. + * \param position [OUT] La position du patch. + */ void cellsInPatch(ICartesianMesh* mesh, UniqueArray& cells_local_id, AMRPatchPosition& position) const; private: + Real3 m_position; Real3 m_length; bool m_is_3d; @@ -110,5 +119,4 @@ class ARCANE_CARTESIANMESH_EXPORT AMRZonePosition /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif - +#endif diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index f3129e2c42..7f354a8e9e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -33,7 +33,7 @@ #include "arcane/core/MeshKind.h" #include "arcane/core/internal/IMeshInternal.h" -#include "arcane/cartesianmesh/CartesianPatchGroup.h" +#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h" #include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/cartesianmesh/CartesianConnectivity.h" #include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h" @@ -47,8 +47,9 @@ #include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h" #include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" -#include "arcane/cartesianmesh/CartesianMeshAMRPatchMng.h" +#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h" #include "arcane/core/IGhostLayerMng.h" +#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h" #include @@ -99,7 +100,7 @@ class CartesianMeshImpl void initCartesianMeshAMRPatchMng() override { if (m_numbering_mng.isNull()) { - initCartesianMeshNumberingMng(); + initCartesianMeshNumberingMngInternal(); } if (m_amr_mng.isNull()) { m_amr_mng = makeRef(new CartesianMeshAMRPatchMng(m_cartesian_mesh, m_numbering_mng.get())); @@ -109,13 +110,13 @@ class CartesianMeshImpl { return m_amr_mng; } - void initCartesianMeshNumberingMng() override + void initCartesianMeshNumberingMngInternal() override { if (m_numbering_mng.isNull()) { - m_numbering_mng = makeRef(new CartesianMeshNumberingMng(m_cartesian_mesh->mesh())); + m_numbering_mng = makeRef(new CartesianMeshNumberingMngInternal(m_cartesian_mesh->mesh())); } } - Ref cartesianMeshNumberingMng() override + Ref cartesianMeshNumberingMngInternal() override { return m_numbering_mng; } @@ -124,7 +125,7 @@ class CartesianMeshImpl CartesianMeshImpl* m_cartesian_mesh = nullptr; Ref m_amr_mng; - Ref m_numbering_mng; + Ref m_numbering_mng; }; public: @@ -279,7 +280,7 @@ CartesianMeshImpl(IMesh* mesh) , m_amr_type(mesh->meshKind().meshAMRKind()) { if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_internal_api.initCartesianMeshNumberingMng(); + m_internal_api.initCartesianMeshNumberingMngInternal(); m_internal_api.initCartesianMeshAMRPatchMng(); // TODO : Voir où mettre la renumérotation. //m_internal_api.cartesianMeshNumberingMng()->renumberingFacesLevel0FromOriginalArcaneNumbering(); @@ -295,7 +296,7 @@ build() { m_properties = new Properties(*(mesh()->properties()),"CartesianMesh"); if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_internal_api.cartesianMeshNumberingMng()->_build(); + m_internal_api.cartesianMeshNumberingMngInternal()->_build(); } } @@ -341,8 +342,8 @@ _saveInfosInProperties() m_properties->set("PatchGroupNamesAvailable", m_patch_group.availableGroupIndex()); if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_internal_api.cartesianMeshNumberingMng()->_saveInfosInProperties(); - m_internal_api.cartesianMeshNumberingMng()->printStatus(); + m_internal_api.cartesianMeshNumberingMngInternal()->_saveInfosInProperties(); + m_internal_api.cartesianMeshNumberingMngInternal()->printStatus(); } } @@ -355,8 +356,8 @@ recreateFromDump() info() << "Creating 'CartesianMesh' infos from dump"; if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_internal_api.cartesianMeshNumberingMng()->_recreateFromDump(); - m_internal_api.cartesianMeshNumberingMng()->printStatus(); + m_internal_api.cartesianMeshNumberingMngInternal()->_recreateFromDump(); + m_internal_api.cartesianMeshNumberingMngInternal()->printStatus(); } // Sauve le numéro de version pour être sur que c'est OK en reprise diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc new file mode 100644 index 0000000000..b3a4029b68 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc @@ -0,0 +1,140 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* CartesianMeshAMRMng.cc (C) 2000-2025 */ +/* */ +/* Gestionnaire de l'AMR par patch d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h" +#include "arcane/cartesianmesh/CartesianMeshPatchListView.h" +#include "arcane/cartesianmesh/CartesianMeshUtils.h" +#include "arcane/cartesianmesh/CartesianPatch.h" + +#include "arcane/cartesianmesh/CartesianMeshAMRMng.h" + +#include "arcane/core/IMesh.h" +#include "arcane/core/MeshKind.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CartesianMeshAMRMng:: +CartesianMeshAMRMng(ICartesianMesh* cmesh) +: m_cmesh(cmesh) +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int32 CartesianMeshAMRMng:: +nbPatch() const +{ + return m_cmesh->nbPatch(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CartesianPatch CartesianMeshAMRMng:: +amrPatch(Int32 index) const +{ + return m_cmesh->amrPatch(index); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CartesianMeshPatchListView CartesianMeshAMRMng:: +patches() const +{ + return m_cmesh->patches(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +refineZone(const AMRZonePosition& position) const +{ + m_cmesh->refinePatch(position); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +coarseZone(const AMRZonePosition& position) const +{ + m_cmesh->coarseZone(position); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +refine() const +{ + m_cmesh->refine(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer CartesianMeshAMRMng:: +reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const +{ + return m_cmesh->reduceNbGhostLayers(level, target_nb_ghost_layers); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +mergePatches() const +{ + m_cmesh->mergePatches(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +createSubLevel() const +{ + auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind(); + if(amr_type == eMeshAMRKind::Cell) { + Ref coarser = CartesianMeshUtils::createCartesianMeshCoarsening2(m_cmesh); + coarser->createCoarseCells(); + } + else if(amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + m_cmesh->_internalApi()->cartesianMeshAMRPatchMng()->createSubLevel(); + } + else if(amr_type == eMeshAMRKind::Patch) { + ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)"); + } + else{ + ARCANE_FATAL("AMR is not enabled"); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h new file mode 100644 index 0000000000..361d019a1a --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h @@ -0,0 +1,69 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* CartesianMeshAMRMng.h (C) 2000-2025 */ +/* */ +/* Gestionnaire de l'AMR par patch d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#ifndef ARCANE_CARTESIANMESH_CARTESIANMESHAMRMNG_H +#define ARCANE_CARTESIANMESH_CARTESIANMESHAMRMNG_H + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/utils/TraceAccessor.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng +{ + public: + + explicit CartesianMeshAMRMng(ICartesianMesh* cmesh); + + public: + + Int32 nbPatch() const; + CartesianPatch amrPatch(Int32 index) const; + CartesianMeshPatchListView patches() const; + + void refineZone(const AMRZonePosition& position) const; + + void coarseZone(const AMRZonePosition& position) const; + + void refine() const; + + Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const; + + void mergePatches() const; + + void createSubLevel() const; + + private: + + ICartesianMesh* m_cmesh; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif //ARCANE_CARTESIANMESH_CARTESIANMESHAMRMNG_H diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index f9a2d80de1..e7368c3c9f 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -12,17 +12,10 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "CartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" #include "arcane/utils/Vector2.h" -#include "arcane/utils/ITraceMng.h" - -#include "arcane/core/IMesh.h" -#include "arcane/core/IParallelMng.h" -#include "arcane/core/VariableTypes.h" -#include "arcane/core/ICartesianMeshGenerationInfo.h" -#include "arcane/core/IItemFamily.h" -#include "arcane/core/Properties.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -34,152 +27,9 @@ namespace Arcane /*---------------------------------------------------------------------------*/ CartesianMeshNumberingMng:: -CartesianMeshNumberingMng(IMesh* mesh) -: TraceAccessor(mesh->traceMng()) -, m_mesh(mesh) -, m_dimension(mesh->dimension()) -, m_pattern(2) -, m_max_level(0) -, m_min_level(0) -, m_converting_numbering_face(true) -, m_ori_level(0) -{ - const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); - - Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); - m_nb_cell_ground.x = global_nb_cells_by_direction[MD_DirX]; - m_nb_cell_ground.y = global_nb_cells_by_direction[MD_DirY]; - m_nb_cell_ground.z = ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ]); - - if (m_nb_cell_ground.x <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", m_nb_cell_ground.x); - if (m_nb_cell_ground.y <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", m_nb_cell_ground.y); - if (m_nb_cell_ground.z <= 0) - ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", m_nb_cell_ground.z); - - if (m_dimension == 2) { - m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y; - m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1); - m_latest_face_uid = (m_nb_cell_ground.x * m_nb_cell_ground.y) * 2 + m_nb_cell_ground.x * 2 + m_nb_cell_ground.y; - } - else { - m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y * m_nb_cell_ground.z; - m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1) * (m_nb_cell_ground.z + 1); - m_latest_face_uid = (m_nb_cell_ground.z + 1) * m_nb_cell_ground.x * m_nb_cell_ground.y + (m_nb_cell_ground.x + 1) * m_nb_cell_ground.y * m_nb_cell_ground.z + (m_nb_cell_ground.y + 1) * m_nb_cell_ground.z * m_nb_cell_ground.x; - } - - m_first_cell_uid_level.add(0); - m_first_node_uid_level.add(0); - m_first_face_uid_level.add(0); - - // Tant qu'on utilise la numérotation d'origine pour le niveau 0, on doit utiliser - // une conversion de la numérotation d'origine vers la nouvelle. - // TODO AH : Ça risque de pas très bien se passer en cas de repartitionnement... - if (m_converting_numbering_face) { - UniqueArray face_uid(CartesianMeshNumberingMng::nbFaceByCell()); - ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(0)) { - CartesianMeshNumberingMng::cellFaceUniqueIds(face_uid, 0, icell->uniqueId()); - for (Integer i = 0; i < CartesianMeshNumberingMng::nbFaceByCell(); ++i) { - m_face_ori_numbering_to_new[icell->face(i).uniqueId()] = face_uid[i]; - m_face_new_numbering_to_ori[face_uid[i]] = icell->face(i).uniqueId(); - // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i]; - } - } - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -_build() -{ - m_properties = makeRef(new Properties(*(m_mesh->properties()), "CartesianMeshNumberingMng")); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -_saveInfosInProperties() -{ - m_properties->set("Version", 1); - m_properties->set("FirstCellUIDByLevel", m_first_cell_uid_level); - - // Voir pour le recalculer à la reprise. - m_properties->set("FirstNodeUIDByLevel", m_first_node_uid_level); - m_properties->set("FirstFaceUIDByLevel", m_first_face_uid_level); - - m_properties->set("OriginalGroundLevelForConverting", m_ori_level); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -_recreateFromDump() -{ - Int32 v = m_properties->getInt32("Version"); - if (v != 1) - ARCANE_FATAL("Bad numbering mng version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1); - - m_properties->get("FirstCellUIDByLevel", m_first_cell_uid_level); - m_properties->get("FirstNodeUIDByLevel", m_first_node_uid_level); - m_properties->get("FirstFaceUIDByLevel", m_first_face_uid_level); - - m_properties->get("OriginalGroundLevelForConverting", m_ori_level); - if (m_ori_level == -1) { - m_converting_numbering_face = false; - m_face_ori_numbering_to_new.clear(); - m_face_new_numbering_to_ori.clear(); - } - - m_nb_cell_ground = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) }; - - m_max_level = m_first_cell_uid_level.size() - 1; - - { - Integer pos = 0; - Int64 max = 0; - Integer iter = 0; - for (const Int64 elem : m_first_cell_uid_level) { - if (elem > max) { - max = elem; - pos = iter; - } - iter++; - } - m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos); - m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos); - m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos); - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -renumberingFacesLevel0FromOriginalArcaneNumbering() +CartesianMeshNumberingMng(ICartesianMesh* mesh) +: m_internal_api(mesh->_internalApi()->cartesianMeshNumberingMngInternal()) { - if (!m_converting_numbering_face) - return; - - UniqueArray face_uid(nbFaceByCell()); - ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(m_ori_level)) { - cellFaceUniqueIds(face_uid, m_ori_level, icell->uniqueId()); - for (Integer i = 0; i < nbFaceByCell(); ++i) { - // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i]; - icell->face(i).mutableItemBase().setUniqueId(face_uid[i]); - } - } - m_mesh->faceFamily()->notifyItemsUniqueIdChanged(); - m_mesh->checkValidMesh(); - - m_converting_numbering_face = false; - m_ori_level = -1; - m_face_ori_numbering_to_new.clear(); - m_face_new_numbering_to_ori.clear(); } /*---------------------------------------------------------------------------*/ @@ -188,123 +38,7 @@ renumberingFacesLevel0FromOriginalArcaneNumbering() void CartesianMeshNumberingMng:: printStatus() { - ITraceMng* tm = m_mesh->traceMng(); - Trace::Setter _(tm, "CartesianMeshNumberingMng"); - - tm->info() << "CartesianMeshNumberingMng status :"; - - // tm->info() << "FirstCellUIDByLevel : " << m_first_cell_uid_level; - // tm->info() << "FirstNodeUIDByLevel : " << m_first_node_uid_level; - // tm->info() << "FirstFaceUIDByLevel : " << m_first_face_uid_level; - - tm->info() << "LatestCellUID : " << m_latest_cell_uid; - tm->info() << "LatestNodeUID : " << m_latest_node_uid; - tm->info() << "LatestFaceUID : " << m_latest_face_uid; - - tm->info() << "MinLevel : " << m_min_level; - tm->info() << "MaxLevel : " << m_max_level; - - tm->info() << "GroundLevelNbCells : " << m_nb_cell_ground; - - if (m_ori_level == -1) { - tm->info() << "Ground Level is renumbered"; - } - else { - tm->info() << "Ground Level is not renumbered -- OriginalGroundLevel : " << m_ori_level; - } - - for (Integer i = m_min_level; i <= m_max_level; ++i) { - tm->info() << "Level " << i << " : "; - tm->info() << "\tUID Cells : [" << firstCellUniqueId(i) << ", " << (firstCellUniqueId(i) + nbCellInLevel(i)) << "["; - tm->info() << "\tUID Nodes : [" << firstNodeUniqueId(i) << ", " << (firstNodeUniqueId(i) + nbNodeInLevel(i)) << "["; - tm->info() << "\tUID Faces : [" << firstFaceUniqueId(i) << ", " << (firstFaceUniqueId(i) + nbFaceInLevel(i)) << "["; - } - - const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); - - Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); - tm->info() << "global_nb_cells_by_direction.x : " << global_nb_cells_by_direction[MD_DirX]; - tm->info() << "global_nb_cells_by_direction.y : " << global_nb_cells_by_direction[MD_DirY]; - tm->info() << "global_nb_cells_by_direction.z : " << global_nb_cells_by_direction[MD_DirZ]; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -prepareLevel(Int32 level) -{ - if (level <= m_max_level && level >= m_min_level) - return; - if (level == m_max_level + 1) { - m_max_level++; - m_first_cell_uid_level.add(m_latest_cell_uid); - m_first_node_uid_level.add(m_latest_node_uid); - m_first_face_uid_level.add(m_latest_face_uid); - } - else if (level == m_min_level - 1) { - m_min_level--; - _pushFront(m_first_cell_uid_level, m_latest_cell_uid); - _pushFront(m_first_node_uid_level, m_latest_node_uid); - _pushFront(m_first_face_uid_level, m_latest_face_uid); - } - else { - ARCANE_FATAL("Level error : {0}", level); - } - - m_latest_cell_uid += nbCellInLevel(level); - m_latest_node_uid += nbNodeInLevel(level); - m_latest_face_uid += nbFaceInLevel(level); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -updateFirstLevel() -{ - const Int32 nb_levels_to_add = -m_min_level; - m_ori_level += nb_levels_to_add; - - if (nb_levels_to_add == 0) { - return; - } - - m_max_level += nb_levels_to_add; - m_min_level += nb_levels_to_add; - - const Integer to_div = m_pattern * nb_levels_to_add; - if (m_dimension == 2) { - m_nb_cell_ground.x /= to_div; - m_nb_cell_ground.y /= to_div; - // z reste à 1. - } - else { - m_nb_cell_ground /= to_div; - } - - // ---------- - // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() - // Recalcule les informations sur le nombre de mailles par direction. - auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, false); - if (!cmgi) - return; - - { - ConstArrayView v = cmgi->ownCellOffsets(); - cmgi->setOwnCellOffsets(v[0] / to_div, v[1] / to_div, v[2] / to_div); - } - { - ConstArrayView v = cmgi->globalNbCells(); - cmgi->setGlobalNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); - } - { - ConstArrayView v = cmgi->ownNbCells(); - cmgi->setOwnNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); - } - cmgi->setFirstOwnCellUniqueId(firstCellUniqueId(0)); - // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() - // ---------- + m_internal_api->printStatus(); } /*---------------------------------------------------------------------------*/ @@ -313,7 +47,7 @@ updateFirstLevel() Int64 CartesianMeshNumberingMng:: firstCellUniqueId(Integer level) const { - return m_first_cell_uid_level[level - m_min_level]; + return m_internal_api->firstCellUniqueId(level); } /*---------------------------------------------------------------------------*/ @@ -322,7 +56,7 @@ firstCellUniqueId(Integer level) const Int64 CartesianMeshNumberingMng:: firstNodeUniqueId(Integer level) const { - return m_first_node_uid_level[level - m_min_level]; + return m_internal_api->firstNodeUniqueId(level); } /*---------------------------------------------------------------------------*/ @@ -331,7 +65,7 @@ firstNodeUniqueId(Integer level) const Int64 CartesianMeshNumberingMng:: firstFaceUniqueId(Integer level) const { - return m_first_face_uid_level[level - m_min_level]; + return m_internal_api->firstFaceUniqueId(level); } /*---------------------------------------------------------------------------*/ @@ -340,7 +74,7 @@ firstFaceUniqueId(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbCellsX(Integer level) const { - return static_cast(static_cast(m_nb_cell_ground.x) * std::pow(m_pattern, level)); + return m_internal_api->globalNbCellsX(level); } /*---------------------------------------------------------------------------*/ @@ -349,7 +83,7 @@ globalNbCellsX(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbCellsY(Integer level) const { - return static_cast(static_cast(m_nb_cell_ground.y) * std::pow(m_pattern, level)); + return m_internal_api->globalNbCellsY(level); } /*---------------------------------------------------------------------------*/ @@ -358,7 +92,7 @@ globalNbCellsY(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbCellsZ(Integer level) const { - return static_cast(static_cast(m_nb_cell_ground.z) * std::pow(m_pattern, level)); + return m_internal_api->globalNbCellsZ(level); } /*---------------------------------------------------------------------------*/ @@ -367,7 +101,7 @@ globalNbCellsZ(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbNodesX(Integer level) const { - return globalNbCellsX(level) + 1; + return m_internal_api->globalNbNodesX(level); } /*---------------------------------------------------------------------------*/ @@ -376,7 +110,7 @@ globalNbNodesX(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbNodesY(Integer level) const { - return globalNbCellsY(level) + 1; + return m_internal_api->globalNbNodesY(level); } /*---------------------------------------------------------------------------*/ @@ -385,7 +119,7 @@ globalNbNodesY(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbNodesZ(Integer level) const { - return globalNbCellsZ(level) + 1; + return m_internal_api->globalNbNodesZ(level); } /*---------------------------------------------------------------------------*/ @@ -394,7 +128,7 @@ globalNbNodesZ(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesX(Integer level) const { - return globalNbCellsX(level) + 1; + return m_internal_api->globalNbFacesX(level); } /*---------------------------------------------------------------------------*/ @@ -403,7 +137,7 @@ globalNbFacesX(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesY(Integer level) const { - return globalNbCellsY(level) + 1; + return m_internal_api->globalNbFacesY(level); } /*---------------------------------------------------------------------------*/ @@ -412,7 +146,7 @@ globalNbFacesY(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesZ(Integer level) const { - return globalNbCellsZ(level) + 1; + return m_internal_api->globalNbFacesZ(level); } /*---------------------------------------------------------------------------*/ @@ -421,7 +155,7 @@ globalNbFacesZ(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesXCartesianView(Integer level) const { - return (globalNbCellsX(level) * 2) + 1; + return m_internal_api->globalNbFacesXCartesianView(level); } /*---------------------------------------------------------------------------*/ @@ -430,7 +164,7 @@ globalNbFacesXCartesianView(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesYCartesianView(Integer level) const { - return (globalNbCellsY(level) * 2) + 1; + return m_internal_api->globalNbFacesYCartesianView(level); } /*---------------------------------------------------------------------------*/ @@ -439,7 +173,7 @@ globalNbFacesYCartesianView(Integer level) const Int64 CartesianMeshNumberingMng:: globalNbFacesZCartesianView(Integer level) const { - return (globalNbCellsZ(level) * 2) + 1; + return m_internal_api->globalNbFacesZCartesianView(level); } /*---------------------------------------------------------------------------*/ @@ -448,13 +182,7 @@ globalNbFacesZCartesianView(Integer level) const Int64 CartesianMeshNumberingMng:: nbCellInLevel(Integer level) const { - if (m_dimension == 2) { - const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); - return nb_cell.x * nb_cell.y; - } - - const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return nb_cell.x * nb_cell.y * nb_cell.z; + return m_internal_api->nbCellInLevel(level); } /*---------------------------------------------------------------------------*/ @@ -463,13 +191,7 @@ nbCellInLevel(Integer level) const Int64 CartesianMeshNumberingMng:: nbNodeInLevel(Integer level) const { - if (m_dimension == 2) { - const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); - return (nb_cell.x + 1) * (nb_cell.y + 1); - } - - const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return (nb_cell.x + 1) * (nb_cell.y + 1) * (nb_cell.z + 1); + return m_internal_api->nbNodeInLevel(level); } /*---------------------------------------------------------------------------*/ @@ -478,13 +200,7 @@ nbNodeInLevel(Integer level) const Int64 CartesianMeshNumberingMng:: nbFaceInLevel(Integer level) const { - if (m_dimension == 2) { - const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); - return (nb_cell.x * nb_cell.y) * 2 + nb_cell.x * 2 + nb_cell.y; - } - - const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return (nb_cell.z + 1) * nb_cell.x * nb_cell.y + (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x; + return m_internal_api->nbFaceInLevel(level); } /*---------------------------------------------------------------------------*/ @@ -493,7 +209,7 @@ nbFaceInLevel(Integer level) const Integer CartesianMeshNumberingMng:: pattern() const { - return m_pattern; + return m_internal_api->pattern(); } /*---------------------------------------------------------------------------*/ @@ -502,17 +218,7 @@ pattern() const Int32 CartesianMeshNumberingMng:: cellLevel(Int64 uid) const { - Integer pos = -1; - Int64 max = 0; - - for (Integer i = m_min_level; i <= m_max_level; ++i) { - const Int64 first_uid = firstCellUniqueId(i); - if (first_uid <= uid && first_uid > max) { - pos = i; - max = first_uid; - } - } - return pos; + return m_internal_api->cellLevel(uid); } /*---------------------------------------------------------------------------*/ @@ -521,17 +227,7 @@ cellLevel(Int64 uid) const Int32 CartesianMeshNumberingMng:: nodeLevel(Int64 uid) const { - Integer pos = -1; - Int64 max = 0; - - for (Integer i = m_min_level; i <= m_max_level; ++i) { - const Int64 first_uid = firstNodeUniqueId(i); - if (first_uid <= uid && first_uid > max) { - pos = i; - max = first_uid; - } - } - return pos; + return m_internal_api->nodeLevel(uid); } /*---------------------------------------------------------------------------*/ @@ -540,1733 +236,475 @@ nodeLevel(Int64 uid) const Int32 CartesianMeshNumberingMng:: faceLevel(Int64 uid) const { - Integer pos = -1; - Int64 max = 0; - - for (Integer i = m_min_level; i <= m_max_level; ++i) { - const Int64 first_uid = firstFaceUniqueId(i); - if (first_uid <= uid && first_uid > max) { - pos = i; - max = first_uid; - } - } - return pos; + return m_internal_api->faceLevel(uid); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes. Int64 CartesianMeshNumberingMng:: offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const { - if (level_from == level_to) { - return coord; - } - else if (level_from < level_to) { - return coord * m_pattern * (level_to - level_from); - } - else { - return coord / (m_pattern * (level_from - level_to)); - } + return m_internal_api->offsetLevelToLevel(coord, level_from, level_to); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes. Int64 CartesianMeshNumberingMng:: faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const { - // Admettons que l'on ai les faces suivantes : - // ┌─0──┬──2─┐ - // 4│ 6│ 8│ - // ├─5──┼─7──┤ - // 9│ 11│ 13│ - // └─10─┴─12─┘ - - // Pour la position d'une face, on considère cette disposition : - // ┌──┬──┬──┬──┬──┐ - // │ │ 0│ │ 2│ │ - // ├──┼──┼──┼──┼──┤ - // │ 4│ │ 6│ │ 8│ - // ├──┼──┼──┼──┼──┤ - // │ │ 5│ │ 7│ │ - // ├──┼──┼──┼──┼──┤ - // │ 9│ │11│ │13│ - // ├──┼──┼──┼──┼──┤ - // │ │10│ │12│ │ - // └──┴──┴──┴──┴──┘ - - if (level_from == level_to) { - return coord; - } - else if (level_from < level_to) { - const Integer pattern = m_pattern * (level_to - level_from); - if (coord % 2 == 0) { - return coord * pattern; - } - else { - return ((coord - 1) * pattern) + 1; - } - } - else { - const Integer pattern = m_pattern * (level_from - level_to); - if (coord % 2 == 0) { - if (coord % (pattern * 2) == 0) { - return coord / pattern; - } - else { - return -1; - } - } - else { - // auto a = coord - 1; - // auto b = a % (pattern * 2); - // auto c = a / (pattern * 2); - // auto d = c * (2 * (pattern - 1)); - // auto e = d + b; - // auto f = coord - e; - // return f; - - return coord - ((Int64((coord - 1) / (pattern * 2)) * (2 * (pattern - 1))) + ((coord - 1) % (pattern * 2))); - } - } + return m_internal_api->faceOffsetLevelToLevel(coord, level_from, level_to); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordX(Int64 uid, Integer level) +cellUniqueIdToCoordX(Int64 uid, Integer level) const { - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_cell_uid = firstCellUniqueId(level); - - uid -= first_cell_uid; - - const Int64 to2d = uid % (nb_cell_x * nb_cell_y); - return to2d % nb_cell_x; + return m_internal_api->cellUniqueIdToCoordX(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordX(Cell cell) +cellUniqueIdToCoordX(Cell cell) const { - return cellUniqueIdToCoordX(cell.uniqueId(), cell.level()); + return m_internal_api->cellUniqueIdToCoordX(cell); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordY(Int64 uid, Integer level) +cellUniqueIdToCoordY(Int64 uid, Integer level) const { - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_cell_uid = firstCellUniqueId(level); - - uid -= first_cell_uid; - - const Int64 to2d = uid % (nb_cell_x * nb_cell_y); - return to2d / nb_cell_x; + return m_internal_api->cellUniqueIdToCoordY(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordY(Cell cell) +cellUniqueIdToCoordY(Cell cell) const { - return cellUniqueIdToCoordY(cell.uniqueId(), cell.level()); + return m_internal_api->cellUniqueIdToCoordY(cell); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordZ(Int64 uid, Integer level) +cellUniqueIdToCoordZ(Int64 uid, Integer level) const { - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_cell_uid = firstCellUniqueId(level); - - uid -= first_cell_uid; - - return uid / (nb_cell_x * nb_cell_y); + return m_internal_api->cellUniqueIdToCoordZ(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueIdToCoordZ(Cell cell) +cellUniqueIdToCoordZ(Cell cell) const { - return cellUniqueIdToCoordZ(cell.uniqueId(), cell.level()); + return m_internal_api->cellUniqueIdToCoordZ(cell); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordX(Int64 uid, Integer level) +nodeUniqueIdToCoordX(Int64 uid, Integer level) const { - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 nb_node_y = globalNbNodesY(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - uid -= first_node_uid; - - const Int64 to2d = uid % (nb_node_x * nb_node_y); - return to2d % nb_node_x; + return m_internal_api->nodeUniqueIdToCoordX(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordX(Node node) +nodeUniqueIdToCoordX(Node node) const { - const Int64 uid = node.uniqueId(); - return nodeUniqueIdToCoordX(uid, nodeLevel(uid)); + return m_internal_api->nodeUniqueIdToCoordX(node); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordY(Int64 uid, Integer level) +nodeUniqueIdToCoordY(Int64 uid, Integer level) const { - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 nb_node_y = globalNbNodesY(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - uid -= first_node_uid; - - const Int64 to2d = uid % (nb_node_x * nb_node_y); - return to2d / nb_node_x; + return m_internal_api->nodeUniqueIdToCoordY(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordY(Node node) +nodeUniqueIdToCoordY(Node node) const { - const Int64 uid = node.uniqueId(); - return nodeUniqueIdToCoordY(uid, nodeLevel(uid)); + return m_internal_api->nodeUniqueIdToCoordY(node); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordZ(Int64 uid, Integer level) +nodeUniqueIdToCoordZ(Int64 uid, Integer level) const { - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 nb_node_y = globalNbNodesY(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - uid -= first_node_uid; - - return uid / (nb_node_x * nb_node_y); + return m_internal_api->nodeUniqueIdToCoordZ(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueIdToCoordZ(Node node) +nodeUniqueIdToCoordZ(Node node) const { - const Int64 uid = node.uniqueId(); - return nodeUniqueIdToCoordZ(uid, nodeLevel(uid)); + return m_internal_api->nodeUniqueIdToCoordZ(node); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordX(Int64 uid, Integer level) -{ - if (m_dimension == 2) { - - const Int64 nb_face_x = globalNbFacesXCartesianView(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - uid -= first_face_uid; - uid += 1; - - // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 : - // - // x = 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ - // y = -1 │ 0│ │ 2│ │ 4│ - // ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ 1│ │ 3│ │ - // ├──┼──┼──┼──┼──┤ - // y = 1 │ 5│ │ 7│ │ 9│ - // ├──┼──┼──┼──┼──┤ - // y = 2 │ │ 6│ │ 8│ │ - // ├──┼──┼──┼──┼──┤ - // y = 3 │10│ │12│ │14│ - // ├──┼──┼──┼──┼──┤ - // y = 4 │ │11│ │13│ │ - // └──┴──┴──┴──┴──┘ - // - // Si on fait "tomber" les faces (tetris), on obtient une numérotation - // cartésienne classique. - - return uid % nb_face_x; - } - else { - const Int64 nb_face_x = globalNbFacesX(level); - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - // Int64 initial_uid = uid; - - uid -= first_face_uid; - - Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); - - // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : - // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 - // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ - // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ - // │ │ │ │ - // - // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], - // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. - // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - - // Pour l'intervalle [0, 11], on remarque que l'origine en X est toujours 1 et que les mailles - // contenant une face sont sur les X impairs. - // Enfin, on a "nb_cell_x" faces en X. - if (uid < three_parts_numbering.x) { - // debug() << "faceUniqueIdToCoordX (1)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); - - return (uid % nb_cell_x) * 2 + 1; - } - - // Pour l'intervalle [12, 23], on remarque que l'origine en X est toujours 0 et que les mailles - // contenant une face sont sur les X pairs. - // Enfin, on a "nb_face_x" faces en X. - else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - uid -= three_parts_numbering.x; - - // debug() << "faceUniqueIdToCoordX (2)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_face_x : " << nb_face_x - // << " -- return : " << ((uid % nb_face_x) * 2); - - return (uid % nb_face_x) * 2; - } - - // Pour l'intervalle [24, 35], on remarque que l'origine en X est toujours 1 et que les mailles - // contenant une face sont sur les X impairs. - // Enfin, on a "nb_cell_x" faces en X. - else { - uid -= three_parts_numbering.x + three_parts_numbering.y; - - // debug() << "faceUniqueIdToCoordX (3)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); - - return (uid % nb_cell_x) * 2 + 1; - } - } +faceUniqueIdToCoordX(Int64 uid, Integer level) const +{ + return m_internal_api->faceUniqueIdToCoordX(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordX(Face face) +faceUniqueIdToCoordX(Face face) const { - const Int64 uid = face.uniqueId(); - return faceUniqueIdToCoordX(uid, faceLevel(uid)); + return m_internal_api->faceUniqueIdToCoordX(face); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordY(Int64 uid, Integer level) -{ - if (m_dimension == 2) { - const Int64 nb_face_x = globalNbFacesXCartesianView(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - uid -= first_face_uid; - uid += 1; - - // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 : - // - // x = 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ - // y = -1 │ 0│ │ 2│ │ 4│ - // ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ 1│ │ 3│ │ - // ├──┼──┼──┼──┼──┤ - // y = 1 │ 5│ │ 7│ │ 9│ - // ├──┼──┼──┼──┼──┤ - // y = 2 │ │ 6│ │ 8│ │ - // ├──┼──┼──┼──┼──┤ - // y = 3 │10│ │12│ │14│ - // ├──┼──┼──┼──┼──┤ - // y = 4 │ │11│ │13│ │ - // └──┴──┴──┴──┴──┘ - // - // Si, en plus, on fait y+1, on simplifie le problème puisque si on fait - // "tomber" les faces (tetris), on obtient une numérotation cartesienne classique. - - const Int64 flat_pos = uid / nb_face_x; - return (flat_pos * 2) + (flat_pos % 2 == uid % 2 ? 0 : 1) - 1; // Le -1 pour "retirer" le niveau imaginaire. - } - else { - const Int64 nb_face_x = globalNbFacesX(level); - const Int64 nb_face_y = globalNbFacesY(level); - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - // Int64 initial_uid = uid; - - uid -= first_face_uid; - - Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); - - // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : - // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 - // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ - // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ - // │ │ │ │ - // - // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], - // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. - // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - - // Pour l'intervalle [0, 11], on remarque que l'origine en Y est toujours 1 et que les mailles - // contenant une face sont sur les Y impairs. - // Enfin, on a "nb_cell_y" faces en Y. - if (uid < three_parts_numbering.x) { - uid %= nb_cell_x * nb_cell_y; - - // debug() << "faceUniqueIdToCoordY (1)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / nb_cell_x) * 2 + 1); - - return (uid / nb_cell_x) * 2 + 1; - } - - // Pour l'intervalle [12, 23], on remarque que l'origine en Y est toujours 1 et que les mailles - // contenant une face sont sur les Y impairs. - // Enfin, on a "nb_cell_y" faces en Y. - else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - uid -= three_parts_numbering.x; - uid %= nb_face_x * nb_cell_y; - - // debug() << "faceUniqueIdToCoordY (2)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_face_x : " << nb_face_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / nb_face_x) * 2 + 1); - - return (uid / nb_face_x) * 2 + 1; - } - - // Pour l'intervalle [24, 35], on remarque que l'origine en Y est toujours 0 et que les mailles - // contenant une face sont sur les Y pairs. - // Enfin, on a "nb_face_y" faces en Y. - else { - uid -= three_parts_numbering.x + three_parts_numbering.y; - uid %= nb_cell_x * nb_face_y; - - // debug() << "faceUniqueIdToCoordY (3)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_face_y : " << nb_face_y - // << " -- return : " << ((uid / nb_cell_x) * 2); - - return (uid / nb_cell_x) * 2; - } - } +faceUniqueIdToCoordY(Int64 uid, Integer level) const +{ + return m_internal_api->faceUniqueIdToCoordY(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordY(Face face) +faceUniqueIdToCoordY(Face face) const { - const Int64 uid = face.uniqueId(); - return faceUniqueIdToCoordY(uid, faceLevel(uid)); + return m_internal_api->faceUniqueIdToCoordY(face); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordZ(Int64 uid, Integer level) -{ - const Int64 nb_face_x = globalNbFacesX(level); - const Int64 nb_face_y = globalNbFacesY(level); - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - // Int64 initial_uid = uid; - - uid -= first_face_uid; - - Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); - - // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : - // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 - // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ - // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ - // │ │ │ │ - // - // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], - // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. - // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - - // Pour l'intervalle [0, 11], on remarque que l'origine en Z est toujours 0 et que les mailles - // contenant une face sont sur les Z pairs. - // Enfin, on a "nb_face_z" faces en Z. - if (uid < three_parts_numbering.x) { - - // debug() << "faceUniqueIdToCoordZ (1)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2); - - return (uid / (nb_cell_x * nb_cell_y)) * 2; - } - - // Pour l'intervalle [12, 23], on remarque que l'origine en Z est toujours 1 et que les mailles - // contenant une face sont sur les Z impairs. - // Enfin, on a "nb_cell_z" faces en Z. - else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - uid -= three_parts_numbering.x; - - // debug() << "faceUniqueIdToCoordZ (2)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_face_x : " << nb_face_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1); - - return (uid / (nb_face_x * nb_cell_y)) * 2 + 1; - } - - // Pour l'intervalle [24, 35], on remarque que l'origine en Z est toujours 1 et que les mailles - // contenant une face sont sur les Z impairs. - // Enfin, on a "nb_cell_z" faces en Z. - else { - uid -= three_parts_numbering.x + three_parts_numbering.y; - - // debug() << "faceUniqueIdToCoordZ (3)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_face_y : " << nb_face_y - // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1); - - return (uid / (nb_cell_x * nb_face_y)) * 2 + 1; - } +faceUniqueIdToCoordZ(Int64 uid, Integer level) const +{ + return m_internal_api->faceUniqueIdToCoordZ(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueIdToCoordZ(Face face) +faceUniqueIdToCoordZ(Face face) const { - const Int64 uid = face.uniqueId(); - return faceUniqueIdToCoordZ(uid, faceLevel(uid)); + return m_internal_api->faceUniqueIdToCoordZ(face); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueId(Integer level, Int64x3 cell_coord) +cellUniqueId(Integer level, Int64x3 cell_coord) const { - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - const Int64 first_cell_uid = firstCellUniqueId(level); - - return (cell_coord.x + cell_coord.y * nb_cell_x + cell_coord.z * nb_cell_x * nb_cell_y) + first_cell_uid; + return m_internal_api->cellUniqueId(level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueId(Integer level, Int64x2 cell_coord) +cellUniqueId(Integer level, Int64x2 cell_coord) const { - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 first_cell_uid = firstCellUniqueId(level); - - return (cell_coord.x + cell_coord.y * nb_cell_x) + first_cell_uid; + return m_internal_api->cellUniqueId(level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueId(Integer level, Int64x3 node_coord) +nodeUniqueId(Integer level, Int64x3 node_coord) const { - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 nb_node_y = globalNbNodesY(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - return (node_coord.x + node_coord.y * nb_node_x + node_coord.z * nb_node_x * nb_node_y) + first_node_uid; + return m_internal_api->nodeUniqueId(level, node_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueId(Integer level, Int64x2 node_coord) +nodeUniqueId(Integer level, Int64x2 node_coord) const { - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - return (node_coord.x + node_coord.y * nb_node_x) + first_node_uid; + return m_internal_api->nodeUniqueId(level, node_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueId(Integer level, Int64x3 face_coord) -{ - const Int64 nb_face_x = globalNbFacesX(level); - const Int64 nb_face_y = globalNbFacesY(level); - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_cell_y = globalNbCellsY(level); - - Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); - Int64 uid = firstFaceUniqueId(level); - - // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : - // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 - // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ - // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ - // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ - // │ │ │ │ - // - // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], - // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. - // Ici, on veut faire l'inverse : passer des coordonnées x,y,z à un uid. - // Pour identifier les trois intervalles, on regarde quelle coordonnée est pair. - // En effet, pour l'intervalle [0, 11], on s'aperçoit que seule la coordonnée z est pair. - // Pour l'intervalle [12, 23], seule la coordonnée x est pair et pour l'intervalle [24, 35], - // seule la coordonnée y est pair. - - // Intervalle [0, 11]. - if (face_coord.z % 2 == 0) { - // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. - face_coord.x -= 1; - face_coord.y -= 1; - - face_coord /= 2; - - // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_cell_x * nb_cell_y * nb_face_z. - uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y); - } - - // Intervalle [12, 23]. - else if (face_coord.x % 2 == 0) { - uid += three_parts_numbering.x; - - // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. - face_coord.y -= 1; - face_coord.z -= 1; - - face_coord /= 2; - - // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_face_x * nb_cell_y * nb_cell_z. - uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y); - } - - // Intervalle [24, 35]. - else if (face_coord.y % 2 == 0) { - uid += three_parts_numbering.x + three_parts_numbering.y; - - // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. - face_coord.x -= 1; - face_coord.z -= 1; - - face_coord /= 2; - - // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_cell_x * nb_face_y * nb_cell_z. - uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y); - } - else { - ARCANE_FATAL("Bizarre -- x : {0} -- y : {1} -- z : {2}", face_coord.x, face_coord.y, face_coord.z); - } - - return uid; +faceUniqueId(Integer level, Int64x3 face_coord) const +{ + return m_internal_api->faceUniqueId(level, face_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueId(Integer level, Int64x2 face_coord) +faceUniqueId(Integer level, Int64x2 face_coord) const { - const Int64 nb_face_x = globalNbFacesXCartesianView(level); - const Int64 first_face_uid = firstFaceUniqueId(level); - - // On considère que l'on a un niveau imaginaire -1 et que - // l'on obtiendra uid+1 (dans la numérotation utilisée normalement, - // la face à la position (1, 0) a un uid = 0). - // - // x = 0 1 2 3 4 - // ┌──┬──┬──┬──┬──┐ - // y = -1 │ 0│ │ 2│ │ 4│ - // ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ 1│ │ 3│ │ - // ├──┼──┼──┼──┼──┤ - // y = 1 │ 5│ │ 7│ │ 9│ - // ├──┼──┼──┼──┼──┤ - // y = 2 │ │ 6│ │ 8│ │ - // ├──┼──┼──┼──┼──┤ - // y = 3 │10│ │12│ │14│ - // ├──┼──┼──┼──┼──┤ - // y = 4 │ │11│ │13│ │ - // └──┴──┴──┴──┴──┘ - // - - face_coord.y += 1; - - const Int64 a = (face_coord.y / 2) * nb_face_x; - - return (face_coord.x + a - 1) + first_face_uid; // Le -1 est pour revenir à la numérotation normale. + return m_internal_api->faceUniqueId(level, face_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Integer CartesianMeshNumberingMng:: -nbNodeByCell() +nbNodeByCell() const { - return static_cast(std::pow(m_pattern, m_mesh->dimension())); + return m_internal_api->nbNodeByCell(); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) +cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const { - if (uid.size() != nbNodeByCell()) - ARCANE_FATAL("Bad size of arrayview"); - - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 nb_node_y = globalNbNodesY(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; - uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; - uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; - uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; - - uid[4] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; - uid[5] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; - uid[6] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; - uid[7] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; + m_internal_api->cellNodeUniqueIds(uid, level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) +cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const { - if (uid.size() != nbNodeByCell()) - ARCANE_FATAL("Bad size of arrayview"); - - const Int64 nb_node_x = globalNbNodesX(level); - const Int64 first_node_uid = firstNodeUniqueId(level); - - uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid; - uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid; - uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid; - uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid; + m_internal_api->cellNodeUniqueIds(uid, level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) +cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const { - if (m_dimension == 2) { - const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level)); - cellNodeUniqueIds(uid, level, cell_coord); - } - else { - const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level)); - cellNodeUniqueIds(uid, level, cell_coord); - } + m_internal_api->cellNodeUniqueIds(uid, level, cell_uid); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Integer CartesianMeshNumberingMng:: -nbFaceByCell() +nbFaceByCell() const { - return m_pattern * m_dimension; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) -{ - if (uid.size() != nbFaceByCell()) - ARCANE_FATAL("Bad size of arrayview"); - - const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - const Int64x3 nb_face(nb_cell + 1); - - const Int64 first_face_uid = firstFaceUniqueId(level); - - // Numérote les faces - // Cet algo n'est pas basé sur l'algo 2D. - // Les UniqueIDs générés sont contigües. - // Il est aussi possible de retrouver les UniqueIDs des faces - // à l'aide de la position de la cellule et la taille du maillage. - // De plus, l'ordre des UniqueIDs des faces d'une cellule est toujours le - // même (en notation localId Arcane (cell.face(i)) : 0, 3, 1, 4, 2, 5). - // Les UniqueIDs générés sont donc les mêmes quelque soit le découpage. - /* - x z - ┌──► │ ┌──► - │ │ │ - y▼12 13 14 │y▼ ┌────┬────┐ - │ 26 │ 27 │ │ │ 24 │ 25 │ - └────┴────┘ │ 0 4 8 - 15 16 17 │ - │ 28 │ 29 │ │ │ │ │ - └────┴────┘ │ 2 6 10 - z=0 │ x=0 - - - - - - - - - - - - - - - - - - - - z=1 │ x=1 - 18 19 20 │ ┌────┬────┐ - │ 32 │ 33 │ │ │ 30 │ 31 │ - └────┴────┘ │ 1 5 9 - 21 22 23 │ - │ 34 │ 35 │ │ │ │ │ - └────┴────┘ │ 3 7 11 - │ - */ - // On a un cube décomposé en huit cellules (2x2x2). - // Le schéma au-dessus représente les faces des cellules de ce cube avec - // les uniqueIDs que l'algorithme génèrera (sans face_adder). - // Pour cet algo, on commence par les faces "xy". - // On énumère d'abord en x, puis en y, puis en z. - // Une fois les faces "xy" numérotées, on fait les faces "yz". - // Toujours le même ordre de numérotation. - // On termine avec les faces "zx", encore dans le même ordre. - // - // Dans l'implémentation ci-dessous, on fait la numérotation - // maille par maille. - - const Int64 total_face_xy = nb_face.z * nb_cell.x * nb_cell.y; - const Int64 total_face_xy_yz = total_face_xy + nb_face.x * nb_cell.y * nb_cell.z; - - const Int64 nb_cell_before_j = cell_coord.y * nb_cell.x; - - uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + (cell_coord.x); - - uid[3] = uid[0] + nb_cell.x * nb_cell.y; - - uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + (cell_coord.x) + total_face_xy; - - uid[4] = uid[1] + 1; - - uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + (cell_coord.x) + total_face_xy_yz; - - uid[5] = uid[2] + nb_cell.x; - - uid[0] += first_face_uid; - uid[1] += first_face_uid; - uid[2] += first_face_uid; - uid[3] += first_face_uid; - uid[4] += first_face_uid; - uid[5] += first_face_uid; + return m_internal_api->nbFaceByCell(); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) -{ - if (uid.size() != nbFaceByCell()) - ARCANE_FATAL("Bad size of arrayview"); - - const Int64 nb_cell_x = globalNbCellsX(level); - const Int64 nb_face_x = nb_cell_x + 1; - const Int64 first_face_uid = firstFaceUniqueId(level); - - // Numérote les faces - // ┌─0──┬──2─┐ - // 4│ 6│ 8│ - // ├─5──┼─7──┤ - // 9│ 11│ 13│ - // └─10─┴─12─┘ - // - // Avec cette numérotation, HAUT < GAUCHE < BAS < DROITE - // Mis à part les uniqueIds de la première ligne de face, tous - // les uniqueIds sont contigües. - - // HAUT - // - "(current_level_nb_face_x + current_level_nb_cell_x)" : - // le nombre de faces GAUCHE BAS DROITE au dessus. - // - "cell_coord.y * (current_level_nb_face_x + current_level_nb_cell_x)" : - // le nombre total de faces GAUCHE BAS DROITE au dessus. - // - "cell_coord.x * 2" - // on avance deux à deux sur les faces d'un même "coté". - uid[0] = cell_coord.x * 2 + cell_coord.y * (nb_face_x + nb_cell_x); - - // BAS - // Pour BAS, c'est comme HAUT mais avec un "nombre de face du dessus" en plus. - uid[2] = uid[0] + (nb_face_x + nb_cell_x); - // GAUCHE - // Pour GAUCHE, c'est l'UID de BAS -1. - uid[3] = uid[2] - 1; - // DROITE - // Pour DROITE, c'est l'UID de BAS +1. - uid[1] = uid[2] + 1; - - uid[0] += first_face_uid; - uid[1] += first_face_uid; - uid[2] += first_face_uid; - uid[3] += first_face_uid; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) +cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const { - if (m_dimension == 2) { - const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level)); - cellFaceUniqueIds(uid, level, cell_coord); - } - else { - const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level)); - cellFaceUniqueIds(uid, level, cell_coord); - } + m_internal_api->cellFaceUniqueIds(uid, level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellUniqueIdsAroundCell(ArrayView uid, Cell cell) +cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const { - cellUniqueIdsAroundCell(uid, cell.uniqueId(), cell.level()); + m_internal_api->cellFaceUniqueIds(uid, level, cell_coord); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) +cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const { - uid.fill(-1); - - const Int64 coord_cell_x = cellUniqueIdToCoordX(cell_uid, level); - const Int64 coord_cell_y = cellUniqueIdToCoordY(cell_uid, level); - - const Int64 nb_cells_x = globalNbCellsX(level); - const Int64 nb_cells_y = globalNbCellsY(level); - - if (m_dimension == 2) { - ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9")); - - for (Integer j = -1; j < 2; ++j) { - const Int64 coord_around_cell_y = coord_cell_y + j; - if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { - - for (Integer i = -1; i < 2; ++i) { - const Int64 coord_around_cell_x = coord_cell_x + i; - if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { - uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(level, Int64x2(coord_around_cell_x, coord_around_cell_y)); - } - } - } - } - } - - else { - ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27")); - - const Int64 coord_cell_z = cellUniqueIdToCoordZ(cell_uid, level); - const Int64 nb_cells_z = globalNbCellsZ(level); - - for (Integer k = -1; k < 2; ++k) { - const Int64 coord_around_cell_z = coord_cell_z + k; - if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) { - - for (Integer j = -1; j < 2; ++j) { - const Int64 coord_around_cell_y = coord_cell_y + j; - if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { - - for (Integer i = -1; i < 2; ++i) { - const Int64 coord_around_cell_x = coord_cell_x + i; - if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { - uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(level, Int64x3(coord_around_cell_x, coord_around_cell_y, coord_around_cell_z)); - } - } - } - } - } - } - } + m_internal_api->cellFaceUniqueIds(uid, level, cell_uid); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -setChildNodeCoordinates(Cell parent_cell) -{ - if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustRefined)) { - ARCANE_FATAL("Cell not II_JustRefined"); - } - - VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates(); - - const Real3& node0(nodes_coords[parent_cell.node(0)]); - const Real3& node1(nodes_coords[parent_cell.node(1)]); - const Real3& node2(nodes_coords[parent_cell.node(2)]); - const Real3& node3(nodes_coords[parent_cell.node(3)]); - - if (m_dimension == 2) { - - /* - = - ┌─────────────────────►= y3 - │ = ▲ l - ▼ = ▼ - X───────────────X◄────►= y2 - /▲ /▲ = - / │ / │ = - / │ / │ = - / │ / │ = - / │ / │ = - / │ / │ = - / │ / │ = - / │ / │ = - X───────────────X◄───────│─────►= y1 - ▲ │ ▲ │ = ▲ k - │ │ │ │ = ▼ - ├──────────────────────────────►= y0 - │ │ │ │ = - │ │ │ │ = - ▼ ▼ ▼ ▼ - ============================== - x0 ◄───► x3 x1 ◄───► x2 - i j - */ - /*! - * \brief Lambda permettant de déterminer la position d'un noeud enfant - * dans une maille parent. - */ - auto txty = [&](Integer pos_x, Integer pos_y) -> Real3 { - const Real x = (Real)pos_x / (Real)m_pattern; - const Real y = (Real)pos_y / (Real)m_pattern; - - const Real i = (node3.x - node0.x) * y + node0.x; - const Real j = (node2.x - node1.x) * y + node1.x; - - const Real k = (node1.y - node0.y) * x + node0.y; - const Real l = (node2.y - node3.y) * x + node3.y; - - const Real tx = (j - i) * x + i; - const Real ty = (l - k) * y + k; - - /* - info() << "[txty]" - << " x : " << x - << " -- y : " << y - << " -- node0 : " << node0 - << " -- node1 : " << node1 - << " -- node2 : " << node2 - << " -- node3 : " << node3 - << " -- i : " << i - << " -- j : " << j - << " -- k : " << k - << " -- l : " << l - << " -- tx : " << tx - << " -- ty : " << ty; - */ - return { tx, ty, 0 }; - }; - - const Integer node_1d_2d_x[] = { 0, 1, 1, 0 }; - const Integer node_1d_2d_y[] = { 0, 0, 1, 1 }; - - for (Integer j = 0; j < m_pattern; ++j) { - for (Integer i = 0; i < m_pattern; ++i) { - - Integer begin = (i == 0 && j == 0 ? 0 : j == 0 ? 1 - : 2); - Integer end = (i == 0 ? nbNodeByCell() : nbNodeByCell() - 1); - Cell child = childCellOfCell(parent_cell, Int64x2(i, j)); - - for (Integer inode = begin; inode < end; ++inode) { - nodes_coords[child.node(inode)] = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]); - // Real3 pos = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]); - // nodes_coords[child.node(inode)] = pos; - // info() << "Node uid : " << child.node(inode).uniqueId() - // << " -- nodeX : " << (i + node_1d_2d_x[inode]) - // << " -- nodeY : " << (j + node_1d_2d_y[inode]) - // << " -- Pos : " << pos; - } - } - } - } - - else { - const Real3& node4(nodes_coords[parent_cell.node(4)]); - const Real3& node5(nodes_coords[parent_cell.node(5)]); - const Real3& node6(nodes_coords[parent_cell.node(6)]); - const Real3& node7(nodes_coords[parent_cell.node(7)]); - - /*! - * \brief Lambda permettant de déterminer la position d'un noeud enfant - * dans une maille parent. - */ - auto txtytz = [&](Integer pos_x, Integer pos_y, Integer pos_z) -> Real3 { - const Real x = (Real)pos_x / (Real)m_pattern; - const Real y = (Real)pos_y / (Real)m_pattern; - const Real z = (Real)pos_z / (Real)m_pattern; - - // Face (m, n, o, p) entre les faces (node0, node1, node2, node3) et (node4, node5, node6, node7). - const Real3 m = (node4 - node0) * z + node0; - const Real3 n = (node5 - node1) * z + node1; - const Real3 o = (node6 - node2) * z + node2; - const Real3 p = (node7 - node3) * z + node3; - - // On calcule tx et ty comme en 2D mais sur la face (m, n, o, p). - const Real i = (p.x - m.x) * y + m.x; - const Real j = (o.x - n.x) * y + n.x; - - const Real tx = (j - i) * x + i; - - const Real k = (n.y - m.y) * x + m.y; - const Real l = (o.y - p.y) * x + p.y; - - const Real ty = (l - k) * y + k; - - const Real q = (p.z - m.z) * y + m.z; - const Real r = (o.z - n.z) * y + n.z; - - const Real s = (n.z - m.z) * x + m.z; - const Real t = (o.z - p.z) * x + p.z; - - const Real tz = (((r - q) * x + q) + ((t - s) * y + s)) * 0.5; - - /* - info() << "[txtytz]" - << " x : " << x - << " -- y : " << y - << " -- z : " << z - << " -- node0 : " << node0 - << " -- node1 : " << node1 - << " -- node2 : " << node2 - << " -- node3 : " << node3 - << " -- node4 : " << node4 - << " -- node5 : " << node5 - << " -- node6 : " << node6 - << " -- node7 : " << node7 - << " -- m : " << m - << " -- n : " << n - << " -- o : " << o - << " -- p : " << p - << " -- j : " << j - << " -- k : " << k - << " -- l : " << l - << " -- q : " << q - << " -- r : " << r - << " -- s : " << s - << " -- t : " << t - << " -- tx : " << tx - << " -- ty : " << ty - << " -- tz : " << tz; - */ - return { tx, ty, tz }; - }; - - const Integer node_1d_3d_x[] = { 0, 1, 1, 0, 0, 1, 1, 0 }; - const Integer node_1d_3d_y[] = { 0, 0, 1, 1, 0, 0, 1, 1 }; - const Integer node_1d_3d_z[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; - - for (Integer k = 0; k < m_pattern; ++k) { - for (Integer j = 0; j < m_pattern; ++j) { - for (Integer i = 0; i < m_pattern; ++i) { - - // TODO : éviter les multiples appels pour un même noeud. - Integer begin = 0; - Integer end = nbNodeByCell(); - Cell child = childCellOfCell(parent_cell, Int64x3(i, j, k)); - - for (Integer inode = begin; inode < end; ++inode) { - nodes_coords[child.node(inode)] = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]); - // Real3 pos = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]); - // nodes_coords[child.node(inode)] = pos; - // info() << "Node uid : " << child.node(inode).uniqueId() - // << " -- nodeX : " << (i + node_1d_3d_x[inode]) - // << " -- nodeY : " << (j + node_1d_3d_y[inode]) - // << " -- nodeZ : " << (k + node_1d_3d_z[inode]) - // << " -- Pos : " << pos; - } - } - } - } - } +cellUniqueIdsAroundCell(ArrayView uid, Cell cell) const +{ + m_internal_api->cellUniqueIdsAroundCell(uid, cell); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -setParentNodeCoordinates(Cell parent_cell) +cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) const { - if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustAdded)) { - ARCANE_FATAL("Cell not II_JustAdded"); - } - - VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates(); - - if (m_dimension == 2) { - nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, 0)).node(0)]; - nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, 0)).node(1)]; - nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, m_pattern - 1)).node(2)]; - nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, m_pattern - 1)).node(3)]; - } - - else { - nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, 0)).node(0)]; - nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, 0)).node(1)]; - nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, 0)).node(2)]; - nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, 0)).node(3)]; - - nodes_coords[parent_cell.node(4)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, m_pattern - 1)).node(4)]; - nodes_coords[parent_cell.node(5)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, m_pattern - 1)).node(5)]; - nodes_coords[parent_cell.node(6)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, m_pattern - 1)).node(6)]; - nodes_coords[parent_cell.node(7)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, m_pattern - 1)).node(7)]; - } + m_internal_api->cellUniqueIdsAroundCell(uid, cell_uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) +parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) const { - // Pour avoir la face parent d'une maille, on passe d'abord de l'uid vers les - // coordonnées de la maille, - // puis on détermine les coordonnées du parent grâce au m_pattern, - // et enfin, on repasse des coordonnées du parent vers son uid. - - if (globalNbCellsX(level - 1) == 0) { - if (do_fatal) { - ARCANE_FATAL("Level {0} do not exist", (level - 1)); - } - return NULL_ITEM_UNIQUE_ID; - } - - if (m_dimension == 2) { - return cellUniqueId(level - 1, - Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1), - offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1))); - } - else { - return cellUniqueId(level - 1, - Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1), - offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1), - offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level - 1))); - } + return m_internal_api->parentCellUniqueIdOfCell(uid, level, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentCellUniqueIdOfCell(Cell cell, bool do_fatal) +parentCellUniqueIdOfCell(Cell cell, bool do_fatal) const { - return parentCellUniqueIdOfCell(cell.uniqueId(), cell.level(), do_fatal); + return m_internal_api->parentCellUniqueIdOfCell(cell, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) +childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) const { - ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) - ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) - ARCANE_ASSERT((child_coord_in_parent.z < m_pattern && child_coord_in_parent.z >= 0), ("Bad child_coord_in_parent.z")) - - const Int64 uid = cell.uniqueId(); - const Int32 level = cell.level(); - - return cellUniqueId(level + 1, - Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x, - offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y, - offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level + 1) + child_coord_in_parent.z)); + return m_internal_api->childCellUniqueIdOfCell(cell, child_coord_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) +childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) const { - ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) - ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) - - const Int64 uid = cell.uniqueId(); - const Int32 level = cell.level(); - - return cellUniqueId(level + 1, - Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x, - offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y)); + return m_internal_api->childCellUniqueIdOfCell(cell, child_coord_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) +childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) const { - if (m_dimension == 2) { - ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent")) - - return childCellUniqueIdOfCell(cell, - Int64x2( - child_index_in_parent % m_pattern, - child_index_in_parent / m_pattern)); - } - - else { - ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent")) - - const Int64 to_2d = child_index_in_parent % (m_pattern * m_pattern); - return childCellUniqueIdOfCell(cell, - Int64x3( - to_2d % m_pattern, - to_2d / m_pattern, - child_index_in_parent / (m_pattern * m_pattern))); - } + return m_internal_api->childCellUniqueIdOfCell(cell, child_index_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Cell CartesianMeshNumberingMng:: -childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) +childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) const { - ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) - ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) - - Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern) + ((Int32)child_coord_in_parent.z * m_pattern * m_pattern)); - const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent); - - // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId - // recherché, on recherche parmi les autres mailles enfants. - if (child.uniqueId() != uid) { - const Int32 nb_children = cell.nbHChildren(); - for (Integer i = 0; i < nb_children; ++i) { - if (cell.hChild(i).uniqueId() == uid) { - return cell.hChild(i); - } - } - ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId()); - } - return child; + return m_internal_api->childCellOfCell(cell, child_coord_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Cell CartesianMeshNumberingMng:: -childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) +childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) const { - ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) - ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) - - Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern)); - const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent); - - // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId - // recherché, on recherche parmi les autres mailles enfants. - if (child.uniqueId() != uid) { - const Int32 nb_children = cell.nbHChildren(); - for (Integer i = 0; i < nb_children; ++i) { - if (cell.hChild(i).uniqueId() == uid) { - return cell.hChild(i); - } - } - ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId()); - } - return child; + return m_internal_api->childCellOfCell(cell, child_coord_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) +parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) const { - // Pour avoir le noeud parent d'un noeud, on passe d'abord de l'uid vers les - // coordonnées du noeud, puis on détermine les coordonnées du parent grâce au m_pattern, - // et enfin, on repasse des coordonnées du parent vers son uid. - - const Int64 coord_x = nodeUniqueIdToCoordX(uid, level); - const Int64 coord_y = nodeUniqueIdToCoordY(uid, level); - - if (coord_x % m_pattern != 0 || coord_y % m_pattern != 0) { - if (do_fatal) { - ARCANE_FATAL("Node uid={0} do not have parent", uid); - } - return NULL_ITEM_UNIQUE_ID; - } - - if (m_dimension == 2) { - return nodeUniqueId(level - 1, - Int64x2(offsetLevelToLevel(coord_x, level, level - 1), - offsetLevelToLevel(coord_y, level, level - 1))); - } - else { - const Int64 coord_z = nodeUniqueIdToCoordZ(uid, level); - - if (coord_z % m_pattern != 0) { - if (do_fatal) { - ARCANE_FATAL("Node uid={0} do not have parent", uid); - } - return NULL_ITEM_UNIQUE_ID; - } - return nodeUniqueId(level - 1, - Int64x3(offsetLevelToLevel(coord_x, level, level - 1), - offsetLevelToLevel(coord_y, level, level - 1), - offsetLevelToLevel(coord_z, level, level - 1))); - } + return m_internal_api->parentNodeUniqueIdOfNode(uid, level, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentNodeUniqueIdOfNode(Node node, bool do_fatal) +parentNodeUniqueIdOfNode(Node node, bool do_fatal) const { - const Int64 uid = node.uniqueId(); - return parentNodeUniqueIdOfNode(uid, nodeLevel(uid), do_fatal); + return m_internal_api->parentNodeUniqueIdOfNode(node, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childNodeUniqueIdOfNode(Int64 uid, Integer level) +childNodeUniqueIdOfNode(Int64 uid, Integer level) const { - if (m_dimension == 2) { - return nodeUniqueId(level + 1, - Int64x2(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1), - offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1))); - } - - else { - return nodeUniqueId(level + 1, - Int64x3(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1), - offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1), - offsetLevelToLevel(nodeUniqueIdToCoordZ(uid, level), level, level + 1))); - } + return m_internal_api->childNodeUniqueIdOfNode(uid, level); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childNodeUniqueIdOfNode(Node node) +childNodeUniqueIdOfNode(Node node) const { - const Int64 uid = node.uniqueId(); - return childNodeUniqueIdOfNode(uid, nodeLevel(uid)); + return m_internal_api->childNodeUniqueIdOfNode(node); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) +parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) const { - if (m_converting_numbering_face && level == m_ori_level) { - uid = m_face_ori_numbering_to_new[uid]; - } - - // Pour avoir la face parent d'une face, on passe d'abord de l'uid vers les - // coordonnées de la face en "vue cartésienne", - // puis on détermine les coordonnées du parent grâce au m_pattern, - // et enfin, on repasse des coordonnées du parent vers son uid. - - const Int64 coord_x = faceUniqueIdToCoordX(uid, level); - const Int64 coord_y = faceUniqueIdToCoordY(uid, level); - - ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x")) - ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y")) - - const Int64 parent_coord_x = faceOffsetLevelToLevel(coord_x, level, level - 1); - const Int64 parent_coord_y = faceOffsetLevelToLevel(coord_y, level, level - 1); - - if (parent_coord_x == -1 || parent_coord_y == -1) { - if (do_fatal) { - ARCANE_FATAL("Face uid={0} do not have parent", uid); - } - return NULL_ITEM_UNIQUE_ID; - } - - ARCANE_ASSERT((parent_coord_x < globalNbFacesXCartesianView(level - 1) && parent_coord_x >= 0), ("Bad parent_coord_x")) - ARCANE_ASSERT((parent_coord_y < globalNbFacesYCartesianView(level - 1) && parent_coord_y >= 0), ("Bad parent_coord_y")) - - if (m_dimension == 2) { - if (m_converting_numbering_face && level - 1 == m_ori_level) { - return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y))]; - } - return faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y)); - } - else { - const Int64 coord_z = faceUniqueIdToCoordZ(uid, level); - ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z")) - - const Int64 parent_coord_z = faceOffsetLevelToLevel(coord_z, level, level - 1); - - if (parent_coord_z == -1) { - if (do_fatal) { - ARCANE_FATAL("Face uid={0} do not have parent", uid); - } - return NULL_ITEM_UNIQUE_ID; - } - - ARCANE_ASSERT((parent_coord_z < globalNbFacesZCartesianView(level - 1) && parent_coord_z >= 0), ("Bad parent_coord_z")) - - // debug() << "Uid : " << uid << " -- CoordX : " << coord_x << " -- CoordY : " << coord_y << " -- CoordZ : " << coord_z; - - if (m_converting_numbering_face && level - 1 == m_ori_level) { - return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z))]; - } - - return faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z)); - } + return m_internal_api->parentFaceUniqueIdOfFace(uid, level, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -parentFaceUniqueIdOfFace(Face face, bool do_fatal) +parentFaceUniqueIdOfFace(Face face, bool do_fatal) const { - const Int64 uid = face.uniqueId(); - return parentFaceUniqueIdOfFace(uid, faceLevel(uid), do_fatal); + return m_internal_api->parentFaceUniqueIdOfFace(face, do_fatal); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) +childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) const { - if (m_converting_numbering_face && level == m_ori_level) { - uid = m_face_ori_numbering_to_new[uid]; - } - - const Int64 coord_x = faceUniqueIdToCoordX(uid, level); - const Int64 coord_y = faceUniqueIdToCoordY(uid, level); - - ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x")) - ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y")) - - Int64 first_child_coord_x = faceOffsetLevelToLevel(coord_x, level, level + 1); - Int64 first_child_coord_y = faceOffsetLevelToLevel(coord_y, level, level + 1); - - ARCANE_ASSERT((first_child_coord_x < globalNbFacesXCartesianView(level + 1) && first_child_coord_x >= 0), ("Bad first_child_coord_x")) - ARCANE_ASSERT((first_child_coord_y < globalNbFacesYCartesianView(level + 1) && first_child_coord_y >= 0), ("Bad first_child_coord_y")) - - if (m_dimension == 2) { - ARCANE_ASSERT((child_index_in_parent < m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent")) - - if (coord_y % 2 == 0) { - first_child_coord_x += child_index_in_parent * 2; - } - else if (coord_x % 2 == 0) { - first_child_coord_y += child_index_in_parent * globalNbFacesY(level + 1); - } - else { - ARCANE_FATAL("Impossible normalement"); - } - - if (m_converting_numbering_face && level + 1 == m_ori_level) { - return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y))]; - } - - return faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y)); - } - - else { - ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent")) - - const Int64 coord_z = faceUniqueIdToCoordZ(uid, level); - ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z")) - - Int64 first_child_coord_z = faceOffsetLevelToLevel(coord_z, level, level + 1); - ARCANE_ASSERT((first_child_coord_z < globalNbFacesZCartesianView(level + 1) && first_child_coord_z >= 0), ("Bad first_child_coord_z")) - - Int64 child_x = child_index_in_parent % m_pattern; - Int64 child_y = child_index_in_parent / m_pattern; - - Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); - - if (uid < three_parts_numbering.x) { - first_child_coord_x += child_x * 2; - first_child_coord_y += child_y * 2; - } - else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - first_child_coord_y += child_x * 2; - first_child_coord_z += child_y * 2; - } - else { - first_child_coord_x += child_x * 2; - first_child_coord_z += child_y * 2; - } - - if (m_converting_numbering_face && level + 1 == m_ori_level) { - return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z))]; - } - - return faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z)); - } + return m_internal_api->childFaceUniqueIdOfFace(uid, level, child_index_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) +childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) const { - const Int64 uid = face.uniqueId(); - return childFaceUniqueIdOfFace(uid, faceLevel(uid), child_index_in_parent); + return m_internal_api->childFaceUniqueIdOfFace(face, child_index_in_parent); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -Int64x3 CartesianMeshNumberingMng:: -_face3DNumberingThreeParts(Integer level) const -{ - const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return { (nb_cell.z + 1) * nb_cell.x * nb_cell.y, (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x }; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshNumberingMng:: -_pushFront(UniqueArray& array, const Int64 elem) +ICartesianMeshNumberingMngInternal* CartesianMeshNumberingMng:: +_internalApi() const { - array.resize(array.size() + 1); - array.back() = elem; - for (Integer i = array.size() - 2; i >= 0; --i) { - std::swap(array[i], array[i + 1]); - } + return m_internal_api.get(); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h index 41b231c6b2..03590f98af 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h @@ -18,15 +18,9 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" - -#include "arcane/utils/TraceAccessor.h" -#include "arcane/utils/Vector3.h" - +#include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/core/Item.h" -#include - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -36,178 +30,132 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -class CartesianMeshNumberingMng -: public TraceAccessor -, public ICartesianMeshNumberingMng -{ - public: +class ICartesianMeshNumberingMngInternal; - explicit CartesianMeshNumberingMng(IMesh* mesh); +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +class ARCANE_CARTESIANMESH_EXPORT CartesianMeshNumberingMng +{ public: - void _build() override; - void _saveInfosInProperties() override; - void _recreateFromDump() override; - - void renumberingFacesLevel0FromOriginalArcaneNumbering() override; - - void printStatus() override; - - void prepareLevel(Int32 level) override; - void updateFirstLevel() override; + explicit CartesianMeshNumberingMng(ICartesianMesh* mesh); - Int64 firstCellUniqueId(Integer level) const override; - Int64 firstNodeUniqueId(Integer level) const override; - Int64 firstFaceUniqueId(Integer level) const override; + public: - Int64 globalNbCellsX(Integer level) const override; - Int64 globalNbCellsY(Integer level) const override; - Int64 globalNbCellsZ(Integer level) const override; + void printStatus(); - Int64 globalNbNodesX(Integer level) const override; - Int64 globalNbNodesY(Integer level) const override; - Int64 globalNbNodesZ(Integer level) const override; + Int64 firstCellUniqueId(Integer level) const; + Int64 firstNodeUniqueId(Integer level) const; + Int64 firstFaceUniqueId(Integer level) const; - Int64 globalNbFacesX(Integer level) const override; - Int64 globalNbFacesY(Integer level) const override; - Int64 globalNbFacesZ(Integer level) const override; + Int64 globalNbCellsX(Integer level) const; + Int64 globalNbCellsY(Integer level) const; + Int64 globalNbCellsZ(Integer level) const; - Int64 globalNbFacesXCartesianView(Integer level) const override; - Int64 globalNbFacesYCartesianView(Integer level) const override; - Int64 globalNbFacesZCartesianView(Integer level) const override; + Int64 globalNbNodesX(Integer level) const; + Int64 globalNbNodesY(Integer level) const; + Int64 globalNbNodesZ(Integer level) const; - Int64 nbCellInLevel(Integer level) const override; - Int64 nbNodeInLevel(Integer level) const override; - Int64 nbFaceInLevel(Integer level) const override; + Int64 globalNbFacesX(Integer level) const; + Int64 globalNbFacesY(Integer level) const; + Int64 globalNbFacesZ(Integer level) const; - Integer pattern() const override; + Int64 globalNbFacesXCartesianView(Integer level) const; + Int64 globalNbFacesYCartesianView(Integer level) const; + Int64 globalNbFacesZCartesianView(Integer level) const; - Int32 cellLevel(Int64 uid) const override; - Int32 nodeLevel(Int64 uid) const override; - Int32 faceLevel(Int64 uid) const override; + Int64 nbCellInLevel(Integer level) const; + Int64 nbNodeInLevel(Integer level) const; + Int64 nbFaceInLevel(Integer level) const; - Int64 offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override; - Int64 faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override; + Integer pattern() const; - Int64 cellUniqueIdToCoordX(Int64 uid, Integer level) override; - Int64 cellUniqueIdToCoordX(Cell cell) override; + Int32 cellLevel(Int64 uid) const; + Int32 nodeLevel(Int64 uid) const; + Int32 faceLevel(Int64 uid) const; - Int64 cellUniqueIdToCoordY(Int64 uid, Integer level) override; - Int64 cellUniqueIdToCoordY(Cell cell) override; + Int64 offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const; + Int64 faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const; - Int64 cellUniqueIdToCoordZ(Int64 uid, Integer level) override; - Int64 cellUniqueIdToCoordZ(Cell cell) override; + Int64 cellUniqueIdToCoordX(Int64 uid, Integer level) const; + Int64 cellUniqueIdToCoordX(Cell cell) const; - Int64 nodeUniqueIdToCoordX(Int64 uid, Integer level) override; - Int64 nodeUniqueIdToCoordX(Node node) override; + Int64 cellUniqueIdToCoordY(Int64 uid, Integer level) const; + Int64 cellUniqueIdToCoordY(Cell cell) const; - Int64 nodeUniqueIdToCoordY(Int64 uid, Integer level) override; - Int64 nodeUniqueIdToCoordY(Node node) override; + Int64 cellUniqueIdToCoordZ(Int64 uid, Integer level) const; + Int64 cellUniqueIdToCoordZ(Cell cell) const; - Int64 nodeUniqueIdToCoordZ(Int64 uid, Integer level) override; - Int64 nodeUniqueIdToCoordZ(Node node) override; + Int64 nodeUniqueIdToCoordX(Int64 uid, Integer level) const; + Int64 nodeUniqueIdToCoordX(Node node) const; - Int64 faceUniqueIdToCoordX(Int64 uid, Integer level) override; - Int64 faceUniqueIdToCoordX(Face face) override; + Int64 nodeUniqueIdToCoordY(Int64 uid, Integer level) const; + Int64 nodeUniqueIdToCoordY(Node node) const; - Int64 faceUniqueIdToCoordY(Int64 uid, Integer level) override; - Int64 faceUniqueIdToCoordY(Face face) override; + Int64 nodeUniqueIdToCoordZ(Int64 uid, Integer level) const; + Int64 nodeUniqueIdToCoordZ(Node node) const; - Int64 faceUniqueIdToCoordZ(Int64 uid, Integer level) override; - Int64 faceUniqueIdToCoordZ(Face face) override; + Int64 faceUniqueIdToCoordX(Int64 uid, Integer level) const; + Int64 faceUniqueIdToCoordX(Face face) const; - Int64 cellUniqueId(Integer level, Int64x3 cell_coord) override; - Int64 cellUniqueId(Integer level, Int64x2 cell_coord) override; + Int64 faceUniqueIdToCoordY(Int64 uid, Integer level) const; + Int64 faceUniqueIdToCoordY(Face face) const; - Int64 nodeUniqueId(Integer level, Int64x3 node_coord) override; - Int64 nodeUniqueId(Integer level, Int64x2 node_coord) override; + Int64 faceUniqueIdToCoordZ(Int64 uid, Integer level) const; + Int64 faceUniqueIdToCoordZ(Face face) const; - Int64 faceUniqueId(Integer level, Int64x3 face_coord) override; - Int64 faceUniqueId(Integer level, Int64x2 face_coord) override; + Int64 cellUniqueId(Integer level, Int64x3 cell_coord) const; + Int64 cellUniqueId(Integer level, Int64x2 cell_coord) const; - Integer nbNodeByCell() override; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + Int64 nodeUniqueId(Integer level, Int64x3 node_coord) const; + Int64 nodeUniqueId(Integer level, Int64x2 node_coord) const; - Integer nbFaceByCell() override; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + Int64 faceUniqueId(Integer level, Int64x3 face_coord) const; + Int64 faceUniqueId(Integer level, Int64x2 face_coord) const; - void cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) override; - void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) override; + Integer nbNodeByCell() const; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const; - void setChildNodeCoordinates(Cell parent_cell) override; - void setParentNodeCoordinates(Cell parent_cell) override; + Integer nbFaceByCell() const; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const; - Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) override; - Int64 parentCellUniqueIdOfCell(Cell cell, bool do_fatal) override; + void cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) const; + void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) const; - Int64 childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) override; - Int64 childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) override; - Int64 childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) override; + Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) const; + Int64 parentCellUniqueIdOfCell(Cell cell, bool do_fatal) const; - Cell childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) override; - Cell childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) override; + Int64 childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) const; + Int64 childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) const; + Int64 childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) const; - Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) override; - Int64 parentNodeUniqueIdOfNode(Node node, bool do_fatal) override; + Cell childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) const; + Cell childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) const; - Int64 childNodeUniqueIdOfNode(Int64 uid, Integer level) override; - Int64 childNodeUniqueIdOfNode(Node node) override; + Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) const; + Int64 parentNodeUniqueIdOfNode(Node node, bool do_fatal) const; - Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) override; - Int64 parentFaceUniqueIdOfFace(Face face, bool do_fatal) override; + Int64 childNodeUniqueIdOfNode(Int64 uid, Integer level) const; + Int64 childNodeUniqueIdOfNode(Node node) const; - Int64 childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) override; - Int64 childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) override; + Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) const; + Int64 parentFaceUniqueIdOfFace(Face face, bool do_fatal) const; - private: + Int64 childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) const; + Int64 childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) const; - /*! - * \brief Méthode permettant de récupérer le nombre de faces des trois parties de la numérotation. - * - * En effet, pour numéroter en 3D, on numérote d'abord les faces xy, puis les faces yz et enfin - * les faces zx. Cette méthode permet de récupérer le nombre de faces {xy, yz, zx}. - * - * \param level Le niveau de la numérotation. - * \return Le nombre de faces {xy, yz, zx}. - */ - Int64x3 _face3DNumberingThreeParts(Integer level) const; + public: - static void _pushFront(UniqueArray& array, Int64 elem); + ICartesianMeshNumberingMngInternal* _internalApi() const; private: - IMesh* m_mesh; - - Ref m_properties; - - Integer m_dimension; - Integer m_pattern; - - UniqueArray m_p_to_l_level; - Int32 m_max_level; - Int32 m_min_level; - - Int64 m_latest_cell_uid; - UniqueArray m_first_cell_uid_level; - - Int64 m_latest_node_uid; - UniqueArray m_first_node_uid_level; - - Int64 m_latest_face_uid; - UniqueArray m_first_face_uid_level; - - Int64x3 m_nb_cell_ground; - - // Partie conversion numérotation d'origine <-> nouvelle numérotation (face). - bool m_converting_numbering_face; - Integer m_ori_level; - std::unordered_map m_face_ori_numbering_to_new; - std::unordered_map m_face_new_numbering_to_ori; + Ref m_internal_api; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc index 2c14aa8e1c..1de36c44e2 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc @@ -31,23 +31,34 @@ namespace Arcane /*---------------------------------------------------------------------------*/ CartesianMeshPatch:: -CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index) +CartesianMeshPatch(ICartesianMesh* cmesh, Integer patch_index, const AMRPatchPosition& position) : TraceAccessor(cmesh->traceMng()) , m_mesh(cmesh) +, m_position(position) , m_amr_patch_index(patch_index) +, m_impl(this) { Integer nb_dir = cmesh->mesh()->dimension(); - for( Integer i=0; i(i); - m_cell_directions[i]._internalInit(cmesh,dir,patch_index); - m_face_directions[i]._internalInit(cmesh,dir,patch_index); - m_node_directions[i]._internalInit(cmesh,dir,patch_index); + m_cell_directions[i]._internalInit(cmesh, dir, patch_index); + m_face_directions[i]._internalInit(cmesh, dir, patch_index); + m_node_directions[i]._internalInit(cmesh, dir, patch_index); } } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +CartesianMeshPatch:: +CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index) +: CartesianMeshPatch(cmesh, patch_index, {}) +{ +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CartesianMeshPatch:: ~CartesianMeshPatch() { diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc index 9c56d9937e..17fef21fff 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc @@ -35,25 +35,6 @@ createCartesianMeshCoarsening2(ICartesianMesh* cm) return cm->_internalApi()->createCartesianMeshCoarsening2(); } -/*! - * \brief Créé une instance pour gérer le déraffinement du maillage (V3?). - * \warning Very experimental method ! - */ -Ref CartesianMeshUtils:: -cartesianMeshAMRPatchMng(ICartesianMesh* cm) -{ - return cm->_internalApi()->cartesianMeshAMRPatchMng(); -} - -/*! - * TODO - */ -Ref CartesianMeshUtils:: -cartesianMeshNumberingMng(ICartesianMesh* cm) -{ - return cm->_internalApi()->cartesianMeshNumberingMng(); -} - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h index c56acf5ece..b2b5bcfc6c 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h @@ -17,8 +17,6 @@ #include "arcane/utils/Ref.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" -#include "arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h" -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -38,19 +36,6 @@ namespace Arcane::CartesianMeshUtils extern "C++" ARCANE_CARTESIANMESH_EXPORT Ref createCartesianMeshCoarsening2(ICartesianMesh* cm); -/*! - * \brief Créé une instance pour gérer le déraffinement du maillage (V3?). - * \warning Very experimental method ! - */ -extern "C++" ARCANE_CARTESIANMESH_EXPORT Ref -cartesianMeshAMRPatchMng(ICartesianMesh* cm); - -/*! - * TODO - */ -extern "C++" ARCANE_CARTESIANMESH_EXPORT Ref -cartesianMeshNumberingMng(ICartesianMesh* cm); - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.h b/arcane/src/arcane/cartesianmesh/CartesianPatch.h index 2c74fb1461..57910a3ada 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.h @@ -111,6 +111,12 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch m_patch->checkValid(); } + AMRPatchPosition position() const + { + ARCANE_CHECK_POINTER(m_patch); + return m_patch->position(); + } + //! Indique si le patch est nul. bool isNull() const { return !m_patch; } diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h index 46f369f519..1a4f9c50ed 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h @@ -27,6 +27,11 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +class ICartesianMeshPatchInternal; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + /*! * \ingroup ArcaneCartesianMesh * \brief Interface d'un patch AMR d'un maillage cartésien. @@ -65,7 +70,9 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatch //! Effectue des vérifications sur la validité de l'instance. virtual void checkValid() const =0; - virtual AMRPatchPosition& position() = 0; + virtual AMRPatchPosition position() const = 0; + + virtual ICartesianMeshPatchInternal* _internalApi() = 0; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc similarity index 98% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc index 5874a8730c..8e827a4fc0 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc @@ -11,9 +11,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPositionLevelGroup.h" - -#include "arcane/core/ArcaneTypes.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h similarity index 98% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h index 11a78c82f6..9e32e71f15 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionLevelGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h @@ -17,7 +17,6 @@ #include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" -#include "arcane/utils/Vector3.h" #include "arcane/utils/UniqueArray.h" /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc similarity index 97% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc index d4951dca47..6d35cbdfa3 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc @@ -11,16 +11,16 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPositionSignature.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" -#include "ICartesianMesh.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/core/ArcaneTypes.h" #include "arcane/core/IMesh.h" #include "arcane/core/IParallelMng.h" #include "arcane/core/ItemEnumerator.h" #include "arcane/utils/FatalErrorException.h" -#include "arccore/trace/ITraceMng.h" -#include "internal/ICartesianMeshInternal.h" +#include "arcane/utils/ITraceMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -60,7 +60,7 @@ AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatc , m_mesh(cmesh) , m_nb_cut(0) , m_stop_cut(false) -, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMng().get()) +, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMngInternal().get()) , m_have_cells(false) , m_is_computed(false) , m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0) @@ -76,7 +76,7 @@ AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatc , m_mesh(cmesh) , m_nb_cut(nb_cut) , m_stop_cut(false) -, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMng().get()) +, m_numbering(cmesh->_internalApi()->cartesianMeshNumberingMngInternal().get()) , m_have_cells(false) , m_is_computed(false) , m_sig_x(patch.maxPoint().x - patch.minPoint().x, 0) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h similarity index 94% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h index dcef338e89..c5ce182ddf 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignature.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h @@ -14,8 +14,8 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "AMRPatchPositionLevelGroup.h" -#include "ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" @@ -67,8 +67,7 @@ class AMRPatchPositionSignature Integer m_nb_cut; bool m_stop_cut; - ICartesianMeshNumberingMng* m_numbering; - + ICartesianMeshNumberingMngInternal* m_numbering; bool m_have_cells; bool m_is_computed; diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc similarity index 98% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc index 98ff90f6ce..af1ba7bea4 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc @@ -11,16 +11,12 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPositionSignatureCut.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h" -#include "ICartesianMesh.h" -#include "arcane/core/ArcaneTypes.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/core/IMesh.h" -#include "arcane/core/IParallelMng.h" -#include "arcane/core/ItemEnumerator.h" #include "arcane/utils/FatalErrorException.h" -#include "arccore/trace/ITraceMng.h" -#include "internal/ICartesianMeshInternal.h" +#include "arcane/utils/ITraceMng.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h similarity index 91% rename from arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h rename to arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h index 6319d112d0..a72aae992a 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPositionSignatureCut.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h @@ -14,13 +14,11 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "AMRPatchPositionLevelGroup.h" -#include "AMRPatchPositionSignature.h" -#include "ICartesianMeshNumberingMng.h" -#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" -#include "arcane/utils/Vector3.h" #include "arcane/utils/UniqueArray.h" /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc similarity index 99% rename from arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc rename to arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc index eb114b3263..a5468c6e22 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc @@ -11,7 +11,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include +#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h" #include "arcane/cartesianmesh/CellDirectionMng.h" #include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" @@ -40,7 +40,7 @@ namespace Arcane /*---------------------------------------------------------------------------*/ CartesianMeshAMRPatchMng:: -CartesianMeshAMRPatchMng(ICartesianMesh* cmesh, ICartesianMeshNumberingMng* numbering_mng) +CartesianMeshAMRPatchMng(ICartesianMesh* cmesh, ICartesianMeshNumberingMngInternal* numbering_mng) : TraceAccessor(cmesh->mesh()->traceMng()) , m_mesh(cmesh->mesh()) , m_cmesh(cmesh) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h similarity index 92% rename from arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h rename to arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h index ce82cd8fbd..5954cd5372 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRPatchMng.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h @@ -17,9 +17,9 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h" #include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/utils/TraceAccessor.h" @@ -38,7 +38,7 @@ class CartesianMeshAMRPatchMng { public: - explicit CartesianMeshAMRPatchMng(ICartesianMesh* cmesh, ICartesianMeshNumberingMng* numbering_mng); + explicit CartesianMeshAMRPatchMng(ICartesianMesh* cmesh, ICartesianMeshNumberingMngInternal* numbering_mng); public: @@ -58,7 +58,7 @@ class CartesianMeshAMRPatchMng IMesh* m_mesh; ICartesianMesh* m_cmesh; - ICartesianMeshNumberingMng* m_num_mng; + ICartesianMeshNumberingMngInternal* m_num_mng; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc new file mode 100644 index 0000000000..3760d271a4 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc @@ -0,0 +1,2278 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* CartesianMeshNumberingMngInternal.cc (C) 2000-2025 */ +/* */ +/* Gestionnaire de numérotation de maillage cartesian. La numérotation */ +/* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h" + +#include "arcane/utils/Vector2.h" +#include "arcane/utils/ITraceMng.h" + +#include "arcane/core/IMesh.h" +#include "arcane/core/IParallelMng.h" +#include "arcane/core/VariableTypes.h" +#include "arcane/core/ICartesianMeshGenerationInfo.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/Properties.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CartesianMeshNumberingMngInternal:: +CartesianMeshNumberingMngInternal(IMesh* mesh) +: TraceAccessor(mesh->traceMng()) +, m_mesh(mesh) +, m_dimension(mesh->dimension()) +, m_pattern(2) +, m_max_level(0) +, m_min_level(0) +, m_converting_numbering_face(true) +, m_ori_level(0) +{ + const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); + + Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); + m_nb_cell_ground.x = global_nb_cells_by_direction[MD_DirX]; + m_nb_cell_ground.y = global_nb_cells_by_direction[MD_DirY]; + m_nb_cell_ground.z = ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ]); + + if (m_nb_cell_ground.x <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", m_nb_cell_ground.x); + if (m_nb_cell_ground.y <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", m_nb_cell_ground.y); + if (m_nb_cell_ground.z <= 0) + ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", m_nb_cell_ground.z); + + if (m_dimension == 2) { + m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y; + m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1); + m_latest_face_uid = (m_nb_cell_ground.x * m_nb_cell_ground.y) * 2 + m_nb_cell_ground.x * 2 + m_nb_cell_ground.y; + } + else { + m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y * m_nb_cell_ground.z; + m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1) * (m_nb_cell_ground.z + 1); + m_latest_face_uid = (m_nb_cell_ground.z + 1) * m_nb_cell_ground.x * m_nb_cell_ground.y + (m_nb_cell_ground.x + 1) * m_nb_cell_ground.y * m_nb_cell_ground.z + (m_nb_cell_ground.y + 1) * m_nb_cell_ground.z * m_nb_cell_ground.x; + } + + m_first_cell_uid_level.add(0); + m_first_node_uid_level.add(0); + m_first_face_uid_level.add(0); + + // Tant qu'on utilise la numérotation d'origine pour le niveau 0, on doit utiliser + // une conversion de la numérotation d'origine vers la nouvelle. + // TODO AH : Ça risque de pas très bien se passer en cas de repartitionnement... + if (m_converting_numbering_face) { + UniqueArray face_uid(CartesianMeshNumberingMngInternal::nbFaceByCell()); + ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(0)) { + CartesianMeshNumberingMngInternal::cellFaceUniqueIds(face_uid, 0, icell->uniqueId()); + for (Integer i = 0; i < CartesianMeshNumberingMngInternal::nbFaceByCell(); ++i) { + m_face_ori_numbering_to_new[icell->face(i).uniqueId()] = face_uid[i]; + m_face_new_numbering_to_ori[face_uid[i]] = icell->face(i).uniqueId(); + // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i]; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +_build() +{ + m_properties = makeRef(new Properties(*(m_mesh->properties()), "CartesianMeshNumberingMngInternal")); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +_saveInfosInProperties() +{ + m_properties->set("Version", 1); + m_properties->set("FirstCellUIDByLevel", m_first_cell_uid_level); + + // Voir pour le recalculer à la reprise. + m_properties->set("FirstNodeUIDByLevel", m_first_node_uid_level); + m_properties->set("FirstFaceUIDByLevel", m_first_face_uid_level); + + m_properties->set("OriginalGroundLevelForConverting", m_ori_level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +_recreateFromDump() +{ + Int32 v = m_properties->getInt32("Version"); + if (v != 1) + ARCANE_FATAL("Bad numbering mng version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1); + + m_properties->get("FirstCellUIDByLevel", m_first_cell_uid_level); + m_properties->get("FirstNodeUIDByLevel", m_first_node_uid_level); + m_properties->get("FirstFaceUIDByLevel", m_first_face_uid_level); + + m_properties->get("OriginalGroundLevelForConverting", m_ori_level); + if (m_ori_level == -1) { + m_converting_numbering_face = false; + m_face_ori_numbering_to_new.clear(); + m_face_new_numbering_to_ori.clear(); + } + + m_nb_cell_ground = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) }; + + m_max_level = m_first_cell_uid_level.size() - 1; + + { + Integer pos = 0; + Int64 max = 0; + Integer iter = 0; + for (const Int64 elem : m_first_cell_uid_level) { + if (elem > max) { + max = elem; + pos = iter; + } + iter++; + } + m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos); + m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos); + m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +renumberingFacesLevel0FromOriginalArcaneNumbering() +{ + if (!m_converting_numbering_face) + return; + + UniqueArray face_uid(nbFaceByCell()); + ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(m_ori_level)) { + cellFaceUniqueIds(face_uid, m_ori_level, icell->uniqueId()); + for (Integer i = 0; i < nbFaceByCell(); ++i) { + // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i]; + icell->face(i).mutableItemBase().setUniqueId(face_uid[i]); + } + } + m_mesh->faceFamily()->notifyItemsUniqueIdChanged(); + m_mesh->checkValidMesh(); + + m_converting_numbering_face = false; + m_ori_level = -1; + m_face_ori_numbering_to_new.clear(); + m_face_new_numbering_to_ori.clear(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +printStatus() +{ + ITraceMng* tm = m_mesh->traceMng(); + Trace::Setter _(tm, "CartesianMeshNumberingMngInternal"); + + tm->info() << "CartesianMeshNumberingMngInternal status :"; + + // tm->info() << "FirstCellUIDByLevel : " << m_first_cell_uid_level; + // tm->info() << "FirstNodeUIDByLevel : " << m_first_node_uid_level; + // tm->info() << "FirstFaceUIDByLevel : " << m_first_face_uid_level; + + tm->info() << "LatestCellUID : " << m_latest_cell_uid; + tm->info() << "LatestNodeUID : " << m_latest_node_uid; + tm->info() << "LatestFaceUID : " << m_latest_face_uid; + + tm->info() << "MinLevel : " << m_min_level; + tm->info() << "MaxLevel : " << m_max_level; + + tm->info() << "GroundLevelNbCells : " << m_nb_cell_ground; + + if (m_ori_level == -1) { + tm->info() << "Ground Level is renumbered"; + } + else { + tm->info() << "Ground Level is not renumbered -- OriginalGroundLevel : " << m_ori_level; + } + + for (Integer i = m_min_level; i <= m_max_level; ++i) { + tm->info() << "Level " << i << " : "; + tm->info() << "\tUID Cells : [" << firstCellUniqueId(i) << ", " << (firstCellUniqueId(i) + nbCellInLevel(i)) << "["; + tm->info() << "\tUID Nodes : [" << firstNodeUniqueId(i) << ", " << (firstNodeUniqueId(i) + nbNodeInLevel(i)) << "["; + tm->info() << "\tUID Faces : [" << firstFaceUniqueId(i) << ", " << (firstFaceUniqueId(i) + nbFaceInLevel(i)) << "["; + } + + const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true); + + Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells(); + tm->info() << "global_nb_cells_by_direction.x : " << global_nb_cells_by_direction[MD_DirX]; + tm->info() << "global_nb_cells_by_direction.y : " << global_nb_cells_by_direction[MD_DirY]; + tm->info() << "global_nb_cells_by_direction.z : " << global_nb_cells_by_direction[MD_DirZ]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +prepareLevel(Int32 level) +{ + if (level <= m_max_level && level >= m_min_level) + return; + if (level == m_max_level + 1) { + m_max_level++; + m_first_cell_uid_level.add(m_latest_cell_uid); + m_first_node_uid_level.add(m_latest_node_uid); + m_first_face_uid_level.add(m_latest_face_uid); + } + else if (level == m_min_level - 1) { + m_min_level--; + _pushFront(m_first_cell_uid_level, m_latest_cell_uid); + _pushFront(m_first_node_uid_level, m_latest_node_uid); + _pushFront(m_first_face_uid_level, m_latest_face_uid); + } + else { + ARCANE_FATAL("Level error : {0}", level); + } + + m_latest_cell_uid += nbCellInLevel(level); + m_latest_node_uid += nbNodeInLevel(level); + m_latest_face_uid += nbFaceInLevel(level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +updateFirstLevel() +{ + const Int32 nb_levels_to_add = -m_min_level; + m_ori_level += nb_levels_to_add; + + if (nb_levels_to_add == 0) { + return; + } + + m_max_level += nb_levels_to_add; + m_min_level += nb_levels_to_add; + + const Integer to_div = m_pattern * nb_levels_to_add; + if (m_dimension == 2) { + m_nb_cell_ground.x /= to_div; + m_nb_cell_ground.y /= to_div; + // z reste à 1. + } + else { + m_nb_cell_ground /= to_div; + } + + // ---------- + // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() + // Recalcule les informations sur le nombre de mailles par direction. + auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, false); + if (!cmgi) + return; + + { + ConstArrayView v = cmgi->ownCellOffsets(); + cmgi->setOwnCellOffsets(v[0] / to_div, v[1] / to_div, v[2] / to_div); + } + { + ConstArrayView v = cmgi->globalNbCells(); + cmgi->setGlobalNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); + } + { + ConstArrayView v = cmgi->ownNbCells(); + cmgi->setOwnNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div); + } + cmgi->setFirstOwnCellUniqueId(firstCellUniqueId(0)); + // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo() + // ---------- +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +firstCellUniqueId(Integer level) const +{ + return m_first_cell_uid_level[level - m_min_level]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +firstNodeUniqueId(Integer level) const +{ + return m_first_node_uid_level[level - m_min_level]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +firstFaceUniqueId(Integer level) const +{ + return m_first_face_uid_level[level - m_min_level]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbCellsX(Integer level) const +{ + return static_cast(static_cast(m_nb_cell_ground.x) * std::pow(m_pattern, level)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbCellsY(Integer level) const +{ + return static_cast(static_cast(m_nb_cell_ground.y) * std::pow(m_pattern, level)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbCellsZ(Integer level) const +{ + return static_cast(static_cast(m_nb_cell_ground.z) * std::pow(m_pattern, level)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbNodesX(Integer level) const +{ + return globalNbCellsX(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbNodesY(Integer level) const +{ + return globalNbCellsY(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbNodesZ(Integer level) const +{ + return globalNbCellsZ(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesX(Integer level) const +{ + return globalNbCellsX(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesY(Integer level) const +{ + return globalNbCellsY(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesZ(Integer level) const +{ + return globalNbCellsZ(level) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesXCartesianView(Integer level) const +{ + return (globalNbCellsX(level) * 2) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesYCartesianView(Integer level) const +{ + return (globalNbCellsY(level) * 2) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +globalNbFacesZCartesianView(Integer level) const +{ + return (globalNbCellsZ(level) * 2) + 1; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nbCellInLevel(Integer level) const +{ + if (m_dimension == 2) { + const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); + return nb_cell.x * nb_cell.y; + } + + const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); + return nb_cell.x * nb_cell.y * nb_cell.z; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nbNodeInLevel(Integer level) const +{ + if (m_dimension == 2) { + const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); + return (nb_cell.x + 1) * (nb_cell.y + 1); + } + + const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); + return (nb_cell.x + 1) * (nb_cell.y + 1) * (nb_cell.z + 1); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nbFaceInLevel(Integer level) const +{ + if (m_dimension == 2) { + const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level)); + return (nb_cell.x * nb_cell.y) * 2 + nb_cell.x * 2 + nb_cell.y; + } + + const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); + return (nb_cell.z + 1) * nb_cell.x * nb_cell.y + (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer CartesianMeshNumberingMngInternal:: +pattern() const +{ + return m_pattern; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int32 CartesianMeshNumberingMngInternal:: +cellLevel(Int64 uid) const +{ + Integer pos = -1; + Int64 max = 0; + + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstCellUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } + } + return pos; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int32 CartesianMeshNumberingMngInternal:: +nodeLevel(Int64 uid) const +{ + Integer pos = -1; + Int64 max = 0; + + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstNodeUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } + } + return pos; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int32 CartesianMeshNumberingMngInternal:: +faceLevel(Int64 uid) const +{ + Integer pos = -1; + Int64 max = 0; + + for (Integer i = m_min_level; i <= m_max_level; ++i) { + const Int64 first_uid = firstFaceUniqueId(i); + if (first_uid <= uid && first_uid > max) { + pos = i; + max = first_uid; + } + } + return pos; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes. +Int64 CartesianMeshNumberingMngInternal:: +offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const +{ + if (level_from == level_to) { + return coord; + } + else if (level_from < level_to) { + return coord * m_pattern * (level_to - level_from); + } + else { + return coord / (m_pattern * (level_from - level_to)); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes. +Int64 CartesianMeshNumberingMngInternal:: +faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const +{ + // Admettons que l'on ai les faces suivantes : + // ┌─0──┬──2─┐ + // 4│ 6│ 8│ + // ├─5──┼─7──┤ + // 9│ 11│ 13│ + // └─10─┴─12─┘ + + // Pour la position d'une face, on considère cette disposition : + // ┌──┬──┬──┬──┬──┐ + // │ │ 0│ │ 2│ │ + // ├──┼──┼──┼──┼──┤ + // │ 4│ │ 6│ │ 8│ + // ├──┼──┼──┼──┼──┤ + // │ │ 5│ │ 7│ │ + // ├──┼──┼──┼──┼──┤ + // │ 9│ │11│ │13│ + // ├──┼──┼──┼──┼──┤ + // │ │10│ │12│ │ + // └──┴──┴──┴──┴──┘ + + if (level_from == level_to) { + return coord; + } + else if (level_from < level_to) { + const Integer pattern = m_pattern * (level_to - level_from); + if (coord % 2 == 0) { + return coord * pattern; + } + else { + return ((coord - 1) * pattern) + 1; + } + } + else { + const Integer pattern = m_pattern * (level_from - level_to); + if (coord % 2 == 0) { + if (coord % (pattern * 2) == 0) { + return coord / pattern; + } + else { + return -1; + } + } + else { + // auto a = coord - 1; + // auto b = a % (pattern * 2); + // auto c = a / (pattern * 2); + // auto d = c * (2 * (pattern - 1)); + // auto e = d + b; + // auto f = coord - e; + // return f; + + return coord - ((Int64((coord - 1) / (pattern * 2)) * (2 * (pattern - 1))) + ((coord - 1) % (pattern * 2))); + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordX(Int64 uid, Integer level) +{ + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_cell_uid = firstCellUniqueId(level); + + uid -= first_cell_uid; + + const Int64 to2d = uid % (nb_cell_x * nb_cell_y); + return to2d % nb_cell_x; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordX(Cell cell) +{ + return cellUniqueIdToCoordX(cell.uniqueId(), cell.level()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordY(Int64 uid, Integer level) +{ + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_cell_uid = firstCellUniqueId(level); + + uid -= first_cell_uid; + + const Int64 to2d = uid % (nb_cell_x * nb_cell_y); + return to2d / nb_cell_x; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordY(Cell cell) +{ + return cellUniqueIdToCoordY(cell.uniqueId(), cell.level()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordZ(Int64 uid, Integer level) +{ + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_cell_uid = firstCellUniqueId(level); + + uid -= first_cell_uid; + + return uid / (nb_cell_x * nb_cell_y); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueIdToCoordZ(Cell cell) +{ + return cellUniqueIdToCoordZ(cell.uniqueId(), cell.level()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordX(Int64 uid, Integer level) +{ + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 nb_node_y = globalNbNodesY(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + uid -= first_node_uid; + + const Int64 to2d = uid % (nb_node_x * nb_node_y); + return to2d % nb_node_x; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordX(Node node) +{ + const Int64 uid = node.uniqueId(); + return nodeUniqueIdToCoordX(uid, nodeLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordY(Int64 uid, Integer level) +{ + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 nb_node_y = globalNbNodesY(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + uid -= first_node_uid; + + const Int64 to2d = uid % (nb_node_x * nb_node_y); + return to2d / nb_node_x; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordY(Node node) +{ + const Int64 uid = node.uniqueId(); + return nodeUniqueIdToCoordY(uid, nodeLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordZ(Int64 uid, Integer level) +{ + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 nb_node_y = globalNbNodesY(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + uid -= first_node_uid; + + return uid / (nb_node_x * nb_node_y); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueIdToCoordZ(Node node) +{ + const Int64 uid = node.uniqueId(); + return nodeUniqueIdToCoordZ(uid, nodeLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordX(Int64 uid, Integer level) +{ + if (m_dimension == 2) { + + const Int64 nb_face_x = globalNbFacesXCartesianView(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + uid -= first_face_uid; + uid += 1; + + // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 : + // + // x = 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ + // y = -1 │ 0│ │ 2│ │ 4│ + // ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ 1│ │ 3│ │ + // ├──┼──┼──┼──┼──┤ + // y = 1 │ 5│ │ 7│ │ 9│ + // ├──┼──┼──┼──┼──┤ + // y = 2 │ │ 6│ │ 8│ │ + // ├──┼──┼──┼──┼──┤ + // y = 3 │10│ │12│ │14│ + // ├──┼──┼──┼──┼──┤ + // y = 4 │ │11│ │13│ │ + // └──┴──┴──┴──┴──┘ + // + // Si on fait "tomber" les faces (tetris), on obtient une numérotation + // cartésienne classique. + + return uid % nb_face_x; + } + else { + const Int64 nb_face_x = globalNbFacesX(level); + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + // Int64 initial_uid = uid; + + uid -= first_face_uid; + + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); + + // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : + // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 + // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + // │ │ │ │ + // + // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], + // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. + // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). + + // Pour l'intervalle [0, 11], on remarque que l'origine en X est toujours 1 et que les mailles + // contenant une face sont sur les X impairs. + // Enfin, on a "nb_cell_x" faces en X. + if (uid < three_parts_numbering.x) { + // debug() << "faceUniqueIdToCoordX (1)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); + + return (uid % nb_cell_x) * 2 + 1; + } + + // Pour l'intervalle [12, 23], on remarque que l'origine en X est toujours 0 et que les mailles + // contenant une face sont sur les X pairs. + // Enfin, on a "nb_face_x" faces en X. + else if (uid < three_parts_numbering.x + three_parts_numbering.y) { + uid -= three_parts_numbering.x; + + // debug() << "faceUniqueIdToCoordX (2)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_face_x : " << nb_face_x + // << " -- return : " << ((uid % nb_face_x) * 2); + + return (uid % nb_face_x) * 2; + } + + // Pour l'intervalle [24, 35], on remarque que l'origine en X est toujours 1 et que les mailles + // contenant une face sont sur les X impairs. + // Enfin, on a "nb_cell_x" faces en X. + else { + uid -= three_parts_numbering.x + three_parts_numbering.y; + + // debug() << "faceUniqueIdToCoordX (3)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); + + return (uid % nb_cell_x) * 2 + 1; + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordX(Face face) +{ + const Int64 uid = face.uniqueId(); + return faceUniqueIdToCoordX(uid, faceLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordY(Int64 uid, Integer level) +{ + if (m_dimension == 2) { + const Int64 nb_face_x = globalNbFacesXCartesianView(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + uid -= first_face_uid; + uid += 1; + + // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 : + // + // x = 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ + // y = -1 │ 0│ │ 2│ │ 4│ + // ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ 1│ │ 3│ │ + // ├──┼──┼──┼──┼──┤ + // y = 1 │ 5│ │ 7│ │ 9│ + // ├──┼──┼──┼──┼──┤ + // y = 2 │ │ 6│ │ 8│ │ + // ├──┼──┼──┼──┼──┤ + // y = 3 │10│ │12│ │14│ + // ├──┼──┼──┼──┼──┤ + // y = 4 │ │11│ │13│ │ + // └──┴──┴──┴──┴──┘ + // + // Si, en plus, on fait y+1, on simplifie le problème puisque si on fait + // "tomber" les faces (tetris), on obtient une numérotation cartesienne classique. + + const Int64 flat_pos = uid / nb_face_x; + return (flat_pos * 2) + (flat_pos % 2 == uid % 2 ? 0 : 1) - 1; // Le -1 pour "retirer" le niveau imaginaire. + } + else { + const Int64 nb_face_x = globalNbFacesX(level); + const Int64 nb_face_y = globalNbFacesY(level); + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + // Int64 initial_uid = uid; + + uid -= first_face_uid; + + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); + + // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : + // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 + // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + // │ │ │ │ + // + // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], + // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. + // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). + + // Pour l'intervalle [0, 11], on remarque que l'origine en Y est toujours 1 et que les mailles + // contenant une face sont sur les Y impairs. + // Enfin, on a "nb_cell_y" faces en Y. + if (uid < three_parts_numbering.x) { + uid %= nb_cell_x * nb_cell_y; + + // debug() << "faceUniqueIdToCoordY (1)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / nb_cell_x) * 2 + 1); + + return (uid / nb_cell_x) * 2 + 1; + } + + // Pour l'intervalle [12, 23], on remarque que l'origine en Y est toujours 1 et que les mailles + // contenant une face sont sur les Y impairs. + // Enfin, on a "nb_cell_y" faces en Y. + else if (uid < three_parts_numbering.x + three_parts_numbering.y) { + uid -= three_parts_numbering.x; + uid %= nb_face_x * nb_cell_y; + + // debug() << "faceUniqueIdToCoordY (2)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_face_x : " << nb_face_x + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / nb_face_x) * 2 + 1); + + return (uid / nb_face_x) * 2 + 1; + } + + // Pour l'intervalle [24, 35], on remarque que l'origine en Y est toujours 0 et que les mailles + // contenant une face sont sur les Y pairs. + // Enfin, on a "nb_face_y" faces en Y. + else { + uid -= three_parts_numbering.x + three_parts_numbering.y; + uid %= nb_cell_x * nb_face_y; + + // debug() << "faceUniqueIdToCoordY (3)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_face_y : " << nb_face_y + // << " -- return : " << ((uid / nb_cell_x) * 2); + + return (uid / nb_cell_x) * 2; + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordY(Face face) +{ + const Int64 uid = face.uniqueId(); + return faceUniqueIdToCoordY(uid, faceLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordZ(Int64 uid, Integer level) +{ + const Int64 nb_face_x = globalNbFacesX(level); + const Int64 nb_face_y = globalNbFacesY(level); + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + // Int64 initial_uid = uid; + + uid -= first_face_uid; + + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); + + // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : + // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 + // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + // │ │ │ │ + // + // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], + // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. + // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). + + // Pour l'intervalle [0, 11], on remarque que l'origine en Z est toujours 0 et que les mailles + // contenant une face sont sur les Z pairs. + // Enfin, on a "nb_face_z" faces en Z. + if (uid < three_parts_numbering.x) { + + // debug() << "faceUniqueIdToCoordZ (1)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2); + + return (uid / (nb_cell_x * nb_cell_y)) * 2; + } + + // Pour l'intervalle [12, 23], on remarque que l'origine en Z est toujours 1 et que les mailles + // contenant une face sont sur les Z impairs. + // Enfin, on a "nb_cell_z" faces en Z. + else if (uid < three_parts_numbering.x + three_parts_numbering.y) { + uid -= three_parts_numbering.x; + + // debug() << "faceUniqueIdToCoordZ (2)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_face_x : " << nb_face_x + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1); + + return (uid / (nb_face_x * nb_cell_y)) * 2 + 1; + } + + // Pour l'intervalle [24, 35], on remarque que l'origine en Z est toujours 1 et que les mailles + // contenant une face sont sur les Z impairs. + // Enfin, on a "nb_cell_z" faces en Z. + else { + uid -= three_parts_numbering.x + three_parts_numbering.y; + + // debug() << "faceUniqueIdToCoordZ (3)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_face_y : " << nb_face_y + // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1); + + return (uid / (nb_cell_x * nb_face_y)) * 2 + 1; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueIdToCoordZ(Face face) +{ + const Int64 uid = face.uniqueId(); + return faceUniqueIdToCoordZ(uid, faceLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueId(Integer level, Int64x3 cell_coord) +{ + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + const Int64 first_cell_uid = firstCellUniqueId(level); + + return (cell_coord.x + cell_coord.y * nb_cell_x + cell_coord.z * nb_cell_x * nb_cell_y) + first_cell_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +cellUniqueId(Integer level, Int64x2 cell_coord) +{ + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 first_cell_uid = firstCellUniqueId(level); + + return (cell_coord.x + cell_coord.y * nb_cell_x) + first_cell_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueId(Integer level, Int64x3 node_coord) +{ + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 nb_node_y = globalNbNodesY(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + return (node_coord.x + node_coord.y * nb_node_x + node_coord.z * nb_node_x * nb_node_y) + first_node_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +nodeUniqueId(Integer level, Int64x2 node_coord) +{ + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + return (node_coord.x + node_coord.y * nb_node_x) + first_node_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueId(Integer level, Int64x3 face_coord) +{ + const Int64 nb_face_x = globalNbFacesX(level); + const Int64 nb_face_y = globalNbFacesY(level); + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_cell_y = globalNbCellsY(level); + + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); + Int64 uid = firstFaceUniqueId(level); + + // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : + // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 + // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + // │ │ │ │ + // + // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11], + // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. + // Ici, on veut faire l'inverse : passer des coordonnées x,y,z à un uid. + // Pour identifier les trois intervalles, on regarde quelle coordonnée est pair. + // En effet, pour l'intervalle [0, 11], on s'aperçoit que seule la coordonnée z est pair. + // Pour l'intervalle [12, 23], seule la coordonnée x est pair et pour l'intervalle [24, 35], + // seule la coordonnée y est pair. + + // Intervalle [0, 11]. + if (face_coord.z % 2 == 0) { + // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. + face_coord.x -= 1; + face_coord.y -= 1; + + face_coord /= 2; + + // On est, à présent et pour cet intervalle, dans une vue cartésienne de + // taille nb_cell_x * nb_cell_y * nb_face_z. + uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y); + } + + // Intervalle [12, 23]. + else if (face_coord.x % 2 == 0) { + uid += three_parts_numbering.x; + + // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. + face_coord.y -= 1; + face_coord.z -= 1; + + face_coord /= 2; + + // On est, à présent et pour cet intervalle, dans une vue cartésienne de + // taille nb_face_x * nb_cell_y * nb_cell_z. + uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y); + } + + // Intervalle [24, 35]. + else if (face_coord.y % 2 == 0) { + uid += three_parts_numbering.x + three_parts_numbering.y; + + // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. + face_coord.x -= 1; + face_coord.z -= 1; + + face_coord /= 2; + + // On est, à présent et pour cet intervalle, dans une vue cartésienne de + // taille nb_cell_x * nb_face_y * nb_cell_z. + uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y); + } + else { + ARCANE_FATAL("Bizarre -- x : {0} -- y : {1} -- z : {2}", face_coord.x, face_coord.y, face_coord.z); + } + + return uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +faceUniqueId(Integer level, Int64x2 face_coord) +{ + const Int64 nb_face_x = globalNbFacesXCartesianView(level); + const Int64 first_face_uid = firstFaceUniqueId(level); + + // On considère que l'on a un niveau imaginaire -1 et que + // l'on obtiendra uid+1 (dans la numérotation utilisée normalement, + // la face à la position (1, 0) a un uid = 0). + // + // x = 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ + // y = -1 │ 0│ │ 2│ │ 4│ + // ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ 1│ │ 3│ │ + // ├──┼──┼──┼──┼──┤ + // y = 1 │ 5│ │ 7│ │ 9│ + // ├──┼──┼──┼──┼──┤ + // y = 2 │ │ 6│ │ 8│ │ + // ├──┼──┼──┼──┼──┤ + // y = 3 │10│ │12│ │14│ + // ├──┼──┼──┼──┼──┤ + // y = 4 │ │11│ │13│ │ + // └──┴──┴──┴──┴──┘ + // + + face_coord.y += 1; + + const Int64 a = (face_coord.y / 2) * nb_face_x; + + return (face_coord.x + a - 1) + first_face_uid; // Le -1 est pour revenir à la numérotation normale. +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer CartesianMeshNumberingMngInternal:: +nbNodeByCell() +{ + return static_cast(std::pow(m_pattern, m_mesh->dimension())); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) +{ + if (uid.size() != nbNodeByCell()) + ARCANE_FATAL("Bad size of arrayview"); + + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 nb_node_y = globalNbNodesY(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; + uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; + uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; + uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid; + + uid[4] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; + uid[5] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; + uid[6] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; + uid[7] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) +{ + if (uid.size() != nbNodeByCell()) + ARCANE_FATAL("Bad size of arrayview"); + + const Int64 nb_node_x = globalNbNodesX(level); + const Int64 first_node_uid = firstNodeUniqueId(level); + + uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid; + uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid; + uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid; + uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) +{ + if (m_dimension == 2) { + const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level)); + cellNodeUniqueIds(uid, level, cell_coord); + } + else { + const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level)); + cellNodeUniqueIds(uid, level, cell_coord); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer CartesianMeshNumberingMngInternal:: +nbFaceByCell() +{ + return m_pattern * m_dimension; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) +{ + if (uid.size() != nbFaceByCell()) + ARCANE_FATAL("Bad size of arrayview"); + + const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); + const Int64x3 nb_face(nb_cell + 1); + + const Int64 first_face_uid = firstFaceUniqueId(level); + + // Numérote les faces + // Cet algo n'est pas basé sur l'algo 2D. + // Les UniqueIDs générés sont contigües. + // Il est aussi possible de retrouver les UniqueIDs des faces + // à l'aide de la position de la cellule et la taille du maillage. + // De plus, l'ordre des UniqueIDs des faces d'une cellule est toujours le + // même (en notation localId Arcane (cell.face(i)) : 0, 3, 1, 4, 2, 5). + // Les UniqueIDs générés sont donc les mêmes quelque soit le découpage. + /* + x z + ┌──► │ ┌──► + │ │ │ + y▼12 13 14 │y▼ ┌────┬────┐ + │ 26 │ 27 │ │ │ 24 │ 25 │ + └────┴────┘ │ 0 4 8 + 15 16 17 │ + │ 28 │ 29 │ │ │ │ │ + └────┴────┘ │ 2 6 10 + z=0 │ x=0 + - - - - - - - - - - - - - - - - - - + z=1 │ x=1 + 18 19 20 │ ┌────┬────┐ + │ 32 │ 33 │ │ │ 30 │ 31 │ + └────┴────┘ │ 1 5 9 + 21 22 23 │ + │ 34 │ 35 │ │ │ │ │ + └────┴────┘ │ 3 7 11 + │ + */ + // On a un cube décomposé en huit cellules (2x2x2). + // Le schéma au-dessus représente les faces des cellules de ce cube avec + // les uniqueIDs que l'algorithme génèrera (sans face_adder). + // Pour cet algo, on commence par les faces "xy". + // On énumère d'abord en x, puis en y, puis en z. + // Une fois les faces "xy" numérotées, on fait les faces "yz". + // Toujours le même ordre de numérotation. + // On termine avec les faces "zx", encore dans le même ordre. + // + // Dans l'implémentation ci-dessous, on fait la numérotation + // maille par maille. + + const Int64 total_face_xy = nb_face.z * nb_cell.x * nb_cell.y; + const Int64 total_face_xy_yz = total_face_xy + nb_face.x * nb_cell.y * nb_cell.z; + + const Int64 nb_cell_before_j = cell_coord.y * nb_cell.x; + + uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + (cell_coord.x); + + uid[3] = uid[0] + nb_cell.x * nb_cell.y; + + uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + (cell_coord.x) + total_face_xy; + + uid[4] = uid[1] + 1; + + uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + (cell_coord.x) + total_face_xy_yz; + + uid[5] = uid[2] + nb_cell.x; + + uid[0] += first_face_uid; + uid[1] += first_face_uid; + uid[2] += first_face_uid; + uid[3] += first_face_uid; + uid[4] += first_face_uid; + uid[5] += first_face_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) +{ + if (uid.size() != nbFaceByCell()) + ARCANE_FATAL("Bad size of arrayview"); + + const Int64 nb_cell_x = globalNbCellsX(level); + const Int64 nb_face_x = nb_cell_x + 1; + const Int64 first_face_uid = firstFaceUniqueId(level); + + // Numérote les faces + // ┌─0──┬──2─┐ + // 4│ 6│ 8│ + // ├─5──┼─7──┤ + // 9│ 11│ 13│ + // └─10─┴─12─┘ + // + // Avec cette numérotation, HAUT < GAUCHE < BAS < DROITE + // Mis à part les uniqueIds de la première ligne de face, tous + // les uniqueIds sont contigües. + + // HAUT + // - "(current_level_nb_face_x + current_level_nb_cell_x)" : + // le nombre de faces GAUCHE BAS DROITE au dessus. + // - "cell_coord.y * (current_level_nb_face_x + current_level_nb_cell_x)" : + // le nombre total de faces GAUCHE BAS DROITE au dessus. + // - "cell_coord.x * 2" + // on avance deux à deux sur les faces d'un même "coté". + uid[0] = cell_coord.x * 2 + cell_coord.y * (nb_face_x + nb_cell_x); + + // BAS + // Pour BAS, c'est comme HAUT mais avec un "nombre de face du dessus" en plus. + uid[2] = uid[0] + (nb_face_x + nb_cell_x); + // GAUCHE + // Pour GAUCHE, c'est l'UID de BAS -1. + uid[3] = uid[2] - 1; + // DROITE + // Pour DROITE, c'est l'UID de BAS +1. + uid[1] = uid[2] + 1; + + uid[0] += first_face_uid; + uid[1] += first_face_uid; + uid[2] += first_face_uid; + uid[3] += first_face_uid; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) +{ + if (m_dimension == 2) { + const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level)); + cellFaceUniqueIds(uid, level, cell_coord); + } + else { + const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level)); + cellFaceUniqueIds(uid, level, cell_coord); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundCell(ArrayView uid, Cell cell) +{ + cellUniqueIdsAroundCell(uid, cell.uniqueId(), cell.level()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) +{ + uid.fill(-1); + + const Int64 coord_cell_x = cellUniqueIdToCoordX(cell_uid, level); + const Int64 coord_cell_y = cellUniqueIdToCoordY(cell_uid, level); + + const Int64 nb_cells_x = globalNbCellsX(level); + const Int64 nb_cells_y = globalNbCellsY(level); + + if (m_dimension == 2) { + ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9")); + + for (Integer j = -1; j < 2; ++j) { + const Int64 coord_around_cell_y = coord_cell_y + j; + if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { + + for (Integer i = -1; i < 2; ++i) { + const Int64 coord_around_cell_x = coord_cell_x + i; + if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(level, Int64x2(coord_around_cell_x, coord_around_cell_y)); + } + } + } + } + } + + else { + ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27")); + + const Int64 coord_cell_z = cellUniqueIdToCoordZ(cell_uid, level); + const Int64 nb_cells_z = globalNbCellsZ(level); + + for (Integer k = -1; k < 2; ++k) { + const Int64 coord_around_cell_z = coord_cell_z + k; + if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) { + + for (Integer j = -1; j < 2; ++j) { + const Int64 coord_around_cell_y = coord_cell_y + j; + if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { + + for (Integer i = -1; i < 2; ++i) { + const Int64 coord_around_cell_x = coord_cell_x + i; + if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(level, Int64x3(coord_around_cell_x, coord_around_cell_y, coord_around_cell_z)); + } + } + } + } + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +setChildNodeCoordinates(Cell parent_cell) +{ + if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustRefined)) { + ARCANE_FATAL("Cell not II_JustRefined"); + } + + VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates(); + + const Real3& node0(nodes_coords[parent_cell.node(0)]); + const Real3& node1(nodes_coords[parent_cell.node(1)]); + const Real3& node2(nodes_coords[parent_cell.node(2)]); + const Real3& node3(nodes_coords[parent_cell.node(3)]); + + if (m_dimension == 2) { + + /* + = + ┌─────────────────────►= y3 + │ = ▲ l + ▼ = ▼ + X───────────────X◄────►= y2 + /▲ /▲ = + / │ / │ = + / │ / │ = + / │ / │ = + / │ / │ = + / │ / │ = + / │ / │ = + / │ / │ = + X───────────────X◄───────│─────►= y1 + ▲ │ ▲ │ = ▲ k + │ │ │ │ = ▼ + ├──────────────────────────────►= y0 + │ │ │ │ = + │ │ │ │ = + ▼ ▼ ▼ ▼ + ============================== + x0 ◄───► x3 x1 ◄───► x2 + i j + */ + /*! + * \brief Lambda permettant de déterminer la position d'un noeud enfant + * dans une maille parent. + */ + auto txty = [&](Integer pos_x, Integer pos_y) -> Real3 { + const Real x = (Real)pos_x / (Real)m_pattern; + const Real y = (Real)pos_y / (Real)m_pattern; + + const Real i = (node3.x - node0.x) * y + node0.x; + const Real j = (node2.x - node1.x) * y + node1.x; + + const Real k = (node1.y - node0.y) * x + node0.y; + const Real l = (node2.y - node3.y) * x + node3.y; + + const Real tx = (j - i) * x + i; + const Real ty = (l - k) * y + k; + + /* + info() << "[txty]" + << " x : " << x + << " -- y : " << y + << " -- node0 : " << node0 + << " -- node1 : " << node1 + << " -- node2 : " << node2 + << " -- node3 : " << node3 + << " -- i : " << i + << " -- j : " << j + << " -- k : " << k + << " -- l : " << l + << " -- tx : " << tx + << " -- ty : " << ty; + */ + return { tx, ty, 0 }; + }; + + const Integer node_1d_2d_x[] = { 0, 1, 1, 0 }; + const Integer node_1d_2d_y[] = { 0, 0, 1, 1 }; + + for (Integer j = 0; j < m_pattern; ++j) { + for (Integer i = 0; i < m_pattern; ++i) { + + Integer begin = (i == 0 && j == 0 ? 0 : j == 0 ? 1 + : 2); + Integer end = (i == 0 ? nbNodeByCell() : nbNodeByCell() - 1); + Cell child = childCellOfCell(parent_cell, Int64x2(i, j)); + + for (Integer inode = begin; inode < end; ++inode) { + nodes_coords[child.node(inode)] = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]); + // Real3 pos = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]); + // nodes_coords[child.node(inode)] = pos; + // info() << "Node uid : " << child.node(inode).uniqueId() + // << " -- nodeX : " << (i + node_1d_2d_x[inode]) + // << " -- nodeY : " << (j + node_1d_2d_y[inode]) + // << " -- Pos : " << pos; + } + } + } + } + + else { + const Real3& node4(nodes_coords[parent_cell.node(4)]); + const Real3& node5(nodes_coords[parent_cell.node(5)]); + const Real3& node6(nodes_coords[parent_cell.node(6)]); + const Real3& node7(nodes_coords[parent_cell.node(7)]); + + /*! + * \brief Lambda permettant de déterminer la position d'un noeud enfant + * dans une maille parent. + */ + auto txtytz = [&](Integer pos_x, Integer pos_y, Integer pos_z) -> Real3 { + const Real x = (Real)pos_x / (Real)m_pattern; + const Real y = (Real)pos_y / (Real)m_pattern; + const Real z = (Real)pos_z / (Real)m_pattern; + + // Face (m, n, o, p) entre les faces (node0, node1, node2, node3) et (node4, node5, node6, node7). + const Real3 m = (node4 - node0) * z + node0; + const Real3 n = (node5 - node1) * z + node1; + const Real3 o = (node6 - node2) * z + node2; + const Real3 p = (node7 - node3) * z + node3; + + // On calcule tx et ty comme en 2D mais sur la face (m, n, o, p). + const Real i = (p.x - m.x) * y + m.x; + const Real j = (o.x - n.x) * y + n.x; + + const Real tx = (j - i) * x + i; + + const Real k = (n.y - m.y) * x + m.y; + const Real l = (o.y - p.y) * x + p.y; + + const Real ty = (l - k) * y + k; + + const Real q = (p.z - m.z) * y + m.z; + const Real r = (o.z - n.z) * y + n.z; + + const Real s = (n.z - m.z) * x + m.z; + const Real t = (o.z - p.z) * x + p.z; + + const Real tz = (((r - q) * x + q) + ((t - s) * y + s)) * 0.5; + + /* + info() << "[txtytz]" + << " x : " << x + << " -- y : " << y + << " -- z : " << z + << " -- node0 : " << node0 + << " -- node1 : " << node1 + << " -- node2 : " << node2 + << " -- node3 : " << node3 + << " -- node4 : " << node4 + << " -- node5 : " << node5 + << " -- node6 : " << node6 + << " -- node7 : " << node7 + << " -- m : " << m + << " -- n : " << n + << " -- o : " << o + << " -- p : " << p + << " -- j : " << j + << " -- k : " << k + << " -- l : " << l + << " -- q : " << q + << " -- r : " << r + << " -- s : " << s + << " -- t : " << t + << " -- tx : " << tx + << " -- ty : " << ty + << " -- tz : " << tz; + */ + return { tx, ty, tz }; + }; + + const Integer node_1d_3d_x[] = { 0, 1, 1, 0, 0, 1, 1, 0 }; + const Integer node_1d_3d_y[] = { 0, 0, 1, 1, 0, 0, 1, 1 }; + const Integer node_1d_3d_z[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + + for (Integer k = 0; k < m_pattern; ++k) { + for (Integer j = 0; j < m_pattern; ++j) { + for (Integer i = 0; i < m_pattern; ++i) { + + // TODO : éviter les multiples appels pour un même noeud. + Integer begin = 0; + Integer end = nbNodeByCell(); + Cell child = childCellOfCell(parent_cell, Int64x3(i, j, k)); + + for (Integer inode = begin; inode < end; ++inode) { + nodes_coords[child.node(inode)] = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]); + // Real3 pos = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]); + // nodes_coords[child.node(inode)] = pos; + // info() << "Node uid : " << child.node(inode).uniqueId() + // << " -- nodeX : " << (i + node_1d_3d_x[inode]) + // << " -- nodeY : " << (j + node_1d_3d_y[inode]) + // << " -- nodeZ : " << (k + node_1d_3d_z[inode]) + // << " -- Pos : " << pos; + } + } + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +setParentNodeCoordinates(Cell parent_cell) +{ + if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustAdded)) { + ARCANE_FATAL("Cell not II_JustAdded"); + } + + VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates(); + + if (m_dimension == 2) { + nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, 0)).node(0)]; + nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, 0)).node(1)]; + nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, m_pattern - 1)).node(2)]; + nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, m_pattern - 1)).node(3)]; + } + + else { + nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, 0)).node(0)]; + nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, 0)).node(1)]; + nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, 0)).node(2)]; + nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, 0)).node(3)]; + + nodes_coords[parent_cell.node(4)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, m_pattern - 1)).node(4)]; + nodes_coords[parent_cell.node(5)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, m_pattern - 1)).node(5)]; + nodes_coords[parent_cell.node(6)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, m_pattern - 1)).node(6)]; + nodes_coords[parent_cell.node(7)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, m_pattern - 1)).node(7)]; + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) +{ + // Pour avoir la face parent d'une maille, on passe d'abord de l'uid vers les + // coordonnées de la maille, + // puis on détermine les coordonnées du parent grâce au m_pattern, + // et enfin, on repasse des coordonnées du parent vers son uid. + + if (globalNbCellsX(level - 1) == 0) { + if (do_fatal) { + ARCANE_FATAL("Level {0} do not exist", (level - 1)); + } + return NULL_ITEM_UNIQUE_ID; + } + + if (m_dimension == 2) { + return cellUniqueId(level - 1, + Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1), + offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1))); + } + else { + return cellUniqueId(level - 1, + Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1), + offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1), + offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level - 1))); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentCellUniqueIdOfCell(Cell cell, bool do_fatal) +{ + return parentCellUniqueIdOfCell(cell.uniqueId(), cell.level(), do_fatal); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) +{ + ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) + ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) + ARCANE_ASSERT((child_coord_in_parent.z < m_pattern && child_coord_in_parent.z >= 0), ("Bad child_coord_in_parent.z")) + + const Int64 uid = cell.uniqueId(); + const Int32 level = cell.level(); + + return cellUniqueId(level + 1, + Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x, + offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y, + offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level + 1) + child_coord_in_parent.z)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) +{ + ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) + ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) + + const Int64 uid = cell.uniqueId(); + const Int32 level = cell.level(); + + return cellUniqueId(level + 1, + Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x, + offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) +{ + if (m_dimension == 2) { + ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent")) + + return childCellUniqueIdOfCell(cell, + Int64x2( + child_index_in_parent % m_pattern, + child_index_in_parent / m_pattern)); + } + + else { + ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent")) + + const Int64 to_2d = child_index_in_parent % (m_pattern * m_pattern); + return childCellUniqueIdOfCell(cell, + Int64x3( + to_2d % m_pattern, + to_2d / m_pattern, + child_index_in_parent / (m_pattern * m_pattern))); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Cell CartesianMeshNumberingMngInternal:: +childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) +{ + ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) + ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) + + Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern) + ((Int32)child_coord_in_parent.z * m_pattern * m_pattern)); + const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent); + + // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId + // recherché, on recherche parmi les autres mailles enfants. + if (child.uniqueId() != uid) { + const Int32 nb_children = cell.nbHChildren(); + for (Integer i = 0; i < nb_children; ++i) { + if (cell.hChild(i).uniqueId() == uid) { + return cell.hChild(i); + } + } + ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId()); + } + return child; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Cell CartesianMeshNumberingMngInternal:: +childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) +{ + ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x")) + ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y")) + + Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern)); + const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent); + + // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId + // recherché, on recherche parmi les autres mailles enfants. + if (child.uniqueId() != uid) { + const Int32 nb_children = cell.nbHChildren(); + for (Integer i = 0; i < nb_children; ++i) { + if (cell.hChild(i).uniqueId() == uid) { + return cell.hChild(i); + } + } + ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId()); + } + return child; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) +{ + // Pour avoir le noeud parent d'un noeud, on passe d'abord de l'uid vers les + // coordonnées du noeud, puis on détermine les coordonnées du parent grâce au m_pattern, + // et enfin, on repasse des coordonnées du parent vers son uid. + + const Int64 coord_x = nodeUniqueIdToCoordX(uid, level); + const Int64 coord_y = nodeUniqueIdToCoordY(uid, level); + + if (coord_x % m_pattern != 0 || coord_y % m_pattern != 0) { + if (do_fatal) { + ARCANE_FATAL("Node uid={0} do not have parent", uid); + } + return NULL_ITEM_UNIQUE_ID; + } + + if (m_dimension == 2) { + return nodeUniqueId(level - 1, + Int64x2(offsetLevelToLevel(coord_x, level, level - 1), + offsetLevelToLevel(coord_y, level, level - 1))); + } + else { + const Int64 coord_z = nodeUniqueIdToCoordZ(uid, level); + + if (coord_z % m_pattern != 0) { + if (do_fatal) { + ARCANE_FATAL("Node uid={0} do not have parent", uid); + } + return NULL_ITEM_UNIQUE_ID; + } + return nodeUniqueId(level - 1, + Int64x3(offsetLevelToLevel(coord_x, level, level - 1), + offsetLevelToLevel(coord_y, level, level - 1), + offsetLevelToLevel(coord_z, level, level - 1))); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentNodeUniqueIdOfNode(Node node, bool do_fatal) +{ + const Int64 uid = node.uniqueId(); + return parentNodeUniqueIdOfNode(uid, nodeLevel(uid), do_fatal); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childNodeUniqueIdOfNode(Int64 uid, Integer level) +{ + if (m_dimension == 2) { + return nodeUniqueId(level + 1, + Int64x2(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1), + offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1))); + } + + else { + return nodeUniqueId(level + 1, + Int64x3(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1), + offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1), + offsetLevelToLevel(nodeUniqueIdToCoordZ(uid, level), level, level + 1))); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childNodeUniqueIdOfNode(Node node) +{ + const Int64 uid = node.uniqueId(); + return childNodeUniqueIdOfNode(uid, nodeLevel(uid)); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) +{ + if (m_converting_numbering_face && level == m_ori_level) { + uid = m_face_ori_numbering_to_new[uid]; + } + + // Pour avoir la face parent d'une face, on passe d'abord de l'uid vers les + // coordonnées de la face en "vue cartésienne", + // puis on détermine les coordonnées du parent grâce au m_pattern, + // et enfin, on repasse des coordonnées du parent vers son uid. + + const Int64 coord_x = faceUniqueIdToCoordX(uid, level); + const Int64 coord_y = faceUniqueIdToCoordY(uid, level); + + ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x")) + ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y")) + + const Int64 parent_coord_x = faceOffsetLevelToLevel(coord_x, level, level - 1); + const Int64 parent_coord_y = faceOffsetLevelToLevel(coord_y, level, level - 1); + + if (parent_coord_x == -1 || parent_coord_y == -1) { + if (do_fatal) { + ARCANE_FATAL("Face uid={0} do not have parent", uid); + } + return NULL_ITEM_UNIQUE_ID; + } + + ARCANE_ASSERT((parent_coord_x < globalNbFacesXCartesianView(level - 1) && parent_coord_x >= 0), ("Bad parent_coord_x")) + ARCANE_ASSERT((parent_coord_y < globalNbFacesYCartesianView(level - 1) && parent_coord_y >= 0), ("Bad parent_coord_y")) + + if (m_dimension == 2) { + if (m_converting_numbering_face && level - 1 == m_ori_level) { + return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y))]; + } + return faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y)); + } + else { + const Int64 coord_z = faceUniqueIdToCoordZ(uid, level); + ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z")) + + const Int64 parent_coord_z = faceOffsetLevelToLevel(coord_z, level, level - 1); + + if (parent_coord_z == -1) { + if (do_fatal) { + ARCANE_FATAL("Face uid={0} do not have parent", uid); + } + return NULL_ITEM_UNIQUE_ID; + } + + ARCANE_ASSERT((parent_coord_z < globalNbFacesZCartesianView(level - 1) && parent_coord_z >= 0), ("Bad parent_coord_z")) + + // debug() << "Uid : " << uid << " -- CoordX : " << coord_x << " -- CoordY : " << coord_y << " -- CoordZ : " << coord_z; + + if (m_converting_numbering_face && level - 1 == m_ori_level) { + return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z))]; + } + + return faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z)); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +parentFaceUniqueIdOfFace(Face face, bool do_fatal) +{ + const Int64 uid = face.uniqueId(); + return parentFaceUniqueIdOfFace(uid, faceLevel(uid), do_fatal); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) +{ + if (m_converting_numbering_face && level == m_ori_level) { + uid = m_face_ori_numbering_to_new[uid]; + } + + const Int64 coord_x = faceUniqueIdToCoordX(uid, level); + const Int64 coord_y = faceUniqueIdToCoordY(uid, level); + + ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x")) + ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y")) + + Int64 first_child_coord_x = faceOffsetLevelToLevel(coord_x, level, level + 1); + Int64 first_child_coord_y = faceOffsetLevelToLevel(coord_y, level, level + 1); + + ARCANE_ASSERT((first_child_coord_x < globalNbFacesXCartesianView(level + 1) && first_child_coord_x >= 0), ("Bad first_child_coord_x")) + ARCANE_ASSERT((first_child_coord_y < globalNbFacesYCartesianView(level + 1) && first_child_coord_y >= 0), ("Bad first_child_coord_y")) + + if (m_dimension == 2) { + ARCANE_ASSERT((child_index_in_parent < m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent")) + + if (coord_y % 2 == 0) { + first_child_coord_x += child_index_in_parent * 2; + } + else if (coord_x % 2 == 0) { + first_child_coord_y += child_index_in_parent * globalNbFacesY(level + 1); + } + else { + ARCANE_FATAL("Impossible normalement"); + } + + if (m_converting_numbering_face && level + 1 == m_ori_level) { + return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y))]; + } + + return faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y)); + } + + else { + ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent")) + + const Int64 coord_z = faceUniqueIdToCoordZ(uid, level); + ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z")) + + Int64 first_child_coord_z = faceOffsetLevelToLevel(coord_z, level, level + 1); + ARCANE_ASSERT((first_child_coord_z < globalNbFacesZCartesianView(level + 1) && first_child_coord_z >= 0), ("Bad first_child_coord_z")) + + Int64 child_x = child_index_in_parent % m_pattern; + Int64 child_y = child_index_in_parent / m_pattern; + + Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); + + if (uid < three_parts_numbering.x) { + first_child_coord_x += child_x * 2; + first_child_coord_y += child_y * 2; + } + else if (uid < three_parts_numbering.x + three_parts_numbering.y) { + first_child_coord_y += child_x * 2; + first_child_coord_z += child_y * 2; + } + else { + first_child_coord_x += child_x * 2; + first_child_coord_z += child_y * 2; + } + + if (m_converting_numbering_face && level + 1 == m_ori_level) { + return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z))]; + } + + return faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z)); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64 CartesianMeshNumberingMngInternal:: +childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) +{ + const Int64 uid = face.uniqueId(); + return childFaceUniqueIdOfFace(uid, faceLevel(uid), child_index_in_parent); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Int64x3 CartesianMeshNumberingMngInternal:: +_face3DNumberingThreeParts(Integer level) const +{ + const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); + return { (nb_cell.z + 1) * nb_cell.x * nb_cell.y, (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x }; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +_pushFront(UniqueArray& array, const Int64 elem) +{ + array.resize(array.size() + 1); + array.back() = elem; + for (Integer i = array.size() - 2; i >= 0; --i) { + std::swap(array[i], array[i + 1]); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h new file mode 100644 index 0000000000..9c070f24a0 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h @@ -0,0 +1,221 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* CartesianMeshNumberingMngInternal.h (C) 2000-2025 */ +/* */ +/* Gestionnaire de numérotation de maillage cartesian. La numérotation */ +/* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#ifndef ARCANE_CARTESIANMESH_CARTESIANMESHNUMBERINGMNGINTERNAL_H +#define ARCANE_CARTESIANMESH_CARTESIANMESHNUMBERINGMNGINTERNAL_H + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" + +#include "arcane/utils/TraceAccessor.h" +#include "arcane/utils/Vector3.h" + +#include "arcane/core/Item.h" + +#include + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class CartesianMeshNumberingMngInternal +: public TraceAccessor +, public ICartesianMeshNumberingMngInternal +{ + public: + + explicit CartesianMeshNumberingMngInternal(IMesh* mesh); + + public: + + void _build() override; + void _saveInfosInProperties() override; + void _recreateFromDump() override; + + void renumberingFacesLevel0FromOriginalArcaneNumbering() override; + + void printStatus() override; + + void prepareLevel(Int32 level) override; + void updateFirstLevel() override; + + Int64 firstCellUniqueId(Integer level) const override; + Int64 firstNodeUniqueId(Integer level) const override; + Int64 firstFaceUniqueId(Integer level) const override; + + Int64 globalNbCellsX(Integer level) const override; + Int64 globalNbCellsY(Integer level) const override; + Int64 globalNbCellsZ(Integer level) const override; + + Int64 globalNbNodesX(Integer level) const override; + Int64 globalNbNodesY(Integer level) const override; + Int64 globalNbNodesZ(Integer level) const override; + + Int64 globalNbFacesX(Integer level) const override; + Int64 globalNbFacesY(Integer level) const override; + Int64 globalNbFacesZ(Integer level) const override; + + Int64 globalNbFacesXCartesianView(Integer level) const override; + Int64 globalNbFacesYCartesianView(Integer level) const override; + Int64 globalNbFacesZCartesianView(Integer level) const override; + + Int64 nbCellInLevel(Integer level) const override; + Int64 nbNodeInLevel(Integer level) const override; + Int64 nbFaceInLevel(Integer level) const override; + + Integer pattern() const override; + + Int32 cellLevel(Int64 uid) const override; + Int32 nodeLevel(Int64 uid) const override; + Int32 faceLevel(Int64 uid) const override; + + Int64 offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override; + Int64 faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override; + + Int64 cellUniqueIdToCoordX(Int64 uid, Integer level) override; + Int64 cellUniqueIdToCoordX(Cell cell) override; + + Int64 cellUniqueIdToCoordY(Int64 uid, Integer level) override; + Int64 cellUniqueIdToCoordY(Cell cell) override; + + Int64 cellUniqueIdToCoordZ(Int64 uid, Integer level) override; + Int64 cellUniqueIdToCoordZ(Cell cell) override; + + Int64 nodeUniqueIdToCoordX(Int64 uid, Integer level) override; + Int64 nodeUniqueIdToCoordX(Node node) override; + + Int64 nodeUniqueIdToCoordY(Int64 uid, Integer level) override; + Int64 nodeUniqueIdToCoordY(Node node) override; + + Int64 nodeUniqueIdToCoordZ(Int64 uid, Integer level) override; + Int64 nodeUniqueIdToCoordZ(Node node) override; + + Int64 faceUniqueIdToCoordX(Int64 uid, Integer level) override; + Int64 faceUniqueIdToCoordX(Face face) override; + + Int64 faceUniqueIdToCoordY(Int64 uid, Integer level) override; + Int64 faceUniqueIdToCoordY(Face face) override; + + Int64 faceUniqueIdToCoordZ(Int64 uid, Integer level) override; + Int64 faceUniqueIdToCoordZ(Face face) override; + + Int64 cellUniqueId(Integer level, Int64x3 cell_coord) override; + Int64 cellUniqueId(Integer level, Int64x2 cell_coord) override; + + Int64 nodeUniqueId(Integer level, Int64x3 node_coord) override; + Int64 nodeUniqueId(Integer level, Int64x2 node_coord) override; + + Int64 faceUniqueId(Integer level, Int64x3 face_coord) override; + Int64 faceUniqueId(Integer level, Int64x2 face_coord) override; + + Integer nbNodeByCell() override; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; + void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + + Integer nbFaceByCell() override; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; + void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + + void cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) override; + void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) override; + + void setChildNodeCoordinates(Cell parent_cell) override; + void setParentNodeCoordinates(Cell parent_cell) override; + + Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) override; + Int64 parentCellUniqueIdOfCell(Cell cell, bool do_fatal) override; + + Int64 childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) override; + Int64 childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) override; + Int64 childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) override; + + Cell childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) override; + Cell childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) override; + + Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) override; + Int64 parentNodeUniqueIdOfNode(Node node, bool do_fatal) override; + + Int64 childNodeUniqueIdOfNode(Int64 uid, Integer level) override; + Int64 childNodeUniqueIdOfNode(Node node) override; + + Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) override; + Int64 parentFaceUniqueIdOfFace(Face face, bool do_fatal) override; + + Int64 childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) override; + Int64 childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) override; + + private: + + /*! + * \brief Méthode permettant de récupérer le nombre de faces des trois parties de la numérotation. + * + * En effet, pour numéroter en 3D, on numérote d'abord les faces xy, puis les faces yz et enfin + * les faces zx. Cette méthode permet de récupérer le nombre de faces {xy, yz, zx}. + * + * \param level Le niveau de la numérotation. + * \return Le nombre de faces {xy, yz, zx}. + */ + Int64x3 _face3DNumberingThreeParts(Integer level) const; + + static void _pushFront(UniqueArray& array, Int64 elem); + + private: + + IMesh* m_mesh; + + Ref m_properties; + + Integer m_dimension; + Integer m_pattern; + + UniqueArray m_p_to_l_level; + Int32 m_max_level; + Int32 m_min_level; + + Int64 m_latest_cell_uid; + UniqueArray m_first_cell_uid_level; + + Int64 m_latest_node_uid; + UniqueArray m_first_node_uid_level; + + Int64 m_latest_face_uid; + UniqueArray m_first_face_uid_level; + + Int64x3 m_nb_cell_ground; + + // Partie conversion numérotation d'origine <-> nouvelle numérotation (face). + bool m_converting_numbering_face; + Integer m_ori_level; + std::unordered_map m_face_ori_numbering_to_new; + std::unordered_map m_face_new_numbering_to_ori; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif //ARCANE_CARTESIANMESH_CARTESIANMESHNUMBERINGMNGINTERNAL_H diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h index 98643b28e1..71aba2b7df 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h @@ -14,6 +14,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +#include "arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h" #include "arcane/utils/TraceAccessor.h" #include "arcane/core/ItemTypes.h" @@ -45,8 +46,32 @@ class CartesianMeshPatch , public ICartesianMeshPatch { friend CartesianMeshImpl; + + class Impl + : public ICartesianMeshPatchInternal + { + public: + + explicit Impl(CartesianMeshPatch* m_patch) + : m_patch(m_patch) + {} + AMRPatchPosition& positionRef() override + { + return m_patch->m_position; + } + void setPosition(const AMRPatchPosition& position) override + { + m_patch->m_position = position; + } + + private: + + CartesianMeshPatch* m_patch; + }; + public: CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index); + CartesianMeshPatch(ICartesianMesh* cmesh, Integer patch_index, const AMRPatchPosition& position); ~CartesianMeshPatch() override; public: CellGroup cells() override; @@ -86,22 +111,31 @@ class CartesianMeshPatch } void checkValid() const override; - AMRPatchPosition& position() override + AMRPatchPosition position() const override { return m_position; } + ICartesianMeshPatchInternal* _internalApi() override + { + return &m_impl; + } + private: + void _internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); void _computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); void _computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); + private: + ICartesianMesh* m_mesh; AMRPatchPosition m_position; CellDirectionMng m_cell_directions[3]; FaceDirectionMng m_face_directions[3]; NodeDirectionMng m_node_directions[3]; Integer m_amr_patch_index; + Impl m_impl; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc similarity index 93% rename from arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc rename to arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc index 74bcc60ec4..401a9f544e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc @@ -10,12 +10,12 @@ /* Gestion du groupe de patchs du maillage cartésien. */ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/CartesianPatchGroup.h" +#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h" -#include "AMRPatchPositionLevelGroup.h" -#include "AMRPatchPositionSignature.h" -#include "AMRPatchPositionSignatureCut.h" -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/utils/ITraceMng.h" #include "arcane/utils/FixedArray.h" @@ -27,7 +27,7 @@ #include "arcane/cartesianmesh/internal/CartesianMeshPatch.h" #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" -#include "arccore/base/StringBuilder.h" +#include "arcane/utils/StringBuilder.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -38,57 +38,6 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -OverlapItemGroupComputeFunctor:: -OverlapItemGroupComputeFunctor(Ref numbering, const AMRPatchPosition& patch_position) -: m_numbering(numbering) -, m_patch_position(patch_position) -{ -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -OverlapItemGroupComputeFunctor:: -~OverlapItemGroupComputeFunctor() = default; - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void OverlapItemGroupComputeFunctor:: -executeFunctor() -{ - ITraceMng* trace = m_group->mesh()->traceMng(); - ItemGroup parent(m_group->parent()); - - m_group->beginTransaction(); - Int32UniqueArray items_lid; - - // Ne fonctionne que pour les cells pour l'instant. - ENUMERATE_ITEM (iitem, parent) { - Cell cell = iitem->toCell(); - - Int64 pos_x = m_numbering->cellUniqueIdToCoordX(cell); - Int64 pos_y = m_numbering->cellUniqueIdToCoordY(cell); - Int64 pos_z = m_numbering->cellUniqueIdToCoordZ(cell); - - if (m_patch_position.isIn(pos_x, pos_y, pos_z)) { - items_lid.add(cell.localId()); - } - } - m_group->setItems(items_lid); - m_group->endTransaction(); - - trace->debug() << "OverlapItemGroupComputeFunctor::execute()" - << " this=" << m_group - << " parent_name=" << parent.name() - << " name=" << m_group->name() - << " parent_count=" << parent.size() - << " mysize=" << m_group->size(); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - // Le patch 0 est un patch spécial "ground". Il ne possède pas de cell_group // dans le tableau "m_amr_patch_cell_groups". // Pour les index, on utilise toujours celui des tableaux m_amr_patches_pointer @@ -97,7 +46,8 @@ executeFunctor() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -CartesianPatchGroup::CartesianPatchGroup(ICartesianMesh* cmesh) +CartesianPatchGroup:: +CartesianPatchGroup(ICartesianMesh* cmesh) : m_cmesh(cmesh) , m_index_new_patches(1) {} @@ -160,11 +110,11 @@ addPatch(CellGroup cell_group, Integer group_index) _createGroundPatch(); if (cell_group.null()) ARCANE_FATAL("Null cell group"); - auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); - _addPatchInstance(makeRef(cdi)); + + AMRPatchPosition position; if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); FixedArray min_n_max; min_n_max[0] = INT64_MAX; min_n_max[1] = INT64_MAX; @@ -223,9 +173,9 @@ addPatch(CellGroup cell_group, Integer group_index) } } - cdi->position().setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] }); - cdi->position().setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); - cdi->position().setLevel(level_r); + position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] }); + position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); + position.setLevel(level_r); } else { Integer level = -1; @@ -244,8 +194,11 @@ addPatch(CellGroup cell_group, Integer group_index) ARCANE_FATAL("Bad level reduced"); } - cdi->position().setLevel(level_r); + position.setLevel(level_r); } + + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, position); + _addPatchInstance(makeRef(cdi)); _addCellGroup(cell_group, cdi); m_cmesh->traceMng()->info() << "addPatch()" @@ -423,21 +376,21 @@ updateLevelsBeforeAddGroundPatch() if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { return; } - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); for (ICartesianMeshPatch* patch : m_amr_patches_pointer) { Integer level = patch->position().level(); // Si le niveau est 0, c'est le patch spécial 0 donc on ne modifie que le max, le niveau reste à 0. if (level == 0) { Int64x3 max_point = patch->position().maxPoint(); if (m_cmesh->mesh()->dimension() == 2) { - patch->position().setMaxPoint({ + patch->_internalApi()->positionRef().setMaxPoint({ numbering->offsetLevelToLevel(max_point.x, level, level - 1), numbering->offsetLevelToLevel(max_point.y, level, level - 1), 1, }); } else { - patch->position().setMaxPoint({ + patch->_internalApi()->positionRef().setMaxPoint({ numbering->offsetLevelToLevel(max_point.x, level, level - 1), numbering->offsetLevelToLevel(max_point.y, level, level - 1), numbering->offsetLevelToLevel(max_point.z, level, level - 1), @@ -446,7 +399,7 @@ updateLevelsBeforeAddGroundPatch() } // Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1" else { - patch->position().setLevel(level + 1); + patch->_internalApi()->positionRef().setLevel(level + 1); } } } @@ -499,7 +452,7 @@ mergePatches() for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) { auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0]; - AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->position(); + AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef(); if (patch_fusion_0.isNull()) continue; @@ -513,7 +466,7 @@ mergePatches() continue; auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1]; - AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->position(); + AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef(); if (patch_fusion_1.isNull()) continue; @@ -575,7 +528,7 @@ refine() old_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, old_max_level); m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << future_max_level; - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); AMRPatchPositionLevelGroup all_patches(future_max_level); @@ -955,10 +908,10 @@ _createGroundPatch() _addPatchInstance(patch); if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); - patch->position().setMinPoint({ 0, 0, 0 }); - patch->position().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) }); - patch->position().setLevel(0); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); + patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 }); + patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) }); + patch->_internalApi()->positionRef().setLevel(0); } } @@ -977,7 +930,7 @@ _addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch) } AMRPatchPosition patch_position = patch->position(); - Ref numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + Ref numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); UniqueArray items_lid; @@ -1258,15 +1211,12 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ Integer group_index = _nextIndexForNewPatch(); String patch_group_name = String("CartesianMeshPatchCells") + group_index; - auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); - + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, new_patch_position); _addPatchInstance(makeRef(cdi)); UniqueArray cells_local_id; - cdi->position() = new_patch_position; - - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); ENUMERATE_ (Cell, icell, parent_patch_cell_group) { Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); @@ -1294,7 +1244,7 @@ _addPatch(const AMRPatchPosition& new_patch_position) { UniqueArray cells_local_id; - auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMng(); + auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) { Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); @@ -1308,8 +1258,7 @@ _addPatch(const AMRPatchPosition& new_patch_position) Integer group_index = _nextIndexForNewPatch(); String patch_group_name = String("CartesianMeshPatchCells") + group_index; - auto* cdi = new CartesianMeshPatch(m_cmesh, group_index); - cdi->position() = new_patch_position; + auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, new_patch_position); _addPatchInstance(makeRef(cdi)); CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h similarity index 91% rename from arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h rename to arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h index c39a9977b6..3d4c7dde6f 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h @@ -25,28 +25,14 @@ namespace Arcane { -class ICartesianMeshNumberingMng; - -class CartesianMeshPatch; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -class OverlapItemGroupComputeFunctor -: public ItemGroupComputeFunctor -{ - public: - - OverlapItemGroupComputeFunctor(Ref numbering, const AMRPatchPosition& patch_position); - ~OverlapItemGroupComputeFunctor(); - - void executeFunctor() override; - - private: +class CartesianMeshPatch; - Ref m_numbering; - AMRPatchPosition m_patch_position; -}; +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup { diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h similarity index 100% rename from arcane/src/arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h rename to arcane/src/arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h diff --git a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h index 05d22cced6..d98ec99d6c 100644 --- a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h @@ -14,8 +14,8 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/ICartesianMeshAMRPatchMng.h" -#include "arcane/cartesianmesh/ICartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/core/ItemTypes.h" @@ -64,10 +64,10 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshInternal virtual Ref cartesianMeshAMRPatchMng() = 0; // TODO - virtual void initCartesianMeshNumberingMng() = 0; + virtual void initCartesianMeshNumberingMngInternal() = 0; //TODO - virtual Ref cartesianMeshNumberingMng() = 0; + virtual Ref cartesianMeshNumberingMngInternal() = 0; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h similarity index 98% rename from arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h rename to arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h index a7ef26fd71..feecc9004e 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* ICartesianMeshNumberingMng.h (C) 2000-2025 */ +/* ICartesianMeshNumberingMngInternal.h (C) 2000-2025 */ /* */ /* Interface de gestionnaire de numérotation pour maillage cartesian. */ /* Dans ces gestionnaires, on considère que l'on a un intervalle des */ @@ -13,8 +13,8 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNG_H -#define ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNG_H +#ifndef ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNGINTERNAL_H +#define ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNGINTERNAL_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -41,11 +41,11 @@ namespace Arcane * cette interface est utilisée (ou alors, il ne faut plus l'utiliser après * renumérotation (attention aux protections/reprises)). */ -class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng +class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal { public: - virtual ~ICartesianMeshNumberingMng() = default; + virtual ~ICartesianMeshNumberingMngInternal() = default; public: @@ -936,4 +936,4 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMng /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif //ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNG_H +#endif //ARCANE_CARTESIANMESH_ICARTESIANMESHNUMBERINGMNGINTERNAL_H diff --git a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h new file mode 100644 index 0000000000..c949c35c89 --- /dev/null +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h @@ -0,0 +1,51 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ICartesianMeshPatchInternal.h (C) 2000-2025 */ +/* */ +/* Informations sur un patch AMR d'un maillage cartésien. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CARTESIANMESH_ICARTESIANMESHPATCHINTERNAL_H +#define ARCANE_CARTESIANMESH_ICARTESIANMESHPATCHINTERNAL_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/core/ItemTypes.h" +#include "arcane/core/VariableTypes.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatchInternal +{ + + public: + + virtual ~ICartesianMeshPatchInternal() = default; + + public: + + virtual AMRPatchPosition& positionRef() = 0; + virtual void setPosition(const AMRPatchPosition& position) = 0; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/arcane/src/arcane/cartesianmesh/srcs.cmake b/arcane/src/arcane/cartesianmesh/srcs.cmake index 24db47c9e4..b1ec5de877 100644 --- a/arcane/src/arcane/cartesianmesh/srcs.cmake +++ b/arcane/src/arcane/cartesianmesh/srcs.cmake @@ -18,8 +18,6 @@ set(ARCANE_SOURCES ICartesianMeshPatch.h CartesianPatch.h CartesianPatch.cc - CartesianPatchGroup.h - CartesianPatchGroup.cc CartesianMeshCoarsening.cc CartesianMeshCoarsening.h CartesianMeshCoarsening2.cc @@ -28,10 +26,6 @@ set(ARCANE_SOURCES CartesianMeshUtils.h CartesianMeshUtils.cc CartesianMeshPatchListView.h - internal/CartesianMeshPatch.h - internal/CartesianMeshUniqueIdRenumbering.h - internal/CartesianMeshUniqueIdRenumbering.cc - internal/ICartesianMeshInternal.h CartesianMeshPatch.cc v2/CartesianGrid.h @@ -40,21 +34,33 @@ set(ARCANE_SOURCES v2/CartesianMeshUniqueIdRenumberingV2.h v2/CartesianMeshUniqueIdRenumberingV2.cc - ICartesianMeshAMRPatchMng.h - CartesianMeshAMRPatchMng.cc - CartesianMeshAMRPatchMng.h + CartesianMeshAMRMng.cc + CartesianMeshAMRMng.h - ICartesianMeshNumberingMng.h CartesianMeshNumberingMng.cc CartesianMeshNumberingMng.h AMRZonePosition.cc AMRZonePosition.h AMRPatchPosition.h AMRPatchPosition.cc - AMRPatchPositionLevelGroup.h - AMRPatchPositionLevelGroup.cc - AMRPatchPositionSignature.h - AMRPatchPositionSignature.cc - AMRPatchPositionSignatureCut.h - AMRPatchPositionSignatureCut.cc + + internal/AMRPatchPositionLevelGroup.h + internal/AMRPatchPositionLevelGroup.cc + internal/AMRPatchPositionSignature.h + internal/AMRPatchPositionSignature.cc + internal/AMRPatchPositionSignatureCut.h + internal/AMRPatchPositionSignatureCut.cc + internal/CartesianMeshNumberingMngInternal.cc + internal/CartesianMeshNumberingMngInternal.h + internal/CartesianMeshPatch.h + internal/CartesianMeshUniqueIdRenumbering.h + internal/CartesianMeshUniqueIdRenumbering.cc + internal/CartesianPatchGroup.h + internal/CartesianPatchGroup.cc + internal/ICartesianMeshInternal.h + internal/ICartesianMeshPatchInternal.h + internal/ICartesianMeshAMRPatchMng.h + internal/CartesianMeshAMRPatchMng.cc + internal/CartesianMeshAMRPatchMng.h + internal/ICartesianMeshNumberingMngInternal.h ) From cb00b98147c049f8c2751d5c794d68b9b7663045 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Mon, 1 Dec 2025 15:28:34 +0100 Subject: [PATCH 12/19] [arcane:cartesianmesh] Add methods to get cells uid around node And : - Add two new patch groups : inPatch and overall, - Add specific methods for AMR Patch using the numbering mng in CartesianConnectivity, CartesianMesh, CartesianMeshPatch, Cell/Face/NodeDirectionMng, --- .../arcane/cartesianmesh/AMRPatchPosition.cc | 9 - .../arcane/cartesianmesh/AMRPatchPosition.h | 1 - .../cartesianmesh/CartesianConnectivity.cc | 218 ++++++++++++++- .../cartesianmesh/CartesianConnectivity.h | 3 + .../src/arcane/cartesianmesh/CartesianMesh.cc | 193 ++++++++++++- .../cartesianmesh/CartesianMeshAMRMng.h | 72 +++++ .../CartesianMeshNumberingMng.cc | 2 +- .../cartesianmesh/CartesianMeshNumberingMng.h | 2 +- .../cartesianmesh/CartesianMeshPatch.cc | 57 +++- .../arcane/cartesianmesh/CartesianPatch.cc | 8 +- .../src/arcane/cartesianmesh/CartesianPatch.h | 2 +- .../arcane/cartesianmesh/CellDirectionMng.cc | 68 ++++- .../arcane/cartesianmesh/CellDirectionMng.h | 37 ++- .../arcane/cartesianmesh/FaceDirectionMng.cc | 261 +++++++++++++++++- .../arcane/cartesianmesh/FaceDirectionMng.h | 59 +++- .../src/arcane/cartesianmesh/ICartesianMesh.h | 23 ++ .../cartesianmesh/ICartesianMeshPatch.h | 2 +- .../arcane/cartesianmesh/NodeDirectionMng.cc | 260 ++++++++++++++++- .../arcane/cartesianmesh/NodeDirectionMng.h | 45 ++- .../internal/AMRPatchPositionLevelGroup.cc | 5 +- .../internal/CartesianMeshAMRPatchMng.cc | 44 +-- .../CartesianMeshNumberingMngInternal.cc | 217 ++++++++++++--- .../CartesianMeshNumberingMngInternal.h | 9 + .../internal/CartesianMeshPatch.h | 3 +- .../internal/CartesianPatchGroup.cc | 99 ++++--- .../internal/CartesianPatchGroup.h | 10 +- .../ICartesianMeshNumberingMngInternal.h | 164 +++++++++-- 27 files changed, 1698 insertions(+), 175 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc index 7e273eb6f8..fc0ddd36d7 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -147,15 +147,6 @@ maxPointWithOverlap() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -bool AMRPatchPosition:: -isIn(Int64 x, Int64 y, Int64 z) const -{ - 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; -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - Int64 AMRPatchPosition:: nbCells() const { diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index e0152533ca..38461c8c97 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -52,7 +52,6 @@ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition Int64x3 minPointWithOverlap() const; Int64x3 maxPointWithOverlap() const; - bool isIn(Int64 x, Int64 y, Int64 z) const; Int64 nbCells() const; std::pair cut(Int64 cut_point, Integer dim) const; diff --git a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc index 5ba6de7d32..3bbaeaafd1 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc @@ -14,10 +14,14 @@ #include "arcane/utils/NotSupportedException.h" #include "arcane/cartesianmesh/CartesianConnectivity.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/IMesh.h" -#include "arcane/IItemFamily.h" -#include "arcane/VariableTypes.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/VariableTypes.h" + +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -63,6 +67,23 @@ _computeInfos(IMesh* mesh, VariableNodeReal3& nodes_coord, /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianConnectivity:: +_computeInfos(ICartesianMesh* cmesh) +{ + m_nodes = NodeInfoListView(cmesh->mesh()->nodeFamily()); + m_cells = CellInfoListView(cmesh->mesh()->cellFamily()); + + if (cmesh->mesh()->dimension() == 2 || cmesh->mesh()->dimension() == 1) + _computeInfos2D(cmesh); + else if (cmesh->mesh()->dimension() == 3) + _computeInfos3D(cmesh); + else + throw NotSupportedException(A_FUNCINFO, "Unknown mesh dimension"); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianConnectivity:: _computeInfos2D(IMesh* mesh, VariableNodeReal3& nodes_coord, VariableCellReal3& cells_coord) @@ -125,6 +146,100 @@ _computeInfos2D(IMesh* mesh, VariableNodeReal3& nodes_coord, /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianConnectivity:: +_computeInfos2D(ICartesianMesh* cmesh) +{ + Ref numbering = cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); + + CartesianConnectivity& cc = *this; + IItemFamily* node_family = cmesh->mesh()->nodeFamily(); + IItemFamily* cell_family = cmesh->mesh()->cellFamily(); + + { + constexpr Integer nb_cell_around_node_max = 4; + Int64 cells_around[nb_cell_around_node_max]; + ArrayView av_cells_around(nb_cell_around_node_max, cells_around); + + // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre : + // + // |2|3| + // . + // |0|1| + // + // y + // ^ + // |->x + // + constexpr Int32 pos_2d[nb_cell_around_node_max] = { P_LowerLeft, P_LowerRight, P_UpperLeft, P_UpperRight }; + + ENUMERATE_ (Node, inode, node_family->allItems()) { + Node node = *inode; + numbering->cellUniqueIdsAroundNode(av_cells_around, node); + + Index& idx = cc._index(node); + idx.fill(NULL_ITEM_LOCAL_ID); + + const Integer nb_cell = node.nbCell(); + for (Integer i = 0; i < nb_cell; ++i) { + Cell cell = node.cell(i); + Integer pos = 0; + for (; pos < nb_cell_around_node_max; ++pos) { + if (cell.uniqueId() == av_cells_around[pos]) + break; + } + if (pos == nb_cell_around_node_max) + continue; + + const Int32 cell_lid = cell.localId(); + idx.v[pos_2d[pos]] = cell_lid; + } + } + } + { + constexpr Integer nb_node_in_cell_max = 4; + Int64 nodes_in_cell[nb_node_in_cell_max]; + ArrayView av_nodes_in_cell(nb_node_in_cell_max, nodes_in_cell); + + // Le CartesianMeshNumberingMng nous donne toujours les noeuds de la maille dans le même ordre : + // + // |3|2| + // . + // |0|1| + // + // y + // ^ + // |->x + // + constexpr Int32 pos_2d[nb_node_in_cell_max] = { P_LowerLeft, P_LowerRight, P_UpperRight, P_UpperLeft }; + + ENUMERATE_ (Cell, icell, cell_family->allItems()) { + Cell cell = *icell; + numbering->cellNodeUniqueIds(av_nodes_in_cell, cell); + + Index& idx = _index(cell); + idx.fill(NULL_ITEM_LOCAL_ID); + + const Integer nb_node = cell.nbNode(); + for (Integer i = 0; i < nb_node; ++i) { + Node node = cell.node(i); + Integer pos = 0; + for (; pos < nb_node_in_cell_max; ++pos) { + if (cell.uniqueId() == av_nodes_in_cell[pos]) + break; + } + if (pos == nb_node_in_cell_max) + continue; + + const Int32 node_lid = node.localId(); + idx.v[pos_2d[pos]] = node_lid; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianConnectivity:: _computeInfos3D(IMesh* mesh, VariableNodeReal3& nodes_coord, VariableCellReal3& cells_coord) @@ -220,6 +335,103 @@ _computeInfos3D(IMesh* mesh, VariableNodeReal3& nodes_coord, /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + +void CartesianConnectivity:: +_computeInfos3D(ICartesianMesh* cmesh) +{ + Ref numbering = cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); + + CartesianConnectivity& cc = *this; + IItemFamily* node_family = cmesh->mesh()->nodeFamily(); + IItemFamily* cell_family = cmesh->mesh()->cellFamily(); + + { + constexpr Integer nb_cell_around_node_max = 8; + Int64 cells_around[nb_cell_around_node_max]; + ArrayView av_cells_around(nb_cell_around_node_max, cells_around); + + // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre : + // + // z = 0 | z = 1 + // |2|3| | |6|7| + // . | . + // |0|1| | |4|5| + // + // y + // ^ + // |->x + // + constexpr Int32 pos_3d[nb_cell_around_node_max] = { P_LowerLeft, P_LowerRight, P_UpperLeft, P_UpperRight, P_TopZLowerLeft, P_TopZLowerRight, P_TopZUpperLeft, P_TopZUpperRight }; + + ENUMERATE_ (Node, inode, node_family->allItems()) { + Node node = *inode; + numbering->cellUniqueIdsAroundNode(av_cells_around, node); + + Index& idx = cc._index(node); + idx.fill(NULL_ITEM_LOCAL_ID); + + const Integer nb_cell = node.nbCell(); + for (Integer i = 0; i < nb_cell; ++i) { + Cell cell = node.cell(i); + Integer pos = 0; + for (; pos < nb_cell_around_node_max; ++pos) { + if (cell.uniqueId() == av_cells_around[pos]) + break; + } + if (pos == nb_cell_around_node_max) + continue; + + const Int32 cell_lid = cell.localId(); + idx.v[pos_3d[pos]] = cell_lid; + } + } + } + { + constexpr Integer nb_node_in_cell_max = 8; + Int64 nodes_in_cell[nb_node_in_cell_max]; + ArrayView av_nodes_in_cell(nb_node_in_cell_max, nodes_in_cell); + + // Le CartesianMeshNumberingMng nous donne toujours les noeuds de la maille dans le même ordre : + // + // z = 0 | z = 1 + // |3|2| | |7|6| + // . | . + // |0|1| | |4|5| + // + // y + // ^ + // |->x + // + constexpr Int32 pos_3d[nb_node_in_cell_max] = { P_LowerLeft, P_LowerRight, P_UpperRight, P_UpperLeft, P_TopZLowerLeft, P_TopZLowerRight, P_TopZUpperRight, P_TopZUpperLeft }; + + ENUMERATE_ (Cell, icell, cell_family->allItems()) { + Cell cell = *icell; + numbering->cellNodeUniqueIds(av_nodes_in_cell, cell); + + Index& idx = _index(cell); + idx.fill(NULL_ITEM_LOCAL_ID); + + const Integer nb_node = cell.nbNode(); + for (Integer i = 0; i < nb_node; ++i) { + Node node = cell.node(i); + Integer pos = 0; + for (; pos < nb_node_in_cell_max; ++pos) { + if (cell.uniqueId() == av_nodes_in_cell[pos]) + break; + } + if (pos == nb_node_in_cell_max) + continue; + + const Int32 node_lid = node.localId(); + idx.v[pos_3d[pos]] = node_lid; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + /*! * \brief Calcule les permutations des 8 ePosition pour chaque direction. * diff --git a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h index 354988b825..f8fa1ed114 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h +++ b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h @@ -221,6 +221,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianConnectivity //! Calcule les infos de connectivité. void _computeInfos(IMesh* mesh, VariableNodeReal3& nodes_coord, VariableCellReal3& cells_coord); + void _computeInfos(ICartesianMesh* cmesh); //! Positionne les tableaux contenant les infos de connectivité void _setStorage(ArrayView nodes_to_cell, ArrayView cells_to_node, const Permutation* permutation); @@ -265,7 +266,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianConnectivity private: void _computeInfos2D(IMesh* mesh, VariableNodeReal3& nodes_coord, VariableCellReal3& cells_coord); + void _computeInfos2D(ICartesianMesh* cmesh); void _computeInfos3D(IMesh* mesh, VariableNodeReal3& nodes_coord, VariableCellReal3& cells_coord); + void _computeInfos3D(ICartesianMesh* cmesh); }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 7f354a8e9e..2706343649 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -173,6 +173,7 @@ class CartesianMeshImpl } void computeDirections() override; + void computeDirectionsV2() override; void recreateFromDump() override; @@ -243,6 +244,13 @@ class CartesianMeshImpl VariableCellReal3& cells_center, VariableFaceReal3& faces_center,CellGroup all_cells, NodeGroup all_nodes, CellGroup own_cells); + + void _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, + CellGroup all_cells, + CellGroup in_patch_cells, + CellGroup overall_cells, + NodeGroup all_nodes); + void _applyRefine(const AMRZonePosition &position); void _applyCoarse(const AMRZonePosition& zone_position); void _addPatch(ConstArrayView parent_cells); @@ -282,8 +290,6 @@ CartesianMeshImpl(IMesh* mesh) if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.initCartesianMeshNumberingMngInternal(); m_internal_api.initCartesianMeshAMRPatchMng(); - // TODO : Voir où mettre la renumérotation. - //m_internal_api.cartesianMeshNumberingMng()->renumberingFacesLevel0FromOriginalArcaneNumbering(); } m_all_items_direction_info = m_patch_group.groundPatch(); } @@ -330,7 +336,7 @@ _saveInfosInProperties() // Sauve les informations des patches UniqueArray patch_group_names; for (Integer i = 1; i < m_patch_group.nbPatch(); ++i) { - patch_group_names.add(m_patch_group.cells(i).name()); + patch_group_names.add(m_patch_group.allCells(i).name()); } m_properties->set("PatchGroupNames",patch_group_names); @@ -407,6 +413,12 @@ _checkAddObservableMeshChanged() void CartesianMeshImpl:: computeDirections() { + if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { + // TODO : Voir où mettre la renumérotation. + m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering(); + computeDirectionsV2(); + return; + } info() << "CartesianMesh: computeDirections()"; m_mesh_timestamp = mesh()->timestamp(); @@ -578,15 +590,15 @@ computeDirections() // Ajoute informations de connectivités pour les patchs AMR // TODO: supporter plusieurs appels à cette méthode ? for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) { - CellGroup cells = m_patch_group.cells(patch_index); + CellGroup cells = m_patch_group.allCells(patch_index); Ref patch = m_patch_group.patch(patch_index); info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch(); patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord); auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); - _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); - _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); if (is_3d) - _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.ownCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); } if (arcaneIsCheck()) @@ -708,6 +720,173 @@ _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellR /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshImpl:: +_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overall_cells, NodeGroup all_nodes) +{ + IItemFamily* cell_family = m_mesh->cellFamily(); + IItemFamily* face_family = m_mesh->faceFamily(); + IItemFamily* node_family = m_mesh->nodeFamily(); + + Int32 max_cell_id = cell_family->maxLocalId(); + Int32 max_face_id = face_family->maxLocalId(); + Int32 max_node_id = node_family->maxLocalId(); + + CellDirectionMng& cell_dm = cdi.cellDirection(dir); + cell_dm._internalResizeInfos(max_cell_id); + + FaceDirectionMng& face_dm = cdi.faceDirection(dir); + face_dm._internalResizeInfos(max_face_id); + + NodeDirectionMng& node_dm = cdi.nodeDirection(dir); + node_dm._internalResizeInfos(max_node_id); + + //TODO: attention à remettre à jour après changement de maillage. + info(4) << "COMPUTE DIRECTION dir=" << dir; + + Int32 prev_local_face = -1; + Int32 next_local_face = m_local_face_direction[dir]; + Integer mesh_dim = m_mesh->dimension(); + // Calcul le numero local de face oppose à la face suivante. + if (mesh_dim == 2) + prev_local_face = (next_local_face + 2) % 4; + else if (mesh_dim == 3) + prev_local_face = (next_local_face + 3) % 6; + + cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face); + + // Positionne pour chaque maille les faces avant et après dans la direction. + // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante + std::set cells_set; + ENUMERATE_CELL (icell, all_cells) { + cells_set.insert(icell.itemLocalId()); + } + + // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles + // soient de même niveau + ENUMERATE_CELL (icell, all_cells) { + Cell cell = *icell; + Int32 my_level = cell.level(); + Face next_face = cell.face(next_local_face); + Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell(); + if (cells_set.find(next_cell.localId()) == cells_set.end()) { + if (next_cell.level() != my_level) { + next_cell = Cell(); + } + } + else if (next_cell.level() != my_level) { + next_cell = Cell(); + } + + Face prev_face = cell.face(prev_local_face); + Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell(); + + if (cells_set.find(prev_cell.localId()) == cells_set.end()) { + if (prev_cell.level() != my_level) { + prev_cell = Cell(); + } + } + else if (prev_cell.level() != my_level) { + prev_cell = Cell(); + } + + cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell); + } + cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overall_cells); + face_dm._internalComputeInfos(cell_dm); + node_dm._internalComputeInfos(cell_dm, all_nodes); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshImpl:: +computeDirectionsV2() +{ + info() << "CartesianMesh: computeDirectionsV2()"; + + m_mesh_timestamp = mesh()->timestamp(); + _checkAddObservableMeshChanged(); + + m_is_amr = m_mesh->isAmrActivated(); + + IItemFamily* cell_family = m_mesh->cellFamily(); + IItemFamily* node_family = m_mesh->nodeFamily(); + + bool is_3d = m_mesh->dimension() == 3; + + m_all_items_direction_info->_internalComputeNodeCellInformations(); + + info() << "Informations from IMesh properties:"; + + auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, true); + + info() << "GlobalNbCell = " << cmgi->globalNbCells(); + info() << "OwnNbCell: " << cmgi->ownNbCells(); + info() << "SubDomainOffset: " << cmgi->subDomainOffsets(); + info() << "OwnCellOffset: " << cmgi->ownCellOffsets(); + + CellGroup all_cells = cell_family->allItems(); + NodeGroup all_nodes = node_family->allItems(); + if (m_is_amr) { + auto x = _buildPatchGroups(mesh()->allLevelCells(0), 0); + all_cells = std::get<0>(x); + all_nodes = std::get<1>(x); + } + if (is_3d) { + m_local_face_direction[MD_DirX] = 4; + m_local_face_direction[MD_DirY] = 5; + m_local_face_direction[MD_DirZ] = 3; + } + else { + m_local_face_direction[MD_DirX] = 1; + m_local_face_direction[MD_DirY] = 2; + } + + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells, CellGroup(), all_nodes); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells, CellGroup(), all_nodes); + if (is_3d) { + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells, CellGroup(), all_nodes); + } + + // Positionne les informations par direction + for (Integer idir = 0, nb_dir = mesh()->dimension(); idir < nb_dir; ++idir) { + CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir); + cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir], + cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]); + } + + info() << "Compute cartesian connectivity"; + + m_permutation_storage.resize(1); + m_permutation_storage[0].compute(); + m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId()); + m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId()); + m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]); + m_connectivity._computeInfos(this); + + // Ajoute informations de connectivités pour les patchs AMR + // TODO: supporter plusieurs appels à cette méthode ? + for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) { + CellGroup cells = m_patch_group.allCells(patch_index); + Ref patch = m_patch_group.patch(patch_index); + info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch(); + patch->_internalComputeNodeCellInformations(); + auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); // TODO A suppr + _computeMeshDirection(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + _computeMeshDirection(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + if (is_3d) + _computeMeshDirection(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + } + + if (arcaneIsCheck()) + checkValid(); + + _saveInfosInProperties(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshImpl:: refinePatch2D(Real2 position,Real2 length) { diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h index 361d019a1a..72bb9e52dd 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h @@ -37,20 +37,92 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng public: + /*! + * \brief Nombre de patchs du maillage. + * + * Il y a toujours au moins un patch qui représente le maillage cartésien. + */ Int32 nbPatch() const; + + /*! + * \brief Retourne le \a index-ième patch du maillage. + * + * Si le maillage est cartésien, il n'y a qu'un seul patch. + * + * L'instance retournée reste valide tant que cette instance n'est pas détruite. + */ CartesianPatch amrPatch(Int32 index) const; + + /*! + * \brief Vue sur la liste des patchs. + */ CartesianMeshPatchListView patches() const; + /*! + * \brief Raffine un bloc du maillage cartésien. + * + * Cette méthode ne peut être appelée que si le maillage est un maillage + * AMR (IMesh::isAmrActivated()==true). + * + * Les mailles dont les positions des centres sont comprises entre + * \a position et \a (position+length) sont raffinées et les informations + * de connectivité correspondantes sont mises à jour. + * + * Cette opération est collective. + */ void refineZone(const AMRZonePosition& position) const; + /*! + * \brief Dé-raffine un bloc du maillage cartésien. + * + * Cette méthode ne peut être appelée que si le maillage est un maillage + * AMR (IMesh::isAmrActivated()==true). + * + * Les mailles dont les positions des centres sont comprises entre + * \a position et \a (position+length) sont dé-raffinées et les informations + * de connectivité correspondantes sont mises à jour. + * + * Toutes les mailles dans la zone de dé-raffinement doivent être du même + * niveau. + * + * Les patchs ne contenant plus de mailles après l'appel à cette méthode + * seront supprimés. + * + * Cette opération est collective. + */ void coarseZone(const AMRZonePosition& position) const; + /*! + * \brief TODO + */ void refine() const; + /*! + * \brief Méthode permettant de supprimer une ou plusieurs couches + * de mailles fantômes sur un niveau de raffinement défini. + * + * Le nombre de couches de mailles fantômes souhaité peut être augmenté + * par la méthode. Il est nécessaire de récupérer la valeur retournée + * pour avoir le nombre de couches de mailles fantômes final. + * + * \param level Le niveau de raffinement concerné par la suppression + * des mailles fantômes. + * + * \param target_nb_ghost_layers Le nombre de couches souhaité après + * appel à cette méthode. ATTENTION : Il peut être ajusté par la méthode. + * + * \return Le nombre de couches de mailles fantômes final. + */ Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const; + /*! + * \brief TODO + */ void mergePatches() const; + /*! + * \brief TODO + */ void createSubLevel() const; private: diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index e7368c3c9f..b4bd8ffd49 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -36,7 +36,7 @@ CartesianMeshNumberingMng(ICartesianMesh* mesh) /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -printStatus() +printStatus() const { m_internal_api->printStatus(); } diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h index 03590f98af..15306ee725 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h @@ -43,7 +43,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshNumberingMng public: - void printStatus(); + void printStatus() const; Int64 firstCellUniqueId(Integer level) const; Int64 firstNodeUniqueId(Integer level) const; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc index 1de36c44e2..9a617abcd9 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshPatch.cc @@ -85,9 +85,10 @@ cells() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -CellGroup CartesianMeshPatch::ownCells() +CellGroup CartesianMeshPatch:: +inPatchCells() { - return cellDirection(MD_DirX).innerCells(); + return cellDirection(MD_DirX).inPatchCells(); } /*---------------------------------------------------------------------------*/ @@ -299,6 +300,58 @@ _internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeRe /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshPatch:: +_internalComputeNodeCellInformations() +{ + int dim = m_mesh->mesh()->dimension(); + Int8 nodes_indirection[CellDirectionMng::MAX_NB_NODE]; + ArrayView av_nodes_indirection(CellDirectionMng::MAX_NB_NODE, nodes_indirection); + // DirX (Top->Z=1 / Previous->X=0 / Next->X=1 / Right->Y=0 / Left->Y=1) + av_nodes_indirection.fill(-1); + av_nodes_indirection[CNP_NextLeft] = 2; + av_nodes_indirection[CNP_NextRight] = 1; + av_nodes_indirection[CNP_PreviousRight] = 0; + av_nodes_indirection[CNP_PreviousLeft] = 3; + if (dim == 3) { + av_nodes_indirection[CNP_TopNextLeft] = 6; + av_nodes_indirection[CNP_TopNextRight] = 5; + av_nodes_indirection[CNP_TopPreviousRight] = 4; + av_nodes_indirection[CNP_TopPreviousLeft] = 7; + } + cellDirection(MD_DirX).setNodesIndirection(av_nodes_indirection); + + // DirY (Top->Z=1 / Previous->Y=0 / Next->Y=1 / Right->X=1 / Left->X=0) + av_nodes_indirection.fill(-1); + av_nodes_indirection[CNP_NextLeft] = 3; + av_nodes_indirection[CNP_NextRight] = 2; + av_nodes_indirection[CNP_PreviousRight] = 1; + av_nodes_indirection[CNP_PreviousLeft] = 0; + if (dim == 3) { + av_nodes_indirection[CNP_TopNextLeft] = 7; + av_nodes_indirection[CNP_TopNextRight] = 6; + av_nodes_indirection[CNP_TopPreviousRight] = 5; + av_nodes_indirection[CNP_TopPreviousLeft] = 4; + } + cellDirection(MD_DirY).setNodesIndirection(av_nodes_indirection); + + if (dim == 3) { + // DirZ (Top->Y=1 / Previous->Z=0 / Next->Z=1 / Right->X=1 / Left->X=0) + av_nodes_indirection.fill(-1); + av_nodes_indirection[CNP_NextLeft] = 4; + av_nodes_indirection[CNP_NextRight] = 5; + av_nodes_indirection[CNP_PreviousRight] = 1; + av_nodes_indirection[CNP_PreviousLeft] = 0; + av_nodes_indirection[CNP_TopNextLeft] = 7; + av_nodes_indirection[CNP_TopNextRight] = 6; + av_nodes_indirection[CNP_TopPreviousRight] = 2; + av_nodes_indirection[CNP_TopPreviousLeft] = 3; + cellDirection(MD_DirZ).setNodesIndirection(av_nodes_indirection); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshPatch:: checkValid() const { diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc index 44617a3998..3da93627c2 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc @@ -30,11 +30,15 @@ cells() ARCANE_CHECK_POINTER(m_patch); return m_patch->cells(); } + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CellGroup CartesianPatch:: -ownCells() +inPatchCells() { ARCANE_CHECK_POINTER(m_patch); - return m_patch->ownCells(); + return m_patch->inPatchCells(); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.h b/arcane/src/arcane/cartesianmesh/CartesianPatch.h index 57910a3ada..baad22ea81 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.h @@ -53,7 +53,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch //! Groupe de mailles du patch CellGroup cells(); - CellGroup ownCells(); + CellGroup inPatchCells(); Integer index() const; Integer level() const diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc index 676cee37bb..0c6c4114a5 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc @@ -16,10 +16,10 @@ #include "arcane/utils/ITraceMng.h" #include "arcane/utils/PlatformUtils.h" -#include "arcane/IItemFamily.h" -#include "arcane/ItemGroup.h" -#include "arcane/IMesh.h" -#include "arcane/UnstructuredMeshConnectivity.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/ItemGroup.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/UnstructuredMeshConnectivity.h" #include "arcane/cartesianmesh/CellDirectionMng.h" #include "arcane/cartesianmesh/ICartesianMesh.h" @@ -43,6 +43,8 @@ class CellDirectionMng::Impl CellGroup m_inner_all_items; CellGroup m_outer_all_items; + CellGroup m_inpatch_all_items; + CellGroup m_overall_all_items; CellGroup m_all_items; ICartesianMesh* m_cartesian_mesh = nullptr; Integer m_patch_index = -1; @@ -151,6 +153,46 @@ _internalComputeInnerAndOuterItems(const ItemGroup& items, const ItemGroup& own_ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CellDirectionMng:: +_internalComputeCellGroups(const CellGroup& all_cells, const CellGroup& in_patch_cells, const CellGroup& overall_cells) +{ + m_p->m_inpatch_all_items = in_patch_cells; + m_p->m_overall_all_items = overall_cells; + m_p->m_all_items = all_cells; + + UniqueArray overall_lid; + overall_cells.view().fillLocalIds(overall_lid); + + UniqueArray inner_lids; + UniqueArray outer_lids; + + ENUMERATE_ (Cell, icell, in_patch_cells) { + Int32 lid = icell.itemLocalId(); + Int32 i1 = m_infos_view[lid].m_next_lid; + Int32 i2 = m_infos_view[lid].m_previous_lid; + if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID || overall_lid.contains(i1) || overall_lid.contains(i2)) + outer_lids.add(lid); + else + inner_lids.add(lid); + } + int dir = (int)m_direction; + IItemFamily* family = all_cells.itemFamily(); + String base_group_name = String("Direction") + dir; + if (m_p->m_patch_index >= 0) + base_group_name = base_group_name + String("AMRPatch") + m_p->m_patch_index; + m_p->m_inner_all_items = family->createGroup(String("AllInner") + base_group_name, inner_lids, true); + m_p->m_outer_all_items = family->createGroup(String("AllOuter") + base_group_name, outer_lids, true); + m_cells = CellInfoListView(family); + + UnstructuredMeshConnectivityView mesh_connectivity; + mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh()); + m_cell_node_view = mesh_connectivity.cellNode(); + m_cell_face_view = mesh_connectivity.cellFace(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CellGroup CellDirectionMng:: allCells() const { @@ -160,6 +202,24 @@ allCells() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +CellGroup CellDirectionMng:: +overallCells() const +{ + return m_p->m_overall_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CellGroup CellDirectionMng:: +inPatchCells() const +{ + return m_p->m_inpatch_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + CellGroup CellDirectionMng:: innerCells() const { diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h index eb344e4019..3fe23e9edd 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h @@ -446,19 +446,49 @@ class ARCANE_CARTESIANMESH_EXPORT CellDirectionMng //! Groupe de toutes les mailles dans la direction. CellGroup allCells() const; + /*! + * \brief Groupe de toutes les mailles de recouvrement dans la direction. + * + * 0 1 2 3 4 + * ┌───┬──┬──┬──┬──┐ + * │ │ │ │ │ │ + * │ ├──┼──┼──┼──┤ + * │ │ │ │ │ │ + * └───┴──┴──┴──┴──┘ + * + * 0 : level -1 + * 1 et 2 : Mailles de recouvrements (overallCells) + * 3 : Mailles externes (outerCells) + * 4 : Mailles internes (innerCells) + * + * La couche de mailles de recouvrements désigne la couche de mailles de même + * niveau autour du patch. Ces mailles peuvent appartenir à un ou plusieurs + * patchs. + */ + CellGroup overallCells() const; + + /*! + * \brief Groupe de toutes les mailles du patch dans la direction. + * + * Regroupe toutes les mailles qui ne sont ni de recouvrement, ni fantôme. + * (`innerCells() + outerCells()` ou simplement `!overallCells()`) + */ + CellGroup inPatchCells() const; + /*! * \brief Groupe de toutes les mailles internes dans la direction. * * Une maille est considérée comme interne si sa maille - * avant ou après n'est pas nulle. + * avant ou après n'est pas nulle et n'est pas une maille de recouvrement. */ - CellGroup innerCells() const; + /*! * \brief Groupe de toutes les mailles externes dans la direction. * * Une maille est considérée comme externe si sa maille - * avant ou après est nulle. + * avant ou après est de recouvrement ou est nulle (si l'on est au bord du + * domaine ou s'il n'y a pas de couches de mailles de recouvrements). */ CellGroup outerCells() const; @@ -566,6 +596,7 @@ class ARCANE_CARTESIANMESH_EXPORT CellDirectionMng * Suppose que init() a été appelé. */ void _internalComputeInnerAndOuterItems(const ItemGroup& items, const ItemGroup& own_items); + void _internalComputeCellGroups(const CellGroup& all_cells, const CellGroup& in_patch_cells, const CellGroup& overall_cells); /*! * \internal diff --git a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc index 10839e297c..a8eafade20 100644 --- a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc @@ -17,13 +17,14 @@ #include "arcane/utils/Real3.h" #include "arcane/utils/PlatformUtils.h" -#include "arcane/IItemFamily.h" -#include "arcane/ItemGroup.h" -#include "arcane/IMesh.h" -#include "arcane/VariableTypes.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/ItemGroup.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/VariableTypes.h" #include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/cartesianmesh/CellDirectionMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" #include @@ -43,6 +44,8 @@ class FaceDirectionMng::Impl public: FaceGroup m_inner_all_items; FaceGroup m_outer_all_items; + FaceGroup m_inpatch_all_items; + FaceGroup m_overall_all_items; FaceGroup m_all_items; ICartesianMesh* m_cartesian_mesh = nullptr; Integer m_patch_index = -1; @@ -176,6 +179,103 @@ _internalComputeInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& c /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void FaceDirectionMng:: +_internalComputeInfos(const CellDirectionMng& cell_dm) +{ + IMesh* mesh = m_p->m_cartesian_mesh->mesh(); + IItemFamily* face_family = mesh->faceFamily(); + IItemFamily* cell_family = mesh->cellFamily(); + int dir = (int)m_direction; + String base_group_name = String("Direction") + dir; + if (m_p->m_patch_index >= 0) + base_group_name = base_group_name + String("AMRPatch") + m_p->m_patch_index; + + // Calcule la liste des faces dans une direction donnée. + // Il faut pour chaque maille ajouter dans la liste des faces + // les deux faces de la direction souhaitées en prenant bien soin + // de ne pas ajouter deux fois la même face. + UniqueArray faces_lid; + { + CellGroup all_cells = cell_dm.allCells(); + faces_lid.reserve(all_cells.size()); + // Ensemble des faces déjà ajoutées + std::set done_faces; + ENUMERATE_ (Cell, icell, all_cells) { + DirCellFace dcf(cell_dm.cellFace(*icell)); + Face next_face = dcf.next(); + Face prev_face = dcf.previous(); + + //! Ajoute la face d'avant à la liste des faces de cette direction + Int32 prev_lid = prev_face.localId(); + if (done_faces.find(prev_lid) == done_faces.end()) { + faces_lid.add(prev_lid); + done_faces.insert(prev_lid); + } + Int32 next_lid = next_face.localId(); + if (done_faces.find(next_lid) == done_faces.end()) { + faces_lid.add(next_lid); + done_faces.insert(next_lid); + } + } + } + + FaceGroup all_faces = face_family->createGroup(String("AllFaces") + base_group_name, Int32ConstArrayView(), true); + all_faces.setItems(faces_lid, true); + + UniqueArray inner_cells_lid; + UniqueArray outer_cells_lid; + cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); + cell_dm.outerCells().view().fillLocalIds(outer_cells_lid); + + UniqueArray inner_lids; + UniqueArray outer_lids; + UniqueArray inpatch_lids; + UniqueArray overall_lids; + ENUMERATE_ (Face, iface, all_faces) { + Int32 lid = iface.itemLocalId(); + Face face = *iface; + if (face.nbCell() == 1) { + if (outer_cells_lid.contains(face.cell(0).localId())) { + outer_lids.add(lid); + inpatch_lids.add(lid); + } + else { + overall_lids.add(lid); + } + } + else { + bool c0_inner_cell = inner_cells_lid.contains(face.cell(0).localId()); + bool c1_inner_cell = inner_cells_lid.contains(face.cell(1).localId()); + if (c0_inner_cell || c1_inner_cell) { + inner_lids.add(lid); + inpatch_lids.add(lid); + } + else { + bool c0_outer_cell = outer_cells_lid.contains(face.cell(0).localId()); + bool c1_outer_cell = outer_cells_lid.contains(face.cell(1).localId()); + if (c0_outer_cell || c1_outer_cell) { + outer_lids.add(lid); + inpatch_lids.add(lid); + } + else { + overall_lids.add(lid); + } + } + } + } + m_p->m_inner_all_items = face_family->createGroup(String("AllInner") + base_group_name, inner_lids, true); + m_p->m_outer_all_items = face_family->createGroup(String("AllOuter") + base_group_name, outer_lids, true); + m_p->m_inpatch_all_items = face_family->createGroup(String("AllInPatch") + base_group_name, inpatch_lids, true); + m_p->m_overall_all_items = face_family->createGroup(String("AllOverall") + base_group_name, overall_lids, true); + m_p->m_all_items = all_faces; + m_cells = CellInfoListView(cell_family); + + _computeCellInfos(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + bool FaceDirectionMng:: _hasFace(Cell cell,Int32 face_local_id) const { @@ -280,6 +380,141 @@ _computeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void FaceDirectionMng:: +_computeCellInfos() const +{ + Ref numbering = m_p->m_cartesian_mesh->_internalApi()->cartesianMeshNumberingMngInternal(); + eMeshDirection dir = m_direction; + // ITraceMng* tm = m_p->m_cartesian_mesh->traceMng(); + + ENUMERATE_ (Face, iface, m_p->m_all_items) { + Face face = *iface; + Cell front_cell = face.frontCell(); + Cell back_cell = face.backCell(); + // tm->info() << "FaceUID : " << face.uniqueId() + // << " -- backCellUID : " << back_cell.uniqueId() + // << " -- backCellLevel : " << back_cell.level() + // << " -- frontCellUID : " << front_cell.uniqueId() + // << " -- frontCellLevel : " << front_cell.level() + // << " -- dir : " << dir; + bool is_inverse = false; + if (!front_cell.null() && !back_cell.null()) { + + // Si la face a deux mailles connectées, regarde le niveau AMR de ces + // deux mailles et s'il est différent, ne conserve que la maille + // dont le niveau AMR est celui de la face. + Int32 front_cell_level = front_cell.level(); + Int32 back_cell_level = back_cell.level(); + if (front_cell_level != back_cell_level) { + Int32 face_level = numbering->faceLevel(face.uniqueId()); + if (front_cell_level != face_level) { + front_cell = Cell(); + } + else { + back_cell = Cell(); + } + } + + if (back_cell.uniqueId() > front_cell.uniqueId()) { + is_inverse = true; + } + } + // L'ordre de la numérotation est décrit dans le fichier + // CartesianMeshAMRPatchMng.cc (tag #priority_owner_2d). + if (back_cell.null()) { + Int64 uids[6]; + ArrayView av_uids(numbering->nbFaceByCell(), uids); + numbering->cellFaceUniqueIds(av_uids, front_cell); + if (m_p->m_cartesian_mesh->mesh()->dimension() == 2) { + if (dir == MD_DirX) { + if (face.uniqueId() == av_uids[1]) + is_inverse = true; + else if (face.uniqueId() != av_uids[3]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[3], face.uniqueId()); + } + else if (dir == MD_DirY) { + if (face.uniqueId() == av_uids[2]) + is_inverse = true; + else if (face.uniqueId() != av_uids[0]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[0], face.uniqueId()); + } + } + else if (m_p->m_cartesian_mesh->mesh()->dimension() == 3) { + if (dir == MD_DirX) { + if (face.uniqueId() == av_uids[4]) + is_inverse = true; + else if (face.uniqueId() != av_uids[1]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[1], face.uniqueId()); + } + else if (dir == MD_DirY) { + if (face.uniqueId() == av_uids[5]) + is_inverse = true; + else if (face.uniqueId() != av_uids[2]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[2], face.uniqueId()); + } + else if (dir == MD_DirZ) { + if (face.uniqueId() == av_uids[3]) + is_inverse = true; + else if (face.uniqueId() != av_uids[0]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[0], face.uniqueId()); + } + } + } + else if (front_cell.null()) { + Int64 uids[6]; + ArrayView av_uids(numbering->nbFaceByCell(), uids); + numbering->cellFaceUniqueIds(av_uids, back_cell); + if (m_p->m_cartesian_mesh->mesh()->dimension() == 2) { + if (dir == MD_DirX) { + if (face.uniqueId() == av_uids[3]) + is_inverse = true; + else if (face.uniqueId() != av_uids[1]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[1], face.uniqueId()); + } + else if (dir == MD_DirY) { + if (face.uniqueId() == av_uids[0]) + is_inverse = true; + else if (face.uniqueId() != av_uids[2]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[2], face.uniqueId()); + } + } + else if (m_p->m_cartesian_mesh->mesh()->dimension() == 3) { + if (dir == MD_DirX) { + if (face.uniqueId() == av_uids[1]) + is_inverse = true; + else if (face.uniqueId() != av_uids[4]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[4], face.uniqueId()); + } + else if (dir == MD_DirY) { + if (face.uniqueId() == av_uids[2]) + is_inverse = true; + else if (face.uniqueId() != av_uids[5]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[5], face.uniqueId()); + } + else if (dir == MD_DirZ) { + if (face.uniqueId() == av_uids[0]) + is_inverse = true; + else if (face.uniqueId() != av_uids[3]) + ARCANE_FATAL("Bad connectivity -- Expected : {0} -- Found : {1}", av_uids[3], face.uniqueId()); + } + } + } + // tm->info() << "FaceUID : " << face.uniqueId() + // << " -- backCellUID : " << back_cell.uniqueId() + // << " -- frontCellUID : " << front_cell.uniqueId() + // << " -- is_inverse : " << is_inverse + // << " -- dir : " << dir; + + if (is_inverse) + m_infos_view[iface.itemLocalId()] = ItemDirectionInfo(back_cell, front_cell); + else + m_infos_view[iface.itemLocalId()] = ItemDirectionInfo(front_cell, back_cell); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + FaceGroup FaceDirectionMng:: allFaces() const { @@ -289,6 +524,24 @@ allFaces() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +FaceGroup FaceDirectionMng:: +overallFaces() const +{ + return m_p->m_overall_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +FaceGroup FaceDirectionMng:: +inPatchFaces() const +{ + return m_p->m_inpatch_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + FaceGroup FaceDirectionMng:: innerFaces() const { diff --git a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h index 221eebb02a..fe805b9297 100644 --- a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h @@ -147,20 +147,60 @@ class ARCANE_CARTESIANMESH_EXPORT FaceDirectionMng //! Groupe de toutes les faces dans la direction. FaceGroup allFaces() const; + /*! + * \brief Groupe de toutes les faces de recouvrement dans la direction. + * + * Ce sont toutes les faces qui ont deux mailles de recouvrement autour. + * + * 0 1 2 3 4 + * ┌───┬──┬──┬──┬──┐ + * │ │ │ │ │ │ + * │ ├──┼──┼──┼──┤ + * │ │ │ │ │ │ + * └───┴──┴──┴──┴──┘ + * + * 0 : level -1 + * 1 et 2 : Mailles de recouvrements (overallCells) + * 3 : Mailles externes (outerCells) + * 4 : Mailles internes (innerCells) + * + * La couche de mailles de recouvrements désigne la couche de mailles de même + * niveau autour du patch. Ces mailles peuvent appartenir à un ou plusieurs + * patchs. + */ + FaceGroup overallFaces() const; + + /*! + * \brief Groupe de toutes les faces du patch dans la direction. + * + * Ce sont toutes les faces qui n'ont pas deux mailles de recouvrement. + * (`innerFaces() + outerFaces()` ou simplement `!overallFaces()`) + * + * \warning Les faces au bord du domaine (ayant donc une seule + * maille "outer") sont incluses dans ce groupe. Il ne faut donc pas supposer + * qu'il y a deux mailles autour de chaque face de ce groupe (pour ça, il + * faut rester avec le groupe innerFaces()). + */ + FaceGroup inPatchFaces() const; + /*! * \brief Groupe de toutes les faces internes dans la direction. * * Une face est considérée comme interne si sa maille - * devant et derrière n'est pas nulle. + * devant et derrière n'est pas nulle et n'est pas une maille de + * recouvrement. */ - FaceGroup innerFaces() const; /*! * \brief Groupe de toutes les faces externes dans la direction. * * Une face est considérée comme externe si sa maille - * devant ou derrière est nulle. + * devant ou derrière est de recouvrement ou est nulle (si l'on est au bord + * du domaine ou s'il n'y a pas de couches de mailles de recouvrements). + * + * \note Les faces entre patchs ne sont pas dupliquées. Donc certaines faces + * de ce groupe peuvent être aussi dans un outerFaces() d'un autre patch. */ FaceGroup outerFaces() const; @@ -216,6 +256,8 @@ class ARCANE_CARTESIANMESH_EXPORT FaceDirectionMng const VariableCellReal3& cells_center, const VariableFaceReal3& faces_center); + void _internalComputeInfos(const CellDirectionMng& cell_dm); + /*! * \internal * Initialise l'instance. @@ -235,17 +277,18 @@ class ARCANE_CARTESIANMESH_EXPORT FaceDirectionMng */ void _internalResizeInfos(Int32 new_size); + void _computeCellInfos(const CellDirectionMng& cell_dm, + const VariableCellReal3& cells_center, + const VariableFaceReal3& faces_center); + void _computeCellInfos() const; + bool _hasFace(Cell cell, Int32 face_local_id) const; + private: SmallSpan m_infos_view; CellInfoListView m_cells; eMeshDirection m_direction; Impl* m_p; - - void _computeCellInfos(const CellDirectionMng& cell_dm, - const VariableCellReal3& cells_center, - const VariableFaceReal3& faces_center); - bool _hasFace(Cell cell, Int32 face_local_id) const; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h index 5f6871856e..9092ca7295 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h @@ -89,6 +89,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * - les informations de direction sont invalidées si le maillage évolue. */ virtual void computeDirections() = 0; + virtual void computeDirectionsV2() = 0; /*! * \brief Recalcule les informations de cartésiennes après une reprise. @@ -105,6 +106,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * \brief Nombre de patchs du maillage. * * Il y a toujours au moins un patch qui représente la maillage cartésien + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual Int32 nbPatch() const = 0; @@ -123,11 +126,15 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * Si le maillage est cartésien, il n'y a qu'un seul patch. * * L'instance retournée reste valide tant que cette instance n'est pas détruite. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual CartesianPatch amrPatch(Int32 index) const = 0; /*! * \brief Vue sur la liste des patchs. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual CartesianMeshPatchListView patches() const = 0; @@ -142,6 +149,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * de connectivité correspondantes sont mises à jour. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void refinePatch2D(Real2 position, Real2 length) = 0; @@ -156,6 +165,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * de connectivité correspondantes sont mises à jour. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void refinePatch3D(Real3 position, Real3 length) = 0; @@ -170,6 +181,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * de connectivité correspondantes sont mises à jour. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void refinePatch(const AMRZonePosition& position) = 0; @@ -190,6 +203,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * seront supprimés. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void coarseZone2D(Real2 position, Real2 length) = 0; @@ -210,6 +225,8 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * seront supprimés. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void coarseZone3D(Real3 position, Real3 length) = 0; @@ -230,9 +247,12 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * seront supprimés. * * Cette opération est collective. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual void coarseZone(const AMRZonePosition& position) = 0; + // TODO A suppr virtual void refine() = 0; /*! @@ -250,9 +270,12 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * appel à cette méthode. ATTENTION : Il peut être ajusté par la méthode. * * \return Le nombre de couches de mailles fantômes final. + * + * \deprecated Utiliser CartesianMeshAMRMng à la place. */ virtual Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) = 0; + // TODO A suppr virtual void mergePatches() = 0; /*! diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h index 1a4f9c50ed..e06aa6e807 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMeshPatch.h @@ -44,7 +44,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshPatch //! Groupe de mailles du patch virtual CellGroup cells() =0; - virtual CellGroup ownCells() = 0; + virtual CellGroup inPatchCells() = 0; //! TODO virtual Integer index() = 0; diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc index 809a221aca..687d189f27 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc @@ -19,14 +19,15 @@ #include "arcane/utils/Real3.h" #include "arcane/utils/PlatformUtils.h" -#include "arcane/IItemFamily.h" -#include "arcane/ItemGroup.h" -#include "arcane/IMesh.h" -#include "arcane/VariableTypes.h" -#include "arcane/UnstructuredMeshConnectivity.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/ItemGroup.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/VariableTypes.h" +#include "arcane/core/UnstructuredMeshConnectivity.h" #include "arcane/cartesianmesh/ICartesianMesh.h" #include "arcane/cartesianmesh/CellDirectionMng.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" #include @@ -49,6 +50,8 @@ class NodeDirectionMng::Impl NodeGroup m_inner_all_items; NodeGroup m_outer_all_items; + NodeGroup m_inpatch_all_items; + NodeGroup m_overall_all_items; NodeGroup m_all_items; ICartesianMesh* m_cartesian_mesh = nullptr; Integer m_patch_index = -1; @@ -197,6 +200,104 @@ _internalComputeInfos(const CellDirectionMng& cell_dm,const NodeGroup& all_nodes /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + +void NodeDirectionMng:: +_internalComputeInfos(const CellDirectionMng& cell_dm, const NodeGroup& all_nodes) +{ + m_infos_view.fill(ItemDirectionInfo()); + + Integer mesh_dim = m_p->m_cartesian_mesh->mesh()->dimension(); + //TODO: ne garder que les noeuds de notre patch + + // Calcul les infos de direction pour les noeuds + ENUMERATE_CELL (icell, cell_dm.allCells()) { + Cell cell = *icell; + DirCellNode cn(cell_dm.cellNode(cell)); + + NodeLocalId node_next_left = cn.nextLeftId(); + NodeLocalId node_next_right = cn.nextRightId(); + + NodeLocalId node_previous_left = cn.previousLeftId(); + NodeLocalId node_previous_right = cn.previousRightId(); + + m_infos_view[node_previous_left].m_next_lid = node_next_left; + m_infos_view[node_next_left].m_previous_lid = node_previous_left; + + m_infos_view[node_previous_right].m_next_lid = node_next_right; + m_infos_view[node_next_right].m_previous_lid = node_previous_right; + + if (mesh_dim == 3) { + NodeLocalId top_node_next_left = cn.topNextLeftId(); + NodeLocalId top_node_next_right = cn.topNextRightId(); + + NodeLocalId top_node_previous_left = cn.topPreviousLeftId(); + NodeLocalId top_node_previous_right = cn.topPreviousRightId(); + + m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left; + m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left; + + m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right; + m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right; + } + } + + UniqueArray inner_cells_lid; + UniqueArray outer_cells_lid; + cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); + cell_dm.outerCells().view().fillLocalIds(outer_cells_lid); + + UniqueArray inner_lids; + UniqueArray outer_lids; + UniqueArray inpatch_lids; + UniqueArray overall_lids; + IItemFamily* family = all_nodes.itemFamily(); + ENUMERATE_ (Node, inode, all_nodes) { + Int32 lid = inode.itemLocalId(); + Integer nb_inner_cells = 0; + Integer nb_outer_cells = 0; + for (Cell cell : inode->cells()) { + if (inner_cells_lid.contains(cell.localId())) { + nb_inner_cells++; + } + else if (outer_cells_lid.contains(cell.localId())) { + nb_outer_cells++; + } + } + if (nb_inner_cells + nb_outer_cells == inode->nbCell()) { + inner_lids.add(lid); + inpatch_lids.add(lid); + } + else if (nb_outer_cells != 0) { + outer_lids.add(lid); + inpatch_lids.add(lid); + } + else { + overall_lids.add(lid); + } + } + int dir = (int)m_direction; + String base_group_name = String("Direction") + dir; + if (m_p->m_patch_index >= 0) + base_group_name = base_group_name + String("AMRPatch") + m_p->m_patch_index; + m_p->m_inner_all_items = family->createGroup(String("AllInner") + base_group_name, inner_lids, true); + m_p->m_outer_all_items = family->createGroup(String("AllOuter") + base_group_name, outer_lids, true); + m_p->m_inpatch_all_items = family->createGroup(String("AllInPatch") + base_group_name, inpatch_lids, true); + m_p->m_overall_all_items = family->createGroup(String("AllOverall") + base_group_name, overall_lids, true); + m_p->m_all_items = all_nodes; + + _filterNodes(); + _computeNodeCellInfos(); + + { + UnstructuredMeshConnectivityView mesh_connectivity; + mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh()); + m_node_cell_view = mesh_connectivity.nodeCell(); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + /*! * \brief Filtre les noeuds devant/derrière pour ne garder que les * noeuds de notre patch. @@ -312,6 +413,137 @@ _computeNodeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& c m_infos_view[node.localId()].setCellIndexes(indexes_ptr); } } +void NodeDirectionMng:: +_computeNodeCellInfos() const +{ + Ref numbering = m_p->m_cartesian_mesh->_internalApi()->cartesianMeshNumberingMngInternal(); + + IndexType indexes_ptr[8]; + ArrayView indexes(8, indexes_ptr); + + NodeGroup dm_all_nodes = this->allNodes(); + eMeshDirection dir = m_direction; + IMesh* mesh = m_p->m_cartesian_mesh->mesh(); + Integer mesh_dim = mesh->dimension(); + + if (mesh_dim == 2) { + constexpr Integer nb_cells_max = 4; + + Int64 uids[nb_cells_max]; + ArrayView av_uids(nb_cells_max, uids); + + // DirX (Previous->X=0 / Next->X=1 / Right->Y=0 / Left->Y=1) + // DirY (Previous->Y=0 / Next->Y=1 / Right->X=1 / Left->X=0) + + // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre : + // + // |2|3| + // . + // |0|1| + // + // y + // ^ + // |->x + // + // Lire : le UID de la maille dans le tableau av_uids à la position 0 rempli par + // "numbering->cellUniqueIdsAroundNode(av_uids, node)" correspond, dans la direction X, + // à la position CNP_PreviousRight. + constexpr Int32 dir_x_pos_2d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft }; + constexpr Int32 dir_y_pos_2d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight }; + + ENUMERATE_ (Node, inode, dm_all_nodes) { + Node node = *inode; + numbering->cellUniqueIdsAroundNode(av_uids, node); + Integer nb_cell = node.nbCell(); + + indexes.fill(DirNode::NULL_CELL); + + for (Integer i = 0; i < nb_cell; ++i) { + Cell cell = node.cell(i); + Integer pos = 0; + for (; pos < nb_cells_max; ++pos) { + if (cell.uniqueId() == av_uids[pos]) + break; + } + if (pos == nb_cells_max) + continue; + + const IndexType bi = (IndexType)i; + if (dir == MD_DirX) { + indexes[dir_x_pos_2d[pos]] = bi; + } + else if (dir == MD_DirY) { + indexes[dir_y_pos_2d[pos]] = bi; + } + } + m_infos_view[node.localId()].setCellIndexes(indexes_ptr); + } + } + else if (mesh_dim == 3) { + constexpr Integer nb_cells_max = 8; + + Int64 uids[nb_cells_max]; + ArrayView av_uids(nb_cells_max, uids); + + // DirX (Top->Z=1 / Previous->X=0 / Next->X=1 / Right->Y=0 / Left->Y=1) + // DirY (Top->Z=1 / Previous->Y=0 / Next->Y=1 / Right->X=1 / Left->X=0) + // DirZ (Top->Y=1 / Previous->Z=0 / Next->Z=1 / Right->X=1 / Left->X=0) + + // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre : + // + // z = 0 | z = 1 + // |2|3| | |6|7| + // . | . + // |0|1| | |4|5| + // + // y + // ^ + // |->x + // + // Lire : le UID de la maille dans le tableau av_uids à la position 2 rempli par + // "numbering->cellUniqueIdsAroundNode(av_uids, node)" correspond, dans la direction Z, + // à la position CNP_TopPreviousLeft. + constexpr Int32 dir_x_pos_3d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft, CNP_TopPreviousRight, CNP_TopNextRight, CNP_TopPreviousLeft, CNP_TopNextLeft }; + constexpr Int32 dir_y_pos_3d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight, CNP_TopPreviousLeft, CNP_TopPreviousRight, CNP_TopNextLeft, CNP_TopNextRight }; + constexpr Int32 dir_z_pos_3d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_TopPreviousLeft, CNP_TopPreviousRight, CNP_NextLeft, CNP_NextRight, CNP_TopNextLeft, CNP_TopNextRight }; + + ENUMERATE_ (Node, inode, dm_all_nodes) { + Node node = *inode; + numbering->cellUniqueIdsAroundNode(av_uids, node); + Integer nb_cell = node.nbCell(); + + indexes.fill(DirNode::NULL_CELL); + + for (Integer i = 0; i < nb_cell; ++i) { + Cell cell = node.cell(i); + Integer pos = 0; + for (; pos < nb_cells_max; ++pos) { + if (cell.uniqueId() == av_uids[pos]) + break; + } + if (pos == nb_cells_max) + continue; + + const IndexType bi = (IndexType)i; + + if (dir == MD_DirX) { + indexes[dir_x_pos_3d[pos]] = bi; + } + else if (dir == MD_DirY) { + indexes[dir_y_pos_3d[pos]] = bi; + } + else if (dir == MD_DirZ) { + indexes[dir_z_pos_3d[pos]] = bi; + } + + m_infos_view[node.localId()].setCellIndexes(indexes_ptr); + } + } + } + else { + ARCANE_FATAL("Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim); + } +} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -325,6 +557,24 @@ allNodes() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +NodeGroup NodeDirectionMng:: +overallNodes() const +{ + return m_p->m_overall_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +NodeGroup NodeDirectionMng:: +inPatchNodes() const +{ + return m_p->m_inpatch_all_items; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + NodeGroup NodeDirectionMng:: innerNodes() const { diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h index 3cfd12c8f4..3192a2169d 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h @@ -332,6 +332,42 @@ class ARCANE_CARTESIANMESH_EXPORT NodeDirectionMng //! Groupe de tous les noeuds dans la direction. NodeGroup allNodes() const; + /*! + * \brief Groupe de tous les noeuds de recouvrement dans la direction. + * + * Un noeud de recouvrement est un noeud qui possède uniquement des mailles + * de recouvrement autour de lui. + * + * 0 1 2 3 4 + * ┌───┬──┬──┬──┬──┐ + * │ │ │ │ │ │ + * │ ├──┼──┼──┼──┤ + * │ │ │ │ │ │ + * └───┴──┴──┴──┴──┘ + * + * 0 : level -1 + * 1 et 2 : Mailles de recouvrements (overallCells) + * 3 : Mailles externes (outerCells) + * 4 : Mailles internes (innerCells) + * + * La couche de mailles de recouvrements désigne la couche de mailles de même + * niveau autour du patch. Ces mailles peuvent appartenir à un ou plusieurs + * patchs. + */ + NodeGroup overallNodes() const; + + /*! + * \brief Groupe de tous les noeuds du patch dans la direction. + * + * Les noeuds du patch sont les noeuds n'ayant pas toutes ces mailles qui + * soient de recouvrement. TODO reformuler + * (`innerNodes() + outerNodes()` ou simplement `!overallNodes()`) + * + * \warning Les noeuds au bord du domaine (donc ayant que des mailles + * "outer") sont inclus dans ce groupe. + */ + NodeGroup inPatchNodes() const; + /*! * \brief Groupe de tous les noeuds internes dans la direction. * @@ -344,7 +380,11 @@ class ARCANE_CARTESIANMESH_EXPORT NodeDirectionMng * \brief Groupe de tous les noeuds externes dans la direction. * * Un noeud est considéré comme externe si son noeud - * avant ou après est nul. + * avant ou après est de recouvrement ou est nul (si l'on est au bord du + * domaine ou s'il n'y a pas de couches de mailles de recouvrements). + * + * \note Les noeuds entre patchs ne sont pas dupliquées. Donc certains noeuds + * de ce groupe peuvent être aussi dans un outerNodes() d'un autre patch. */ NodeGroup outerNodes() const; @@ -384,6 +424,8 @@ class ARCANE_CARTESIANMESH_EXPORT NodeDirectionMng void _internalComputeInfos(const CellDirectionMng& cell_dm, const NodeGroup& all_nodes, const VariableCellReal3& cells_center); + void _internalComputeInfos(const CellDirectionMng& cell_dm, const NodeGroup& all_nodes); + /*! * \internal * Initialise l'instance. @@ -429,6 +471,7 @@ class ARCANE_CARTESIANMESH_EXPORT NodeDirectionMng void _computeNodeCellInfos(const CellDirectionMng& cell_dm, const VariableCellReal3& cells_center); + void _computeNodeCellInfos() const; void _filterNodes(); }; diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc index 8e827a4fc0..68b1bb7da2 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc @@ -12,6 +12,7 @@ /*---------------------------------------------------------------------------*/ #include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" +#include /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -26,9 +27,7 @@ AMRPatchPositionLevelGroup:: AMRPatchPositionLevelGroup(Integer max_level) : m_max_level(max_level) , m_patches(max_level+1) -{ - -} +{} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc index a5468c6e22..adc0d34bc7 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc @@ -317,16 +317,16 @@ refine() // #arcane_order_to_around_2d // Note pour les maillages cartésiens 2D : // Les itérateurs sur les faces itèrent dans l'ordre (pour la maille 4 ici) : - // 1. Face entre [4, 1], - // 2. Face entre [4, 5], - // 3. Face entre [4, 7], - // 4. Face entre [4, 3], + // 0. Face entre [4, 1], + // 1. Face entre [4, 5], + // 2. Face entre [4, 7], + // 3. Face entre [4, 3], // // Les itérateurs sur les noeuds itèrent dans l'ordre (pour la maille 4 ici) : - // 1. Noeud entre [4, 0] - // 2. Noeud entre [4, 2] - // 3. Noeud entre [4, 8] - // 4. Noeud entre [4, 6] + // 0. Noeud entre [4, 0] + // 1. Noeud entre [4, 2] + // 2. Noeud entre [4, 8] + // 3. Noeud entre [4, 6] // Chaque chiffre désigne une maille parente et une priorité (0 étant la priorité la plus forte). // 4 = parent_cell ("nous") @@ -845,22 +845,22 @@ refine() // #arcane_order_to_around_3d // Note pour les maillages cartésiens 3D : // Les itérateurs sur les faces itèrent dans l'ordre (pour la maille 13 ici) : - // 1. Face entre [13, 4], - // 2. Face entre [13, 12], - // 3. Face entre [13, 10], - // 4. Face entre [13, 22], - // 5. Face entre [13, 14], - // 6. Face entre [13, 16], + // 0. Face entre [13, 4], + // 1. Face entre [13, 12], + // 2. Face entre [13, 10], + // 3. Face entre [13, 22], + // 4. Face entre [13, 14], + // 5. Face entre [13, 16], // // Les itérateurs sur les noeuds itèrent dans l'ordre (pour la maille 13 ici) : - // 1. Noeud entre [13, 0] - // 2. Noeud entre [13, 2] - // 3. Noeud entre [13, 8] - // 4. Noeud entre [13, 6] - // 5. Noeud entre [13, 18] - // 6. Noeud entre [13, 20] - // 7. Noeud entre [13, 26] - // 8. Noeud entre [13, 24] + // 0. Noeud entre [13, 0] + // 1. Noeud entre [13, 2] + // 2. Noeud entre [13, 8] + // 3. Noeud entre [13, 6] + // 4. Noeud entre [13, 18] + // 5. Noeud entre [13, 20] + // 6. Noeud entre [13, 26] + // 7. Noeud entre [13, 24] // Chaque chiffre désigne une maille parente et une priorité (0 étant la priorité la plus forte). // 13 = parent_cell ("nous") diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc index 3760d271a4..db04c7e96d 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc @@ -503,7 +503,7 @@ Int32 CartesianMeshNumberingMngInternal:: cellLevel(Int64 uid) const { Integer pos = -1; - Int64 max = 0; + Int64 max = -1; for (Integer i = m_min_level; i <= m_max_level; ++i) { const Int64 first_uid = firstCellUniqueId(i); @@ -512,6 +512,14 @@ cellLevel(Int64 uid) const max = first_uid; } } +#ifdef ARCANE_CHECK + if (max == -1) { + ARCANE_FATAL("CellUID is not in any patch (UID too low)"); + } + if (uid >= firstCellUniqueId(pos) + nbCellInLevel(pos)) { + ARCANE_FATAL("CellUID is not in any patch (UID too high)"); + } +#endif return pos; } @@ -522,7 +530,7 @@ Int32 CartesianMeshNumberingMngInternal:: nodeLevel(Int64 uid) const { Integer pos = -1; - Int64 max = 0; + Int64 max = -1; for (Integer i = m_min_level; i <= m_max_level; ++i) { const Int64 first_uid = firstNodeUniqueId(i); @@ -531,6 +539,14 @@ nodeLevel(Int64 uid) const max = first_uid; } } +#ifdef ARCANE_CHECK + if (max == -1) { + ARCANE_FATAL("NodeUID is not in any patch (UID too low)"); + } + if (uid >= firstNodeUniqueId(pos) + nbNodeInLevel(pos)) { + ARCANE_FATAL("NodeUID is not in any patch (UID too high)"); + } +#endif return pos; } @@ -541,7 +557,7 @@ Int32 CartesianMeshNumberingMngInternal:: faceLevel(Int64 uid) const { Integer pos = -1; - Int64 max = 0; + Int64 max = -1; for (Integer i = m_min_level; i <= m_max_level; ++i) { const Int64 first_uid = firstFaceUniqueId(i); @@ -550,6 +566,14 @@ faceLevel(Int64 uid) const max = first_uid; } } +#ifdef ARCANE_CHECK + if (max == -1) { + ARCANE_FATAL("FaceUID is not in any patch (UID too low)"); + } + if (uid >= firstFaceUniqueId(pos) + nbFaceInLevel(pos)) { + ARCANE_FATAL("FaceUID is not in any patch (UID too high)"); + } +#endif return pos; } @@ -563,12 +587,10 @@ offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const if (level_from == level_to) { return coord; } - else if (level_from < level_to) { + if (level_from < level_to) { return coord * m_pattern * (level_to - level_from); } - else { - return coord / (m_pattern * (level_from - level_to)); - } + return coord / (m_pattern * (level_from - level_to)); } /*---------------------------------------------------------------------------*/ @@ -1395,6 +1417,15 @@ cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshNumberingMngInternal:: +cellNodeUniqueIds(ArrayView uid, Cell cell) +{ + cellNodeUniqueIds(uid, cell.level(), cell.uniqueId().asInt64()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Integer CartesianMeshNumberingMngInternal:: nbFaceByCell() { @@ -1550,61 +1581,123 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMngInternal:: -cellUniqueIdsAroundCell(ArrayView uid, Cell cell) +cellFaceUniqueIds(ArrayView uid, Cell cell) { - cellUniqueIdsAroundCell(uid, cell.uniqueId(), cell.level()); + cellFaceUniqueIds(uid, cell.level(), cell.uniqueId().asInt64()); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMngInternal:: -cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) +cellUniqueIdsAroundCell(ArrayView uid, Int64x3 cell_coord, Int32 level) { - uid.fill(-1); + ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27")); - const Int64 coord_cell_x = cellUniqueIdToCoordX(cell_uid, level); - const Int64 coord_cell_y = cellUniqueIdToCoordY(cell_uid, level); + uid.fill(-1); const Int64 nb_cells_x = globalNbCellsX(level); const Int64 nb_cells_y = globalNbCellsY(level); + const Int64 nb_cells_z = globalNbCellsZ(level); - if (m_dimension == 2) { - ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9")); + for (Integer k = -1; k < 2; ++k) { + const Int64 coord_around_cell_z = cell_coord.z + k; + if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) { - for (Integer j = -1; j < 2; ++j) { - const Int64 coord_around_cell_y = coord_cell_y + j; - if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { + for (Integer j = -1; j < 2; ++j) { + const Int64 coord_around_cell_y = cell_coord.y + j; + if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { - for (Integer i = -1; i < 2; ++i) { - const Int64 coord_around_cell_x = coord_cell_x + i; - if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { - uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(level, Int64x2(coord_around_cell_x, coord_around_cell_y)); + for (Integer i = -1; i < 2; ++i) { + const Int64 coord_around_cell_x = cell_coord.x + i; + if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(level, Int64x3{ coord_around_cell_x, coord_around_cell_y, coord_around_cell_z }); + } } } } } } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundCell(ArrayView uid, Int64x2 cell_coord, Int32 level) +{ + ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9")); + + uid.fill(-1); + + const Int64 nb_cells_x = globalNbCellsX(level); + const Int64 nb_cells_y = globalNbCellsY(level); + + for (Integer j = -1; j < 2; ++j) { + const Int64 coord_around_cell_y = cell_coord.y + j; + if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { + + for (Integer i = -1; i < 2; ++i) { + const Int64 coord_around_cell_x = cell_coord.x + i; + if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(level, Int64x2{ coord_around_cell_x, coord_around_cell_y }); + } + } + } + } +} +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) +{ + if (m_dimension == 2) { + const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level)); + cellUniqueIdsAroundCell(uid, cell_coord, level); + } else { - ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27")); + const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level)); + cellUniqueIdsAroundCell(uid, cell_coord, level); + } +} - const Int64 coord_cell_z = cellUniqueIdToCoordZ(cell_uid, level); - const Int64 nb_cells_z = globalNbCellsZ(level); +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundCell(ArrayView uid, Cell cell) +{ + cellUniqueIdsAroundCell(uid, cell.uniqueId().asInt64(), cell.level()); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ - for (Integer k = -1; k < 2; ++k) { - const Int64 coord_around_cell_z = coord_cell_z + k; - if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) { +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundNode(ArrayView uid, Int64x3 node_coord, Int32 level) +{ + ARCANE_ASSERT((uid.size() == 8), ("Size of uid array != 8")); - for (Integer j = -1; j < 2; ++j) { - const Int64 coord_around_cell_y = coord_cell_y + j; - if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) { + uid.fill(-1); - for (Integer i = -1; i < 2; ++i) { - const Int64 coord_around_cell_x = coord_cell_x + i; - if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) { - uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(level, Int64x3(coord_around_cell_x, coord_around_cell_y, coord_around_cell_z)); - } + const Int64 nb_cells_x = globalNbCellsX(level); + const Int64 nb_cells_y = globalNbCellsY(level); + const Int64 nb_cells_z = globalNbCellsZ(level); + + for (Integer k = -1; k < 1; ++k) { + const Int64 coord_cell_z = node_coord.z + k; + if (coord_cell_z >= 0 && coord_cell_z < nb_cells_z) { + + for (Integer j = -1; j < 1; ++j) { + const Int64 coord_cell_y = node_coord.y + j; + if (coord_cell_y >= 0 && coord_cell_y < nb_cells_y) { + + for (Integer i = -1; i < 1; ++i) { + const Int64 coord_cell_x = node_coord.x + i; + if (coord_cell_x >= 0 && coord_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 2) + ((k + 1) * 4)] = cellUniqueId(level, Int64x3{ coord_cell_x, coord_cell_y, coord_cell_z }); } } } @@ -1616,6 +1709,58 @@ cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundNode(ArrayView uid, Int64x2 node_coord, Int32 level) +{ + ARCANE_ASSERT((uid.size() == 4), ("Size of uid array != 4")); + + uid.fill(-1); + + const Int64 nb_cells_x = globalNbCellsX(level); + const Int64 nb_cells_y = globalNbCellsY(level); + + for (Integer j = -1; j < 1; ++j) { + const Int64 coord_cell_y = node_coord.y + j; + if (coord_cell_y >= 0 && coord_cell_y < nb_cells_y) { + + for (Integer i = -1; i < 1; ++i) { + const Int64 coord_cell_x = node_coord.x + i; + if (coord_cell_x >= 0 && coord_cell_x < nb_cells_x) { + uid[(i + 1) + ((j + 1) * 2)] = cellUniqueId(level, Int64x2{ coord_cell_x, coord_cell_y }); + } + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundNode(ArrayView uid, Int64 node_uid, Int32 level) +{ + if (m_dimension == 2) { + const Int64x2 node_coord{ nodeUniqueIdToCoordX(node_uid, level), nodeUniqueIdToCoordY(node_uid, level) }; + cellUniqueIdsAroundNode(uid, node_coord, level); + } + else { + const Int64x3 node_coord{ nodeUniqueIdToCoordX(node_uid, level), nodeUniqueIdToCoordY(node_uid, level), nodeUniqueIdToCoordZ(node_uid, level) }; + cellUniqueIdsAroundNode(uid, node_coord, level); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMngInternal:: +cellUniqueIdsAroundNode(ArrayView uid, Node node) +{ + cellUniqueIdsAroundNode(uid, node.uniqueId().asInt64(), nodeLevel(node.uniqueId().asInt64())); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshNumberingMngInternal:: setChildNodeCoordinates(Cell parent_cell) { diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h index 9c070f24a0..5a9102c1c5 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h @@ -130,15 +130,24 @@ class CartesianMeshNumberingMngInternal void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + void cellNodeUniqueIds(ArrayView uid, Cell cell) override; Integer nbFaceByCell() override; void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) override; void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) override; void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) override; + void cellFaceUniqueIds(ArrayView uid, Cell cell) override; + void cellUniqueIdsAroundCell(ArrayView uid, Int64x3 cell_coord, Int32 level) override; + void cellUniqueIdsAroundCell(ArrayView uid, Int64x2 cell_coord, Int32 level) override; void cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) override; void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) override; + void cellUniqueIdsAroundNode(ArrayView uid, Int64x3 node_coord, Int32 level) override; + void cellUniqueIdsAroundNode(ArrayView uid, Int64x2 node_coord, Int32 level) override; + void cellUniqueIdsAroundNode(ArrayView uid, Int64 node_uid, Int32 level) override; + void cellUniqueIdsAroundNode(ArrayView uid, Node node) override; + void setChildNodeCoordinates(Cell parent_cell) override; void setParentNodeCoordinates(Cell parent_cell) override; diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h index 71aba2b7df..3572b4dc33 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshPatch.h @@ -75,7 +75,7 @@ class CartesianMeshPatch ~CartesianMeshPatch() override; public: CellGroup cells() override; - CellGroup ownCells() override; + CellGroup inPatchCells() override; Integer index() override { return m_amr_patch_index; @@ -124,6 +124,7 @@ class CartesianMeshPatch private: void _internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); + void _internalComputeNodeCellInformations(); void _computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); void _computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord); diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc index 401a9f544e..54bdf1d53a 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc @@ -202,11 +202,11 @@ addPatch(CellGroup cell_group, Integer group_index) _addCellGroup(cell_group, cdi); m_cmesh->traceMng()->info() << "addPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() << " -- m_amr_patches : " << m_amr_patches.size() << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); + << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); m_cmesh->traceMng()->info() << "Min Point : " << cdi->position().minPoint(); m_cmesh->traceMng()->info() << "Max Point : " << cdi->position().maxPoint(); @@ -245,24 +245,36 @@ patchListView() const /*---------------------------------------------------------------------------*/ CellGroup CartesianPatchGroup:: -cells(const Integer index) +allCells(const Integer index) { if (index == 0) { ARCANE_FATAL("You cannot get cells of ground patch with this method"); } - return m_amr_patch_cell_groups[index - 1]; + return m_amr_patch_cell_groups_all[index - 1]; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ CellGroup CartesianPatchGroup:: -ownCells(Integer index) +inPatchCells(Integer index) { if (index == 0) { ARCANE_FATAL("You cannot get cells of ground patch with this method"); } - return m_amr_patch_cell_groups_own[index - 1]; + return m_amr_patch_cell_groups_inpatch[index - 1]; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +CellGroup CartesianPatchGroup:: +overallCells(Integer index) +{ + if (index == 0) { + ARCANE_FATAL("You cannot get cells of ground patch with this method"); + } + return m_amr_patch_cell_groups_overall[index - 1]; } /*---------------------------------------------------------------------------*/ @@ -301,10 +313,13 @@ removePatch(const Integer index) void CartesianPatchGroup:: removeCellsInAllPatches(ConstArrayView cells_local_id) { - for (CellGroup cells : m_amr_patch_cell_groups) { + for (CellGroup cells : m_amr_patch_cell_groups_all) { cells.removeItems(cells_local_id); } - for (CellGroup cells : m_amr_patch_cell_groups_own) { + for (CellGroup cells : m_amr_patch_cell_groups_inpatch) { + cells.removeItems(cells_local_id); + } + for (CellGroup cells : m_amr_patch_cell_groups_overall) { cells.removeItems(cells_local_id); } } @@ -352,9 +367,9 @@ applyPatchEdit(bool remove_empty_patches) if (remove_empty_patches) { // TODO : Pas vraiment compatible avec les mailles overlap. - UniqueArray size_of_patches(m_amr_patch_cell_groups.size()); - for (Integer i = 0; i < m_amr_patch_cell_groups.size(); ++i) { - size_of_patches[i] = m_amr_patch_cell_groups[i].size(); + UniqueArray size_of_patches(m_amr_patch_cell_groups_all.size()); + for (Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) { + size_of_patches[i] = m_amr_patch_cell_groups_all[i].size(); } m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches); for (Integer i = 0; i < size_of_patches.size(); ++i) { @@ -486,8 +501,8 @@ mergePatches() index_n_nb_cells[p0].second = patch_fusion_0.nbCells(); UniqueArray local_ids; - cells(index_p1).view().fillLocalIds(local_ids); - cells(index_p0).addItems(local_ids, false); + allCells(index_p1).view().fillLocalIds(local_ids); + allCells(index_p0).addItems(local_ids, false); m_cmesh->traceMng()->info() << "Remove patch : " << index_p1; removePatch(index_p1); @@ -847,10 +862,12 @@ _removeOnePatch(Integer index) m_available_group_index.add(m_amr_patches[index]->index()); m_cmesh->traceMng()->info() << "_removeOnePatch() -- Save group_index : " << m_available_group_index.back(); - m_amr_patch_cell_groups[index - 1].clear(); - m_amr_patch_cell_groups.remove(index - 1); - m_amr_patch_cell_groups_own[index - 1].clear(); - m_amr_patch_cell_groups_own.remove(index - 1); + m_amr_patch_cell_groups_all[index - 1].clear(); + m_amr_patch_cell_groups_all.remove(index - 1); + m_amr_patch_cell_groups_inpatch[index - 1].clear(); + m_amr_patch_cell_groups_inpatch.remove(index - 1); + m_amr_patch_cell_groups_overall[index - 1].clear(); + m_amr_patch_cell_groups_overall.remove(index - 1); m_amr_patches_pointer.remove(index); m_amr_patches.remove(index); @@ -878,14 +895,18 @@ _removeAllPatches() { Ref ground_patch = m_amr_patches.front(); - for (CellGroup cell_group : m_amr_patch_cell_groups) { + for (CellGroup cell_group : m_amr_patch_cell_groups_all) { cell_group.clear(); } - for (CellGroup cell_group : m_amr_patch_cell_groups_own) { + for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) { cell_group.clear(); } - m_amr_patch_cell_groups.clear(); - m_amr_patch_cell_groups_own.clear(); + for (CellGroup cell_group : m_amr_patch_cell_groups_overall) { + cell_group.clear(); + } + m_amr_patch_cell_groups_all.clear(); + m_amr_patch_cell_groups_inpatch.clear(); + m_amr_patch_cell_groups_overall.clear(); m_amr_patches_pointer.clear(); m_amr_patches.clear(); m_available_group_index.clear(); @@ -921,36 +942,40 @@ _createGroundPatch() void CartesianPatchGroup:: _addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch) { - m_amr_patch_cell_groups.add(cell_group); + m_amr_patch_cell_groups_all.add(cell_group); if (patch->position().isNull()) { // Patch non-régulier. - m_amr_patch_cell_groups_own.add(cell_group); + m_amr_patch_cell_groups_inpatch.add(cell_group); + m_amr_patch_cell_groups_overall.add(CellGroup()); return; } AMRPatchPosition patch_position = patch->position(); Ref numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); - UniqueArray items_lid; + UniqueArray inpatch_items_lid; + UniqueArray overall_items_lid; ENUMERATE_ (Cell, icell, cell_group) { Cell cell = *icell; - if (!cell.isOwn()) { - continue; - } - Int64 pos_x = numbering->cellUniqueIdToCoordX(cell); Int64 pos_y = numbering->cellUniqueIdToCoordY(cell); Int64 pos_z = numbering->cellUniqueIdToCoordZ(cell); - if (patch_position.isIn(pos_x, pos_y, pos_z)) { - items_lid.add(cell.localId()); + if (cell.isOwn() && patch_position.isIn(pos_x, pos_y, pos_z)) { + inpatch_items_lid.add(cell.localId()); + } + else { + overall_items_lid.add(cell.localId()); } } - CellGroup own = m_cmesh->mesh()->cellFamily()->createGroup(cell_group.name().clone() + "_Own", items_lid, true); - m_amr_patch_cell_groups_own.add(own); + CellGroup own = m_cmesh->mesh()->cellFamily()->createGroup(cell_group.name().clone() + "_InPatch", inpatch_items_lid, true); + m_amr_patch_cell_groups_inpatch.add(own); + + CellGroup overall = m_cmesh->mesh()->cellFamily()->createGroup(cell_group.name().clone() + "_Overall", overall_items_lid, true); + m_amr_patch_cell_groups_overall.add(overall); } /*---------------------------------------------------------------------------*/ @@ -1188,7 +1213,7 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) // << " -- Min point : " << new_patch.minPoint() // << " -- Max point : " << new_patch.maxPoint() // << " -- Level : " << new_patch.level(); - _addCutPatch(new_patch, m_amr_patch_cell_groups[index_patch - 1]); + _addCutPatch(new_patch, m_amr_patch_cell_groups_all[index_patch - 1]); d_nb_patch_final++; } } @@ -1230,10 +1255,10 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ _addCellGroup(parent_cells, cdi); m_cmesh->traceMng()->info() << "_addCutPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() << " -- m_amr_patches : " << m_amr_patches.size() << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); + << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); } /*---------------------------------------------------------------------------*/ @@ -1265,10 +1290,10 @@ _addPatch(const AMRPatchPosition& new_patch_position) _addCellGroup(parent_cells, cdi); m_cmesh->traceMng()->info() << "_addPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups.size() + << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() << " -- m_amr_patches : " << m_amr_patches.size() << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups.back().name(); + << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h index 3d4c7dde6f..4ff715e468 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h @@ -54,8 +54,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup CartesianMeshPatchListView patchListView() const; - CellGroup cells(Integer index); - CellGroup ownCells(Integer index); + CellGroup allCells(Integer index); + CellGroup inPatchCells(Integer index); + CellGroup overallCells(Integer index); void clear(); @@ -97,8 +98,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup private: - UniqueArray m_amr_patch_cell_groups; - UniqueArray m_amr_patch_cell_groups_own; + UniqueArray m_amr_patch_cell_groups_all; + UniqueArray m_amr_patch_cell_groups_inpatch; + UniqueArray m_amr_patch_cell_groups_overall; UniqueArray m_amr_patches_pointer; UniqueArray> m_amr_patches; ICartesianMesh* m_cmesh; diff --git a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h index feecc9004e..71aa6b4b51 100644 --- a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h @@ -233,23 +233,31 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal /*! * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" - * contenant les noeuds. - * - * En 2D, on peut avoir cette vue : - * x = 0 1 2 3 4 - * ┌──┬──┬──┬──┬──┐ - * y = 0 │ │ 1│ │ 3│ │ - * ├──┼──┼──┼──┼──┤ - * y = 1 │ 5│ │ 7│ │ 9│ - * ├──┼──┼──┼──┼──┤ - * y = 2 │ │ 6│ │ 8│ │ - * ├──┼──┼──┼──┼──┤ - * y = 3 │10│ │12│ │14│ - * ├──┼──┼──┼──┼──┤ - * y = 4 │ │11│ │13│ │ - * └──┴──┴──┴──┴──┘ - * - * Et en 3D : + * contenant les faces. + * + * En 2D, on peut avoir cette vue (pour un maillage de 2x2 mailles) : + * x = 0 1 2 3 4 + * ┌──┬──┬──┬──┬──┐ + * y = -1 │ 0│ │ 2│ │ 4│ + * ┌──┬──┬──┬──┬──┐ + * y = 0 │ │ 1│ │ 3│ │ + * ├──┼──┼──┼──┼──┤ + * y = 1 │ 5│ │ 7│ │ 9│ + * ├──┼──┼──┼──┼──┤ + * y = 2 │ │ 6│ │ 8│ │ + * ├──┼──┼──┼──┼──┤ + * y = 3 │10│ │12│ │14│ + * ├──┼──┼──┼──┼──┤ + * y = 4 │ │11│ │13│ │ + * └──┴──┴──┴──┴──┘ + * (dans cette vue, les mailles se situent aux X et Y impaires + * (donc ici, [1, 1], [3, 1], [1, 3] et [3, 3])). + * + * \note En 2D, on considère que l'on a un niveau imaginaire y=-1. + * \warning Afin de commencer la numérotation à 0, dans les méthodes + * retournant un uniqueId de face 2D, on fait FaceUID-1. + * + * Et en 3D (pour un maillage de 2x2x2 mailles) : * z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 * x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 * ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ @@ -265,6 +273,9 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal * └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ * │ │ │ │ * + * (dans cette vue, les mailles se situent aux X, Y et Z impaires + * (donc ici, [1, 1, 1], [3, 1, 1], [1, 3, 1], &c)). + * * \param level Le niveau. * \return La taille de la grille en X. */ @@ -272,7 +283,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal /*! * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" - * contenant les noeuds. + * contenant les faces. * * Un exemple de cette vue est disponible dans la documentation de \a globalNbFacesXCartesianView. * @@ -283,7 +294,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal /*! * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" - * contenant les noeuds. + * contenant les faces. * * Un exemple de cette vue est disponible dans la documentation de \a globalNbFacesXCartesianView. * @@ -666,6 +677,21 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal */ virtual void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) = 0; + /*! + * \brief Méthode permettant de récupérer les uniqueIds des noeuds d'une maille. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des noeuds + * d'une maille d'Arcane. + * 3--2 + * ^y | | + * | 0--1 + * ->x + * + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbNodeByCell(). + * \param cell La maille. + */ + virtual void cellNodeUniqueIds(ArrayView uid, Cell cell) = 0; + /*! * \brief Méthode permettant de récupérer le nombre de faces dans une maille. * @@ -724,6 +750,49 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal */ virtual void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) = 0; + /*! + * \brief Méthode permettant de récupérer les uniqueIds des faces d'une maille. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des faces + * d'une maille d'Arcane. + * -2- + * ^y 3 1 + * | -0- + * ->x + * + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbFaceByCell(). + * \param cell La maille. + */ + virtual void cellFaceUniqueIds(ArrayView uid, Cell cell) = 0; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'une maille. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 27. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille au centre. + */ + virtual void cellUniqueIdsAroundCell(ArrayView uid, Int64x3 cell_coord, Int32 level) = 0; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'une maille. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 9. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille au centre. + */ + virtual void cellUniqueIdsAroundCell(ArrayView uid, Int64x2 cell_coord, Int32 level) = 0; + /*! * \brief Méthode permettant de récupérer les uniqueIds des mailles autour de la maille passée * en paramètre. @@ -753,6 +822,63 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshNumberingMngInternal */ virtual void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) = 0; + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'un noeud. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 8. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + */ + virtual void cellUniqueIdsAroundNode(ArrayView uid, Int64x3 node_coord, Int32 level) = 0; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'un noeud. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + */ + virtual void cellUniqueIdsAroundNode(ArrayView uid, Int64x2 node_coord, Int32 level) = 0; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour du noeud passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4 en 2D ou de 8 en 3D. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param node_uid L'uniqueId du noeud. + * \param level Le niveau du noeud. + */ + virtual void cellUniqueIdsAroundNode(ArrayView uid, Int64 node_uid, Int32 level) = 0; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour du noeud passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4 en 2D ou de 8 en 3D. + * + * \param uid [OUT] Les uniqueIds des mailles autour. + * \param node Le noeud. + */ + virtual void cellUniqueIdsAroundNode(ArrayView uid, Node node) = 0; + /*! * \brief Méthode permettant de définir les coordonnées spatiales des noeuds des mailles enfants * d'une maille parent. From c517219f0b0efa7586af6fdc0d10caccdc61020d Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Tue, 2 Dec 2025 10:27:48 +0100 Subject: [PATCH 13/19] [arcane:cartesianmesh] Restore legacy amr-type=1 --- .../src/arcane/cartesianmesh/CartesianMesh.cc | 44 ++-- .../arcane/cartesianmesh/CellDirectionMng.cc | 29 +-- .../arcane/cartesianmesh/CellDirectionMng.h | 2 +- .../arcane/cartesianmesh/FaceDirectionMng.cc | 38 ++-- .../arcane/cartesianmesh/NodeDirectionMng.cc | 31 +-- .../internal/CartesianPatchGroup.cc | 204 +++++++++--------- 6 files changed, 143 insertions(+), 205 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 2706343649..1644c2894e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -243,7 +243,7 @@ class CartesianMeshImpl void _computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir, VariableCellReal3& cells_center, VariableFaceReal3& faces_center,CellGroup all_cells, - NodeGroup all_nodes, CellGroup own_cells); + NodeGroup all_nodes); void _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, @@ -560,15 +560,15 @@ computeDirections() if (next_face_x!=(-1)){ m_local_face_direction[MD_DirX] = next_face_x; - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, cells_center, faces_center, all_cells, all_nodes, all_cells); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, cells_center, faces_center, all_cells, all_nodes); } if (next_face_y!=(-1)){ m_local_face_direction[MD_DirY] = next_face_y; - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, cells_center, faces_center, all_cells, all_nodes, all_cells); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, cells_center, faces_center, all_cells, all_nodes); } if (next_face_z != (-1)) { m_local_face_direction[MD_DirZ] = next_face_z; - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, cells_center, faces_center, all_cells, all_nodes, all_cells); + _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, cells_center, faces_center, all_cells, all_nodes); } // Positionne les informations par direction @@ -595,10 +595,10 @@ computeDirections() info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch(); patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord); auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); - _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); - _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes); + _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes); if (is_3d) - _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes, m_patch_group.inPatchCells(patch_index)); + _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes); } if (arcaneIsCheck()) @@ -642,7 +642,7 @@ _buildPatchGroups(const CellGroup& cells,Integer patch_level) void CartesianMeshImpl:: _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center, - VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes, CellGroup own_cells) + VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes) { IItemFamily* cell_family = m_mesh->cellFamily(); IItemFamily* face_family = m_mesh->faceFamily(); @@ -689,30 +689,20 @@ _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellR Int32 my_level = cell.level(); Face next_face = cell.face(next_local_face); Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell(); - if (cells_set.find(next_cell.localId()) == cells_set.end()) { - if (next_cell.level() != my_level) { - next_cell = Cell(); - } - } - else if (next_cell.level() != my_level) { + if (cells_set.find(next_cell.localId()) == cells_set.end()) + next_cell = Cell(); + else if (next_cell.level() != my_level) next_cell = Cell(); - } Face prev_face = cell.face(prev_local_face); Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell(); - - if (cells_set.find(prev_cell.localId()) == cells_set.end()) { - if (prev_cell.level() != my_level) { - prev_cell = Cell(); - } - } - else if (prev_cell.level() != my_level) { + if (cells_set.find(prev_cell.localId()) == cells_set.end()) + prev_cell = Cell(); + else if (prev_cell.level() != my_level) prev_cell = Cell(); - } - cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell); } - cell_dm._internalComputeInnerAndOuterItems(all_cells, own_cells); + cell_dm._internalComputeInnerAndOuterItems(all_cells); face_dm._internalComputeInfos(cell_dm,cells_center,faces_center); node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center); } @@ -1236,7 +1226,7 @@ _applyCoarse(const AMRZonePosition& zone_position) else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { debug() << "Coarsen with specific coarser (for cartesian mesh only)"; m_patch_group.removeCellsInAllPatches(patch_position); - m_patch_group.applyPatchEdit(true); + m_patch_group.applyPatchEdit(false); computeDirections(); m_internal_api.cartesianMeshAMRPatchMng()->flagCellToCoarsen(cells_local_id, true); @@ -1261,7 +1251,7 @@ _applyCoarse(const AMRZonePosition& zone_position) void CartesianMeshImpl:: checkValid() const { - return; // TODO : Modification des outers à prendre en compte. + //return; // TODO : Modification des outers à prendre en compte. info(4) << "Check valid CartesianMesh"; Integer nb_patch = nbPatch(); for( Integer i=0; icreateGroup(String("AllFaces")+base_group_name,Int32ConstArrayView(),true); all_faces.setItems(faces_lid,true); - UniqueArray inner_cells_lid; - cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); - UniqueArray inner_lids; UniqueArray outer_lids; - ENUMERATE_ (Face, iface, all_faces) { - Int32 lid = iface.itemLocalId(); - Face face = *iface; + ENUMERATE_FACE (iitem, all_faces) { + Int32 lid = iitem.itemLocalId(); + Face face = *iitem; // TODO: ne pas utiser nbCell() mais faire cela via le std::set utilisé précédemment - if (face.nbCell() == 1) { + if (face.nbCell() == 1) outer_lids.add(lid); - } - else { - bool c0_inner_cell = inner_cells_lid.contains(face.cell(0).localId()); - bool c1_inner_cell = inner_cells_lid.contains(face.cell(1).localId()); - // Si au moins une des mailles est interne, alors la face est interne. - // TODO : Gérer les faces communes. - if (c0_inner_cell || c1_inner_cell) { - inner_lids.add(lid); - } - else { - outer_lids.add(lid); - } - } + else + inner_lids.add(lid); } m_p->m_inner_all_items = face_family->createGroup(String("AllInner")+base_group_name,inner_lids,true); m_p->m_outer_all_items = face_family->createGroup(String("AllOuter")+base_group_name,outer_lids,true); @@ -316,12 +302,12 @@ _computeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells Cell back_cell = face.backCell(); // Vérifie que les mailles sont dans notre patch. - // if (!front_cell.null()) - // if (patch_cells_set.find(front_cell.localId())==patch_cells_set.end()) - // front_cell = Cell(); - // if (!back_cell.null()) - // if (patch_cells_set.find(back_cell.localId())==patch_cells_set.end()) - // back_cell = Cell(); + if (!front_cell.null()) + if (patch_cells_set.find(front_cell.localId()) == patch_cells_set.end()) + front_cell = Cell(); + if (!back_cell.null()) + if (patch_cells_set.find(back_cell.localId()) == patch_cells_set.end()) + back_cell = Cell(); bool is_inverse = false; if (!front_cell.null()){ diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc index 687d189f27..6e28e652e9 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc @@ -151,34 +151,17 @@ _internalComputeInfos(const CellDirectionMng& cell_dm,const NodeGroup& all_nodes } } - UniqueArray inner_cells_lid; - cell_dm.innerCells().view().fillLocalIds(inner_cells_lid); - - UniqueArray inner_lids; - UniqueArray outer_lids; + Int32UniqueArray inner_lids; + Int32UniqueArray outer_lids; IItemFamily* family = all_nodes.itemFamily(); - ENUMERATE_ (Node, inode, all_nodes) { - Int32 lid = inode.itemLocalId(); + ENUMERATE_ITEM (iitem, all_nodes) { + Int32 lid = iitem.itemLocalId(); Int32 i1 = m_infos_view[lid].m_next_lid; Int32 i2 = m_infos_view[lid].m_previous_lid; - if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID) { + if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID) outer_lids.add(lid); - } - else { - // Si au moins une des mailles est interne, alors le noeud est interne. - // TODO : Gérer les noeuds communs peut-être une autre méthode plus performante. - bool is_outer = true; - for (Cell cell : inode->cells()) { - if (inner_cells_lid.contains(cell.localId())) { - inner_lids.add(lid); - is_outer = false; - break; - } - } - if (is_outer) { - outer_lids.add(lid); - } - } + else + inner_lids.add(lid); } int dir = (int)m_direction; String base_group_name = String("Direction")+dir; diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc index 54bdf1d53a..e3885526ba 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc @@ -88,11 +88,6 @@ addPatchAfterRestore(CellGroup cell_group) String index_str = name.substring(23); group_index = std::stoi(index_str.localstr()); } - // Ancien checkpoint. - else if (name.startsWith("CartesianMeshPatchParentCells")) { - String index_str = name.substring(29); - group_index = std::stoi(index_str.localstr()); - } else { ARCANE_FATAL("Invalid group"); } @@ -177,40 +172,21 @@ addPatch(CellGroup cell_group, Integer group_index) position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); position.setLevel(level_r); } - else { - Integer level = -1; - ENUMERATE_ (Cell, icell, cell_group) { - if (level == -1) { - level = icell->level(); - } - if (level != icell->level()) { - ARCANE_FATAL("Level pb -- Zone with cells to different levels -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, icell->level(), icell->uniqueId()); - } - } - - Integer level_r = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level); - - if (level != -1 && level != level_r) { - ARCANE_FATAL("Bad level reduced"); - } - - position.setLevel(level_r); - } auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, position); _addPatchInstance(makeRef(cdi)); _addCellGroup(cell_group, cdi); - m_cmesh->traceMng()->info() << "addPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() - << " -- m_amr_patches : " << m_amr_patches.size() - << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() - << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); - - m_cmesh->traceMng()->info() << "Min Point : " << cdi->position().minPoint(); - m_cmesh->traceMng()->info() << "Max Point : " << cdi->position().maxPoint(); - m_cmesh->traceMng()->info() << "Level : " << cdi->position().level(); + // m_cmesh->traceMng()->info() << "addPatch()" + // << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() + // << " -- m_amr_patches : " << m_amr_patches.size() + // << " -- m_amr_patches_pointer : " << m_amr_patches_pointer.size() + // << " -- group_index : " << group_index + // << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); + // + // m_cmesh->traceMng()->info() << "Min Point : " << cdi->position().minPoint(); + // m_cmesh->traceMng()->info() << "Max Point : " << cdi->position().maxPoint(); + // m_cmesh->traceMng()->info() << "Level : " << cdi->position().level(); } /*---------------------------------------------------------------------------*/ @@ -259,6 +235,9 @@ allCells(const Integer index) CellGroup CartesianPatchGroup:: inPatchCells(Integer index) { + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); + } if (index == 0) { ARCANE_FATAL("You cannot get cells of ground patch with this method"); } @@ -271,6 +250,9 @@ inPatchCells(Integer index) CellGroup CartesianPatchGroup:: overallCells(Integer index) { + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); + } if (index == 0) { ARCANE_FATAL("You cannot get cells of ground patch with this method"); } @@ -313,13 +295,10 @@ removePatch(const Integer index) void CartesianPatchGroup:: removeCellsInAllPatches(ConstArrayView cells_local_id) { - for (CellGroup cells : m_amr_patch_cell_groups_all) { - cells.removeItems(cells_local_id); - } - for (CellGroup cells : m_amr_patch_cell_groups_inpatch) { - cells.removeItems(cells_local_id); + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Method available only with AMR Cell"); } - for (CellGroup cells : m_amr_patch_cell_groups_overall) { + for (CellGroup cells : m_amr_patch_cell_groups_all) { cells.removeItems(cells_local_id); } } @@ -330,6 +309,9 @@ removeCellsInAllPatches(ConstArrayView cells_local_id) void CartesianPatchGroup:: removeCellsInAllPatches(const AMRPatchPosition& zone_to_delete) { + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); + } // Attention si suppression de la suppression en deux étapes : _splitPatch() supprime aussi des patchs. // i = 1 car on ne peut pas déraffjner le patch ground. const Integer nb_patchs = m_amr_patches_pointer.size(); @@ -355,7 +337,7 @@ removeCellsInAllPatches(const AMRPatchPosition& zone_to_delete) void CartesianPatchGroup:: applyPatchEdit(bool remove_empty_patches) { - m_cmesh->mesh()->traceMng()->info() << "applyPatchEdit() -- Remove nb patch : " << m_patches_to_delete.size(); + // m_cmesh->mesh()->traceMng()->info() << "applyPatchEdit() -- Remove nb patch : " << m_patches_to_delete.size(); std::sort(m_patches_to_delete.begin(), m_patches_to_delete.end(), [](const Integer a, const Integer b) { @@ -366,7 +348,9 @@ applyPatchEdit(bool remove_empty_patches) m_patches_to_delete.clear(); if (remove_empty_patches) { - // TODO : Pas vraiment compatible avec les mailles overlap. + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("remove_empty_patches=true available only with AMR Cell"); + } UniqueArray size_of_patches(m_amr_patch_cell_groups_all.size()); for (Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) { size_of_patches[i] = m_amr_patch_cell_groups_all[i].size(); @@ -504,7 +488,7 @@ mergePatches() allCells(index_p1).view().fillLocalIds(local_ids); allCells(index_p0).addItems(local_ids, false); - m_cmesh->traceMng()->info() << "Remove patch : " << index_p1; + // m_cmesh->traceMng()->info() << "Remove patch : " << index_p1; removePatch(index_p1); fusion = true; @@ -521,6 +505,9 @@ mergePatches() void CartesianPatchGroup:: refine() { + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { + ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); + } Integer dimension = m_cmesh->mesh()->dimension(); Integer nb_overlap_cells = 1; Integer min_level = 0; @@ -542,13 +529,13 @@ refine() future_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, future_max_level); old_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, old_max_level); - m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << future_max_level; + // m_cmesh->traceMng()->info() << "Min level : " << min_level << " -- Max level : " << future_max_level; auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal(); AMRPatchPositionLevelGroup all_patches(future_max_level); for (Integer level = future_max_level; level >= min_level; --level) { - m_cmesh->traceMng()->info() << "Refine Level " << level << " with " << nb_overlap_cells << " layers of overlap cells"; + // m_cmesh->traceMng()->info() << "Refine Level " << level << " with " << nb_overlap_cells << " layers of overlap cells"; if (level != future_max_level) { ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) { @@ -563,10 +550,10 @@ refine() } } } - m_cmesh->traceMng()->info() << "All patch level+1 with margin (can be overlap) : "; - for (auto& elem : all_patches.patches(level + 1)) { - m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.minPointWithOverlap() << " -- max = " << elem.maxPointWithOverlap(); - } + // m_cmesh->traceMng()->info() << "All patch level+1 with margin (can be overlap) : "; + // for (auto& elem : all_patches.patches(level + 1)) { + // m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.minPointWithOverlap() << " -- max = " << elem.maxPointWithOverlap(); + // } } AMRPatchPosition all_level; @@ -588,16 +575,16 @@ refine() nb_overlap_cells += 1; ///////// - - Real global_efficacity = 0; - m_cmesh->traceMng()->info() << "All patch : "; - for (auto& elem : sig_array) { - m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.patch().minPoint() << " -- max = " << elem.patch().maxPoint() << " -- Efficacité : " << elem.efficacity(); - global_efficacity += elem.efficacity(); - } - global_efficacity /= sig_array.size(); - m_cmesh->traceMng()->info() << "Global efficacity : " << global_efficacity; + /* { + Real global_efficacity = 0; + m_cmesh->traceMng()->info() << "All patch : "; + for (auto& elem : sig_array) { + m_cmesh->traceMng()->info() << "\tPatch -- min = " << elem.patch().minPoint() << " -- max = " << elem.patch().maxPoint() << " -- Efficacité : " << elem.efficacity(); + global_efficacity += elem.efficacity(); + } + global_efficacity /= sig_array.size(); + m_cmesh->traceMng()->info() << "Global efficacity : " << global_efficacity; UniqueArray out(numbering->globalNbCellsY(level) * numbering->globalNbCellsX(level), -1); Array2View av_out(out.data(), numbering->globalNbCellsY(level), numbering->globalNbCellsX(level)); ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { @@ -646,7 +633,7 @@ refine() } m_cmesh->traceMng()->info() << str; } - + */ //////////// } @@ -660,9 +647,6 @@ refine() } } - // for (Integer i = 1; i < m_amr_patches.size(); ++i) { - // _removeOnePatch(i); - // } _removeAllPatches(); applyPatchEdit(false); @@ -682,6 +666,7 @@ refine() } } + /* { UniqueArray out(numbering->globalNbCellsY(level) * numbering->globalNbCellsX(level), -1); Array2View av_out(out.data(), numbering->globalNbCellsY(level), numbering->globalNbCellsX(level)); @@ -715,6 +700,7 @@ refine() } m_cmesh->traceMng()->info() << str; } + */ amr->refine(); @@ -730,7 +716,7 @@ refine() } } - m_cmesh->traceMng()->info() << "max_level : " << future_max_level << " -- min_level : " << min_level; + // m_cmesh->traceMng()->info() << "max_level : " << future_max_level << " -- min_level : " << min_level; // On retire les mailles qui n'auront plus de parent. // Exemple : @@ -767,7 +753,7 @@ refine() icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen); } } - + /* { UniqueArray out(numbering->globalNbCellsY(level - 1) * numbering->globalNbCellsX(level - 1), -1); Array2View av_out(out.data(), numbering->globalNbCellsY(level - 1), numbering->globalNbCellsX(level - 1)); @@ -800,6 +786,7 @@ refine() } m_cmesh->traceMng()->info() << str; } + */ amr->coarsen(true); } @@ -812,17 +799,17 @@ refine() } } - m_cmesh->traceMng()->info() << "NbPatch : " << m_cmesh->patches().size(); - - for (Integer i = 0; i < m_cmesh->patches().size(); ++i) { - auto patch = m_cmesh->amrPatch(i); - m_cmesh->traceMng()->info() << "Patch #" << i; - m_cmesh->traceMng()->info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); - m_cmesh->traceMng()->info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); - m_cmesh->traceMng()->info() << "\tLevel : " << patch.patchInterface()->position().level(); - m_cmesh->traceMng()->info() << "\tNbCells : " << patch.patchInterface()->cells().size(); - m_cmesh->traceMng()->info() << "\tIndex : " << patch.patchInterface()->index(); - } + // m_cmesh->traceMng()->info() << "NbPatch : " << m_cmesh->patches().size(); + // + // for (Integer i = 0; i < m_cmesh->patches().size(); ++i) { + // auto patch = m_cmesh->amrPatch(i); + // m_cmesh->traceMng()->info() << "Patch #" << i; + // m_cmesh->traceMng()->info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); + // m_cmesh->traceMng()->info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); + // m_cmesh->traceMng()->info() << "\tLevel : " << patch.patchInterface()->position().level(); + // m_cmesh->traceMng()->info() << "\tNbCells : " << patch.patchInterface()->cells().size(); + // m_cmesh->traceMng()->info() << "\tIndex : " << patch.patchInterface()->index(); + // } } /*---------------------------------------------------------------------------*/ @@ -860,14 +847,17 @@ void CartesianPatchGroup:: _removeOnePatch(Integer index) { m_available_group_index.add(m_amr_patches[index]->index()); - m_cmesh->traceMng()->info() << "_removeOnePatch() -- Save group_index : " << m_available_group_index.back(); + // m_cmesh->traceMng()->info() << "_removeOnePatch() -- Save group_index : " << m_available_group_index.back(); m_amr_patch_cell_groups_all[index - 1].clear(); m_amr_patch_cell_groups_all.remove(index - 1); - m_amr_patch_cell_groups_inpatch[index - 1].clear(); - m_amr_patch_cell_groups_inpatch.remove(index - 1); - m_amr_patch_cell_groups_overall[index - 1].clear(); - m_amr_patch_cell_groups_overall.remove(index - 1); + + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + m_amr_patch_cell_groups_inpatch[index - 1].clear(); + m_amr_patch_cell_groups_inpatch.remove(index - 1); + m_amr_patch_cell_groups_overall[index - 1].clear(); + m_amr_patch_cell_groups_overall.remove(index - 1); + } m_amr_patches_pointer.remove(index); m_amr_patches.remove(index); @@ -898,15 +888,19 @@ _removeAllPatches() for (CellGroup cell_group : m_amr_patch_cell_groups_all) { cell_group.clear(); } - for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) { - cell_group.clear(); - } - for (CellGroup cell_group : m_amr_patch_cell_groups_overall) { - cell_group.clear(); - } m_amr_patch_cell_groups_all.clear(); - m_amr_patch_cell_groups_inpatch.clear(); - m_amr_patch_cell_groups_overall.clear(); + + if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) { + for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) { + cell_group.clear(); + } + for (CellGroup cell_group : m_amr_patch_cell_groups_overall) { + cell_group.clear(); + } + m_amr_patch_cell_groups_inpatch.clear(); + m_amr_patch_cell_groups_overall.clear(); + } + m_amr_patches_pointer.clear(); m_amr_patches.clear(); m_available_group_index.clear(); @@ -944,10 +938,10 @@ _addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch) { m_amr_patch_cell_groups_all.add(cell_group); - if (patch->position().isNull()) { + if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { // Patch non-régulier. - m_amr_patch_cell_groups_inpatch.add(cell_group); - m_amr_patch_cell_groups_overall.add(CellGroup()); + // m_amr_patch_cell_groups_inpatch.add(cell_group); + // m_amr_patch_cell_groups_overall.add(CellGroup()); return; } @@ -1002,10 +996,10 @@ _isPatchInContact(const AMRPatchPosition& patch_position0, const AMRPatchPositio void CartesianPatchGroup:: _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) { - m_cmesh->traceMng()->info() << "Coarse Zone" - << " -- Min point : " << part_to_remove.minPoint() - << " -- Max point : " << part_to_remove.maxPoint() - << " -- Level : " << part_to_remove.level(); + // m_cmesh->traceMng()->info() << "Coarse Zone" + // << " -- Min point : " << part_to_remove.minPoint() + // << " -- Max point : " << part_to_remove.maxPoint() + // << " -- Level : " << part_to_remove.level(); // p1 est le bout de patch qu'il faut retirer de p0. // On a donc uniquement quatre cas à traiter (sachant que p0 et p1 sont @@ -1254,11 +1248,11 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); _addCellGroup(parent_cells, cdi); - m_cmesh->traceMng()->info() << "_addCutPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() - << " -- m_amr_patches : " << m_amr_patches.size() - << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); + // m_cmesh->traceMng()->info() << "_addCutPatch()" + // << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() + // << " -- m_amr_patches : " << m_amr_patches.size() + // << " -- group_index : " << group_index + // << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); } /*---------------------------------------------------------------------------*/ @@ -1289,11 +1283,11 @@ _addPatch(const AMRPatchPosition& new_patch_position) CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); _addCellGroup(parent_cells, cdi); - m_cmesh->traceMng()->info() << "_addPatch()" - << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() - << " -- m_amr_patches : " << m_amr_patches.size() - << " -- group_index : " << group_index - << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); + // m_cmesh->traceMng()->info() << "_addPatch()" + // << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() + // << " -- m_amr_patches : " << m_amr_patches.size() + // << " -- group_index : " << group_index + // << " -- cell_group name : " << m_amr_patch_cell_groups_all.back().name(); } /*---------------------------------------------------------------------------*/ From 38d9a2d1cd9cd1181ab1daf2c26f095f8c221579 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Tue, 2 Dec 2025 15:45:00 +0100 Subject: [PATCH 14/19] [arcane:cartesianmesh] Add doc --- .../tests/AMRCartesianMeshTesterModule.cc | 44 +- .../arcane/cartesianmesh/AMRPatchPosition.cc | 18 +- .../arcane/cartesianmesh/AMRPatchPosition.h | 229 ++++- .../arcane/cartesianmesh/AMRZonePosition.cc | 12 +- .../arcane/cartesianmesh/AMRZonePosition.h | 3 +- .../src/arcane/cartesianmesh/CartesianMesh.cc | 218 ++--- .../cartesianmesh/CartesianMeshAMRMng.cc | 47 +- .../cartesianmesh/CartesianMeshAMRMng.h | 97 +- .../cartesianmesh/CartesianMeshGlobal.h | 9 + .../CartesianMeshNumberingMng.cc | 107 ++- .../cartesianmesh/CartesianMeshNumberingMng.h | 908 +++++++++++++++++- .../src/arcane/cartesianmesh/CartesianPatch.h | 21 +- .../src/arcane/cartesianmesh/ICartesianMesh.h | 27 +- .../internal/AMRPatchPositionLevelGroup.cc | 10 +- .../internal/AMRPatchPositionLevelGroup.h | 16 +- .../internal/AMRPatchPositionSignature.cc | 16 +- .../internal/AMRPatchPositionSignature.h | 30 +- .../internal/AMRPatchPositionSignatureCut.cc | 202 ++-- .../internal/AMRPatchPositionSignatureCut.h | 12 +- .../internal/CartesianMeshAMRPatchMng.cc | 11 +- .../internal/CartesianMeshAMRPatchMng.h | 14 +- .../CartesianMeshNumberingMngInternal.cc | 2 +- .../CartesianMeshNumberingMngInternal.h | 2 +- .../internal/CartesianPatchGroup.cc | 54 +- .../internal/CartesianPatchGroup.h | 11 +- .../internal/ICartesianMeshInternal.h | 19 +- .../internal/ICartesianMeshPatchInternal.h | 6 +- 27 files changed, 1717 insertions(+), 428 deletions(-) diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 4daba5d9ec..7f58aa8575 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -42,6 +42,7 @@ #include "arcane/core/IGhostLayerMng.h" #include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/cartesianmesh/AMRZonePosition.h" #include "arcane/cartesianmesh/CellDirectionMng.h" #include "arcane/cartesianmesh/FaceDirectionMng.h" #include "arcane/cartesianmesh/NodeDirectionMng.h" @@ -511,6 +512,7 @@ _computeCenters() void AMRCartesianMeshTesterModule:: _initAMR() { + CartesianMeshAMRMng amr_mng(m_cartesian_mesh); // Regarde si on dé-raffine le maillage initial if (options()->coarseAtInit()){ // Il faut que les directions aient été calculées avant d'appeler le dé-raffinement @@ -527,7 +529,6 @@ _initAMR() // Ref coarser = CartesianMeshUtils::createCartesianMeshCoarsening2(m_cartesian_mesh); // coarser->createCoarseCells(); // } - CartesianMeshAMRMng amr_mng(m_cartesian_mesh); amr_mng.createSubLevel(); CartesianMeshPatchListView patches = m_cartesian_mesh->patches(); @@ -545,15 +546,15 @@ _initAMR() // à raffiner celles qui sont contenues dans le boîte englobante // spécifiée dans le jeu de données. Int32 dim = defaultMesh()->dimension(); - if (dim==2){ - for( const auto& x : options()->refinement2d() ){ - m_cartesian_mesh->refinePatch({x->position(), x->length()}); + if (dim == 2) { + for (const auto& x : options()->refinement2d()) { + amr_mng.refineZone({ x->position(), x->length() }); m_cartesian_mesh->computeDirections(); } } - if (dim==3){ - for( const auto& x : options()->refinement3d() ){ - m_cartesian_mesh->refinePatch({x->position(), x->length()}); + if (dim == 3) { + for (const auto& x : options()->refinement3d()) { + amr_mng.refineZone({ x->position(), x->length() }); m_cartesian_mesh->computeDirections(); } } @@ -566,6 +567,7 @@ void AMRCartesianMeshTesterModule:: _coarseZone() { Int32 dim = defaultMesh()->dimension(); + CartesianMeshAMRMng amr_mng(m_cartesian_mesh); if (dim == 2) { //UniqueArray cells_in_patchs; @@ -574,7 +576,7 @@ _coarseZone() // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs); // defaultMesh()->modifier()->coarsenItemsV2(true); // cells_in_patchs.clear(); - m_cartesian_mesh->coarseZone({{x->position()}, {x->length()}}); + amr_mng.coarseZone({ { x->position() }, { x->length() } }); m_cartesian_mesh->computeDirections(); } } @@ -585,7 +587,7 @@ _coarseZone() // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs); // defaultMesh()->modifier()->coarsenItemsV2(true); // cells_in_patchs.clear(); - m_cartesian_mesh->coarseZone({{x->position()}, {x->length()}}); + amr_mng.coarseZone({ { x->position() }, { x->length() } }); m_cartesian_mesh->computeDirections(); } } @@ -597,7 +599,9 @@ _coarseZone() void AMRCartesianMeshTesterModule:: _mergePatches() { - m_cartesian_mesh->mergePatches(); + CartesianMeshAMRMng amr_mng(m_cartesian_mesh); + amr_mng.mergePatches(); + m_cartesian_mesh->computeDirections(); } @@ -624,16 +628,16 @@ void AMRCartesianMeshTesterModule:: compute() { _compute1(); - info() << "NbPatch : " << m_cartesian_mesh->nbPatch(); - info() << "NbPatch : " << m_cartesian_mesh->patches().size(); - - for (Integer i = 0; i < m_cartesian_mesh->patches().size(); ++i) { - auto patch = m_cartesian_mesh->amrPatch(i); - info() << "Patch #" << i; - info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); - info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); - info() << "\tLevel : " << patch.patchInterface()->position().level(); - } + // info() << "NbPatch : " << m_cartesian_mesh->nbPatch(); + // info() << "NbPatch : " << m_cartesian_mesh->patches().size(); + // + // for (Integer i = 0; i < m_cartesian_mesh->patches().size(); ++i) { + // auto patch = m_cartesian_mesh->amrPatch(i); + // info() << "Patch #" << i; + // info() << "\tMin Point : " << patch.patchInterface()->position().minPoint(); + // info() << "\tMax Point : " << patch.patchInterface()->position().maxPoint(); + // info() << "\tLevel : " << patch.patchInterface()->position().level(); + // } } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc index fc0ddd36d7..1c0e66c226 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.cc @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPosition.cc (C) 2000-2025 */ +/* AMRPatchPosition.cc (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Position d'un patch AMR d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -209,9 +209,13 @@ canBeFusion(const AMRPatchPosition& other_patch) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -void AMRPatchPosition:: +bool AMRPatchPosition:: fusion(const AMRPatchPosition& other_patch) { + if (!canBeFusion(other_patch)) { + return false; + } + const Int64x3 min_point = other_patch.minPoint(); const Int64x3 max_point = other_patch.maxPoint(); @@ -235,6 +239,8 @@ fusion(const AMRPatchPosition& other_patch) else if (m_max_point.z < max_point.z) { m_max_point.z = max_point.z; } + + return true; } /*---------------------------------------------------------------------------*/ @@ -297,7 +303,7 @@ length() const /*---------------------------------------------------------------------------*/ bool AMRPatchPosition:: -isIn(Integer x, Integer y, Integer z) const +isIn(Int64 x, Int64 y, Int64 z) const { 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; } @@ -306,7 +312,7 @@ isIn(Integer x, Integer y, Integer z) const /*---------------------------------------------------------------------------*/ bool AMRPatchPosition:: -isInWithOverlap(Integer x, Integer y, Integer z) const +isInWithOverlap(Int64 x, Int64 y, Int64 z) const { const Int64x3 min_point = minPointWithOverlap(); const Int64x3 max_point = maxPointWithOverlap(); @@ -317,7 +323,7 @@ isInWithOverlap(Integer x, Integer y, Integer z) const /*---------------------------------------------------------------------------*/ bool AMRPatchPosition:: -isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const +isInWithOverlap(Int64 x, Int64 y, Int64 z, Integer overlap) const { const Int64x3 min_point = m_min_point - overlap; const Int64x3 max_point = m_max_point + overlap; diff --git a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h index 38461c8c97..ae3faa29dd 100644 --- a/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRPatchPosition.h @@ -5,17 +5,17 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPosition.h (C) 2000-2025 */ +/* AMRPatchPosition.h (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Position d'un patch AMR d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ #ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITION_H #define ARCANE_CARTESIANMESH_AMRPATCHPOSITION_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/utils/Vector3.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" +#include "arcane/utils/Vector3.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -26,48 +26,259 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +/*! + * \brief Classe permettant de définir la position d'un patch dans le maillage + * cartésien. + * + * La position d'un patch est désigné par la position de deux mailles dans la + * grille. La position "min" et la position "max" forment une boite englobante. + * + * \warning La maille à la position "min" est incluse dans la boite, mais la + * maille à la position "max" est exclue. + * + * \note La position du patch est globale pour le maillage cartesien. Le + * découpage en sous-domaine n'est pas pris en compte (exemple avec la méthode + * \a nbCells() de cette classe qui donne le nombre de mailles du patch sans + * tenir compte des sous-domaines). + * + * Les positions des mailles peuvent être obtenues par le + * CartesianMeshNumberingMng. + * + * \warning Cette classe est valide uniquement pour un pattern de raffinement de + * 2 (modifier ça ne devrait pas être complexe, si besoin). + */ class ARCANE_CARTESIANMESH_EXPORT AMRPatchPosition { public: + /*! + * \brief Constructeur pour une position nulle. + * Une position nulle est définie par un level = -2. + */ AMRPatchPosition(); - // TODO Faire operator= + + /*! + * \brief Constructeur de copie. + * \param src La position à copier. + */ AMRPatchPosition(const AMRPatchPosition& src); + AMRPatchPosition& operator=(const AMRPatchPosition&) = default; ~AMRPatchPosition(); public: + /*! + * \brief Méthode permettant de récupérer le niveau du patch. + * \return Le niveau du patch. + */ Integer level() const; + + /*! + * \brief Méthode permettant de définir le niveau du patch. + * \param level Le niveau du patch. + */ void setLevel(Integer level); + /*! + * \brief Méthode permettant de récupérer la position min de la boite + * englobante. + * + * \return La position min. + */ Int64x3 minPoint() const; + + /*! + * \brief Méthode permettant de définir la position min de la boite + * englobante. + * \param min_point la position min. + */ void setMinPoint(Int64x3 min_point); + + /*! + * \brief Méthode permettant de récupérer la position max de la boite + * englobante. + * + * \return La position max. + */ Int64x3 maxPoint() const; + + /*! + * \brief Méthode permettant de définir la position max de la boite + * englobante. + * \param max_point la position max. + */ void setMaxPoint(Int64x3 max_point); + /*! + * \brief Méthode permettant de récupérer le nombre de couches de mailles de + * recouvrement du patch. + * + * \return le nombre de couches de mailles de recouvrement + */ Integer overlapLayerSize() const; + + /*! + * \brief Méthode permettant de définir le nombre de couches de mailles de + * recouvrement du patch. + * \param layer_size le nombre de couches de mailles de recouvrement + */ void setOverlapLayerSize(Integer layer_size); + /*! + * \brief Méthode permettant de récupérer la position min de la boite + * englobante en incluant la couche de mailles de recouvrement. + * \return La position min avec la couche de mailles de recouvrement. + */ Int64x3 minPointWithOverlap() const; - Int64x3 maxPointWithOverlap() const; + /*! + * \brief Méthode permettant de récupérer la position max de la boite + * englobante en incluant la couche de mailles de recouvrement. + * \return La position max avec la couche de mailles de recouvrement. + */ + Int64x3 maxPointWithOverlap() const; + /*! + * \brief Méthode permettant de connaitre le nombre de mailles du patch + * selon sa position. + * + * \warning Le nombre de mailles est calculé avec les positions min et max + * (sans la couche de recouvrement). Ce nombre est donc le même pour tous + * les sous-domaines. Attention à ne pas comparer ce nombre avec le nombre + * de mailles du groupe de mailles qui peut être associé à cette classe et + * qui peut être différent pour chaque sous-domaine. + * + * \return Le nombre de maille du patch. + */ Int64 nbCells() const; + + /*! + * \brief Méthode permettant de découper le patch en deux patchs selon un + * point de découpe. + * + * \param cut_point Le point de découpe. + * \param dim La dimension qui doit être découpée. + * \return Les deux positions de patch résultant de la découpe. + */ std::pair cut(Int64 cut_point, Integer dim) const; + + /*! + * \brief Méthode permettant de savoir si notre patch peut être fusionné + * avec \a other_patch. + * + * \param other_patch Le patch à verifier. + * \return True si la fusion est possible. + */ bool canBeFusion(const AMRPatchPosition& other_patch) const; - void fusion(const AMRPatchPosition& other_patch); + + /*! + * \brief Méthode permettant de fusionner \a other_patch avec le nôtre. + * + * Une vérification de possibilité de fusion (via \a canBeFusion()) est + * réalisée avant de fusionner. Si la fusion est impossible, on retourne + * false. Sinon, on fusionne et on retourne true. + * + * \param other_patch Le patch avec lequel fusionner. + * \return true si la fusion à été réalisé, false si la fusion est + * impossible. + */ + bool fusion(const AMRPatchPosition& other_patch); + + /*! + * \brief Méthode permettant de savoir si la position du patch est nulle. + * + * \warning On ne vérifie pas la validité de la position. + * + * \return True si le patch est nulle. + */ bool isNull() const; + /*! + * \brief Méthode permettant de créer un \a AMRPatchPosition pour le niveau + * supérieur. + * + * \param dim La dimension du maillage. + * \return Un \a AMRPatchPosition de niveau supérieur. + */ AMRPatchPosition patchUp(Integer dim) const; + + /*! + * \brief Méthode permettant de créer un \a AMRPatchPosition pour le niveau + * inférieur. + * + * Si la position min n'est pas divisible par deux, on arrondit à l'entier + * inférieur. + * + * Si la position max n'est pas divisible par deux, on arrondit à l'entier + * supérieur. + * + * Pour la couche de recouvrement, cette méthode s'assure que l'on n'aura + * jamais plus d'un niveau de différence entre deux mailles de niveaux + * différents. + * + * \warning patch.patchDown(patch.patchUp(X)) != patch et + * patch.patchUp(patch.patchDown(X)) != patch. + * + * \param dim La dimension du maillage. + * \return Un \a AMRPatchPosition de niveau inférieur. + */ AMRPatchPosition patchDown(Integer dim) const; + /*! + * \brief Méthode permettant de connaitre la taille du patch (en nombre de + * mailles par direction). + * + * \return La taille du patch. + */ Int64x3 length() const; - bool isIn(Integer x, Integer y, Integer z) const; - bool isInWithOverlap(Integer x, Integer y, Integer z) const; - bool isInWithOverlap(Integer x, Integer y, Integer z, Integer overlap) const; + /*! + * \brief Méthode permettant de savoir si une maille de position x,y,z est + * incluse dans ce patch. + * + * Pour inclure la couche de recouvrement, utiliser la méthode + * \a isInWithOverlap(). + * + * \param x Position X de la maille. + * \param y Position Y de la maille. + * \param z Position Z de la maille. + * + * \return True si la maille est dans le patch. + */ + bool isIn(Int64 x, Int64 y, Int64 z) const; + + /*! + * \brief Méthode permettant de savoir si une maille de position x,y,z est + * incluse dans ce patch avec couche de recouvrement. + * + * \param x Position X de la maille. + * \param y Position Y de la maille. + * \param z Position Z de la maille. + * + * \return True si la maille est dans le patch. + */ + bool isInWithOverlap(Int64 x, Int64 y, Int64 z) const; + + /*! + * \brief Méthode permettant de savoir si une maille de position x,y,z est + * incluse dans ce patch avec couche de recouvrement fourni en paramètre. + * \param x Position X de la maille. + * \param y Position Y de la maille. + * \param z Position Z de la maille. + * \param overlap Le nombre de mailles de recouvrement de la couche. + * + * \return True si la maille est dans le patch. + */ + bool isInWithOverlap(Int64 x, Int64 y, Int64 z, Integer overlap) const; + /*! + * \brief Méthode permettant de savoir si notre patch est en contact avec le + * patch \a other. + * + * \param other Le patch à verifier. + * \return True si les patchs sont en contact. + */ bool haveIntersection(const AMRPatchPosition& other) const; private: diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc index 6776c86f96..aba0680654 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.cc @@ -12,13 +12,17 @@ #include "arcane/cartesianmesh/AMRZonePosition.h" -#include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/utils/FixedArray.h" +#include "arcane/utils/ITraceMng.h" + #include "arcane/core/IMesh.h" #include "arcane/core/MeshKind.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" #include "arcane/core/IParallelMng.h" -#include "arcane/utils/FixedArray.h" -#include "arcane/utils/ITraceMng.h" + +#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" + +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h index b7da5d2517..d00d099f02 100644 --- a/arcane/src/arcane/cartesianmesh/AMRZonePosition.h +++ b/arcane/src/arcane/cartesianmesh/AMRZonePosition.h @@ -14,10 +14,9 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPosition.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" #include "arcane/utils/Real3.h" #include "arcane/core/VariableTypes.h" -#include "arcane/cartesianmesh/CartesianMeshGlobal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 1644c2894e..2b2716462f 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -35,6 +35,7 @@ #include "arcane/cartesianmesh/internal/CartesianPatchGroup.h" #include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/cartesianmesh/AMRZonePosition.h" #include "arcane/cartesianmesh/CartesianConnectivity.h" #include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h" #include "arcane/cartesianmesh/CartesianMeshCoarsening.h" @@ -120,6 +121,7 @@ class CartesianMeshImpl { return m_numbering_mng; } + CartesianPatchGroup& cartesianPatchGroup() override { return m_cartesian_mesh->_cartesianPatchGroup(); } private: @@ -173,7 +175,6 @@ class CartesianMeshImpl } void computeDirections() override; - void computeDirectionsV2() override; void recreateFromDump() override; @@ -195,12 +196,8 @@ class CartesianMeshImpl void coarseZone3D(Real3 position, Real3 length) override; void coarseZone(const AMRZonePosition& position) override; - void refine() override; - Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override; - void mergePatches() override; - void renumberItemsUniqueId(const CartesianMeshRenumberingInfo& v) override; void checkValid() const override; @@ -215,6 +212,8 @@ class CartesianMeshImpl // Implémentation de 'ICartesianMeshInternal' Ref _createCartesianMeshCoarsening2(); void _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id); + CartesianPatchGroup& _cartesianPatchGroup() { return m_patch_group; } + void _computeDirectionsV2(); private: @@ -245,11 +244,11 @@ class CartesianMeshImpl VariableFaceReal3& faces_center,CellGroup all_cells, NodeGroup all_nodes); - void _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, - CellGroup all_cells, - CellGroup in_patch_cells, - CellGroup overall_cells, - NodeGroup all_nodes); + void _computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, + CellGroup all_cells, + CellGroup in_patch_cells, + CellGroup overall_cells, + NodeGroup all_nodes); void _applyRefine(const AMRZonePosition &position); void _applyCoarse(const AMRZonePosition& zone_position); @@ -349,7 +348,7 @@ _saveInfosInProperties() if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { m_internal_api.cartesianMeshNumberingMngInternal()->_saveInfosInProperties(); - m_internal_api.cartesianMeshNumberingMngInternal()->printStatus(); + //m_internal_api.cartesianMeshNumberingMngInternal()->printStatus(); } } @@ -416,7 +415,7 @@ computeDirections() if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { // TODO : Voir où mettre la renumérotation. m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering(); - computeDirectionsV2(); + _computeDirectionsV2(); return; } info() << "CartesianMesh: computeDirections()"; @@ -711,86 +710,7 @@ _computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellR /*---------------------------------------------------------------------------*/ void CartesianMeshImpl:: -_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overall_cells, NodeGroup all_nodes) -{ - IItemFamily* cell_family = m_mesh->cellFamily(); - IItemFamily* face_family = m_mesh->faceFamily(); - IItemFamily* node_family = m_mesh->nodeFamily(); - - Int32 max_cell_id = cell_family->maxLocalId(); - Int32 max_face_id = face_family->maxLocalId(); - Int32 max_node_id = node_family->maxLocalId(); - - CellDirectionMng& cell_dm = cdi.cellDirection(dir); - cell_dm._internalResizeInfos(max_cell_id); - - FaceDirectionMng& face_dm = cdi.faceDirection(dir); - face_dm._internalResizeInfos(max_face_id); - - NodeDirectionMng& node_dm = cdi.nodeDirection(dir); - node_dm._internalResizeInfos(max_node_id); - - //TODO: attention à remettre à jour après changement de maillage. - info(4) << "COMPUTE DIRECTION dir=" << dir; - - Int32 prev_local_face = -1; - Int32 next_local_face = m_local_face_direction[dir]; - Integer mesh_dim = m_mesh->dimension(); - // Calcul le numero local de face oppose à la face suivante. - if (mesh_dim == 2) - prev_local_face = (next_local_face + 2) % 4; - else if (mesh_dim == 3) - prev_local_face = (next_local_face + 3) % 6; - - cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face); - - // Positionne pour chaque maille les faces avant et après dans la direction. - // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante - std::set cells_set; - ENUMERATE_CELL (icell, all_cells) { - cells_set.insert(icell.itemLocalId()); - } - - // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles - // soient de même niveau - ENUMERATE_CELL (icell, all_cells) { - Cell cell = *icell; - Int32 my_level = cell.level(); - Face next_face = cell.face(next_local_face); - Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell(); - if (cells_set.find(next_cell.localId()) == cells_set.end()) { - if (next_cell.level() != my_level) { - next_cell = Cell(); - } - } - else if (next_cell.level() != my_level) { - next_cell = Cell(); - } - - Face prev_face = cell.face(prev_local_face); - Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell(); - - if (cells_set.find(prev_cell.localId()) == cells_set.end()) { - if (prev_cell.level() != my_level) { - prev_cell = Cell(); - } - } - else if (prev_cell.level() != my_level) { - prev_cell = Cell(); - } - - cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell); - } - cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overall_cells); - face_dm._internalComputeInfos(cell_dm); - node_dm._internalComputeInfos(cell_dm, all_nodes); -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -void CartesianMeshImpl:: -computeDirectionsV2() +_computeDirectionsV2() { info() << "CartesianMesh: computeDirectionsV2()"; @@ -832,10 +752,10 @@ computeDirectionsV2() m_local_face_direction[MD_DirY] = 2; } - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells, CellGroup(), all_nodes); - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells, CellGroup(), all_nodes); + _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells, CellGroup(), all_nodes); + _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells, CellGroup(), all_nodes); if (is_3d) { - _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells, CellGroup(), all_nodes); + _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells, CellGroup(), all_nodes); } // Positionne les informations par direction @@ -862,10 +782,10 @@ computeDirectionsV2() info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch(); patch->_internalComputeNodeCellInformations(); auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); // TODO A suppr - _computeMeshDirection(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); - _computeMeshDirection(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + _computeMeshDirectionV2(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + _computeMeshDirectionV2(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); if (is_3d) - _computeMeshDirection(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); + _computeMeshDirectionV2(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); } if (arcaneIsCheck()) @@ -877,6 +797,85 @@ computeDirectionsV2() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshImpl:: +_computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overall_cells, NodeGroup all_nodes) +{ + IItemFamily* cell_family = m_mesh->cellFamily(); + IItemFamily* face_family = m_mesh->faceFamily(); + IItemFamily* node_family = m_mesh->nodeFamily(); + + Int32 max_cell_id = cell_family->maxLocalId(); + Int32 max_face_id = face_family->maxLocalId(); + Int32 max_node_id = node_family->maxLocalId(); + + CellDirectionMng& cell_dm = cdi.cellDirection(dir); + cell_dm._internalResizeInfos(max_cell_id); + + FaceDirectionMng& face_dm = cdi.faceDirection(dir); + face_dm._internalResizeInfos(max_face_id); + + NodeDirectionMng& node_dm = cdi.nodeDirection(dir); + node_dm._internalResizeInfos(max_node_id); + + //TODO: attention à remettre à jour après changement de maillage. + info(4) << "COMPUTE DIRECTION dir=" << dir; + + Int32 prev_local_face = -1; + Int32 next_local_face = m_local_face_direction[dir]; + Integer mesh_dim = m_mesh->dimension(); + // Calcul le numero local de face oppose à la face suivante. + if (mesh_dim == 2) + prev_local_face = (next_local_face + 2) % 4; + else if (mesh_dim == 3) + prev_local_face = (next_local_face + 3) % 6; + + cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face); + + // Positionne pour chaque maille les faces avant et après dans la direction. + // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante + std::set cells_set; + ENUMERATE_CELL (icell, all_cells) { + cells_set.insert(icell.itemLocalId()); + } + + // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles + // soient de même niveau + ENUMERATE_CELL (icell, all_cells) { + Cell cell = *icell; + Int32 my_level = cell.level(); + Face next_face = cell.face(next_local_face); + Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell(); + if (cells_set.find(next_cell.localId()) == cells_set.end()) { + if (next_cell.level() != my_level) { + next_cell = Cell(); + } + } + else if (next_cell.level() != my_level) { + next_cell = Cell(); + } + + Face prev_face = cell.face(prev_local_face); + Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell(); + + if (cells_set.find(prev_cell.localId()) == cells_set.end()) { + if (prev_cell.level() != my_level) { + prev_cell = Cell(); + } + } + else if (prev_cell.level() != my_level) { + prev_cell = Cell(); + } + + cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell); + } + cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overall_cells); + face_dm._internalComputeInfos(cell_dm); + node_dm._internalComputeInfos(cell_dm, all_nodes); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianMeshImpl:: refinePatch2D(Real2 position,Real2 length) { @@ -937,17 +936,6 @@ coarseZone(const AMRZonePosition& position) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -void CartesianMeshImpl:: -refine() -{ - if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_patch_group.refine(); - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - Integer CartesianMeshImpl:: reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) { @@ -1105,18 +1093,6 @@ reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -void CartesianMeshImpl:: -mergePatches() -{ - if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) { - m_patch_group.mergePatches(); - m_patch_group.applyPatchEdit(false); - } -} - -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - void CartesianMeshImpl:: _addPatchFromExistingChildren(ConstArrayView parent_cells_local_id) { diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc index b3a4029b68..d318d0c6d2 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc @@ -5,22 +5,27 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshAMRMng.cc (C) 2000-2025 */ +/* CartesianMeshAMRMng.cc (C) 2000-2025 */ /* */ -/* Gestionnaire de l'AMR par patch d'un maillage cartésien. */ +/* Gestionnaire de l'AMR pour un maillage cartésien. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h" -#include "arcane/cartesianmesh/CartesianMeshPatchListView.h" -#include "arcane/cartesianmesh/CartesianMeshUtils.h" -#include "arcane/cartesianmesh/CartesianPatch.h" - #include "arcane/cartesianmesh/CartesianMeshAMRMng.h" +#include "arcane/utils/FatalErrorException.h" + #include "arcane/core/IMesh.h" #include "arcane/core/MeshKind.h" + +#include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/cartesianmesh/CartesianPatch.h" +#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h" +#include "arcane/cartesianmesh/CartesianMeshPatchListView.h" +#include "arcane/cartesianmesh/CartesianMeshUtils.h" + #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" +#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -34,8 +39,7 @@ namespace Arcane CartesianMeshAMRMng:: CartesianMeshAMRMng(ICartesianMesh* cmesh) : m_cmesh(cmesh) -{ -} +{} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -86,9 +90,22 @@ coarseZone(const AMRZonePosition& position) const /*---------------------------------------------------------------------------*/ void CartesianMeshAMRMng:: -refine() const +adaptMesh(bool clear_refine_flag) const { - m_cmesh->refine(); + auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind(); + if (amr_type == eMeshAMRKind::Cell) { + ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); + } + m_cmesh->_internalApi()->cartesianPatchGroup().refine(clear_refine_flag); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshAMRMng:: +clearRefineRelatedFlags() const +{ + m_cmesh->_internalApi()->cartesianPatchGroup().clearRefineRelatedFlags(); } /*---------------------------------------------------------------------------*/ @@ -106,7 +123,13 @@ reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const void CartesianMeshAMRMng:: mergePatches() const { - m_cmesh->mergePatches(); + auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind(); + if (amr_type == eMeshAMRKind::Cell) { + return; + } + + m_cmesh->_internalApi()->cartesianPatchGroup().mergePatches(); + m_cmesh->_internalApi()->cartesianPatchGroup().applyPatchEdit(false); } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h index 72bb9e52dd..4d672ef70e 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshAMRMng.h (C) 2000-2025 */ +/* CartesianMeshAMRMng.h (C) 2000-2025 */ /* */ -/* Gestionnaire de l'AMR par patch d'un maillage cartésien. */ +/* Gestionnaire de l'AMR pour un maillage cartésien. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -17,8 +17,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/utils/TraceAccessor.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -29,10 +28,20 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +/*! + * \brief Classe permettant d'accéder aux méthodes spécifiques AMR du maillage + * cartesien. + * + * Une instance de cette classe est valide tant que le ICartesianMesh passé en + * paramètre du constructeur est valide. + */ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng { public: + /*! + * \brief Constructeur. + */ explicit CartesianMeshAMRMng(ICartesianMesh* cmesh); public: @@ -93,9 +102,62 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng void coarseZone(const AMRZonePosition& position) const; /*! - * \brief TODO + * \brief Méthode permettant d'adapter le raffinement du maillage selon les + * mailles à raffiner. + * + * Cette méthode ne peut être appelée que si le maillage est un maillage + * AMR (IMesh::isAmrActivated()==true) et que le type de l'AMR est 3 + * (PatchCartesianMeshOnly). + * + * Avant d'appeler cette méthode, il faut ajouter le flag "II_Refine" sur les + * mailles qui doivent être raffinées. Il est possible de le faire niveau par + * niveau ou plusieurs niveaux d'un coup (si plusieurs niveaux existent + * déjà). + * Pour être sûr de n'avoir aucun flag déjà présent sur le maillage, il est + * possible d'appeler la méthode \a clearRefineRelatedFlags(). + * Dans le cas d'un raffinement niveau par niveau, il est possible de mettre + * le paramètre \a clear_refine_flag à false afin de garder les flags des + * niveaux inférieurs et d'éviter d'avoir à les recalculer. Pour le dernier + * niveau, il est recommandé de mettre le paramètre \a clear_refine_flag à + * true pour supprimer les flags devenu inutiles (ou d'appeler la méthode + * clearRefineRelatedFlags()). + * + * Les mailles n'ayant pas de flag "II_Refine" seront déraffinées. + * + * Afin d'éviter les mailles orphelines, si une maille est marquée + * "II_Refine", alors la maille parente est marquée "II_Refine". + * + * Exemple d'exécution : + * ``` + * CartesianMeshAMRMng amr_mng(cmesh()); + * amr_mng.clearRefineRelatedFlags(); + * for (Integer level = 0; level < 2; ++level){ + * computeInLevel(level); // Va mettre des flags II_Refine sur les mailles + * amr_mng.adaptMesh(false); + * } + * amr_mng.clearRefineRelatedFlags(); + * ``` + * + * Cette opération est collective. + * + * \param clear_refine_flag true si l'on souhaite supprimer les flags + * II_Refine après adaptation. */ - void refine() const; + void adaptMesh(bool clear_refine_flag) const; + + /*! + * \brief Méthode permettant de supprimer les flags liés au raffinement de + * toutes les mailles. + * + * Les flags concernés sont : + * - ItemFlags::II_Coarsen + * - ItemFlags::II_Refine + * - ItemFlags::II_JustCoarsened + * - ItemFlags::II_JustRefined + * - ItemFlags::II_JustAdded + * - ItemFlags::II_CoarsenInactive + */ + void clearRefineRelatedFlags() const; /*! * \brief Méthode permettant de supprimer une ou plusieurs couches @@ -116,12 +178,31 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const; /*! - * \brief TODO + * \brief Méthode permettant de fusionner les patchs qui peuvent l'être. + * + * Cette méthode ne peut être appelée que si le maillage est un maillage + * AMR (IMesh::isAmrActivated()==true). + * Si le type de l'AMR n'est pas 3 (PatchCartesianMeshOnly), la méthode ne + * fait rien. + * + * Cette méthode peut être utile après plusieurs appels à \a refineZone() et à + * \a coarseZone(). En revanche, un appel à cette méthode est inutile après + * un appel à \a adaptMesh() car \a adaptMesh() s'en occupe. */ void mergePatches() const; /*! - * \brief TODO + * \brief Méthode permettant de créer un sous-niveau ("niveau -1"). + * + * Cette méthode ne peut être appelée que si le maillage est un maillage + * AMR (IMesh::isAmrActivated()==true). + * + * Dans le cas d'utilisation de l'AMR type 3 (PatchCartesianMeshOnly), il est + * possible d'appeler cette méthode en cours de calcul et autant de fois que + * nécessaire (tant qu'il est possible de diviser la taille du niveau 0 par + * 2). + * Une fois le niveau -1 créé, tous les niveaux sont "remontés" (donc le + * niveau -1 devient le niveau 0 "ground"). */ void createSubLevel() const; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h b/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h index eba5854c09..15eabd7447 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h @@ -44,6 +44,15 @@ class CartesianMeshRenumberingInfo; class ICartesianMeshInternal; class CartesianMeshPatchListView; class CartesianPatch; +class AMRZonePosition; +class AMRPatchPosition; +class AMRPatchPositionLevelGroup; +class AMRPatchPositionSignature; +class AMRPatchPositionSignatureCut; +class CartesianPatchGroup; +class ICartesianMeshAMRPatchMng; +class ICartesianMeshNumberingMngInternal; +class ICartesianMeshPatchInternal; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc index b4bd8ffd49..09b03d71d2 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.cc @@ -15,6 +15,10 @@ #include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" #include "arcane/utils/Vector2.h" +#include "arcane/utils/Vector3.h" + +#include "arcane/cartesianmesh/ICartesianMesh.h" + #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" /*---------------------------------------------------------------------------*/ @@ -29,8 +33,7 @@ namespace Arcane CartesianMeshNumberingMng:: CartesianMeshNumberingMng(ICartesianMesh* mesh) : m_internal_api(mesh->_internalApi()->cartesianMeshNumberingMngInternal()) -{ -} +{} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -423,7 +426,7 @@ faceUniqueIdToCoordZ(Face face) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueId(Integer level, Int64x3 cell_coord) const +cellUniqueId(Int64x3 cell_coord, Integer level) const { return m_internal_api->cellUniqueId(level, cell_coord); } @@ -432,7 +435,7 @@ cellUniqueId(Integer level, Int64x3 cell_coord) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -cellUniqueId(Integer level, Int64x2 cell_coord) const +cellUniqueId(Int64x2 cell_coord, Integer level) const { return m_internal_api->cellUniqueId(level, cell_coord); } @@ -441,7 +444,7 @@ cellUniqueId(Integer level, Int64x2 cell_coord) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueId(Integer level, Int64x3 node_coord) const +nodeUniqueId(Int64x3 node_coord, Integer level) const { return m_internal_api->nodeUniqueId(level, node_coord); } @@ -450,7 +453,7 @@ nodeUniqueId(Integer level, Int64x3 node_coord) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -nodeUniqueId(Integer level, Int64x2 node_coord) const +nodeUniqueId(Int64x2 node_coord, Integer level) const { return m_internal_api->nodeUniqueId(level, node_coord); } @@ -459,7 +462,7 @@ nodeUniqueId(Integer level, Int64x2 node_coord) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueId(Integer level, Int64x3 face_coord) const +faceUniqueId(Int64x3 face_coord, Integer level) const { return m_internal_api->faceUniqueId(level, face_coord); } @@ -468,7 +471,7 @@ faceUniqueId(Integer level, Int64x3 face_coord) const /*---------------------------------------------------------------------------*/ Int64 CartesianMeshNumberingMng:: -faceUniqueId(Integer level, Int64x2 face_coord) const +faceUniqueId(Int64x2 face_coord, Integer level) const { return m_internal_api->faceUniqueId(level, face_coord); } @@ -486,7 +489,7 @@ nbNodeByCell() const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const +cellNodeUniqueIds(Int64x3 cell_coord, Integer level, ArrayView uid) const { m_internal_api->cellNodeUniqueIds(uid, level, cell_coord); } @@ -495,7 +498,7 @@ cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const +cellNodeUniqueIds(Int64x2 cell_coord, Integer level, ArrayView uid) const { m_internal_api->cellNodeUniqueIds(uid, level, cell_coord); } @@ -504,7 +507,7 @@ cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const +cellNodeUniqueIds(Int64 cell_uid, Integer level, ArrayView uid) const { m_internal_api->cellNodeUniqueIds(uid, level, cell_uid); } @@ -512,6 +515,15 @@ cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshNumberingMng:: +cellNodeUniqueIds(Cell cell, ArrayView uid) const +{ + m_internal_api->cellNodeUniqueIds(uid, cell); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Integer CartesianMeshNumberingMng:: nbFaceByCell() const { @@ -522,7 +534,7 @@ nbFaceByCell() const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const +cellFaceUniqueIds(Int64x3 cell_coord, Integer level, ArrayView uid) const { m_internal_api->cellFaceUniqueIds(uid, level, cell_coord); } @@ -531,7 +543,7 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const +cellFaceUniqueIds(Int64x2 cell_coord, Integer level, ArrayView uid) const { m_internal_api->cellFaceUniqueIds(uid, level, cell_coord); } @@ -540,7 +552,7 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const +cellFaceUniqueIds(Int64 cell_uid, Integer level, ArrayView uid) const { m_internal_api->cellFaceUniqueIds(uid, level, cell_uid); } @@ -549,7 +561,34 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellUniqueIdsAroundCell(ArrayView uid, Cell cell) const +cellFaceUniqueIds(Cell cell, ArrayView uid) const +{ + m_internal_api->cellFaceUniqueIds(uid, cell); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundCell(Int64x3 cell_coord, Int32 level, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundCell(uid, cell_coord, level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundCell(Int64x2 cell_coord, Int32 level, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundCell(uid, cell_coord, level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundCell(Cell cell, ArrayView uid) const { m_internal_api->cellUniqueIdsAroundCell(uid, cell); } @@ -558,7 +597,43 @@ cellUniqueIdsAroundCell(ArrayView uid, Cell cell) const /*---------------------------------------------------------------------------*/ void CartesianMeshNumberingMng:: -cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) const +cellUniqueIdsAroundNode(Int64x3 node_coord, Int32 level, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundNode(uid, node_coord, level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundNode(Int64x2 node_coord, Int32 level, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundNode(uid, node_coord, level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundNode(Int64 node_uid, Int32 level, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundNode(uid, node_uid, level); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundNode(Node node, ArrayView uid) const +{ + m_internal_api->cellUniqueIdsAroundNode(uid, node); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void CartesianMeshNumberingMng:: +cellUniqueIdsAroundCell(Int64 cell_uid, Int32 level, ArrayView uid) const { m_internal_api->cellUniqueIdsAroundCell(uid, cell_uid, level); } diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h index 15306ee725..be2870d1f5 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshNumberingMng.h @@ -18,7 +18,9 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +#include "arcane/utils/Ref.h" #include "arcane/core/Item.h" /*---------------------------------------------------------------------------*/ @@ -35,6 +37,15 @@ class ICartesianMeshNumberingMngInternal; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +/*! + * \brief Interface de gestionnaire de numérotation pour maillage cartesian. + * + * Dans ces gestionnaires, on considère que l'on a un intervalle d'uniqueIds + * attribué à chaque niveau du maillage. + * + * \warning Le maillage ne doit pas être renuméroté si cette numérotation est + * utilisée. + */ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshNumberingMng { public: @@ -43,110 +54,951 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshNumberingMng public: + /*! + * \brief Méthode permettant de décrire l'état de l'objet. + */ void printStatus() const; + /*! + * \brief Méthode permettant de récupérer le premier unique id utilisé par les mailles d'un niveau. + * L'appel de cette méthode avec level et level+1 permet de récupérer l'intervalle des uniqueids + * d'un niveau. + * + * \param level Le niveau. + * \return Le premier uid des mailles du niveau. + */ Int64 firstCellUniqueId(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le premier unique id utilisé par les noeuds d'un niveau. + * L'appel de cette méthode avec level et level+1 permet de récupérer l'intervalle des uniqueids + * d'un niveau. + * + * \param level Le niveau. + * \return Le premier uid des noeuds du niveau. + */ Int64 firstNodeUniqueId(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le premier unique id utilisé par les faces d'un niveau. + * L'appel de cette méthode avec level et level+1 permet de récupérer l'intervalle des uniqueids + * d'un niveau. + * + * \param level Le niveau. + * \return Le premier uid des faces du niveau. + */ Int64 firstFaceUniqueId(Integer level) const; + /*! + * \brief Méthode permettant de récupérer le nombre de mailles global en X d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de mailles en X. + */ Int64 globalNbCellsX(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de mailles global en Y d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de mailles en Y. + */ Int64 globalNbCellsY(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de mailles global en Z d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de mailles en Z. + */ Int64 globalNbCellsZ(Integer level) const; + /*! + * \brief Méthode permettant de récupérer le nombre de noeuds global en X d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de noeuds en X. + */ Int64 globalNbNodesX(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de noeuds global en Y d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de noeuds en Y. + */ Int64 globalNbNodesY(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de noeuds global en Z d'un niveau. + * + * \param level Le niveau. + * \return Le nombre de noeuds en Z. + */ Int64 globalNbNodesZ(Integer level) const; + /*! + * \brief Méthode permettant de récupérer le nombre de faces global en X d'un niveau. + * + * Admettons que l'on ai les faces suivantes : + * ┌─0──┬──2─┐ + * 4│ 6│ 8│ + * ├─5──┼─7──┤ + * 9│ 11│ 13│ + * └─10─┴─12─┘ + * + * Donc, on a 2x2 mailles. + * En X, on a 3 faces. + * + * Pour le nombre de faces en vue cartésienne, voir \a globalNbFacesXCartesianView. + * + * \param level Le niveau. + * \return Le nombre de faces en X. + */ Int64 globalNbFacesX(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de faces global en Y d'un niveau. + * + * Admettons que l'on ai les faces suivantes : + * ┌─0──┬──2─┐ + * 4│ 6│ 8│ + * ├─5──┼─7──┤ + * 9│ 11│ 13│ + * └─10─┴─12─┘ + * + * Donc, on a 2x2 mailles. + * En Y, on a 3 faces. + * + * Pour le nombre de faces en vue cartésienne, voir \a globalNbFacesYCartesianView. + * + * \param level Le niveau. + * \return Le nombre de faces en Y. + */ Int64 globalNbFacesY(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de faces global en Z d'un niveau. + * + * Admettons que l'on ai les faces suivantes : + * ┌─0──┬──2─┐ + * 4│ 6│ 8│ + * ├─5──┼─7──┤ + * 9│ 11│ 13│ + * └─10─┴─12─┘ + * + * Si on a 2x2x2 mailles, on aura, en Z, 3 faces. + * + * Pour le nombre de faces en vue cartésienne, voir \a globalNbFacesZCartesianView. + * + * \param level Le niveau. + * \return Le nombre de faces en Z. + */ Int64 globalNbFacesZ(Integer level) const; + /*! + * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" + * contenant les faces. + * + * En 2D, on peut avoir cette vue (pour un maillage de 2x2 mailles) : + * x = 0 1 2 3 4 + * ┌──┬──┬──┬──┬──┐ + * y = -1 │ 0│ │ 2│ │ 4│ + * ┌──┬──┬──┬──┬──┐ + * y │ │ 1│ │ 3│ │ + * ├──┼──┼──┼──┼──┤ + * y = 1 │ 5│ │ 7│ │ 9│ + * ├──┼──┼──┼──┼──┤ + * y = 2 │ │ 6│ │ 8│ │ + * ├──┼──┼──┼──┼──┤ + * y = 3 │10│ │12│ │14│ + * ├──┼──┼──┼──┼──┤ + * y = 4 │ │11│ │13│ │ + * └──┴──┴──┴──┴──┘ + * (dans cette vue, les mailles se situent aux X et Y impaires + * (donc ici, [1, 1], [3, 1], [1, 3] et [3, 3])). + * + * \note En 2D, on considère que l'on a un niveau imaginaire y=-1. + * \warning Afin de commencer la numérotation à 0, dans les méthodes + * retournant un uniqueId de face 2D, on fait FaceUID-1. + * + * Et en 3D (pour un maillage de 2x2x2 mailles) : + * z │ z = 1 │ z = 2 │ z = 3 │ z = 4 + * x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + * ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + * y │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + * ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + * y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + * ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + * y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + * ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + * y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + * ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + * y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + * └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + * │ │ │ │ + * + * (dans cette vue, les mailles se situent aux X, Y et Z impaires + * (donc ici, [1, 1, 1], [3, 1, 1], [1, 3, 1], &c)). + * + * \param level Le niveau. + * \return La taille de la grille en X. + */ Int64 globalNbFacesXCartesianView(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" + * contenant les faces. + * + * Un exemple de cette vue est disponible dans la documentation de \a globalNbFacesXCartesianView. + * + * \param level Le niveau. + * \return La taille de la grille en Y. + */ Int64 globalNbFacesYCartesianView(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la taille de la vue "grille cartésienne" + * contenant les faces. + * + * Un exemple de cette vue est disponible dans la documentation de \a globalNbFacesXCartesianView. + * + * \param level Le niveau. + * \return La taille de la grille en Z. + */ Int64 globalNbFacesZCartesianView(Integer level) const; + /*! + * \brief Méthode permettant de récupérer le nombre de mailles total dans un niveau. + * + * \param level Le niveau. + * \return Le nombre de mailles dans le niveau. + */ Int64 nbCellInLevel(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de noeuds total dans un niveau. + * + * \param level Le niveau. + * \return Le nombre de noeuds dans le niveau. + */ Int64 nbNodeInLevel(Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de faces total dans un niveau. + * + * \param level Le niveau. + * \return Le nombre de faces dans le niveau. + */ Int64 nbFaceInLevel(Integer level) const; + /*! + * \brief Méthode permettant de récupérer le pattern de raffinement utilisé dans chaque maille. + * Par exemple, si le pattern vaut 2, chaque maille parente aura 2*2 mailles filles (2*2*2 en 3D). + * + * \return Le pattern de raffinement. + */ Integer pattern() const; + /*! + * \brief Méthode permettant de récupérer le niveau d'une maille avec son uid. + * + * \param uid L'uniqueId de la maille. + * \return Le niveau de la maille. + */ Int32 cellLevel(Int64 uid) const; + + /*! + * \brief Méthode permettant de récupérer le niveau d'un noeud avec son uid. + * + * \param uid L'uniqueId du noeud. + * \return Le niveau du noeud. + */ Int32 nodeLevel(Int64 uid) const; + + /*! + * \brief Méthode permettant de récupérer le niveau d'une face avec son uid. + * + * \param uid L'uniqueId de la face. + * \return Le niveau de la face. + */ Int32 faceLevel(Int64 uid) const; + /*! + * \brief Méthode permettant d'obtenir la position du premier noeud/maille fille à partir de la position + * du noeud/maille parent. + * + * Exemple : si l'on a un maillage 2D de 2*2 mailles et un pattern de raffinement de 2, + * on sait que la grille de niveau 1 (pour les patchs de niveau 1) sera de 4*4 mailles. + * Le premier noeud/maille fille du noeud/maille parent (Xp=1,Yp=0) aura la position Xf=Xp*Pattern=2 (idem pour Y). + * + * \param coord La position X ou Y ou Z du noeud/maille parent. + * \param level_from Le niveau parent. + * \param level_to Le niveau enfant. + * \return La position de la première fille du noeud/maille parent. + */ Int64 offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const; + + /*! + * \brief Méthode permettant d'obtenir la position de la première face enfant à partir de la position + * de la face parente. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param coord La position X ou Y ou Z de la face parente. + * \param level_from Le niveau parent. + * \param level_to Le niveau enfant. + * \return La position du premier enfant de la face parente. + */ Int64 faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'une maille grâce à son uniqueId. + * + * \param uid L'uniqueId de la maille. + * \param level Le niveau de la maille. + * \return La position en X de la maille. + */ Int64 cellUniqueIdToCoordX(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'une maille. + * + * \param cell La maille. + * \return La position en X de la maille. + */ Int64 cellUniqueIdToCoordX(Cell cell) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'une maille grâce à son uniqueId. + * + * \param uid L'uniqueId de la maille. + * \param level Le niveau de la maille. + * \return La position en Y de la maille. + */ Int64 cellUniqueIdToCoordY(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'une maille. + * + * \param cell La maille. + * \return La position en Y de la maille. + */ Int64 cellUniqueIdToCoordY(Cell cell) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'une maille grâce à son uniqueId. + * + * \param uid L'uniqueId de la maille. + * \param level Le niveau de la maille. + * \return La position en Z de la maille. + */ Int64 cellUniqueIdToCoordZ(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'une maille. + * + * \param cell La maille. + * \return La position en Z de la maille. + */ Int64 cellUniqueIdToCoordZ(Cell cell) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'un noeud grâce à son uniqueId. + * + * \param uid L'uniqueId du noeud. + * \param level Le niveau du noeud. + * \return La position en X du noeud. + */ Int64 nodeUniqueIdToCoordX(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'un noeud. + * + * \param node Le noeud. + * \return La position en X du noeud. + */ Int64 nodeUniqueIdToCoordX(Node node) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'un noeud grâce à son uniqueId. + * + * \param uid L'uniqueId du noeud. + * \param level Le niveau du noeud. + * \return La position en Y du noeud. + */ Int64 nodeUniqueIdToCoordY(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'un noeud. + * + * \param node Le noeud. + * \return La position en Y du noeud. + */ Int64 nodeUniqueIdToCoordY(Node node) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'un noeud grâce à son uniqueId. + * + * \param uid L'uniqueId du noeud. + * \param level Le niveau du noeud. + * \return La position en Z du noeud. + */ Int64 nodeUniqueIdToCoordZ(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'un noeud. + * + * \param node Le noeud. + * \return La position en Z du noeud. + */ Int64 nodeUniqueIdToCoordZ(Node node) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'une face grâce à son uniqueId. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param uid L'uniqueId de la face. + * \param level Le niveau de la face. + * \return La position en X de la face. + */ Int64 faceUniqueIdToCoordX(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en X d'une face. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param face La face. + * \return La position en X de la face. + */ Int64 faceUniqueIdToCoordX(Face face) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'une face grâce à son uniqueId. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param uid L'uniqueId de la face. + * \param level Le niveau de la face. + * \return La position en Y de la face. + */ Int64 faceUniqueIdToCoordY(Int64 uid, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer la coordonnée en Y d'une face. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param face La face. + * \return La position en Y de la face. + */ Int64 faceUniqueIdToCoordY(Face face) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'une face grâce à son uniqueId. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param uid L'uniqueId de la face. + * \param level Le niveau de la face. + * \return La position en Z de la face. + */ Int64 faceUniqueIdToCoordZ(Int64 uid, Integer level) const; - Int64 faceUniqueIdToCoordZ(Face face) const; - - Int64 cellUniqueId(Integer level, Int64x3 cell_coord) const; - Int64 cellUniqueId(Integer level, Int64x2 cell_coord) const; - Int64 nodeUniqueId(Integer level, Int64x3 node_coord) const; - Int64 nodeUniqueId(Integer level, Int64x2 node_coord) const; - - Int64 faceUniqueId(Integer level, Int64x3 face_coord) const; - Int64 faceUniqueId(Integer level, Int64x2 face_coord) const; + /*! + * \brief Méthode permettant de récupérer la coordonnée en Z d'une face. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param face La face. + * \return La position en Z de la face. + */ + Int64 faceUniqueIdToCoordZ(Face face) const; + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une maille à partir de sa position et de son niveau. + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille. + * \return L'uniqueId de la maille. + */ + Int64 cellUniqueId(Int64x3 cell_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une maille à partir de sa position et de son niveau. + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille. + * \return L'uniqueId de la maille. + */ + Int64 cellUniqueId(Int64x2 cell_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'un noeud à partir de sa position et de son niveau. + * + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + * \return L'uniqueId du noeud. + */ + Int64 nodeUniqueId(Int64x3 node_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'un noeud à partir de sa position et de son niveau. + * + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + * \return L'uniqueId du noeud. + */ + Int64 nodeUniqueId(Int64x2 node_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une face à partir de sa position et de son niveau. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param face_coord La position de la face. + * \param level Le niveau de la face. + * \return L'uniqueId de la face. + */ + Int64 faceUniqueId(Int64x3 face_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une face à partir de sa position et de son niveau. + * + * Attention, les coordonnées utilisées ici sont les coordonnées des faces en "vue cartésienne" + * (voir \a globalNbFacesXCartesianView ). + * + * \param face_coord La position de la face. + * \param level Le niveau de la face. + * \return L'uniqueId de la face. + */ + Int64 faceUniqueId(Int64x2 face_coord, Integer level) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de noeuds dans une maille. + * + * \return Le nombre de noeuds d'une maille. + */ Integer nbNodeByCell() const; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const; - void cellNodeUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const; + /*! + * \brief Méthode permettant de récupérer les uniqueIds des noeuds d'une maille à partir de + * ses coordonnées. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des noeuds + * d'une maille d'Arcane. + * 3--2 + * ^y | | + * | 0--1 + * ->x + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille (et donc des noeuds). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbNodeByCell(). + */ + void cellNodeUniqueIds(Int64x3 cell_coord, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des noeuds d'une maille à partir de + * ses coordonnées. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des noeuds + * d'une maille d'Arcane. + * 3--2 + * ^y | | + * | 0--1 + * ->x + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille (et donc des noeuds). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbNodeByCell(). + */ + void cellNodeUniqueIds(Int64x2 cell_coord, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des noeuds d'une maille à partir de + * son uniqueId. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des noeuds + * d'une maille d'Arcane. + * 3--2 + * ^y | | + * | 0--1 + * ->x + * + * \param cell_uid L'uniqueId de la maille. + * \param level Le niveau de la maille (et donc des noeuds). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbNodeByCell(). + */ + void cellNodeUniqueIds(Int64 cell_uid, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des noeuds d'une maille. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des noeuds + * d'une maille d'Arcane. + * 3--2 + * ^y | | + * | 0--1 + * ->x + * + * \param cell La maille. + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbNodeByCell(). + */ + void cellNodeUniqueIds(Cell cell, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer le nombre de faces dans une maille. + * + * \return Le nombre de faces d'une maille. + */ Integer nbFaceByCell() const; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) const; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64x2 cell_coord) const; - void cellFaceUniqueIds(ArrayView uid, Integer level, Int64 cell_uid) const; - - void cellUniqueIdsAroundCell(ArrayView uid, Int64 cell_uid, Int32 level) const; - void cellUniqueIdsAroundCell(ArrayView uid, Cell cell) const; - - Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) const; - Int64 parentCellUniqueIdOfCell(Cell cell, bool do_fatal) const; + /*! + * \brief Méthode permettant de récupérer les uniqueIds des faces d'une maille à partir de + * ses coordonnées. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des faces + * d'une maille d'Arcane. + * -2- + * ^y 3 1 + * | -0- + * ->x + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille (et donc des faces). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbFaceByCell(). + */ + void cellFaceUniqueIds(Int64x3 cell_coord, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des faces d'une maille à partir de + * ses coordonnées. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des faces + * d'une maille d'Arcane. + * -2- + * ^y 3 1 + * | -0- + * ->x + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille (et donc des faces). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbFaceByCell(). + */ + void cellFaceUniqueIds(Int64x2 cell_coord, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des faces d'une maille à partir de + * son uniqueId. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des faces + * d'une maille d'Arcane. + * -2- + * ^y 3 1 + * | -0- + * ->x + * + * \param cell_uid L'uniqueId de la maille. + * \param level Le niveau de la maille (et donc des faces). + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbFaceByCell(). + */ + void cellFaceUniqueIds(Int64 cell_uid, Integer level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des faces d'une maille. + * + * L'ordre dans lequel les uniqueIds sont placés correspond à l'ordre d'énumération des faces + * d'une maille d'Arcane. + * -2- + * ^y 3 1 + * | -0- + * ->x + * + * \param cell La maille. + * \param uid [OUT] Les uniqueIds de la maille. La taille de l'ArrayView doit être égal à nbFaceByCell(). + */ + void cellFaceUniqueIds(Cell cell, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'une maille. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 27. + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille au centre. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundCell(Int64x3 cell_coord, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'une maille. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 9. + * + * \param cell_coord La position de la maille. + * \param level Le niveau de la maille au centre. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundCell(Int64x2 cell_coord, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour de la maille passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 9 en 2D et de 27 en 3D. + * + * \param cell_uid L'uniqueId de la maille au centre. + * \param level Le niveau de la maille au centre. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundCell(Int64 cell_uid, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour de la maille passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 9 en 2D et de 27 en 3D. + * + * \param cell La maille au centre. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundCell(Cell cell, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'un noeud. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 8. + * + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundNode(Int64x3 node_coord, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour d'un noeud. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4. + * + * \param node_coord La position du noeud. + * \param level Le niveau du noeud. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundNode(Int64x2 node_coord, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour du noeud passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4 en 2D ou de 8 en 3D. + * + * \param node_uid L'uniqueId du noeud. + * \param level Le niveau du noeud. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundNode(Int64 node_uid, Int32 level, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer les uniqueIds des mailles autour du noeud passée + * en paramètre. + * + * S'il n'y a pas de maille à un endroit autour (si on est au bord du maillage par exemple), + * on met un uniqueId = -1. + * + * La vue passée en paramètre doit faire une taille de 4 en 2D ou de 8 en 3D. + * + * \param node Le noeud. + * \param uid [OUT] Les uniqueIds des mailles autour. + */ + void cellUniqueIdsAroundNode(Node node, ArrayView uid) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'une maille. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param uid L'uniqueId de la maille enfant. + * \param level Le niveau de la maille enfant. + * \return L'uniqueId de la maille parent de la maille passé en paramètre. + */ + Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'une maille. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param cell La maille enfant. + * \return L'uniqueId de la maille parent de la maille passé en paramètre. + */ + Int64 parentCellUniqueIdOfCell(Cell cell, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une maille enfant d'une maille parent + * à partir de la position de la maille enfant dans la maille parent. + * + * \param cell La maille parent. + * \param child_coord_in_parent La position de l'enfant dans la maille parent. + * \return L'uniqueId de la maille enfant demandée. + */ Int64 childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une maille enfant d'une maille parent + * à partir de la position de la maille enfant dans la maille parent. + * + * \param cell La maille parent. + * \param child_coord_in_parent La position de l'enfant dans la maille parent. + * \return L'uniqueId de la maille enfant demandée. + */ Int64 childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une maille enfant d'une maille parent + * à partir de l'index de la maille enfant dans la maille parent. + * + * \param cell La maille parent. + * \param child_index_in_parent L'index de l'enfant dans la maille parent. + * \return L'uniqueId de la maille enfant demandée. + */ Int64 childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent) const; + /*! + * \brief Méthode permettant de récupérer une maille enfant d'une maille parent + * à partir de la position de la maille enfant dans la maille parent. + * + * \param cell La maille parent. + * \param child_coord_in_parent La position de l'enfant dans la maille parent. + * \return La maille enfant demandée. + */ Cell childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) const; - Cell childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) const; - Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) const; - Int64 parentNodeUniqueIdOfNode(Node node, bool do_fatal) const; + /*! + * \brief Méthode permettant de récupérer une maille enfant d'une maille parent + * à partir de la position de la maille enfant dans la maille parent. + * + * \param cell La maille parent. + * \param child_coord_in_parent La position de l'enfant dans la maille parent. + * \return La maille enfant demandée. + */ + Cell childCellOfCell(Cell cell, Int64x2 child_coord_in_parent) const; + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'un noeud. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param uid L'uniqueId du noeud enfant. + * \param level Le niveau du noeud enfant. + * \return L'uniqueId du noeud parent du noeud enfant. + */ + Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'un noeud. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param node Le noeud enfant. + * \return L'uniqueId du noeud parent du noeud passé en paramètre. + */ + Int64 parentNodeUniqueIdOfNode(Node node, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'un noeud enfant d'un noeud parent. + * + * \param uid L'uniqueId du noeud enfant. + * \param level Le niveau du noeud enfant. + * \return L'uniqueId du noeud enfant demandée. + */ Int64 childNodeUniqueIdOfNode(Int64 uid, Integer level) const; - Int64 childNodeUniqueIdOfNode(Node node) const; - Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) const; - Int64 parentFaceUniqueIdOfFace(Face face, bool do_fatal) const; + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'un noeud enfant d'un noeud parent. + * + * \param node Le noeud parent. + * \return L'uniqueId du noeud enfant demandée. + */ + Int64 childNodeUniqueIdOfNode(Node node) const; + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'une face. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param uid L'uniqueId de la face enfant. + * \param level Le niveau de la face enfant. + * \return L'uniqueId de la face parent de la face enfant. + */ + Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId du parent d'une face. + * + * Si \a do_fatal est vrai, une erreur fatale est générée si le parent n'existe + * pas, sinon l'uniqueId retourné a pour valeur NULL_ITEM_UNIQUE_ID. + * + * \param face La face enfant. + * \return L'uniqueId de la face parent de la face passé en paramètre. + */ + Int64 parentFaceUniqueIdOfFace(Face face, bool do_fatal = true) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une face enfant d'une face parent + * à partir de l'index de la face enfant dans la face parent. + * + * \param uid L'uniqueId de la face parent. + * \param level Le niveau de la face parent. + * \param child_index_in_parent L'index de l'enfant dans la face parent. + * \return L'uniqueId de la face enfant demandée. + */ Int64 childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) const; + + /*! + * \brief Méthode permettant de récupérer l'uniqueId d'une face enfant d'une face parent + * à partir de l'index de la face enfant dans la face parent. + * + * \param face La face parent. + * \param child_index_in_parent L'index de l'enfant dans la face parent. + * \return L'uniqueId de la face enfant demandée. + */ Int64 childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent) const; public: diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.h b/arcane/src/arcane/cartesianmesh/CartesianPatch.h index baad22ea81..a805174c5c 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.h +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.h @@ -51,11 +51,24 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch public: - //! Groupe de mailles du patch + //! Groupe de mailles du patch (incluant les mailles de recouvrement). CellGroup cells(); + + /*! + * \brief Groupe de mailles du patch (sans les mailles de recouvrement). + * + * Valide uniquement avec l'AMR type 3 (PatchCartesianMeshOnly). + */ CellGroup inPatchCells(); + //! Index du patch dans le tableau des patchs. Integer index() const; + + /*! + * \brief Niveau du patch. + * + * Valide uniquement avec l'AMR type 3 (PatchCartesianMeshOnly). + */ Integer level() const { ARCANE_CHECK_POINTER(m_patch); @@ -111,6 +124,12 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatch m_patch->checkValid(); } + /*! + * \brief Méthode permettant de récupérer la position du patch dans le + * maillage cartesien. + * + * \return Une copie de la position. + */ AMRPatchPosition position() const { ARCANE_CHECK_POINTER(m_patch); diff --git a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h index 9092ca7295..2bd5138800 100644 --- a/arcane/src/arcane/cartesianmesh/ICartesianMesh.h +++ b/arcane/src/arcane/cartesianmesh/ICartesianMesh.h @@ -14,7 +14,6 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRZonePosition.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" #include "arcane/core/ArcaneTypes.h" @@ -28,6 +27,7 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + /*! * \ingroup ArcaneCartesianMesh * \brief Interface d'un maillage cartésien. @@ -89,7 +89,6 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * - les informations de direction sont invalidées si le maillage évolue. */ virtual void computeDirections() = 0; - virtual void computeDirectionsV2() = 0; /*! * \brief Recalcule les informations de cartésiennes après une reprise. @@ -127,14 +126,14 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * L'instance retournée reste valide tant que cette instance n'est pas détruite. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::amrPatch() à la place. */ virtual CartesianPatch amrPatch(Int32 index) const = 0; /*! * \brief Vue sur la liste des patchs. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::amrPatch() à la place. */ virtual CartesianMeshPatchListView patches() const = 0; @@ -150,7 +149,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::refineZone() à la place. */ virtual void refinePatch2D(Real2 position, Real2 length) = 0; @@ -166,7 +165,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::refineZone() à la place. */ virtual void refinePatch3D(Real3 position, Real3 length) = 0; @@ -182,7 +181,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::refineZone() à la place. */ virtual void refinePatch(const AMRZonePosition& position) = 0; @@ -204,7 +203,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::coarseZone2D() à la place. */ virtual void coarseZone2D(Real2 position, Real2 length) = 0; @@ -226,7 +225,7 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::coarseZone2D() à la place. */ virtual void coarseZone3D(Real3 position, Real3 length) = 0; @@ -248,13 +247,10 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * Cette opération est collective. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::coarseZone2D() à la place. */ virtual void coarseZone(const AMRZonePosition& position) = 0; - // TODO A suppr - virtual void refine() = 0; - /*! * \brief Méthode permettant de supprimer une ou plusieurs couches * de mailles fantômes sur un niveau de raffinement défini. @@ -271,13 +267,10 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMesh * * \return Le nombre de couches de mailles fantômes final. * - * \deprecated Utiliser CartesianMeshAMRMng à la place. + * \deprecated Utiliser CartesianMeshAMRMng::reduceNbGhostLayers() à la place. */ virtual Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) = 0; - // TODO A suppr - virtual void mergePatches() = 0; - /*! * \brief Renumérote les uniqueId() des entités. * diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc index 68b1bb7da2..05bf8247d2 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.cc @@ -5,13 +5,16 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionLevelGroup.cc (C) 2000-2025 */ +/* AMRPatchPositionLevelGroup.cc (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Groupe de position de patch AMR réparti par niveau. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ #include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" + +#include "arcane/cartesianmesh/AMRPatchPosition.h" + #include /*---------------------------------------------------------------------------*/ @@ -117,9 +120,8 @@ fusionPatches(UniqueArray& patch_position, bool remove_null) // << " -- 1 Min point : " << patch_fusion_1.minPoint() // << " -- 1 Max point : " << patch_fusion_1.maxPoint() // << " -- 1 Level : " << patch_fusion_1.level(); - if (patch_fusion_0.canBeFusion(patch_fusion_1)) { + if (patch_fusion_0.fusion(patch_fusion_1)) { // m_cmesh->traceMng()->info() << "Fusion OK"; - patch_fusion_0.fusion(patch_fusion_1); patch_fusion_1.setLevel(-2); // Devient null. fusion = true; break; diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h index 9e32e71f15..d6d0ac018c 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h @@ -5,16 +5,15 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionLevelGroup.h (C) 2000-2025 */ +/* AMRPatchPositionLevelGroup.h (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Groupe de position de patch AMR réparti par niveau. */ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONLEVELGROUP_H -#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONLEVELGROUP_H +#ifndef ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONLEVELGROUP_H +#define ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONLEVELGROUP_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" #include "arcane/utils/UniqueArray.h" @@ -31,7 +30,8 @@ namespace Arcane class AMRPatchPositionLevelGroup { public: - AMRPatchPositionLevelGroup(Integer max_level); + + explicit AMRPatchPositionLevelGroup(Integer max_level); ~AMRPatchPositionLevelGroup(); public: @@ -43,6 +43,7 @@ class AMRPatchPositionLevelGroup static void fusionPatches(UniqueArray& patch_position, bool remove_null); private: + Integer m_max_level; UniqueArray> m_patches; }; @@ -55,5 +56,4 @@ class AMRPatchPositionLevelGroup /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif - +#endif diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc index 6d35cbdfa3..1a6874c827 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc @@ -5,22 +5,28 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionSignature.cc (C) 2000-2025 */ +/* AMRPatchPositionSignature.cc (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Calcul des signatures d'une position de patch. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ #include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" -#include "arcane/cartesianmesh/ICartesianMesh.h" +#include "arcane/utils/FatalErrorException.h" +#include "arcane/utils/ITraceMng.h" +#include "arcane/utils/Math.h" + #include "arcane/core/ArcaneTypes.h" #include "arcane/core/IMesh.h" #include "arcane/core/IParallelMng.h" #include "arcane/core/ItemEnumerator.h" -#include "arcane/utils/FatalErrorException.h" -#include "arcane/utils/ITraceMng.h" +#include "arcane/core/ItemGroup.h" + +#include "arcane/cartesianmesh/ICartesianMesh.h" + #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h index c5ce182ddf..8adf03ccd6 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.h @@ -5,23 +5,21 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionSignature.h (C) 2000-2025 */ +/* AMRPatchPositionSignature.h (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Calcul des signatures d'une position de patch. */ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURE_H -#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURE_H +#ifndef ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONSIGNATURE_H +#define ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONSIGNATURE_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" -#include "arcane/cartesianmesh/AMRPatchPosition.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" -#include "arcane/utils/Vector3.h" #include "arcane/utils/UniqueArray.h" +#include "arcane/cartesianmesh/AMRPatchPosition.h" + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -34,12 +32,14 @@ namespace Arcane class AMRPatchPositionSignature { public: + AMRPatchPositionSignature(); AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches); AMRPatchPositionSignature(AMRPatchPosition patch, ICartesianMesh* cmesh, AMRPatchPositionLevelGroup* all_patches, Integer nb_cut); ~AMRPatchPositionSignature(); public: + void compress(); void fillSig(); bool isValid() const; @@ -49,15 +49,14 @@ class AMRPatchPositionSignature std::pair cut(Integer dim, Integer cut_point) const; bool isIn(Integer x, Integer y, Integer z) const; - ConstArrayView sigX()const; - ConstArrayView sigY()const; + ConstArrayView sigX() const; + ConstArrayView sigY() const; ConstArrayView sigZ() const; - AMRPatchPosition patch()const; + AMRPatchPosition patch() const; ICartesianMesh* mesh() const; - bool stopCut()const; + bool stopCut() const; void setStopCut(bool stop_cut); - bool isComputed()const; - + bool isComputed() const; private: @@ -87,5 +86,4 @@ class AMRPatchPositionSignature /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif - +#endif diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc index af1ba7bea4..0f323b53ed 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.cc @@ -5,18 +5,22 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionSignatureCut.cc (C) 2000-2025 */ +/* AMRPatchPositionSignatureCut.cc (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Méthodes de découpages de patchs selon leurs signatures. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ #include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h" -#include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/core/IMesh.h" #include "arcane/utils/FatalErrorException.h" -#include "arcane/utils/ITraceMng.h" +#include "arcane/utils/Math.h" + +#include "arcane/core/IMesh.h" + +#include "arcane/cartesianmesh/ICartesianMesh.h" + +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -129,79 +133,79 @@ cut(const AMRPatchPositionSignature& sig) Real x_efficacity = 0; auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); { - sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; fst_x.compute(); snd_x.compute(); if (fst_x.isValid() && snd_x.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" - << " -- min = " << fst_x.patch().minPoint() - << " -- max = " << fst_x.patch().maxPoint() - << " -- efficacity : " << fst_x.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" - << " -- min = " << snd_x.patch().minPoint() - << " -- max = " << snd_x.patch().maxPoint() - << " -- efficacity : " << snd_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" + // << " -- min = " << fst_x.patch().minPoint() + // << " -- max = " << fst_x.patch().maxPoint() + // << " -- efficacity : " << fst_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" + // << " -- min = " << snd_x.patch().minPoint() + // << " -- max = " << snd_x.patch().maxPoint() + // << " -- efficacity : " << snd_x.efficacity(); x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // } } Real y_efficacity = 0; auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; fst_y.compute(); snd_y.compute(); if (fst_y.isValid() && snd_y.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" - << " -- min = " << fst_y.patch().minPoint() - << " -- max = " << fst_y.patch().maxPoint() - << " -- efficacity : " << fst_y.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" - << " -- min = " << snd_y.patch().minPoint() - << " -- max = " << snd_y.patch().maxPoint() - << " -- efficacity : " << snd_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" + // << " -- min = " << fst_y.patch().minPoint() + // << " -- max = " << fst_y.patch().maxPoint() + // << " -- efficacity : " << fst_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" + // << " -- min = " << snd_y.patch().minPoint() + // << " -- max = " << snd_y.patch().maxPoint() + // << " -- efficacity : " << snd_y.efficacity(); y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // } } Real z_efficacity = 0; auto [fst_z, snd_z] = sig.cut(MD_DirZ, cut_point_z); { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; fst_z.compute(); snd_z.compute(); if (fst_z.isValid() && snd_z.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- Z.fst_z" - << " -- min = " << fst_z.patch().minPoint() - << " -- max = " << fst_z.patch().maxPoint() - << " -- efficacity : " << fst_z.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- Z.snd_z" - << " -- min = " << snd_z.patch().minPoint() - << " -- max = " << snd_z.patch().maxPoint() - << " -- efficacity : " << snd_z.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Z.fst_z" + // << " -- min = " << fst_z.patch().minPoint() + // << " -- max = " << fst_z.patch().maxPoint() + // << " -- efficacity : " << fst_z.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Z.snd_z" + // << " -- min = " << snd_z.patch().minPoint() + // << " -- max = " << snd_z.patch().maxPoint() + // << " -- efficacity : " << snd_z.efficacity(); z_efficacity = (fst_z.efficacity() + snd_z.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + // } } if (sig.efficacity() > x_efficacity && sig.efficacity() > y_efficacity && sig.efficacity() > z_efficacity) { @@ -224,53 +228,53 @@ cut(const AMRPatchPositionSignature& sig) Real x_efficacity = 0; auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); { - sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; fst_x.compute(); snd_x.compute(); if (fst_x.isValid() && snd_x.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" - << " -- min = " << fst_x.patch().minPoint() - << " -- max = " << fst_x.patch().maxPoint() - << " -- efficacity : " << fst_x.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" - << " -- min = " << snd_x.patch().minPoint() - << " -- max = " << snd_x.patch().maxPoint() - << " -- efficacity : " << snd_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- X.fst_x" + // << " -- min = " << fst_x.patch().minPoint() + // << " -- max = " << fst_x.patch().maxPoint() + // << " -- efficacity : " << fst_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- X.snd_x" + // << " -- min = " << snd_x.patch().minPoint() + // << " -- max = " << snd_x.patch().maxPoint() + // << " -- efficacity : " << snd_x.efficacity(); x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // } } Real y_efficacity = 0; auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; fst_y.compute(); snd_y.compute(); if (fst_y.isValid() && snd_y.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" - << " -- min = " << fst_y.patch().minPoint() - << " -- max = " << fst_y.patch().maxPoint() - << " -- efficacity : " << fst_y.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" - << " -- min = " << snd_y.patch().minPoint() - << " -- max = " << snd_y.patch().maxPoint() - << " -- efficacity : " << snd_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Y.fst_y" + // << " -- min = " << fst_y.patch().minPoint() + // << " -- max = " << fst_y.patch().maxPoint() + // << " -- efficacity : " << fst_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- Y.snd_y" + // << " -- min = " << snd_y.patch().minPoint() + // << " -- max = " << snd_y.patch().maxPoint() + // << " -- efficacity : " << snd_y.efficacity(); y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // } } if (sig.efficacity() > x_efficacity && sig.efficacity() > y_efficacity) { @@ -290,20 +294,20 @@ cut(const AMRPatchPositionSignature& sig) Real x_efficacity = 0; auto [fst_x, snd_x] = sig.cut(MD_DirX, cut_point_x); - sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X -- Cut Point : " << cut_point_x; fst_x.compute(); snd_x.compute(); if (fst_x.isValid() && snd_x.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.fst_x : " << fst_x.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.snd_x : " << snd_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.fst_x : " << fst_x.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity X.snd_x : " << snd_x.efficacity(); x_efficacity = (fst_x.efficacity() + snd_x.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity X : " << x_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute X invalid (too small) -- fst_x.length() : " << fst_x.patch().length() << " -- snd_x.length() : " << snd_x.patch().length(); + // } if (sig.efficacity() > x_efficacity) { return {}; } @@ -314,20 +318,20 @@ cut(const AMRPatchPositionSignature& sig) Real y_efficacity = 0; auto [fst_y, snd_y] = sig.cut(MD_DirY, cut_point_y); - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y -- Cut Point : " << cut_point_y; fst_y.compute(); snd_y.compute(); if (fst_y.isValid() && snd_y.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.fst_y : " << fst_y.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.snd_y : " << snd_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.fst_y : " << fst_y.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y.snd_y : " << snd_y.efficacity(); y_efficacity = (fst_y.efficacity() + snd_y.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Y : " << y_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Y invalid (too small) -- fst_y.length() : " << fst_y.patch().length() << " -- snd_y.length() : " << snd_y.patch().length(); + // } if (sig.efficacity() > y_efficacity) { return {}; } @@ -337,20 +341,20 @@ cut(const AMRPatchPositionSignature& sig) Real z_efficacity = 0; auto [fst_z, snd_z] = sig.cut(MD_DirZ, cut_point_z); - sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Z -- Cut Point : " << cut_point_z; fst_z.compute(); snd_z.compute(); if (fst_z.isValid() && snd_z.isValid()) { - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.fst_z : " << fst_z.efficacity(); - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.snd_z : " << snd_z.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.fst_z : " << fst_z.efficacity(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z.snd_z : " << snd_z.efficacity(); z_efficacity = (fst_z.efficacity() + snd_z.efficacity()) / 2; - sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; - } - else { - sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + // sig.mesh()->traceMng()->info() << "Cut() -- efficacity Z : " << z_efficacity; } + // else { + // sig.mesh()->traceMng()->info() << "Cut() -- Compute Z invalid (too small) -- fst_z.length() : " << fst_z.patch().length() << " -- snd_z.length() : " << snd_z.patch().length(); + // } if (sig.efficacity() > z_efficacity) { return {}; } @@ -374,7 +378,7 @@ cut(UniqueArray& sig_array_a) for (Integer i = 0; i < array_in.size(); ++i) { AMRPatchPositionSignature sig = array_in[i]; - sig.mesh()->traceMng()->info() << "Cut() -- i : " << i; + // sig.mesh()->traceMng()->info() << "Cut() -- i : " << i; if (!sig.stopCut()) { if (!sig.isComputed()) { @@ -387,21 +391,21 @@ cut(UniqueArray& sig_array_a) need_cut = true; array_out.add(fst); array_out.add(snd); - sig.mesh()->traceMng()->info() << "First Signature :"; - sig.mesh()->traceMng()->info() << "\tmin = " << fst.patch().minPoint() << " -- max = " << fst.patch().maxPoint() << " -- length = " << fst.patch().length(); - sig.mesh()->traceMng()->info() << "Second Signature :"; - sig.mesh()->traceMng()->info() << "\tmin = " << snd.patch().minPoint() << " -- max = " << snd.patch().maxPoint() << " -- length = " << snd.patch().length(); + // sig.mesh()->traceMng()->info() << "First Signature :"; + // sig.mesh()->traceMng()->info() << "\tmin = " << fst.patch().minPoint() << " -- max = " << fst.patch().maxPoint() << " -- length = " << fst.patch().length(); + // sig.mesh()->traceMng()->info() << "Second Signature :"; + // sig.mesh()->traceMng()->info() << "\tmin = " << snd.patch().minPoint() << " -- max = " << snd.patch().maxPoint() << " -- length = " << snd.patch().length(); continue; } - sig.mesh()->traceMng()->info() << "Invalid Signature"; + // sig.mesh()->traceMng()->info() << "Invalid Signature"; sig.setStopCut(true); } else { sig.setStopCut(true); } } - sig.mesh()->traceMng()->info() << "No Update"; - sig.mesh()->traceMng()->info() << "\tmin = " << sig.patch().minPoint() << " -- max = " << sig.patch().maxPoint(); + // sig.mesh()->traceMng()->info() << "No Update"; + // sig.mesh()->traceMng()->info() << "\tmin = " << sig.patch().minPoint() << " -- max = " << sig.patch().maxPoint(); array_out.add(sig); } array_in.clear(); diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h index a72aae992a..d0520ab117 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h @@ -5,20 +5,16 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* AMRPatchPositionSignatureCut.h (C) 2000-2025 */ +/* AMRPatchPositionSignatureCut.h (C) 2000-2025 */ /* */ -/* Informations sur un patch AMR d'un maillage cartésien. */ +/* Méthodes de découpages de patchs selon leurs signatures. */ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURECUT_H -#define ARCANE_CARTESIANMESH_AMRPATCHPOSITIONSIGNATURECUT_H +#ifndef ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONSIGNATURECUT_H +#define ARCANE_CARTESIANMESH_INTERNAL_AMRPATCHPOSITIONSIGNATURECUT_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" -#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" #include "arcane/cartesianmesh/CartesianMeshGlobal.h" - #include "arcane/utils/UniqueArray.h" /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc index adc0d34bc7..8481bf2a59 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.cc @@ -13,14 +13,11 @@ #include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h" -#include "arcane/cartesianmesh/CellDirectionMng.h" -#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" - #include "arcane/utils/Array2View.h" #include "arcane/utils/Array3View.h" #include "arcane/utils/FixedArray.h" #include "arcane/utils/Vector2.h" +#include "arcane/utils/Vector3.h" #include "arcane/core/IGhostLayerMng.h" #include "arcane/core/IMesh.h" @@ -30,6 +27,12 @@ #include "arcane/core/IMeshModifier.h" #include "arcane/core/materials/IMeshMaterialMng.h" +#include "arcane/cartesianmesh/CellDirectionMng.h" +#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" + +#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h index 5954cd5372..ed977f4a18 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h @@ -11,18 +11,22 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_CARTESIANMESHAMRPATCHMNG_H -#define ARCANE_CARTESIANMESH_CARTESIANMESHAMRPATCHMNG_H +#ifndef ARCANE_CARTESIANMESH_INTERNAL_CARTESIANMESHAMRPATCHMNG_H +#define ARCANE_CARTESIANMESH_INTERNAL_CARTESIANMESHAMRPATCHMNG_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h" -#include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" #include "arcane/utils/TraceAccessor.h" +#include "arcane/core/IMesh.h" + +#include "arcane/cartesianmesh/internal/ICartesianMeshAMRPatchMng.h" + +#include + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc index db04c7e96d..e0b20c7f93 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshNumberingMngInternal.cc (C) 2000-2025 */ +/* CartesianMeshNumberingMngInternal.cc (C) 2000-2025 */ /* */ /* Gestionnaire de numérotation de maillage cartesian. La numérotation */ /* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h index 5a9102c1c5..700d41b727 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshNumberingMngInternal.h (C) 2000-2025 */ +/* CartesianMeshNumberingMngInternal.h (C) 2000-2025 */ /* */ /* Gestionnaire de numérotation de maillage cartesian. La numérotation */ /* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc index e3885526ba..c133ef07c1 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc @@ -12,22 +12,22 @@ #include "arcane/cartesianmesh/internal/CartesianPatchGroup.h" -#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" -#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" -#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h" -#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" - -#include "arcane/utils/ITraceMng.h" #include "arcane/utils/FixedArray.h" #include "arcane/utils/Vector3.h" +#include "arcane/utils/StringBuilder.h" #include "arcane/core/IMesh.h" #include "arcane/core/IParallelMng.h" #include "arcane/core/MeshKind.h" +#include "arcane/cartesianmesh/ICartesianMesh.h" + #include "arcane/cartesianmesh/internal/CartesianMeshPatch.h" #include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h" -#include "arcane/utils/StringBuilder.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h" +#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h" +#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -478,9 +478,8 @@ mergePatches() // << " -- 1 Max point : " << patch_fusion_1.maxPoint() // << " -- 1 Level : " << patch_fusion_1.level(); - if (patch_fusion_0.canBeFusion(patch_fusion_1)) { + if (patch_fusion_0.fusion(patch_fusion_1)) { // m_cmesh->traceMng()->info() << "Fusion OK"; - patch_fusion_0.fusion(patch_fusion_1); patch_fusion_1.setLevel(-2); // Devient null. index_n_nb_cells[p0].second = patch_fusion_0.nbCells(); @@ -503,7 +502,7 @@ mergePatches() /*---------------------------------------------------------------------------*/ void CartesianPatchGroup:: -refine() +refine(bool clear_refine_flag) { if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); @@ -639,12 +638,7 @@ refine() { - constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine | - ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined | - ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive); - ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { - icell->mutableItemBase().removeFlags(flags_to_remove); - } + clearRefineRelatedFlags(); } _removeAllPatches(); @@ -792,10 +786,12 @@ refine() } m_cmesh->computeDirections(); - { - constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine); + if (clear_refine_flag) { ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { - icell->mutableItemBase().removeFlags(flags_to_remove); + if (icell->hasFlags(ItemFlags::II_Coarsen)) { + ARCANE_FATAL("Pas normal"); + } + icell->mutableItemBase().removeFlags(ItemFlags::II_Refine); } } @@ -815,6 +811,20 @@ refine() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +clearRefineRelatedFlags() const +{ + constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine | + ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined | + ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive); + ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) { + icell->mutableItemBase().removeFlags(flags_to_remove); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: rebuildAvailableGroupIndex(ConstArrayView available_group_index) { @@ -1187,8 +1197,8 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) if (m_cmesh->mesh()->dimension() == 2) { min_point_of_patch_to_exclude.z = 0; } - m_cmesh->traceMng()->info() << "Nb of new patch before fusion : " << new_patch_out.size(); - m_cmesh->traceMng()->info() << "min_point_of_patch_to_exclude : " << min_point_of_patch_to_exclude; + // m_cmesh->traceMng()->info() << "Nb of new patch before fusion : " << new_patch_out.size(); + // m_cmesh->traceMng()->info() << "min_point_of_patch_to_exclude : " << min_point_of_patch_to_exclude; // On met à null le patch représentant le bout de patch à retirer. for (AMRPatchPosition& new_patch : new_patch_out) { @@ -1211,7 +1221,7 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) d_nb_patch_final++; } } - m_cmesh->traceMng()->info() << "Nb of new patch after fusion : " << d_nb_patch_final; + // m_cmesh->traceMng()->info() << "Nb of new patch after fusion : " << d_nb_patch_final; } removePatch(index_patch); diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h index 4ff715e468..93117f2416 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h @@ -14,11 +14,10 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/core/ItemTypes.h" -#include "arcane/cartesianmesh/ICartesianMeshPatch.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" + +#include "arcane/utils/UniqueArray.h" #include "arcane/cartesianmesh/CartesianMeshPatchListView.h" -#include "arcane/cartesianmesh/ICartesianMesh.h" -#include "arcane/core/ItemGroupComputeFunctor.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -72,7 +71,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup void mergePatches(); - void refine(); + void refine(bool clear_refine_flag); + + void clearRefineRelatedFlags() const; void rebuildAvailableGroupIndex(ConstArrayView available_group_index); diff --git a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h index d98ec99d6c..67e165a31d 100644 --- a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshInternal.h @@ -27,6 +27,12 @@ namespace Arcane /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + +class CartesianPatchGroup; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + /*! * \internal * \brief Partie interne de ICartesianMesh. @@ -63,11 +69,20 @@ class ARCANE_CARTESIANMESH_EXPORT ICartesianMeshInternal */ virtual Ref cartesianMeshAMRPatchMng() = 0; - // TODO + /*! + * \brief Méthode permettant de créer une instance de CartesianMeshNumberingMngInternal. + */ virtual void initCartesianMeshNumberingMngInternal() = 0; - //TODO + /*! + * \brief Méthode permettant de récupérer l'instance de CartesianMeshNumberingMngInternal. + */ virtual Ref cartesianMeshNumberingMngInternal() = 0; + + /*! + * \brief Méthode permettant de récupérer le CartesianPatchGroup. + */ + virtual CartesianPatchGroup& cartesianPatchGroup() = 0; }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h index c949c35c89..79340f131f 100644 --- a/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/ICartesianMeshPatchInternal.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* ICartesianMeshPatchInternal.h (C) 2000-2025 */ +/* ICartesianMeshPatchInternal.h (C) 2000-2025 */ /* */ /* Informations sur un patch AMR d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ @@ -14,9 +14,7 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/cartesianmesh/AMRPatchPosition.h" -#include "arcane/core/ItemTypes.h" -#include "arcane/core/VariableTypes.h" +#include "arcane/cartesianmesh/CartesianMeshGlobal.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ From a4d7f266f0e48c9ab7606194d137567bcdf9ec1d Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Thu, 4 Dec 2025 17:14:24 +0100 Subject: [PATCH 15/19] [arcane:cartesianmesh] Fix errors in connectivity computing --- .../cartesianmesh/CartesianConnectivity.cc | 4 +-- .../src/arcane/cartesianmesh/CartesianMesh.cc | 25 ++++++------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc index 3bbaeaafd1..a74b59bd13 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc @@ -224,7 +224,7 @@ _computeInfos2D(ICartesianMesh* cmesh) Node node = cell.node(i); Integer pos = 0; for (; pos < nb_node_in_cell_max; ++pos) { - if (cell.uniqueId() == av_nodes_in_cell[pos]) + if (node.uniqueId() == av_nodes_in_cell[pos]) break; } if (pos == nb_node_in_cell_max) @@ -416,7 +416,7 @@ _computeInfos3D(ICartesianMesh* cmesh) Node node = cell.node(i); Integer pos = 0; for (; pos < nb_node_in_cell_max; ++pos) { - if (cell.uniqueId() == av_nodes_in_cell[pos]) + if (node.uniqueId() == av_nodes_in_cell[pos]) break; } if (pos == nb_node_in_cell_max) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc index 2b2716462f..518b963fc8 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMesh.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMesh.cc @@ -788,8 +788,9 @@ _computeDirectionsV2() _computeMeshDirectionV2(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes); } - if (arcaneIsCheck()) - checkValid(); + // TODO : Voir pour modifier cette méthode. + // if (arcaneIsCheck()) + // checkValid(); _saveInfosInProperties(); } @@ -834,35 +835,24 @@ _computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup a // Positionne pour chaque maille les faces avant et après dans la direction. // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante std::set cells_set; - ENUMERATE_CELL (icell, all_cells) { + ENUMERATE_ (Cell, icell, all_cells) { cells_set.insert(icell.itemLocalId()); } // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles // soient de même niveau - ENUMERATE_CELL (icell, all_cells) { + ENUMERATE_ (Cell, icell, all_cells) { Cell cell = *icell; Int32 my_level = cell.level(); Face next_face = cell.face(next_local_face); Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell(); - if (cells_set.find(next_cell.localId()) == cells_set.end()) { - if (next_cell.level() != my_level) { - next_cell = Cell(); - } - } - else if (next_cell.level() != my_level) { + if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) { next_cell = Cell(); } Face prev_face = cell.face(prev_local_face); Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell(); - - if (cells_set.find(prev_cell.localId()) == cells_set.end()) { - if (prev_cell.level() != my_level) { - prev_cell = Cell(); - } - } - else if (prev_cell.level() != my_level) { + if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) { prev_cell = Cell(); } @@ -1227,7 +1217,6 @@ _applyCoarse(const AMRZonePosition& zone_position) void CartesianMeshImpl:: checkValid() const { - //return; // TODO : Modification des outers à prendre en compte. info(4) << "Check valid CartesianMesh"; Integer nb_patch = nbPatch(); for( Integer i=0; i Date: Thu, 4 Dec 2025 17:16:21 +0100 Subject: [PATCH 16/19] [arcane:cartesianmesh,tests] Change 3D numbering order And update hashes for faceUID checking. --- ...rtesianMesh2D-PatchCartesianMeshOnly-1.arc | 8 +- ...rtesianMesh2D-PatchCartesianMeshOnly-2.arc | 8 +- ...rtesianMesh2D-PatchCartesianMeshOnly-3.arc | 8 +- ...rtesianMesh2D-PatchCartesianMeshOnly-4.arc | 8 +- ...rtesianMesh2D-PatchCartesianMeshOnly-5.arc | 7 +- ...2D-PatchCartesianMeshOnly-CoarseZone-1.arc | 7 +- ...2D-PatchCartesianMeshOnly-CoarseZone-2.arc | 7 +- ...InitialCoarse-PatchCartesianMeshOnly-1.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-2.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-3.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-4.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-5.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-6.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-7.arc | 8 +- ...InitialCoarse-PatchCartesianMeshOnly-8.arc | 7 +- ...se-PatchCartesianMeshOnly-CoarseZone-1.arc | 7 +- ...rtesianMesh3D-PatchCartesianMeshOnly-1.arc | 2 +- ...rtesianMesh3D-PatchCartesianMeshOnly-2.arc | 2 +- ...rtesianMesh3D-PatchCartesianMeshOnly-3.arc | 2 +- ...rtesianMesh3D-PatchCartesianMeshOnly-4.arc | 4 +- ...3D-PatchCartesianMeshOnly-CoarseZone-1.arc | 4 +- ...3D-PatchCartesianMeshOnly-CoarseZone-2.arc | 4 +- ...3D-PatchCartesianMeshOnly-CoarseZone-3.arc | 4 +- ...3D-PatchCartesianMeshOnly-CoarseZone-4.arc | 4 +- ...InitialCoarse-PatchCartesianMeshOnly-1.arc | 2 +- ...InitialCoarse-PatchCartesianMeshOnly-2.arc | 2 +- ...InitialCoarse-PatchCartesianMeshOnly-3.arc | 2 +- ...InitialCoarse-PatchCartesianMeshOnly-4.arc | 4 +- ...InitialCoarse-PatchCartesianMeshOnly-5.arc | 4 +- ...InitialCoarse-PatchCartesianMeshOnly-6.arc | 4 +- ...se-PatchCartesianMeshOnly-CoarseZone-1.arc | 4 +- .../CartesianMeshNumberingMngInternal.cc | 261 +++++++++--------- .../CartesianMeshNumberingMngInternal.h | 8 +- 33 files changed, 252 insertions(+), 188 deletions(-) diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-1.arc index 07071056d4..1d0cd01ba4 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-1.arc @@ -47,10 +47,14 @@ 4 16 12 48 c162b8092f50639d0e8d83ef6439043e - a4b9d143dabca55819722e363022c00c + + + d1ffc0d59dbe81cadb57c1d9c14bc5e2 b1a1189e7febabd5c2b0e3d0f1e91c57 + 05ec4fa803a51eedc91a383a777602ae - a48051badfc0eeca42d4a6b05c00600a + + f1b4f34921e20175ce3565984a902e49 86af3e90b283a6565742f0c7db1f33f3 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc index c40fcebdca..ed1a56a32a 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-2.arc @@ -60,10 +60,14 @@ 4 4 4 4 4 12 12 12 12 12 c162b8092f50639d0e8d83ef6439043e - a4b9d143dabca55819722e363022c00c + + + d1ffc0d59dbe81cadb57c1d9c14bc5e2 b1a1189e7febabd5c2b0e3d0f1e91c57 + cb549edddaf0b8ebba0e90de287a36f2 - 352e81effbc5a34d3237517091accd2f + + fd7a15e474bdcff394e776034d8df86f 329c56f1ccba78ce502cfc2001e0e716 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc index 7ca2131653..ddf3fc0ee4 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-3.arc @@ -60,10 +60,14 @@ 4 16 12 48 c162b8092f50639d0e8d83ef6439043e - a4b9d143dabca55819722e363022c00c + + + d1ffc0d59dbe81cadb57c1d9c14bc5e2 b1a1189e7febabd5c2b0e3d0f1e91c57 + 05ec4fa803a51eedc91a383a777602ae - a48051badfc0eeca42d4a6b05c00600a + + f1b4f34921e20175ce3565984a902e49 86af3e90b283a6565742f0c7db1f33f3 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-4.arc index 55919b239d..bcc98d3137 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-4.arc @@ -51,10 +51,14 @@ 4 8 8 12 24 24 4f6e3623644ee01fd476f5f385a86d63 - 3810620acfbfdb8356e0ae1321d234b2 + + + 89e6cbcf6f5ae7f6ffda7ffb54a9dda5 c308bbf6b06bb6f83ffcaf9669286a77 + 11b2632fc81c72880c6bf06f82a37d6e - 24222edf08d6cac277814f3daa4501a4 + + fbf098b120e158237e383636b52affe1 3273f83c9794fc6bdd1a4382f84e44d0 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-5.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-5.arc index 566f32b33a..90539b54bf 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-5.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-5.arc @@ -47,10 +47,13 @@ 16 16 20 20 d9bda47b8232ef43ac7a8d86d193090a - 542d7f574af6aa7c8352ab30fd6e1756 + + + 0dc25efa3d0c49eeeb48fd01a21645db d3d68d4ddecd3bde5738ac942e17f3b9 56d01ab8ec9cdaba5fc092ae1680afe8 - aabfb9b5e481a88ae2b485d6f20fd3cf + + 5618d0b768afe7f57b328506e213a62a 953548f021995149882b9b7c19849ff1 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc index f8d4d2e290..61f844293f 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -65,10 +65,13 @@ 25 4 8 8 12 228ccabec148d8994007ec68e78ff7d4 - 2a641fe98a56f0938992201e96d1cee8 + + + 72db90136e254db309faaa5351174a38 f3b6adc61a780f25ff6580c7c9f39142 86c7ad69500971e5d3c70b5235d729bb - 67cd454129841abf8dd3b9cc55d6ab4a + + fa3dc69088debc112adbc2bd2badff81 22e4d56a6bae8ba70e2e387b00111330 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc index 19f9880dc6..e30734ac73 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-PatchCartesianMeshOnly-CoarseZone-2.arc @@ -78,10 +78,13 @@ 100 36 48 64 72 bc4723a3ae6b84325bb17509f94d624b - 1d4aba023756b0548b078f7915e2001e + + + 0eb269ca13f2241a9922ed69e371795b 8874beeeeb07e91d1d49868bcce26b21 37f20b21b2eb8c41d589128e9f7c2ab1 - 9976902a8decf9d761d200c3d4b135e7 + + e63ff700fb353ae950cc1837ed766e7f 5f9f718794bdc870ba496d14f4b7bd33 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc index 8c845d970d..9734e4b23f 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc @@ -47,10 +47,14 @@ 4 16 64 12 48 192 4a6217f9352c7168e50c4936d24dcfd4 - 2b1d775d942edb86c900dcfd5ec34963 + + + fd2882117f9c2e0be1ca628ada7e01b7 b4393f81ee32b8d0d1f58c2199307cb9 + 1b3b79c88b906c7ea30055461ab40dc3 - 24d088e8a475328d0d8bbc6a80568282 + + f80dfd53f8f74771489acf74ad5e416a d060d0a4629df55c0e31deb1a9a9fbc3 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc index 1b00ba700a..01d81885d7 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc @@ -47,10 +47,14 @@ 4 16 64 12 48 192 4a6217f9352c7168e50c4936d24dcfd4 - 2b1d775d942edb86c900dcfd5ec34963 + + + fd2882117f9c2e0be1ca628ada7e01b7 b4393f81ee32b8d0d1f58c2199307cb9 + 1b3b79c88b906c7ea30055461ab40dc3 - 24d088e8a475328d0d8bbc6a80568282 + + f80dfd53f8f74771489acf74ad5e416a d060d0a4629df55c0e31deb1a9a9fbc3 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc index 33f2fd58a5..7977bc6e49 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc @@ -47,10 +47,14 @@ 16 64 256 48 192 768 022636abec5864f5eba9bfede0d353d8 - e336302a8acf3ceff59d983362b3f430 + + + 97729f00685b8fe898ea64bd0652e182 2508f369f438bec453bde7439dfab6c3 + 23f32dabc9a6199b0f77523630cc2a7c - 05aa80941c48106bc0bfb14a4713a540 + + 2be9af18f378a737d3bf81039bba9e29 a497a5f8d77c6dab70ccb414f7d9ae20 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc index 688d0256f3..8ef06576c2 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc @@ -47,10 +47,14 @@ 16 64 32 48 192 96 bfc28548e16d92620894553886d14e10 - 259a096743a77ac3161c5d5caa2fa195 + + + 70a8d404324d63a73ec54eea9a66983c 62a70cd12a7cea4ffd3e978d131daa58 + 01dfe69b9523f60aa5b2272d9c0f5956 - 41622c019ba3355990b889919f04e828 + + e3f9052522b7300f2c510a19f73ebb9d 15285920a71247986bf03915c10cdf69 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc index 8f531b9127..ee430d0aac 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc @@ -65,10 +65,14 @@ 48 192 12 8 64 72 32 128 4 8 76 72 133eed4a37931e6cd103f2fb12c354eb - 0ba793345bd95bd20e83fc7cd6de9f02 + + + 08b182320114192503596d6ef7efd3a9 7eec15be89bd293981c7b92df927cb78 + 79e40896e730176e1a414963c519aef7 - c0ab6a48abafb95ffa42ddc45cbd5a99 + + d2e8aeb6faa02b4695fc15ecc9c2c5c8 6e9662e8aedab69325d92c9cb67c18d9 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc index 969fdadb43..aba115b44e 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc @@ -65,10 +65,14 @@ 48 192 12 8 64 72 120 480 12 8 192 216 133eed4a37931e6cd103f2fb12c354eb - 0ba793345bd95bd20e83fc7cd6de9f02 + + + 08b182320114192503596d6ef7efd3a9 7eec15be89bd293981c7b92df927cb78 + 79e40896e730176e1a414963c519aef7 - c0ab6a48abafb95ffa42ddc45cbd5a99 + + d2e8aeb6faa02b4695fc15ecc9c2c5c8 6e9662e8aedab69325d92c9cb67c18d9 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc index 3d21da44fa..9990dd1347 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-7.arc @@ -50,10 +50,14 @@ 1600 6400 484 516 2064 0 d908f0b0fb7d7b8f5191444cee921518 - 7a55f9bbcd8ffe328455b774c619bb34 + + + f2b6f769b25c76e345530e4526f17fec cfa32d74b8f1ba19ab55eae6e84ce87a + 04f730c075fc1e636790583d4e8b8646 - ff5f7573b0107d492962605201ce6499 + + 23558cab23146443187e7ea9da0b3cb8 bcd8f765aa2599913658588408bd995b diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc index f641a73309..99b1fe0147 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-8.arc @@ -67,10 +67,13 @@ 1600 6400 484 1144 1936 3600 1600 516 2064 0 0 528 720 960 2ec1e04de3e4927fcb7578afedba1446 - 52335db38b14b6c2655b35770ea92dd2 + + + bfecdca16516f3683e0747a083f54400 66dae987c5a023af83c87cd6131d86f4 7e24e79d5b9aff75821178382e8f28d1 - 930ac5e4d435ae95a6b483f906383b0b + + 781a519094e067f52adf1e694e669cc8 1d9186fdcce9a53553218d893b476c89 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc index 23ab648942..0e9c2bad09 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh2D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -63,10 +63,13 @@ 16 48 8 16 16 16 bc99948909b1c4499d164c6da40dcad9 - f4914df7549e82882fc28849b89c8b5f + + + b05ddde6c89024bed01b3ec7f61d43e8 6e75535e29f9cb664058906a6e54c0a6 aadacb309fd2f436af0c8fd4959af8e7 - 9897ea6879fa40978a487931568562cf + + 75e27b65937b33641399ea4c3d1cd3e0 4d240366d0b76e05b254e0da4ead19ef diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-1.arc index 80cf80826d..6d5c61dd16 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-1.arc @@ -50,7 +50,7 @@ 5b12ac3a6d9ed116b024074cdef808c6 1ee6fc646290a97f10cef6795ac106f0 4744835ec9bc87f441a87f90bd9ab316 - 60ef888dde8214f6e7e96ea17f7cbb29 + a97000978b09b376b3e3caf931354315 5985ba24d611bfac8b708c2d30f0a821 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc index f97cafe7b0..123a6920a2 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-2.arc @@ -79,7 +79,7 @@ 5b12ac3a6d9ed116b024074cdef808c6 1ee6fc646290a97f10cef6795ac106f0 9b08918c51db2517dd59e9c8194708a8 - 436913077cf6cda018aef54ca7dd456e + 9428dabb240644fefb2e9fbf83f97c9d e974c5f17047b2eb7253bff0c937e99a diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc index 1a8da306f6..5da6c49c03 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-3.arc @@ -79,7 +79,7 @@ 5b12ac3a6d9ed116b024074cdef808c6 1ee6fc646290a97f10cef6795ac106f0 4744835ec9bc87f441a87f90bd9ab316 - 60ef888dde8214f6e7e96ea17f7cbb29 + a97000978b09b376b3e3caf931354315 5985ba24d611bfac8b708c2d30f0a821 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-4.arc index 1744d27b21..c772be482d 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-4.arc @@ -51,10 +51,10 @@ 8 64 64 2a94c530c6fc1e564f43fcdc26673d45 - 14bda59f9a744a38dd0a47eb32292df4 + aca4c7354239d631906cbbcaddfce4b2 a02bbff14ec87be39f4672a8cd936501 a0560ca2bb8199808562e8cdd7e91549 - 8fa021d8bc6345fca16a5b2106b9c385 + 7bade7add00635817cdb7094eb042a9a 03b9105a6a18fa65bab7f57384453a01 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc index e0d33f3346..069c729cfa 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -67,10 +67,10 @@ 125 8 16 16 16 32 48 72 df3786d49d37ad67e721c927500d6fd1 - b0a24dbeeea1bba8b887155109d5a312 + fde2439e36a81ef94dc2fbcf88fd750d 0e51a40d9d1a79d115f4bb5ddeefd827 7b972b16de85388414d158e1d0d0f934 - d566487c11780b6e9801c0457b560542 + e530a9f3b04d4794e58e53b8e0351750 f5756692579d9efafeade38c72812304 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc index 3d690add71..d53b85ecff 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-2.arc @@ -95,10 +95,10 @@ 1000 216 432 576 768 864 1024 194910d2bfdfb101b23a3ce372f4e60d - 145355f865846e248eea6a3458cb5cd9 + 40759f3dc739bdf026ddafe426e9a28d b025a6b3ac6545c730498d9967a65511 f6963e475c46948814d514eb1b26d8fa - 2e30a9808bbf5e4e873bae8f9607a975 + 5f1f4961083996db69b2016d512b52ec 286822b809191f89a85623e3a95bd9f6 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc index 05514e55a0..8037566338 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-3.arc @@ -66,10 +66,10 @@ 125 16 16 24 24 32 48 48 549c906b4835458793357c764e285d6c - 2408a4cfc18f1c81c1238708ee7a7219 + 2470beb5b4e98e14b204a2150718c269 67073338e696ff7e73e429ed9965fd28 cfe748e9a5ab3902c1fb7fee89f916b4 - 07d5c9133b3756c85a285a3caabdacad + 750c9dd4600a3b72e107098a257c0a63 8edd0c2fa02d38971e90684f90b01e40 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc index b93b60caa0..25a4feca9a 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-PatchCartesianMeshOnly-CoarseZone-4.arc @@ -95,10 +95,10 @@ 1000 360 432 576 720 768 1024 38ce8a131e14a4ef3db4e9ac0b1b40e6 - dab2908cc09b1572c08793666b2ebe10 + 9e8309d28e7614f73d513f2e49962df7 5148e6e7af0ae779041a8bb42a7ca637 7853a0e71c60141f5ce3ef1611ed0ce8 - 19b26d1b513014c1c568ba812dc0c23f + f42e6c55a9cd2d6300e35fc33ae85d5e 5f291689ed9db06199bfec171a2dee95 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc index 9c1ca7dc42..a07f3b9d6f 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-1.arc @@ -51,7 +51,7 @@ be24e6e593b925b836e14e77e71b2fa8 810038612b615339d58e9df030ecac6f 89d8e402a49d2762e21e552fbcb7b179 - c3546a0b715659952dd09d2ee26ac8f0 + 740e42da191ee7a74e0fbe55f250de00 f50094a413133995e237857d606ff73c diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc index 28b92aa719..2348ff1274 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-2.arc @@ -51,7 +51,7 @@ be24e6e593b925b836e14e77e71b2fa8 810038612b615339d58e9df030ecac6f 89d8e402a49d2762e21e552fbcb7b179 - c3546a0b715659952dd09d2ee26ac8f0 + 740e42da191ee7a74e0fbe55f250de00 f50094a413133995e237857d606ff73c diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc index d616eaa969..745cf152d5 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-3.arc @@ -51,7 +51,7 @@ e35ce2254ab2fa4c4213656e022939a9 d6c5dea0caeb38b6be110739aaca7721 211d4e251942ab55a6b66c321eccc9f7 - cb65230b631f089bd12afe3ca17be4bc + 0a48d41ce4dcb712dcaf331154efae9a 8a8b8e862f8b945cc4e86cad3a097f20 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc index 8be437eaef..5ed9187823 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-4.arc @@ -48,10 +48,10 @@ 64 512 384 448 3584 2688 9a6ecb9085b0f90823a1b98e57abb659 - ab46d8e71c3d4a033c0f431c8d9b5458 + e6e329dfd3688eb2fc8d7c9721e73d86 5ed44fd6b3d490cef95cfdc4ec3b82eb 242f80e5b3b8fcc4786a5e25b0559cce - c49a60ea221e9ec9476465869b6a2cc8 + 5e0c8bb5737256b7c58616cf4346d6a8 ed54a31be6004e06c81b98a4c21439bb diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc index fbeebb86b1..d6f118d4fe 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-5.arc @@ -56,10 +56,10 @@ 32 256 32 16 40 320 32 16 292074b8de182d037fed5361ec74bdce - 82298cc699557c6cf594d5518bbead53 + ca50bf895683774ee8821dc7b7a18ac5 0ed0ccf01939cd86c83e0af0ac830d21 79ac1c393e6237b247e695f2b7b3aeff - 5e637cbbc7a9e3f94bb023b94529d984 + 8fe664c847fe17d1bc46cd0593ce3033 0fcae39769e6ab2dc095c72770b1ab4e diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc index bc50217771..773ae53a73 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-6.arc @@ -53,10 +53,10 @@ 1200 9600 1440 1440 912 7296 1920 2400 116ad9966194965be13328f287dac0e5 - f61273cea361175b897d72924b1b55d1 + 2c47b01dd094aa3fe22f2dc0d8090c18 e5defe21854a4b80e6c36efaa946b0d7 79ede14c38dbd56fa463b2d55e167210 - 92bed091fbffdfb86fae62d9b24f3c44 + c42a6fbcbe1b0a27d6f7b9063e2f4928 1c2503eb4ea72163fdf9a62e78a17352 diff --git a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc index f594e97d62..50e05dcc8a 100644 --- a/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc +++ b/arcane/ceapart/tests/testAMRCartesianMesh3D-WithInitialCoarse-PatchCartesianMeshOnly-CoarseZone-1.arc @@ -64,10 +64,10 @@ 64 384 576 32 48 64 96 128 128 f1eedebec73b1051ef2b7a77ed815702 - 0b1bba1f8971df16968f9648112dcbb1 + 920e9a4adc1ecf1a1ed725bf5811d131 85f1a6bff5d48797f358c0145fb9127c a362e7707f0455ec1fdc7e787488bc36 - acf1ed66f073090ef1254410deb54fdb + 6106b305e17b620b0c7b91d6fa0c18a6 0a299b23e95a42809e3e7b1156b78039 diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc index e0b20c7f93..b659dba926 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.cc @@ -8,7 +8,9 @@ /* CartesianMeshNumberingMngInternal.cc (C) 2000-2025 */ /* */ /* Gestionnaire de numérotation de maillage cartesian. La numérotation */ -/* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ +/* des mailles et des noeuds est assez classique, la numérotation des faces */ +/* est expliquée (entre autres) dans les méthodes 'faceUniqueId()' et */ +/* 'cellFaceUniqueIds()'. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -66,7 +68,7 @@ CartesianMeshNumberingMngInternal(IMesh* mesh) else { m_latest_cell_uid = m_nb_cell_ground.x * m_nb_cell_ground.y * m_nb_cell_ground.z; m_latest_node_uid = (m_nb_cell_ground.x + 1) * (m_nb_cell_ground.y + 1) * (m_nb_cell_ground.z + 1); - m_latest_face_uid = (m_nb_cell_ground.z + 1) * m_nb_cell_ground.x * m_nb_cell_ground.y + (m_nb_cell_ground.x + 1) * m_nb_cell_ground.y * m_nb_cell_ground.z + (m_nb_cell_ground.y + 1) * m_nb_cell_ground.z * m_nb_cell_ground.x; + m_latest_face_uid = (m_nb_cell_ground.x + 1) * m_nb_cell_ground.y * m_nb_cell_ground.z + (m_nb_cell_ground.y + 1) * m_nb_cell_ground.z * m_nb_cell_ground.x + (m_nb_cell_ground.z + 1) * m_nb_cell_ground.x * m_nb_cell_ground.y; } m_first_cell_uid_level.add(0); @@ -484,7 +486,7 @@ nbFaceInLevel(Integer level) const } const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return (nb_cell.z + 1) * nb_cell.x * nb_cell.y + (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x; + return (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x + (nb_cell.z + 1) * nb_cell.x * nb_cell.y; } /*---------------------------------------------------------------------------*/ @@ -858,15 +860,15 @@ faceUniqueIdToCoordX(Int64 uid, Integer level) // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │ // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ // │ │ │ │ // @@ -874,36 +876,36 @@ faceUniqueIdToCoordX(Int64 uid, Integer level) // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - // Pour l'intervalle [0, 11], on remarque que l'origine en X est toujours 1 et que les mailles - // contenant une face sont sur les X impairs. - // Enfin, on a "nb_cell_x" faces en X. + // Pour l'intervalle [0, 11], on remarque que l'origine en X est toujours 0 et que les mailles + // contenant une face sont sur les X pairs. + // Enfin, on a "nb_face_x" faces en X. if (uid < three_parts_numbering.x) { - // debug() << "faceUniqueIdToCoordX (1)" + + // debug() << "faceUniqueIdToCoordX (2)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); + // << " -- nb_face_x : " << nb_face_x + // << " -- return : " << ((uid % nb_face_x) * 2); - return (uid % nb_cell_x) * 2 + 1; + return (uid % nb_face_x) * 2; } - // Pour l'intervalle [12, 23], on remarque que l'origine en X est toujours 0 et que les mailles - // contenant une face sont sur les X pairs. - // Enfin, on a "nb_face_x" faces en X. + // Pour l'intervalle [12, 23], on remarque que l'origine en X est toujours 1 et que les mailles + // contenant une face sont sur les X impairs. + // Enfin, on a "nb_cell_x" faces en X. else if (uid < three_parts_numbering.x + three_parts_numbering.y) { uid -= three_parts_numbering.x; - - // debug() << "faceUniqueIdToCoordX (2)" + // debug() << "faceUniqueIdToCoordX (3)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_face_x : " << nb_face_x - // << " -- return : " << ((uid % nb_face_x) * 2); + // << " -- nb_cell_x : " << nb_cell_x + // << " -- return : " << ((uid % nb_cell_x) * 2 + 1); - return (uid % nb_face_x) * 2; + return (uid % nb_cell_x) * 2 + 1; } // Pour l'intervalle [24, 35], on remarque que l'origine en X est toujours 1 et que les mailles @@ -911,8 +913,7 @@ faceUniqueIdToCoordX(Int64 uid, Integer level) // Enfin, on a "nb_cell_x" faces en X. else { uid -= three_parts_numbering.x + three_parts_numbering.y; - - // debug() << "faceUniqueIdToCoordX (3)" + // debug() << "faceUniqueIdToCoordX (1)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level @@ -988,15 +989,15 @@ faceUniqueIdToCoordY(Int64 uid, Integer level) // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │ // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ // │ │ │ │ // @@ -1004,29 +1005,10 @@ faceUniqueIdToCoordY(Int64 uid, Integer level) // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - // Pour l'intervalle [0, 11], on remarque que l'origine en Y est toujours 1 et que les mailles + // Pour l'intervalle [0, 1], on remarque que l'origine en Y est toujours 1 et que les mailles // contenant une face sont sur les Y impairs. // Enfin, on a "nb_cell_y" faces en Y. if (uid < three_parts_numbering.x) { - uid %= nb_cell_x * nb_cell_y; - - // debug() << "faceUniqueIdToCoordY (1)" - // << " -- true uid : " << initial_uid - // << " -- uid : " << uid - // << " -- level : " << level - // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / nb_cell_x) * 2 + 1); - - return (uid / nb_cell_x) * 2 + 1; - } - - // Pour l'intervalle [12, 23], on remarque que l'origine en Y est toujours 1 et que les mailles - // contenant une face sont sur les Y impairs. - // Enfin, on a "nb_cell_y" faces en Y. - else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - uid -= three_parts_numbering.x; uid %= nb_face_x * nb_cell_y; // debug() << "faceUniqueIdToCoordY (2)" @@ -1041,11 +1023,11 @@ faceUniqueIdToCoordY(Int64 uid, Integer level) return (uid / nb_face_x) * 2 + 1; } - // Pour l'intervalle [24, 35], on remarque que l'origine en Y est toujours 0 et que les mailles + // Pour l'intervalle [12, 23], on remarque que l'origine en Y est toujours 0 et que les mailles // contenant une face sont sur les Y pairs. // Enfin, on a "nb_face_y" faces en Y. - else { - uid -= three_parts_numbering.x + three_parts_numbering.y; + else if (uid < three_parts_numbering.x + three_parts_numbering.y) { + uid -= three_parts_numbering.x; uid %= nb_cell_x * nb_face_y; // debug() << "faceUniqueIdToCoordY (3)" @@ -1059,6 +1041,25 @@ faceUniqueIdToCoordY(Int64 uid, Integer level) return (uid / nb_cell_x) * 2; } + + // Pour l'intervalle [24, 35], on remarque que l'origine en Y est toujours 1 et que les mailles + // contenant une face sont sur les Y impairs. + // Enfin, on a "nb_cell_y" faces en Y. + else { + uid -= three_parts_numbering.x + three_parts_numbering.y; + uid %= nb_cell_x * nb_cell_y; + + // debug() << "faceUniqueIdToCoordY (1)" + // << " -- true uid : " << initial_uid + // << " -- uid : " << uid + // << " -- level : " << level + // << " -- three_parts_numbering : " << three_parts_numbering + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / nb_cell_x) * 2 + 1); + + return (uid / nb_cell_x) * 2 + 1; + } } } @@ -1094,15 +1095,15 @@ faceUniqueIdToCoordZ(Int64 uid, Integer level) // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │ // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ // │ │ │ │ // @@ -1110,21 +1111,21 @@ faceUniqueIdToCoordZ(Int64 uid, Integer level) // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35]. // On récupère ces intervalles avec la méthode face3DNumberingThreeParts(). - // Pour l'intervalle [0, 11], on remarque que l'origine en Z est toujours 0 et que les mailles - // contenant une face sont sur les Z pairs. - // Enfin, on a "nb_face_z" faces en Z. + // Pour l'intervalle [0, 11], on remarque que l'origine en Z est toujours 1 et que les mailles + // contenant une face sont sur les Z impairs. + // Enfin, on a "nb_cell_z" faces en Z. if (uid < three_parts_numbering.x) { - // debug() << "faceUniqueIdToCoordZ (1)" + // debug() << "faceUniqueIdToCoordZ (2)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_face_x : " << nb_face_x // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2); + // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1); - return (uid / (nb_cell_x * nb_cell_y)) * 2; + return (uid / (nb_face_x * nb_cell_y)) * 2 + 1; } // Pour l'intervalle [12, 23], on remarque que l'origine en Z est toujours 1 et que les mailles @@ -1133,34 +1134,34 @@ faceUniqueIdToCoordZ(Int64 uid, Integer level) else if (uid < three_parts_numbering.x + three_parts_numbering.y) { uid -= three_parts_numbering.x; - // debug() << "faceUniqueIdToCoordZ (2)" + // debug() << "faceUniqueIdToCoordZ (3)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level // << " -- three_parts_numbering : " << three_parts_numbering - // << " -- nb_face_x : " << nb_face_x - // << " -- nb_cell_y : " << nb_cell_y - // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1); + // << " -- nb_cell_x : " << nb_cell_x + // << " -- nb_face_y : " << nb_face_y + // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1); - return (uid / (nb_face_x * nb_cell_y)) * 2 + 1; + return (uid / (nb_cell_x * nb_face_y)) * 2 + 1; } - // Pour l'intervalle [24, 35], on remarque que l'origine en Z est toujours 1 et que les mailles - // contenant une face sont sur les Z impairs. - // Enfin, on a "nb_cell_z" faces en Z. + // Pour l'intervalle [24, 35], on remarque que l'origine en Z est toujours 0 et que les mailles + // contenant une face sont sur les Z pairs. + // Enfin, on a "nb_face_z" faces en Z. else { uid -= three_parts_numbering.x + three_parts_numbering.y; - // debug() << "faceUniqueIdToCoordZ (3)" + // debug() << "faceUniqueIdToCoordZ (1)" // << " -- true uid : " << initial_uid // << " -- uid : " << uid // << " -- level : " << level // << " -- three_parts_numbering : " << three_parts_numbering // << " -- nb_cell_x : " << nb_cell_x - // << " -- nb_face_y : " << nb_face_y - // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1); + // << " -- nb_cell_y : " << nb_cell_y + // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2); - return (uid / (nb_cell_x * nb_face_y)) * 2 + 1; + return (uid / (nb_cell_x * nb_cell_y)) * 2; } } @@ -1242,15 +1243,15 @@ faceUniqueId(Integer level, Int64x3 face_coord) // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ - // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │ + // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │ + // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │ + // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │ + // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │ // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ - // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │ + // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │ // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ // │ │ │ │ // @@ -1263,46 +1264,47 @@ faceUniqueId(Integer level, Int64x3 face_coord) // seule la coordonnée y est pair. // Intervalle [0, 11]. - if (face_coord.z % 2 == 0) { + if (face_coord.x % 2 == 0) { + // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. - face_coord.x -= 1; face_coord.y -= 1; + face_coord.z -= 1; face_coord /= 2; // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_cell_x * nb_cell_y * nb_face_z. - uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y); + // taille nb_face_x * nb_cell_y * nb_cell_z. + uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y); } // Intervalle [12, 23]. - else if (face_coord.x % 2 == 0) { + else if (face_coord.y % 2 == 0) { uid += three_parts_numbering.x; // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. - face_coord.y -= 1; + face_coord.x -= 1; face_coord.z -= 1; face_coord /= 2; // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_face_x * nb_cell_y * nb_cell_z. - uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y); + // taille nb_cell_x * nb_face_y * nb_cell_z. + uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y); } // Intervalle [24, 35]. - else if (face_coord.y % 2 == 0) { + else if (face_coord.z % 2 == 0) { uid += three_parts_numbering.x + three_parts_numbering.y; // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte. face_coord.x -= 1; - face_coord.z -= 1; + face_coord.y -= 1; face_coord /= 2; // On est, à présent et pour cet intervalle, dans une vue cartésienne de - // taille nb_cell_x * nb_face_y * nb_cell_z. - uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y); + // taille nb_cell_x * nb_cell_y * nb_face_z. + uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y); } else { ARCANE_FATAL("Bizarre -- x : {0} -- y : {1} -- z : {2}", face_coord.x, face_coord.y, face_coord.z); @@ -1452,55 +1454,54 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) // Il est aussi possible de retrouver les UniqueIDs des faces // à l'aide de la position de la cellule et la taille du maillage. // De plus, l'ordre des UniqueIDs des faces d'une cellule est toujours le - // même (en notation localId Arcane (cell.face(i)) : 0, 3, 1, 4, 2, 5). + // même (en notation localId Arcane (cell.face(i)) : 1, 4, 2, 5, 0, 3). // Les UniqueIDs générés sont donc les mêmes quelque soit le découpage. - /* - x z - ┌──► │ ┌──► - │ │ │ - y▼12 13 14 │y▼ ┌────┬────┐ - │ 26 │ 27 │ │ │ 24 │ 25 │ - └────┴────┘ │ 0 4 8 - 15 16 17 │ - │ 28 │ 29 │ │ │ │ │ - └────┴────┘ │ 2 6 10 - z=0 │ x=0 - - - - - - - - - - - - - - - - - - - - z=1 │ x=1 - 18 19 20 │ ┌────┬────┐ - │ 32 │ 33 │ │ │ 30 │ 31 │ - └────┴────┘ │ 1 5 9 - 21 22 23 │ - │ 34 │ 35 │ │ │ │ │ - └────┴────┘ │ 3 7 11 - │ - */ + // + // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 : + // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4 + // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 + // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ + // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │ + // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ + // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │ + // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ + // │ │ │ │ + // + // (dans cette vue, les mailles se situent aux X, Y et Z impaires + // (donc ici, [1, 1, 1], [3, 1, 1], [1, 3, 1], &c)). + // // On a un cube décomposé en huit cellules (2x2x2). // Le schéma au-dessus représente les faces des cellules de ce cube avec // les uniqueIDs que l'algorithme génèrera (sans face_adder). - // Pour cet algo, on commence par les faces "xy". + // Pour cet algo, on commence par les faces "yz" (direction X). // On énumère d'abord en x, puis en y, puis en z. - // Une fois les faces "xy" numérotées, on fait les faces "yz". + // Une fois les faces "yz" numérotées, on fait les faces "zx" (direction Y). // Toujours le même ordre de numérotation. - // On termine avec les faces "zx", encore dans le même ordre. + // On termine avec les faces "xy" (direction Z), encore dans le même ordre. // // Dans l'implémentation ci-dessous, on fait la numérotation // maille par maille. - const Int64 total_face_xy = nb_face.z * nb_cell.x * nb_cell.y; - const Int64 total_face_xy_yz = total_face_xy + nb_face.x * nb_cell.y * nb_cell.z; + const Int64 total_face_yz = nb_face.x * nb_cell.y * nb_cell.z; + const Int64 total_face_yz_zx = total_face_yz + nb_face.y * nb_cell.z * nb_cell.x; const Int64 nb_cell_before_j = cell_coord.y * nb_cell.x; - uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + (cell_coord.x); + uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + cell_coord.x + total_face_yz_zx; uid[3] = uid[0] + nb_cell.x * nb_cell.y; - uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + (cell_coord.x) + total_face_xy; + uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + cell_coord.x; uid[4] = uid[1] + 1; - uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + (cell_coord.x) + total_face_xy_yz; + uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + cell_coord.x + total_face_yz; uid[5] = uid[2] + nb_cell.x; @@ -1510,6 +1511,8 @@ cellFaceUniqueIds(ArrayView uid, Integer level, Int64x3 cell_coord) uid[3] += first_face_uid; uid[4] += first_face_uid; uid[5] += first_face_uid; + + // debug() << "Coord : " << cell_coord << " -- UIDs : " << uid; } /*---------------------------------------------------------------------------*/ @@ -2361,16 +2364,16 @@ childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level); if (uid < three_parts_numbering.x) { - first_child_coord_x += child_x * 2; - first_child_coord_y += child_y * 2; + first_child_coord_y += child_x * 2; + first_child_coord_z += child_y * 2; } else if (uid < three_parts_numbering.x + three_parts_numbering.y) { - first_child_coord_y += child_x * 2; + first_child_coord_x += child_x * 2; first_child_coord_z += child_y * 2; } else { first_child_coord_x += child_x * 2; - first_child_coord_z += child_y * 2; + first_child_coord_y += child_y * 2; } if (m_converting_numbering_face && level + 1 == m_ori_level) { @@ -2398,7 +2401,7 @@ Int64x3 CartesianMeshNumberingMngInternal:: _face3DNumberingThreeParts(Integer level) const { const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level)); - return { (nb_cell.z + 1) * nb_cell.x * nb_cell.y, (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x }; + return { (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x, (nb_cell.z + 1) * nb_cell.x * nb_cell.y }; } /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h index 700d41b727..dcef8bc948 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h @@ -8,12 +8,14 @@ /* CartesianMeshNumberingMngInternal.h (C) 2000-2025 */ /* */ /* Gestionnaire de numérotation de maillage cartesian. La numérotation */ -/* utilisée ici est la même que celle utilisée dans la renumérotation V2. */ +/* des mailles et des noeuds est assez classique, la numérotation des faces */ +/* est expliquée (entre autres) dans les méthodes 'faceUniqueId()' et */ +/* 'cellFaceUniqueIds()'. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_CARTESIANMESH_CARTESIANMESHNUMBERINGMNGINTERNAL_H -#define ARCANE_CARTESIANMESH_CARTESIANMESHNUMBERINGMNGINTERNAL_H +#ifndef ARCANE_CARTESIANMESH_INTERNAL_CARTESIANMESHNUMBERINGMNGINTERNAL_H +#define ARCANE_CARTESIANMESH_INTERNAL_CARTESIANMESHNUMBERINGMNGINTERNAL_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ From 524392de92dc0239b4fb93401a61a9f736bf3c20 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Thu, 4 Dec 2025 17:18:12 +0100 Subject: [PATCH 17/19] [arcane:cartesianmesh] Add methods to enable overlap cells layer --- .../tests/AMRCartesianMeshTesterModule.cc | 4 +- .../cartesianmesh/CartesianMeshAMRMng.cc | 47 +++++++++++++- .../cartesianmesh/CartesianMeshAMRMng.h | 26 ++++---- .../internal/CartesianPatchGroup.cc | 64 ++++++++++++++++++- .../internal/CartesianPatchGroup.h | 5 ++ 5 files changed, 125 insertions(+), 21 deletions(-) diff --git a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc index 7f58aa8575..7dae270cf1 100644 --- a/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc +++ b/arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc @@ -513,6 +513,8 @@ void AMRCartesianMeshTesterModule:: _initAMR() { CartesianMeshAMRMng amr_mng(m_cartesian_mesh); + amr_mng.enableOverlapLayer(false); + // Regarde si on dé-raffine le maillage initial if (options()->coarseAtInit()){ // Il faut que les directions aient été calculées avant d'appeler le dé-raffinement @@ -842,7 +844,7 @@ _checkDirections() } if (cell_hash != expected_hash) - ARCANE_FATAL("Bad hash for uniqueId() for direction items of family '{0}' v= {1} expected='{2}'", + ARCANE_FATAL("Bad hash for uniqueId() for direction items of family '{0}' v='{1}' expected='{2}'", item_family->fullName(), cell_hash, expected_hash); }; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc index d318d0c6d2..a6cbb29ee9 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc @@ -90,13 +90,42 @@ coarseZone(const AMRZonePosition& position) const /*---------------------------------------------------------------------------*/ void CartesianMeshAMRMng:: -adaptMesh(bool clear_refine_flag) const +adaptMesh() const { + /* + * Dans le cas d'un raffinement niveau par niveau, il est possible de mettre + * le paramètre \a clear_refine_flag à false afin de garder les flags des + * niveaux inférieurs et d'éviter d'avoir à les recalculer. Pour le dernier + * niveau, il est recommandé de mettre le paramètre \a clear_refine_flag à + * true pour supprimer les flags devenu inutiles (ou d'appeler la méthode + * clearRefineRelatedFlags()). + * + * Les mailles n'ayant pas de flag "II_Refine" seront déraffinées. + * + * Afin d'éviter les mailles orphelines, si une maille est marquée + * "II_Refine", alors la maille parente est marquée "II_Refine". + * + * Exemple d'exécution : + * ``` + * CartesianMeshAMRMng amr_mng(cmesh()); + * amr_mng.clearRefineRelatedFlags(); + * for (Integer level = 0; level < 2; ++level){ + * computeInLevel(level); // Va mettre des flags II_Refine sur les mailles + * amr_mng.adaptMesh(false); + * } + * amr_mng.clearRefineRelatedFlags(); + * ``` + * + * Cette opération est collective. + * + * \param clear_refine_flag true si l'on souhaite supprimer les flags + * II_Refine après adaptation. + */ auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind(); if (amr_type == eMeshAMRKind::Cell) { ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); } - m_cmesh->_internalApi()->cartesianPatchGroup().refine(clear_refine_flag); + m_cmesh->_internalApi()->cartesianPatchGroup().refine(true); } /*---------------------------------------------------------------------------*/ @@ -111,6 +140,20 @@ clearRefineRelatedFlags() const /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianMeshAMRMng:: +enableOverlapLayer(bool enable) const +{ + auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind(); + if (amr_type == eMeshAMRKind::Cell) { + return; + } + m_cmesh->_internalApi()->cartesianPatchGroup().setOverlapLayerSizeTopLevel(enable ? 2 : 0); + m_cmesh->computeDirections(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + Integer CartesianMeshAMRMng:: reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const { diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h index 4d672ef70e..447aa3decd 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h @@ -105,6 +105,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng * \brief Méthode permettant d'adapter le raffinement du maillage selon les * mailles à raffiner. * + * \warning Méthode expérimentale. + * * Cette méthode ne peut être appelée que si le maillage est un maillage * AMR (IMesh::isAmrActivated()==true) et que le type de l'AMR est 3 * (PatchCartesianMeshOnly). @@ -115,13 +117,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng * déjà). * Pour être sûr de n'avoir aucun flag déjà présent sur le maillage, il est * possible d'appeler la méthode \a clearRefineRelatedFlags(). - * Dans le cas d'un raffinement niveau par niveau, il est possible de mettre - * le paramètre \a clear_refine_flag à false afin de garder les flags des - * niveaux inférieurs et d'éviter d'avoir à les recalculer. Pour le dernier - * niveau, il est recommandé de mettre le paramètre \a clear_refine_flag à - * true pour supprimer les flags devenu inutiles (ou d'appeler la méthode - * clearRefineRelatedFlags()). - * + * Les mailles n'ayant pas de flag "II_Refine" seront déraffinées. * * Afin d'éviter les mailles orphelines, si une maille est marquée @@ -132,18 +128,16 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng * CartesianMeshAMRMng amr_mng(cmesh()); * amr_mng.clearRefineRelatedFlags(); * for (Integer level = 0; level < 2; ++level){ - * computeInLevel(level); // Va mettre des flags II_Refine sur les mailles - * amr_mng.adaptMesh(false); + * // Va faire ses calculs et mettre des flags II_Refine sur les mailles + * // du niveau 0 jusqu'au niveau level. + * computeInLevel(0, level); + * amr_mng.adaptMesh(); * } - * amr_mng.clearRefineRelatedFlags(); * ``` * * Cette opération est collective. - * - * \param clear_refine_flag true si l'on souhaite supprimer les flags - * II_Refine après adaptation. */ - void adaptMesh(bool clear_refine_flag) const; + void adaptMesh() const; /*! * \brief Méthode permettant de supprimer les flags liés au raffinement de @@ -159,7 +153,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng */ void clearRefineRelatedFlags() const; - /*! + void enableOverlapLayer(bool enable) const; + + /*! * \brief Méthode permettant de supprimer une ou plusieurs couches * de mailles fantômes sur un niveau de raffinement défini. * diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc index c133ef07c1..660618a5fa 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc @@ -50,6 +50,8 @@ CartesianPatchGroup:: CartesianPatchGroup(ICartesianMesh* cmesh) : m_cmesh(cmesh) , m_index_new_patches(1) +, m_size_of_overlap_layer_sub_top_level(0) +, m_higher_level(0) {} /*---------------------------------------------------------------------------*/ @@ -171,6 +173,9 @@ addPatch(CellGroup cell_group, Integer group_index) position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] }); position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] }); position.setLevel(level_r); + + if (level_r > m_higher_level) + m_higher_level = level_r; } auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, position); @@ -364,6 +369,14 @@ applyPatchEdit(bool remove_empty_patches) _removeMultiplePatches(m_patches_to_delete); m_patches_to_delete.clear(); } + + m_higher_level = 0; + for (const auto patch : m_amr_patches_pointer) { + const Integer level = patch->_internalApi()->positionRef().level(); + if (level > m_higher_level) { + m_higher_level = level; + } + } } /*---------------------------------------------------------------------------*/ @@ -399,6 +412,9 @@ updateLevelsBeforeAddGroundPatch() // Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1" else { patch->_internalApi()->positionRef().setLevel(level + 1); + if (level + 1 > m_higher_level) { + m_higher_level = level + 1; + } } } } @@ -504,11 +520,17 @@ mergePatches() void CartesianPatchGroup:: refine(bool clear_refine_flag) { + // TODO : Le paramètre clear_refine_flag doit être à true pour l'instant. + // À cause des mailles de recouvrements, on doit regénérer les patchs + // de tous les niveaux à chaque fois. Pour que ça fonctionne, il + // faudrait demander le nombre de niveaux qui sera généré en tout, + // pour cette itération, pour calculer en avance la taille de la + // couche de recouvrement de chaque niveau. if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) { ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly"); } Integer dimension = m_cmesh->mesh()->dimension(); - Integer nb_overlap_cells = 1; + Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level; Integer min_level = 0; Integer future_max_level = -1; // Désigne le niveau max qui aura des enfants, donc le futur level max +1. Integer old_max_level = -1; // Mais s'il reste des mailles à des niveaux plus haut, il faut les retirer. @@ -558,7 +580,7 @@ refine(bool clear_refine_flag) AMRPatchPosition all_level; all_level.setLevel(level); all_level.setMinPoint({ 0, 0, 0 }); - all_level.setMaxPoint({ static_cast(numbering->globalNbCellsX(level)), static_cast(numbering->globalNbCellsY(level)), static_cast(numbering->globalNbCellsZ(level)) }); + all_level.setMaxPoint({ numbering->globalNbCellsX(level), numbering->globalNbCellsY(level), numbering->globalNbCellsZ(level) }); all_level.setOverlapLayerSize(nb_overlap_cells); AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches); @@ -843,6 +865,35 @@ availableGroupIndex() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void CartesianPatchGroup:: +setOverlapLayerSizeTopLevel(Integer size_of_overlap_layer_top_level) +{ + m_size_of_overlap_layer_sub_top_level = (size_of_overlap_layer_top_level + 1) / 2; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +Integer CartesianPatchGroup:: +overlapLayerSize(Integer level) +{ + if (level < 0 || level > m_higher_level) { + ARCANE_FATAL("Level doesn't exist"); + } + if (level == m_higher_level) { + return m_size_of_overlap_layer_sub_top_level * 2; + } + Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level; + for (Integer i = m_higher_level - 1; i > level; --i) { + nb_overlap_cells /= 2; + nb_overlap_cells += 1; + } + return nb_overlap_cells; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void CartesianPatchGroup:: _addPatchInstance(Ref v) { @@ -1233,6 +1284,9 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove) void CartesianPatchGroup:: _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group) { + // Si cette méthode est utilisé par une autre méthode que _splitPatch(), + // voir si la mise à jour de m_higher_level est nécessaire. + // (jusque-là, ce n'est pas utile vu qu'il y aura appel à applyPatchEdit()). if (parent_patch_cell_group.null()) ARCANE_FATAL("Null cell group"); @@ -1250,7 +1304,7 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_ Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell); Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell); Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell); - if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { // TODO : Ajouter overlap dans .arc + if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { cells_local_id.add(icell.localId()); } } @@ -1293,6 +1347,10 @@ _addPatch(const AMRPatchPosition& new_patch_position) CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true); _addCellGroup(parent_cells, cdi); + if (new_patch_position.level() > m_higher_level) { + m_higher_level = new_patch_position.level(); + } + // m_cmesh->traceMng()->info() << "_addPatch()" // << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size() // << " -- m_amr_patches : " << m_amr_patches.size() diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h index 93117f2416..415527ee16 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h @@ -79,6 +79,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup ConstArrayView availableGroupIndex(); + void setOverlapLayerSizeTopLevel(Integer size_of_overlap_layer_top_level); + Integer overlapLayerSize(Integer level); + private: Integer _nextIndexForNewPatch(); @@ -108,6 +111,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup UniqueArray m_patches_to_delete; Int32 m_index_new_patches; UniqueArray m_available_group_index; + Integer m_size_of_overlap_layer_sub_top_level; + Integer m_higher_level; }; /*---------------------------------------------------------------------------*/ From 23217ebea4e7fad2756e8136424693d7c9322b36 Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Fri, 5 Dec 2025 13:39:36 +0100 Subject: [PATCH 18/19] [arcane:cartesianmesh,tests] Fix compilation with windows and update headers --- arcane/ceapart/src/arcane/tests/AdiProjectionModule.cc | 2 ++ arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc | 4 ++-- arcane/src/arcane/cartesianmesh/CartesianConnectivity.h | 4 ++-- arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h | 5 +++-- arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc | 4 ++-- arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h | 4 ++-- arcane/src/arcane/cartesianmesh/CartesianPatch.cc | 4 ++-- arcane/src/arcane/cartesianmesh/CellDirectionMng.cc | 4 ++-- arcane/src/arcane/cartesianmesh/CellDirectionMng.h | 4 ++-- arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc | 4 ++-- arcane/src/arcane/cartesianmesh/FaceDirectionMng.h | 4 ++-- arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc | 4 ++-- arcane/src/arcane/cartesianmesh/NodeDirectionMng.h | 4 ++-- 13 files changed, 27 insertions(+), 24 deletions(-) diff --git a/arcane/ceapart/src/arcane/tests/AdiProjectionModule.cc b/arcane/ceapart/src/arcane/tests/AdiProjectionModule.cc index bff21b258c..6fbd16185c 100644 --- a/arcane/ceapart/src/arcane/tests/AdiProjectionModule.cc +++ b/arcane/ceapart/src/arcane/tests/AdiProjectionModule.cc @@ -11,6 +11,8 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +#include "arcane/utils/FatalErrorException.h" + #include "arcane/core/ITimeLoopMng.h" #include "arcane/core/ITimeLoopService.h" #include "arcane/core/ITimeLoop.h" diff --git a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc index a74b59bd13..395ae77110 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianConnectivity.cc (C) 2000-2023 */ +/* CartesianConnectivity.cc (C) 2000-2025 */ /* */ /* Maillage cartésien. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h index f8fa1ed114..b918f6d787 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h +++ b/arcane/src/arcane/cartesianmesh/CartesianConnectivity.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianConnectivity.h (C) 2000-2023 */ +/* CartesianConnectivity.h (C) 2000-2025 */ /* */ /* Informations de connectivité d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h b/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h index 15eabd7447..69c40daee3 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshGlobal.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshGlobal.h (C) 2000-2023 */ +/* CartesianMeshGlobal.h (C) 2000-2025 */ /* */ /* Déclarations de la composante 'arcane_cartesianmesh'. */ /*---------------------------------------------------------------------------*/ @@ -44,6 +44,7 @@ class CartesianMeshRenumberingInfo; class ICartesianMeshInternal; class CartesianMeshPatchListView; class CartesianPatch; +class CartesianMeshAMRMng; class AMRZonePosition; class AMRPatchPosition; class AMRPatchPositionLevelGroup; diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc index 17fef21fff..ea2b5ab147 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshUtils.cc (C) 2000-2024 */ +/* CartesianMeshUtils.cc (C) 2000-2025 */ /* */ /* Fonctions utilitaires associées à 'ICartesianMesh'. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h index b2b5bcfc6c..09459db41f 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshUtils.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianMeshUtils.h (C) 2000-2024 */ +/* CartesianMeshUtils.h (C) 2000-2025 */ /* */ /* Fonctions utilitaires associées à 'ICartesianMesh'. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc index 3da93627c2..621cf5d045 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianPatch.cc +++ b/arcane/src/arcane/cartesianmesh/CartesianPatch.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CartesianPatch.cc (C) 2000-2023 */ +/* CartesianPatch.cc (C) 2000-2025 */ /* */ /* Patch AMR d'un maillage cartésien. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc index 21d067e85e..ece6e267e0 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CellDirectionMng.cc (C) 2000-2023 */ +/* CellDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les mailles d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h index 82150c509b..2033653936 100644 --- a/arcane/src/arcane/cartesianmesh/CellDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/CellDirectionMng.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* CellDirectionMng.cc (C) 2000-2023 */ +/* CellDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les mailles d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc index 2291ef2ce5..10086f95ff 100644 --- a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* FaceDirectionMng.cc (C) 2000-2023 */ +/* FaceDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les faces d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h index fe805b9297..b143ba4fab 100644 --- a/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/FaceDirectionMng.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* FaceDirectionMng.cc (C) 2000-2022 */ +/* FaceDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les faces d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc index 6e28e652e9..cf20323f14 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* NodeDirectionMng.cc (C) 2000-2022 */ +/* NodeDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les mailles d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h index 3192a2169d..98edb31876 100644 --- a/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h +++ b/arcane/src/arcane/cartesianmesh/NodeDirectionMng.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* NodeDirectionMng.cc (C) 2000-2022 */ +/* NodeDirectionMng.cc (C) 2000-2025 */ /* */ /* Infos sur les noeuds d'une direction X Y ou Z d'un maillage structuré. */ /*---------------------------------------------------------------------------*/ From 70975edbac83544f9b8836ac13cdc4e69683332f Mon Sep 17 00:00:00 2001 From: Alexandre l'Heritier Date: Fri, 5 Dec 2025 14:25:00 +0100 Subject: [PATCH 19/19] [arcane:cartesianmesh] Fix compilation with macOS and windows --- .../cartesianmesh/CartesianMeshAMRMng.h | 2 ++ .../internal/AMRPatchPositionSignature.cc | 24 +++++++++---------- .../internal/CartesianPatchGroup.h | 3 +++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h index 447aa3decd..d881ca03f5 100644 --- a/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h +++ b/arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h @@ -17,6 +17,8 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +#include "arcane/core/ItemTypes.h" + #include "arcane/cartesianmesh/CartesianMeshGlobal.h" /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc index 1a6874c827..96bdc2527e 100644 --- a/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc +++ b/arcane/src/arcane/cartesianmesh/internal/AMRPatchPositionSignature.cc @@ -216,9 +216,9 @@ fillSig() continue; } - Integer pos_x = m_numbering->cellUniqueIdToCoordX(*icell); - Integer pos_y = m_numbering->cellUniqueIdToCoordY(*icell); - Integer pos_z = m_numbering->cellUniqueIdToCoordZ(*icell); + const Int64 pos_x = m_numbering->cellUniqueIdToCoordX(*icell); + const Int64 pos_y = m_numbering->cellUniqueIdToCoordY(*icell); + const Int64 pos_z = m_numbering->cellUniqueIdToCoordZ(*icell); if ( pos_x < m_patch.minPoint().x || pos_x >= m_patch.maxPoint().x || @@ -252,24 +252,24 @@ fillSig() Int64x3 begin; Int64x3 end; - begin.x = std::max(min.x, 0l); - end.x = std::min(max.x, m_sig_x.size() + 0l); + begin.x = std::max(min.x, static_cast(0)); + end.x = std::min(max.x, static_cast(m_sig_x.size())); - begin.y = std::max(min.y, 0l); - end.y = std::min(max.y, m_sig_y.size() + 0l); + begin.y = std::max(min.y, static_cast(0)); + end.y = std::min(max.y, static_cast(m_sig_y.size())); if (m_mesh->mesh()->dimension() == 2) { begin.z = 0; end.z = 1; } else { - begin.z = std::max(min.z, 0l); - end.z = std::min(max.z, m_sig_z.size() + 0l); + begin.z = std::max(min.z, static_cast(0)); + end.z = std::min(max.z, static_cast(m_sig_z.size())); } - for (Integer k = begin.z; k < end.z; ++k) { - for (Integer j = begin.y; j < end.y; ++j) { - for (Integer i = begin.x; i < end.x; ++i) { + for (Int64 k = begin.z; k < end.z; ++k) { + for (Int64 j = begin.y; j < end.y; ++j) { + for (Int64 i = begin.x; i < end.x; ++i) { m_sig_x[i]++; m_sig_y[j]++; m_sig_z[k]++; diff --git a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h index 415527ee16..ec6f1b085b 100644 --- a/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h +++ b/arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h @@ -16,7 +16,10 @@ #include "arcane/cartesianmesh/CartesianMeshGlobal.h" +#include "arcane/core/ItemGroup.h" + #include "arcane/utils/UniqueArray.h" + #include "arcane/cartesianmesh/CartesianMeshPatchListView.h" /*---------------------------------------------------------------------------*/