14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/NotImplementedException.h"
16#include "arcane/utils/AutoDestroyUserData.h"
17#include "arcane/utils/IUserDataList.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/Convert.h"
24#include "arcane/core/IMesh.h"
25#include "arcane/core/ItemPrinter.h"
26#include "arcane/core/IItemFamily.h"
27#include "arcane/core/IParallelMng.h"
28#include "arcane/core/VariableTypes.h"
29#include "arcane/core/Properties.h"
30#include "arcane/core/IMeshModifier.h"
31#include "arcane/core/MeshStats.h"
32#include "arcane/core/ICartesianMeshGenerationInfo.h"
33#include "arcane/core/MeshEvents.h"
34#include "arcane/core/MeshKind.h"
35#include "arcane/core/internal/IMeshInternal.h"
37#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
38#include "arcane/cartesianmesh/ICartesianMesh.h"
39#include "arcane/cartesianmesh/AMRZonePosition.h"
40#include "arcane/cartesianmesh/CartesianConnectivity.h"
41#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
42#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
43#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
44#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
45#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
46#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
48#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
49#include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h"
50#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h"
52#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h"
53#include "arcane/core/IGhostLayerMng.h"
54#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h"
79class CartesianMeshImpl
84 :
public ICartesianMeshInternal
88 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
89 : m_cartesian_mesh(cartesian_mesh)
97 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
101 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
103 void initCartesianMeshAMRPatchMng()
override
105 if (m_numbering_mng.
isNull()) {
106 initCartesianMeshNumberingMngInternal();
109 m_amr_mng =
makeRef(
new CartesianMeshAMRPatchMng(m_cartesian_mesh, m_numbering_mng.
get()));
116 void initCartesianMeshNumberingMngInternal()
override
118 if (m_numbering_mng.
isNull()) {
119 m_numbering_mng =
makeRef(
new CartesianMeshNumberingMngInternal(m_cartesian_mesh->
mesh()));
124 return m_numbering_mng;
126 CartesianPatchGroup& cartesianPatchGroup()
override {
return m_cartesian_mesh->_cartesianPatchGroup(); }
128 void saveInfosInProperties()
override { m_cartesian_mesh->_saveInfosInProperties(); }
132 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
143 void build()
override;
153 return m_all_items_direction_info->cellDirection(dir);
158 return m_all_items_direction_info->cellDirection(idir);
163 return m_all_items_direction_info->faceDirection(dir);
168 return m_all_items_direction_info->faceDirection(idir);
173 return m_all_items_direction_info->nodeDirection(dir);
178 return m_all_items_direction_info->nodeDirection(idir);
187 return m_connectivity;
212 ICartesianMeshInternal*
_internalApi()
override {
return &m_internal_api; }
214 void computeDirectionsPatchV2(
Integer index)
override;
221 CartesianPatchGroup& _cartesianPatchGroup() {
return m_patch_group; }
222 void _computeDirectionsV2();
226 InternalApi m_internal_api;
229 Int32 m_local_face_direction[3] = { -1, -1, -1 };
230 IMesh* m_mesh =
nullptr;
231 Ref<CartesianMeshPatch> m_all_items_direction_info;
232 CartesianConnectivity m_connectivity;
233 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
234 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
235 UniqueArray<CartesianConnectivity::Permutation> m_permutation_storage;
236 bool m_is_amr =
false;
238 CartesianPatchGroup m_patch_group;
239 ScopedPtrT<Properties> m_properties;
241 EventObserverPool m_event_pool;
242 bool m_is_mesh_event_added =
false;
243 Int64 m_mesh_timestamp = 0;
248 void _computeMeshDirection(CartesianMeshPatch& cdi,
eMeshDirection dir,
253 void _computeMeshDirectionV2(CartesianMeshPatch& cdi,
eMeshDirection dir,
259 void _applyRefine(
const AMRZonePosition& position);
260 void _applyCoarse(
const AMRZonePosition& zone_position);
261 void _addPatch(ConstArrayView<Int32> parent_cells);
262 void _saveInfosInProperties();
264 std::tuple<CellGroup, NodeGroup>
266 void _checkNeedComputeDirections();
267 void _checkAddObservableMeshChanged();
274arcaneCreateCartesianMesh(
IMesh* mesh)
285CartesianMeshImpl(
IMesh* mesh)
287, m_internal_api(this)
293, m_amr_type(mesh->meshKind().meshAMRKind())
296 m_internal_api.initCartesianMeshNumberingMngInternal();
297 m_internal_api.initCartesianMeshAMRPatchMng();
299 m_all_items_direction_info = m_patch_group.groundPatch();
305void CartesianMeshImpl::
308 m_properties =
new Properties(*(
mesh()->properties()),
"CartesianMesh");
310 m_internal_api.cartesianMeshNumberingMngInternal()->build();
312 m_patch_group.build();
317 const Int32 SERIALIZE_VERSION = 1;
323void CartesianMeshImpl::
324_checkNeedComputeDirections()
327 if (m_mesh_timestamp != new_timestamp) {
328 info() <<
"Le horodatage du maillage a changé (ancien=" << m_mesh_timestamp <<
" nouveau=" << new_timestamp <<
")";
336void CartesianMeshImpl::
337_saveInfosInProperties()
340 m_properties->set(
"Version", SERIALIZE_VERSION);
342 m_patch_group.saveInfosInProperties();
345 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
356 info() <<
"Création des infos 'CartesianMesh' à partir du dump";
359 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
360 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
364 Int32 v = m_properties->getInt32(
"Version");
365 if (v != SERIALIZE_VERSION)
366 ARCANE_FATAL(
"Mauvaise version de sérialisation : tentative de lecture à partir d'un point de contrôle incompatible v={0} attendu={1}",
367 v, SERIALIZE_VERSION);
369 m_patch_group.recreateFromDump();
371 m_all_items_direction_info = m_patch_group.groundPatch();
379void CartesianMeshImpl::
380_checkAddObservableMeshChanged()
382 if (m_is_mesh_event_added)
384 m_is_mesh_event_added =
true;
387 auto f1 = [&](
const MeshEventArgs&) { this->_checkNeedComputeDirections(); };
399 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
400 _computeDirectionsV2();
403 info() <<
"CartesianMesh: computeDirections()";
406 _checkAddObservableMeshChanged();
408 m_is_amr = m_mesh->isAmrActivated();
418 for (NodeLocalId inode : cell.
nodeIds())
419 center += nodes_coord[inode];
421 cells_center[icell] = center;
426 for (NodeLocalId inode : face.
nodeIds())
427 center += nodes_coord[inode];
429 faces_center[iface] = center;
434 Int32 next_face_x = -1;
435 Int32 next_face_y = -1;
436 Int32 next_face_z = -1;
439 Cell cell0 = cell_view[0];
442 Real3 cell_center = cells_center[cell0];
449 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
451 for (
Integer i = 0; i < nb_node; ++i) {
453 info(4) <<
"Nœud I=" << i <<
" nœud=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
456 bool is_3d = m_mesh->dimension() == 3;
466 for (
Integer i = 0; i < nb_face; ++i) {
469 Real3 next_center = faces_center[f];
471 Real diff_x = next_center.
x - cell_center.
x;
472 Real diff_y = next_center.
y - cell_center.
y;
473 Real diff_z = next_center.
z - cell_center.
z;
475 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
477 if (diff_x > max_x) {
482 if (diff_y > max_y) {
487 if (diff_z > max_z) {
492 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
493 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
494 info(4) <<
"Avancement dans la direction Z -> " << next_face_z;
500 for (
Integer i = 0; i < nb_face; ++i) {
503 Real3 next_center = faces_center[f];
505 Real diff_x = next_center.
x - cell_center.
x;
506 Real diff_y = next_center.
y - cell_center.
y;
508 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
510 if (diff_x > max_x) {
515 if (diff_y > max_y) {
520 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
521 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
523 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
525 info() <<
"Informations des propriétés IMesh:";
527 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
529 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
530 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
531 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
532 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
537 auto x = _buildPatchGroups(
mesh()->allLevelCells(0), 0);
538 all_cells = std::get<0>(x);
539 all_nodes = std::get<1>(x);
542 if (next_face_x != (-1)) {
543 m_local_face_direction[
MD_DirX] = next_face_x;
544 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
546 if (next_face_y != (-1)) {
547 m_local_face_direction[
MD_DirY] = next_face_y;
548 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
550 if (next_face_z != (-1)) {
551 m_local_face_direction[
MD_DirZ] = next_face_z;
552 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
556 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
558 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
559 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
562 info() <<
"Calcul de la connectivité cartésienne";
564 m_permutation_storage.resize(1);
565 m_permutation_storage[0].compute();
566 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
567 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
568 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
569 m_connectivity._computeInfos(
mesh(), nodes_coord, cells_center);
573 for (
Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
574 CellGroup cells = m_patch_group.allCells(patch_index);
576 info() <<
"Nom du patch AMR=" << cells.
name() <<
" taille=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
577 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
578 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
579 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
580 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
582 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
588 _saveInfosInProperties();
594std::tuple<CellGroup, NodeGroup> CartesianMeshImpl::
607 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
612 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
616 info(4) <<
"PATCH_CELLS nom=" << patch_cells.
name() <<
" taille=" << patch_cells.
size();
617 info(4) <<
"PATCH_NODES nom=" << patch_nodes.
name() <<
" taille=" << patch_nodes.
size();
618 return { patch_cells, patch_nodes };
624void CartesianMeshImpl::
628 IItemFamily* cell_family = m_mesh->cellFamily();
629 IItemFamily* face_family = m_mesh->faceFamily();
630 IItemFamily* node_family = m_mesh->nodeFamily();
633 Int32 max_face_id = face_family->maxLocalId();
634 Int32 max_node_id = node_family->maxLocalId();
636 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
637 cell_dm._internalResizeInfos(max_cell_id);
639 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
640 face_dm._internalResizeInfos(max_face_id);
642 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
643 node_dm._internalResizeInfos(max_node_id);
646 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
648 Int32 prev_local_face = -1;
649 Int32 next_local_face = m_local_face_direction[dir];
650 Integer mesh_dim = m_mesh->dimension();
653 prev_local_face = (next_local_face + 2) % 4;
654 else if (mesh_dim == 3)
655 prev_local_face = (next_local_face + 3) % 6;
657 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
661 std::set<Int32> cells_set;
663 cells_set.insert(icell.itemLocalId());
670 Int32 my_level = cell.level();
671 Face next_face = cell.face(next_local_face);
672 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
673 if (cells_set.find(next_cell.localId()) == cells_set.end())
675 else if (next_cell.level() != my_level)
678 Face prev_face = cell.face(prev_local_face);
679 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
680 if (cells_set.find(prev_cell.localId()) == cells_set.end())
682 else if (prev_cell.level() != my_level)
684 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
686 cell_dm._internalComputeInnerAndOuterItems(all_cells);
687 face_dm._internalComputeInfos(cell_dm, cells_center, faces_center);
688 node_dm._internalComputeInfos(cell_dm, all_nodes, cells_center);
694void CartesianMeshImpl::
695_computeDirectionsV2()
697 info() <<
"CartesianMesh: computeDirectionsV2()";
700 _checkAddObservableMeshChanged();
702 m_is_amr = m_mesh->isAmrActivated();
704 if (m_mesh->dimension() == 3) {
705 m_local_face_direction[
MD_DirX] = 4;
706 m_local_face_direction[
MD_DirY] = 5;
707 m_local_face_direction[
MD_DirZ] = 3;
710 m_local_face_direction[
MD_DirX] = 1;
711 m_local_face_direction[
MD_DirY] = 2;
714 info() <<
"Compute cartesian connectivity";
716 m_permutation_storage.resize(1);
717 m_permutation_storage[0].compute();
718 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
719 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
720 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
721 m_connectivity._computeInfos(
this);
724 for (
Integer patch_index = 0; patch_index < m_patch_group.nbPatch(); ++patch_index) {
725 computeDirectionsPatchV2(patch_index);
731 _saveInfosInProperties();
737void CartesianMeshImpl::
738computeDirectionsPatchV2(
Integer patch_index)
740 bool is_3d = m_mesh->dimension() == 3;
742 CellGroup cells = m_patch_group.allCells(patch_index);
743 Ref<CartesianMeshPatch>
patch = m_patch_group.patch(patch_index);
745 if (
patch->index() == -1) {
746 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
747 info() <<
"Informations depuis les propriétés IMesh:";
748 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
749 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
750 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
751 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
753 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
754 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
755 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
756 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
760 info() <<
"Nom du patch AMR=" << cells.name() <<
" taille=" << cells.size() <<
" index=" << patch_index <<
" trueindex=" <<
patch->index() <<
" nbPatch=" << m_patch_group.nbPatch();
762 const AMRPatchPosition position =
patch->position();
763 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
765 patch->_internalComputeNodeCellInformations();
766 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
767 _computeMeshDirectionV2(*
patch.get(),
MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
768 _computeMeshDirectionV2(*
patch.get(),
MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
770 _computeMeshDirectionV2(*
patch.get(),
MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
776void CartesianMeshImpl::
779 IItemFamily* cell_family = m_mesh->cellFamily();
780 IItemFamily* face_family = m_mesh->faceFamily();
781 IItemFamily* node_family = m_mesh->nodeFamily();
783 Int32 max_cell_id = cell_family->maxLocalId();
784 Int32 max_face_id = face_family->maxLocalId();
785 Int32 max_node_id = node_family->maxLocalId();
787 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
788 cell_dm._internalResizeInfos(max_cell_id);
790 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
791 face_dm._internalResizeInfos(max_face_id);
793 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
794 node_dm._internalResizeInfos(max_node_id);
797 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
799 Int32 prev_local_face = -1;
800 Int32 next_local_face = m_local_face_direction[dir];
801 Integer mesh_dim = m_mesh->dimension();
804 prev_local_face = (next_local_face + 2) % 4;
805 else if (mesh_dim == 3)
806 prev_local_face = (next_local_face + 3) % 6;
808 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
812 std::set<Int32> cells_set;
814 cells_set.insert(icell.itemLocalId());
821 Int32 my_level = cell.level();
822 Face next_face = cell.face(next_local_face);
823 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
824 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
828 Face prev_face = cell.face(prev_local_face);
829 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
830 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
834 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
836 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
837 face_dm._internalComputeInfos(cell_dm);
838 node_dm._internalComputeInfos(cell_dm, all_nodes);
847 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
857 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
867 _applyRefine(position);
868 _saveInfosInProperties();
877 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
887 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
897 _applyCoarse(position);
898 _saveInfosInProperties();
908 ARCANE_FATAL(
"Vous ne pouvez pas réduire le nombre de couches fantômes du niveau 0 avec cette méthode");
912 const Int32 max_nb_layer = 128;
916 level_max = std::max(level_max, icell->level());
924 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
927 if (level_0_nb_ghost_layer == 0) {
936 if (target_nb_ghost_layers % 2 != 0) {
937 target_nb_ghost_layers++;
940 if (target_nb_ghost_layers == nb_ghost_layer) {
941 return nb_ghost_layer;
946 Integer parent_level = level - 1;
947 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
953 std::function<void(
Cell)> children_list;
955 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
956 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
958 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
959 children_list(cell.hChild(i));
972 Cell front_cell = iface->frontCell();
973 Cell back_cell = iface->backCell();
975 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
976 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
977 for (
Node node : iface->nodes()) {
978 level_node[node] = 0;
984 bool is_modif =
true;
985 Int32 current_layer = 0;
990 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
994 Int32 min = max_nb_layer;
997 for (
Node node : icell->nodes()) {
998 Int32 nlevel = level_node[node];
1000 min = std::min(min, nlevel);
1001 max = std::max(max, nlevel);
1006 if (min != current_layer) {
1011 if (min == max_nb_layer && max == -1) {
1015 Integer new_level = ((min == max) ? min + 1 : max);
1017 for (
Node node : icell->nodes()) {
1018 Int32 nlevel = level_node[node];
1020 level_node[node] = new_level;
1026 level_cell[icell] = min;
1031 if (min >= parent_target_nb_ghost_layer) {
1032 children_list(*icell);
1036 if (current_layer >= max_nb_layer) {
1037 ARCANE_FATAL(
"Erreur dans l'algorithme du compteur de couches fantômes. Signalez-le s'il vous plaît.");
1042 for (
Integer i = level_max - 1; i >= 0; --i) {
1049 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1050 m_mesh->modifier()->coarsenItemsV2(
false);
1053 info() <<
"Nb de couches fantômes pour le niveau " << level <<
" : " << target_nb_ghost_layers;
1055 return target_nb_ghost_layers;
1061void CartesianMeshImpl::
1064 _addPatch(parent_cells_local_id);
1072void CartesianMeshImpl::
1073_addPatch(ConstArrayView<Int32> parent_cells)
1078 UniqueArray<Int32> children_local_id;
1079 CellInfoListView cells(m_mesh->
cellFamily());
1080 for (Int32 cell_local_id : parent_cells) {
1081 Cell c = cells[cell_local_id];
1082 for (
Integer k = 0; k < c.nbHChildren(); ++k) {
1083 Cell child = c.hChild(k);
1084 children_local_id.add(child.localId());
1088 m_patch_group.addPatch(children_local_id);
1094void CartesianMeshImpl::
1098 UniqueArray<Int32> cells_local_id;
1099 position.cellsInPatch(
mesh(), cells_local_id);
1101 Integer nb_cell = cells_local_id.size();
1102 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1104 IParallelMng* pm = m_mesh->parallelMng();
1106 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1107 if (total_nb_cell == 0)
1110 debug() <<
"Raffine avec modifier() (pour tous les types de maillage)";
1111 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1112 m_mesh->modifier()->adapt();
1114 _addPatch(cells_local_id);
1118 debug() <<
"Raffine avec un raffineur spécifique (pour maillage cartésien uniquement)";
1119 m_patch_group.addPatch(position);
1123 ARCANE_FATAL(
"L'AMR de patch général n'est pas implémenté. Veuillez utiliser PatchCartesianMeshOnly (3)");
1130 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1138void CartesianMeshImpl::
1142 UniqueArray<Int32> cells_local_id;
1144 zone_position.cellsInPatch(
mesh(), cells_local_id);
1146 Integer nb_cell = cells_local_id.size();
1147 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1149 IParallelMng* pm = m_mesh->parallelMng();
1151 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1152 if (total_nb_cell == 0)
1155 debug() <<
"Coarsening avec modifier() (pour tous les types de maillage)";
1156 m_patch_group.removeCellsInAllPatches(cells_local_id);
1158 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1159 m_mesh->modifier()->coarsenItemsV2(
true);
1163 debug() <<
"Coarsening avec un grossisseur spécifique (pour maillage cartésien uniquement)";
1164 m_patch_group.removeCellsInZone(zone_position);
1168 ARCANE_FATAL(
"L'AMR de patch général n'est pas implémenté. Veuillez utiliser PatchCartesianMeshOnly (3)");
1175 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1186 info(4) <<
"Vérification du maillage cartésien valide";
1188 for (
Integer i = 0; i < nb_patch; ++i) {
1200 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1203 Int32 face_method = v.renumberFaceMethod();
1204 if (face_method != 0 && face_method != 1)
1205 ARCANE_FATAL(
"Valeur '{0}' invalide pour renumberFaceMethod(). Les valeurs valides sont 0 ou 1",
1207 if (face_method == 1)
1211 Int32 patch_method = v.renumberPatchMethod();
1212 if (patch_method < 0 || patch_method > 4) {
1213 ARCANE_FATAL(
"Valeur '{0}' invalide pour renumberPatchMethod(). Les valeurs valides sont 0, 1, 2, 3 ou 4",
1217 ARCANE_FATAL(
"La renumérotation des éléments du maillage n'est pas compatible avec ce type d'AMR");
1220 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1221 CartesianMeshUniqueIdRenumbering renumberer(
this, cmgi, v.parentPatch(), patch_method);
1222 renumberer.renumber();
1224 else if (patch_method == 2) {
1225 warning() <<
"La méthode de patch 2 est expérimentale !";
1226 CartesianMeshUniqueIdRenumberingV2 renumberer(
this, cmgi);
1227 renumberer.renumber();
1231 if (v.isSortAfterRenumbering()) {
1232 info() <<
"Compactage et tri après renumérotation";
1233 m_mesh->nodeFamily()->compactItems(
true);
1234 m_mesh->faceFamily()->compactItems(
true);
1235 m_mesh->cellFamily()->compactItems(
true);
1253_createCartesianMeshCoarsening2()
1269 const char* name =
"CartesianMesh";
1278 ARCANE_FATAL(
"Le maillage {0} n'a pas encore été créé", h.meshName());
1285 mesh->_internalApi()->setMeshKind(mk);
1291 ARCANE_FATAL(
"Impossible de caster en ICartesianMesh*");
1292 return adud->data();
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les mécanismes de gestion des évènements.
Classe permettant de définir une zone d'un maillage.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Informations de connectivité d'un maillage cartésien.
Déraffine un maillage cartésien par 2.
Déraffine un maillage cartésien par 2.
Informations spécifiques pour un maillage cartésien.
void refinePatch3D(Real3 position, Real3 length) override
Raffine en 3D un bloc du maillage cartésien.
Int32 nbPatch() const override
Nombre de patchs du maillage.
Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override
Méthode permettant de supprimer une ou plusieurs couches de mailles fantômes sur un niveau de raffine...
void refinePatch(const AMRZonePosition &position) override
Raffine un bloc du maillage cartésien.
ITraceMng * traceMng() const override
Gestionnaire de traces associé.
CellDirectionMng cellDirection(Integer idir) override
Liste des mailles dans la direction dir (0, 1 ou 2).
void recreateFromDump() override
Recalcule les informations de cartésiennes après une reprise.
void computeDirections() override
Calcule les infos pour les accès par direction.
FaceDirectionMng faceDirection(Integer idir) override
Liste des faces dans la direction dir (0, 1 ou 2).
void coarseZone(const AMRZonePosition &position) override
Dé-raffine un bloc du maillage cartésien.
NodeDirectionMng nodeDirection(Integer idir) override
Liste des noeuds dans la direction dir (0, 1 ou 2).
void checkValid() const override
Effectue des vérifications sur la validité de l'instance.
IMesh * mesh() const override
Maillage associé à ce maillage cartésien.
FaceDirectionMng faceDirection(eMeshDirection dir) override
Liste des faces dans la direction dir.
NodeDirectionMng nodeDirection(eMeshDirection dir) override
Liste des noeuds dans la direction dir.
void refinePatch2D(Real2 position, Real2 length) override
Raffine en 2D un bloc du maillage cartésien.
ICartesianMeshPatch * patch(Int32 index) const override
Retourne le index-ième patch du maillage.
void coarseZone2D(Real2 position, Real2 length) override
Dé-raffine en 2D un bloc du maillage cartésien.
void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v) override
Renumérote les uniqueId() des entités.
ICartesianMeshInternal * _internalApi() override
API interne à Arcane.
void coarseZone3D(Real3 position, Real3 length) override
Dé-raffine en 3D un bloc du maillage cartésien.
Ref< CartesianMeshCoarsening > createCartesianMeshCoarsening() override
Créé une instance pour gérer le déraffinement du maillage.
CartesianPatch amrPatch(Int32 index) const override
Retourne le index-ième patch du maillage.
CellDirectionMng cellDirection(eMeshDirection dir) override
Liste des mailles dans la direction dir.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
Vue sur une liste de patchs.
Informations pour la renumérotation.
Patch AMR d'un maillage cartésien.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Vue sur les informations des mailles.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Vue constante d'un tableau de type T.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Interface d'un patch AMR d'un maillage cartésien.
virtual void checkValid() const =0
Effectue des vérifications sur la validité de l'instance.
Interface d'un maillage cartésien.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Récupère ou créé la référence associée à mesh.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
Interface d'une famille d'entités.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual Int32 maxLocalId() const =0
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual Int64 timestamp()=0
Compteur indiquant le temps de dernière modification du maillage.
virtual EventObservable< const MeshEventArgs & > & eventObservable(eMeshEventType type)=0
Observable pour un évènement.
Interface du gestionnaire de traces.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Classe de base d'une vue sur une connectivité non structurée.
NodeGroup nodeGroup() const
Groupe des noeuds des éléments de ce groupe.
const String & name() const
Nom du groupe.
ItemVectorView view() const
Vue sur les entités du groupe.
Integer size() const
Nombre d'éléments du groupe.
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul).
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe.
Classe utilitaire pour imprimer les infos sur une entité.
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
Node node(Int32 i) const
i-ème noeud de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
Arguments des évènements sur le maillage.
Classe de compatibilité pour contenir un MeshHandle ou un IMesh*.
const MeshHandle & handle() const
handle associé.
IMesh * meshOrNull() const
Retourne le maillage associé à cette instance.
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Caractéristiques d'un maillage.
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Classe gérant un vecteur réel 2-dimensionnel.
Classe gérant un vecteur réel de 3 dimensions.
bool isNull() const
Indique si le compteur référence une instance non nulle.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Référence à une instance.
Chaîne de caractères unicode.
Classe d'accès aux traces.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
ItemVectorViewT< Cell > CellVectorView
Vue sur un vecteur de mailles.
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Node, Int32 > VariableNodeInt32
Grandeur au noeud de type entier 32 bits.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
Int32 toInt32(Real r)
Convertit un Real en Int32.
@ ReduceSum
Somme des valeurs.
@ ReduceMax
Maximum des valeurs.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
bool arcaneIsCheck()
Vrai si on est en mode vérification.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
@ Cartesian
Maillage cartésien.
eMeshDirection
Type de la direction pour un maillage structuré
@ EndPrepareDump
Evènement envoyé à la fin de prepareForDump().
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
eMeshAMRKind
Type de maillage AMR.
@ Patch
Le maillage est AMR par patch.
@ Cell
Le maillage est AMR par maille.
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire).
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet