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"
23#include "arcane/core/IMesh.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/IItemFamily.h"
26#include "arcane/core/IParallelMng.h"
27#include "arcane/core/VariableTypes.h"
28#include "arcane/core/Properties.h"
29#include "arcane/core/IMeshModifier.h"
30#include "arcane/core/MeshStats.h"
31#include "arcane/core/ICartesianMeshGenerationInfo.h"
32#include "arcane/core/MeshEvents.h"
33#include "arcane/core/MeshKind.h"
34#include "arcane/core/internal/IMeshInternal.h"
36#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
37#include "arcane/cartesianmesh/ICartesianMesh.h"
38#include "arcane/cartesianmesh/AMRZonePosition.h"
39#include "arcane/cartesianmesh/CartesianConnectivity.h"
40#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
41#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
42#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
43#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
44#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
45#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
47#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
48#include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h"
49#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h"
51#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h"
52#include "arcane/core/IGhostLayerMng.h"
53#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h"
78class CartesianMeshImpl
83 :
public ICartesianMeshInternal
87 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
88 : m_cartesian_mesh(cartesian_mesh)
96 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
100 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
102 void initCartesianMeshAMRPatchMng()
override
104 if (m_numbering_mng.
isNull()) {
105 initCartesianMeshNumberingMngInternal();
108 m_amr_mng =
makeRef(
new CartesianMeshAMRPatchMng(m_cartesian_mesh, m_numbering_mng.
get()));
115 void initCartesianMeshNumberingMngInternal()
override
117 if (m_numbering_mng.
isNull()) {
118 m_numbering_mng =
makeRef(
new CartesianMeshNumberingMngInternal(m_cartesian_mesh->
mesh()));
123 return m_numbering_mng;
125 CartesianPatchGroup& cartesianPatchGroup()
override {
return m_cartesian_mesh->_cartesianPatchGroup(); }
127 void saveInfosInProperties()
override { m_cartesian_mesh->_saveInfosInProperties(); }
131 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
142 void build()
override;
152 return m_all_items_direction_info->cellDirection(dir);
157 return m_all_items_direction_info->cellDirection(idir);
162 return m_all_items_direction_info->faceDirection(dir);
167 return m_all_items_direction_info->faceDirection(idir);
172 return m_all_items_direction_info->nodeDirection(dir);
177 return m_all_items_direction_info->nodeDirection(idir);
186 return m_connectivity;
211 ICartesianMeshInternal*
_internalApi()
override {
return &m_internal_api; }
213 void computeDirectionsPatchV2(
Integer index)
override;
220 CartesianPatchGroup& _cartesianPatchGroup() {
return m_patch_group; }
221 void _computeDirectionsV2();
225 InternalApi m_internal_api;
228 Int32 m_local_face_direction[3] = { -1, -1, -1 };
229 IMesh* m_mesh =
nullptr;
230 Ref<CartesianMeshPatch> m_all_items_direction_info;
231 CartesianConnectivity m_connectivity;
232 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
233 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
234 UniqueArray<CartesianConnectivity::Permutation> m_permutation_storage;
235 bool m_is_amr =
false;
237 CartesianPatchGroup m_patch_group;
238 ScopedPtrT<Properties> m_properties;
240 EventObserverPool m_event_pool;
241 bool m_is_mesh_event_added =
false;
242 Int64 m_mesh_timestamp = 0;
247 void _computeMeshDirection(CartesianMeshPatch& cdi,
eMeshDirection dir,
252 void _computeMeshDirectionV2(CartesianMeshPatch& cdi,
eMeshDirection dir,
258 void _applyRefine(
const AMRZonePosition& position);
259 void _applyCoarse(
const AMRZonePosition& zone_position);
260 void _addPatch(ConstArrayView<Int32> parent_cells);
261 void _saveInfosInProperties();
263 std::tuple<CellGroup, NodeGroup>
265 void _checkNeedComputeDirections();
266 void _checkAddObservableMeshChanged();
273arcaneCreateCartesianMesh(
IMesh* mesh)
284CartesianMeshImpl(
IMesh* mesh)
286, m_internal_api(this)
292, m_amr_type(mesh->meshKind().meshAMRKind())
295 m_internal_api.initCartesianMeshNumberingMngInternal();
296 m_internal_api.initCartesianMeshAMRPatchMng();
298 m_all_items_direction_info = m_patch_group.groundPatch();
304void CartesianMeshImpl::
307 m_properties =
new Properties(*(
mesh()->properties()),
"CartesianMesh");
309 m_internal_api.cartesianMeshNumberingMngInternal()->build();
311 m_patch_group.build();
316 const Int32 SERIALIZE_VERSION = 1;
322void CartesianMeshImpl::
323_checkNeedComputeDirections()
326 if (m_mesh_timestamp != new_timestamp) {
327 info() <<
"Mesh timestamp has changed (old=" << m_mesh_timestamp <<
" new=" << new_timestamp <<
")";
335void CartesianMeshImpl::
336_saveInfosInProperties()
339 m_properties->set(
"Version", SERIALIZE_VERSION);
341 m_patch_group.saveInfosInProperties();
344 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
355 info() <<
"Creating 'CartesianMesh' infos from dump";
358 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
359 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
363 Int32 v = m_properties->getInt32(
"Version");
364 if (v != SERIALIZE_VERSION)
365 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
366 v, SERIALIZE_VERSION);
368 m_patch_group.recreateFromDump();
370 m_all_items_direction_info = m_patch_group.groundPatch();
378void CartesianMeshImpl::
379_checkAddObservableMeshChanged()
381 if (m_is_mesh_event_added)
383 m_is_mesh_event_added =
true;
386 auto f1 = [&](
const MeshEventArgs&) { this->_checkNeedComputeDirections(); };
398 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
399 _computeDirectionsV2();
402 info() <<
"CartesianMesh: computeDirections()";
405 _checkAddObservableMeshChanged();
407 m_is_amr = m_mesh->isAmrActivated();
417 for (NodeLocalId inode : cell.
nodeIds())
418 center += nodes_coord[inode];
420 cells_center[icell] = center;
425 for (NodeLocalId inode : face.
nodeIds())
426 center += nodes_coord[inode];
428 faces_center[iface] = center;
433 Int32 next_face_x = -1;
434 Int32 next_face_y = -1;
435 Int32 next_face_z = -1;
438 Cell cell0 = cell_view[0];
441 Real3 cell_center = cells_center[cell0];
448 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
450 for (
Integer i = 0; i < nb_node; ++i) {
452 info(4) <<
"Node I=" << i <<
" node=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
455 bool is_3d = m_mesh->dimension() == 3;
465 for (
Integer i = 0; i < nb_face; ++i) {
468 Real3 next_center = faces_center[f];
470 Real diff_x = next_center.
x - cell_center.
x;
471 Real diff_y = next_center.
y - cell_center.
y;
472 Real diff_z = next_center.
z - cell_center.
z;
474 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
476 if (diff_x > max_x) {
481 if (diff_y > max_y) {
486 if (diff_z > max_z) {
491 info(4) <<
"Advance in direction X -> " << next_face_x;
492 info(4) <<
"Advance in direction Y -> " << next_face_y;
493 info(4) <<
"Advance in direction Z -> " << next_face_z;
499 for (
Integer i = 0; i < nb_face; ++i) {
502 Real3 next_center = faces_center[f];
504 Real diff_x = next_center.
x - cell_center.
x;
505 Real diff_y = next_center.
y - cell_center.
y;
507 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
509 if (diff_x > max_x) {
514 if (diff_y > max_y) {
519 info(4) <<
"Advance in direction X -> " << next_face_x;
520 info(4) <<
"Advance in direction Y -> " << next_face_y;
522 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
524 info() <<
"Informations from IMesh properties:";
526 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
528 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
529 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
530 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
531 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
536 auto x = _buildPatchGroups(
mesh()->allLevelCells(0), 0);
537 all_cells = std::get<0>(x);
538 all_nodes = std::get<1>(x);
541 if (next_face_x != (-1)) {
542 m_local_face_direction[
MD_DirX] = next_face_x;
543 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
545 if (next_face_y != (-1)) {
546 m_local_face_direction[
MD_DirY] = next_face_y;
547 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
549 if (next_face_z != (-1)) {
550 m_local_face_direction[
MD_DirZ] = next_face_z;
551 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
555 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
557 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
558 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
561 info() <<
"Compute cartesian connectivity";
563 m_permutation_storage.resize(1);
564 m_permutation_storage[0].compute();
565 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
566 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
567 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
568 m_connectivity._computeInfos(
mesh(), nodes_coord, cells_center);
572 for (
Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
573 CellGroup cells = m_patch_group.allCells(patch_index);
575 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
576 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
577 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
578 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
579 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
581 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
587 _saveInfosInProperties();
593std::tuple<CellGroup, NodeGroup> CartesianMeshImpl::
606 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
611 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
615 info(4) <<
"PATCH_CELLS name=" << patch_cells.
name() <<
" size=" << patch_cells.
size();
616 info(4) <<
"PATCH_NODES name=" << patch_nodes.
name() <<
" size=" << patch_nodes.
size();
617 return { patch_cells, patch_nodes };
623void CartesianMeshImpl::
627 IItemFamily* cell_family = m_mesh->cellFamily();
628 IItemFamily* face_family = m_mesh->faceFamily();
629 IItemFamily* node_family = m_mesh->nodeFamily();
632 Int32 max_face_id = face_family->maxLocalId();
633 Int32 max_node_id = node_family->maxLocalId();
635 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
636 cell_dm._internalResizeInfos(max_cell_id);
638 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
639 face_dm._internalResizeInfos(max_face_id);
641 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
642 node_dm._internalResizeInfos(max_node_id);
645 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
647 Int32 prev_local_face = -1;
648 Int32 next_local_face = m_local_face_direction[dir];
649 Integer mesh_dim = m_mesh->dimension();
652 prev_local_face = (next_local_face + 2) % 4;
653 else if (mesh_dim == 3)
654 prev_local_face = (next_local_face + 3) % 6;
656 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
660 std::set<Int32> cells_set;
662 cells_set.insert(icell.itemLocalId());
669 Int32 my_level = cell.level();
670 Face next_face = cell.face(next_local_face);
671 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
672 if (cells_set.find(next_cell.localId()) == cells_set.end())
674 else if (next_cell.level() != my_level)
677 Face prev_face = cell.face(prev_local_face);
678 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
679 if (cells_set.find(prev_cell.localId()) == cells_set.end())
681 else if (prev_cell.level() != my_level)
683 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
685 cell_dm._internalComputeInnerAndOuterItems(all_cells);
686 face_dm._internalComputeInfos(cell_dm, cells_center, faces_center);
687 node_dm._internalComputeInfos(cell_dm, all_nodes, cells_center);
693void CartesianMeshImpl::
694_computeDirectionsV2()
696 info() <<
"CartesianMesh: computeDirectionsV2()";
699 _checkAddObservableMeshChanged();
701 m_is_amr = m_mesh->isAmrActivated();
703 if (m_mesh->dimension() == 3) {
704 m_local_face_direction[
MD_DirX] = 4;
705 m_local_face_direction[
MD_DirY] = 5;
706 m_local_face_direction[
MD_DirZ] = 3;
709 m_local_face_direction[
MD_DirX] = 1;
710 m_local_face_direction[
MD_DirY] = 2;
713 info() <<
"Compute cartesian connectivity";
715 m_permutation_storage.resize(1);
716 m_permutation_storage[0].compute();
717 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
718 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
719 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
720 m_connectivity._computeInfos(
this);
723 for (
Integer patch_index = 0; patch_index < m_patch_group.nbPatch(); ++patch_index) {
724 computeDirectionsPatchV2(patch_index);
730 _saveInfosInProperties();
736void CartesianMeshImpl::
737computeDirectionsPatchV2(
Integer patch_index)
739 bool is_3d = m_mesh->dimension() == 3;
741 CellGroup cells = m_patch_group.allCells(patch_index);
742 Ref<CartesianMeshPatch>
patch = m_patch_group.patch(patch_index);
744 if (
patch->index() == -1) {
745 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
746 info() <<
"Informations from IMesh properties:";
747 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
748 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
749 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
750 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
752 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
753 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
754 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
755 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
759 info() <<
"AMR Patch name=" << cells.name() <<
" size=" << cells.size() <<
" index=" << patch_index <<
" trueindex=" <<
patch->index() <<
" nbPatch=" << m_patch_group.nbPatch();
761 const AMRPatchPosition position =
patch->position();
762 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
764 patch->_internalComputeNodeCellInformations();
765 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
766 _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);
767 _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);
769 _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);
775void CartesianMeshImpl::
778 IItemFamily* cell_family = m_mesh->cellFamily();
779 IItemFamily* face_family = m_mesh->faceFamily();
780 IItemFamily* node_family = m_mesh->nodeFamily();
782 Int32 max_cell_id = cell_family->maxLocalId();
783 Int32 max_face_id = face_family->maxLocalId();
784 Int32 max_node_id = node_family->maxLocalId();
786 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
787 cell_dm._internalResizeInfos(max_cell_id);
789 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
790 face_dm._internalResizeInfos(max_face_id);
792 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
793 node_dm._internalResizeInfos(max_node_id);
796 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
798 Int32 prev_local_face = -1;
799 Int32 next_local_face = m_local_face_direction[dir];
800 Integer mesh_dim = m_mesh->dimension();
803 prev_local_face = (next_local_face + 2) % 4;
804 else if (mesh_dim == 3)
805 prev_local_face = (next_local_face + 3) % 6;
807 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
811 std::set<Int32> cells_set;
813 cells_set.insert(icell.itemLocalId());
820 Int32 my_level = cell.level();
821 Face next_face = cell.face(next_local_face);
822 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
823 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
827 Face prev_face = cell.face(prev_local_face);
828 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
829 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
833 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
835 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
836 face_dm._internalComputeInfos(cell_dm);
837 node_dm._internalComputeInfos(cell_dm, all_nodes);
846 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
856 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
866 _applyRefine(position);
867 _saveInfosInProperties();
876 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
886 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
896 _applyCoarse(position);
897 _saveInfosInProperties();
907 ARCANE_FATAL(
"You cannot reduce number of ghost layer of level 0 with this method");
911 const Int32 max_nb_layer = 128;
915 level_max = std::max(level_max, icell->level());
923 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
926 if (level_0_nb_ghost_layer == 0) {
935 if (target_nb_ghost_layers % 2 != 0) {
936 target_nb_ghost_layers++;
939 if (target_nb_ghost_layers == nb_ghost_layer) {
940 return nb_ghost_layer;
945 Integer parent_level = level - 1;
946 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
952 std::function<void(
Cell)> children_list;
954 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
955 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
957 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
958 children_list(cell.hChild(i));
971 Cell front_cell = iface->frontCell();
972 Cell back_cell = iface->backCell();
974 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
975 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
976 for (
Node node : iface->nodes()) {
977 level_node[node] = 0;
983 bool is_modif =
true;
984 Int32 current_layer = 0;
989 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
993 Int32 min = max_nb_layer;
996 for (
Node node : icell->nodes()) {
997 Int32 nlevel = level_node[node];
999 min = std::min(min, nlevel);
1000 max = std::max(max, nlevel);
1005 if (min != current_layer) {
1010 if (min == max_nb_layer && max == -1) {
1014 Integer new_level = ((min == max) ? min + 1 : max);
1016 for (
Node node : icell->nodes()) {
1017 Int32 nlevel = level_node[node];
1019 level_node[node] = new_level;
1025 level_cell[icell] = min;
1030 if (min >= parent_target_nb_ghost_layer) {
1031 children_list(*icell);
1035 if (current_layer >= max_nb_layer) {
1036 ARCANE_FATAL(
"Error in ghost layer counter algo. Report it plz.");
1041 for (
Integer i = level_max - 1; i >= 0; --i) {
1048 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1049 m_mesh->modifier()->coarsenItemsV2(
false);
1052 info() <<
"Nb ghost layer for level " << level <<
" : " << target_nb_ghost_layers;
1054 return target_nb_ghost_layers;
1060void CartesianMeshImpl::
1063 _addPatch(parent_cells_local_id);
1071void CartesianMeshImpl::
1072_addPatch(ConstArrayView<Int32> parent_cells)
1077 UniqueArray<Int32> children_local_id;
1078 CellInfoListView cells(m_mesh->
cellFamily());
1079 for (Int32 cell_local_id : parent_cells) {
1080 Cell c = cells[cell_local_id];
1081 for (
Integer k = 0; k < c.nbHChildren(); ++k) {
1082 Cell child = c.hChild(k);
1083 children_local_id.add(child.localId());
1087 m_patch_group.addPatch(children_local_id);
1093void CartesianMeshImpl::
1097 UniqueArray<Int32> cells_local_id;
1098 position.cellsInPatch(
mesh(), cells_local_id);
1100 Integer nb_cell = cells_local_id.size();
1101 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1103 IParallelMng* pm = m_mesh->parallelMng();
1105 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1106 if (total_nb_cell == 0)
1109 debug() <<
"Refine with modifier() (for all mesh types)";
1110 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1111 m_mesh->modifier()->adapt();
1113 _addPatch(cells_local_id);
1117 debug() <<
"Refine with specific refiner (for cartesian mesh only)";
1118 m_patch_group.addPatch(position);
1122 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1129 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1137void CartesianMeshImpl::
1141 UniqueArray<Int32> cells_local_id;
1143 zone_position.cellsInPatch(
mesh(), cells_local_id);
1145 Integer nb_cell = cells_local_id.size();
1146 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1148 IParallelMng* pm = m_mesh->parallelMng();
1150 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1151 if (total_nb_cell == 0)
1154 debug() <<
"Coarse with modifier() (for all mesh types)";
1155 m_patch_group.removeCellsInAllPatches(cells_local_id);
1157 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1158 m_mesh->modifier()->coarsenItemsV2(
true);
1162 debug() <<
"Coarsen with specific coarser (for cartesian mesh only)";
1163 m_patch_group.removeCellsInZone(zone_position);
1167 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1174 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1185 info(4) <<
"Check valid CartesianMesh";
1187 for (
Integer i = 0; i < nb_patch; ++i) {
1199 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1202 Int32 face_method = v.renumberFaceMethod();
1203 if (face_method != 0 && face_method != 1)
1204 ARCANE_FATAL(
"Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1206 if (face_method == 1)
1210 Int32 patch_method = v.renumberPatchMethod();
1211 if (patch_method < 0 || patch_method > 4) {
1212 ARCANE_FATAL(
"Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1216 ARCANE_FATAL(
"Mesh items renumbering is not compatible with this type of AMR");
1219 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1220 CartesianMeshUniqueIdRenumbering renumberer(
this, cmgi, v.parentPatch(), patch_method);
1221 renumberer.renumber();
1223 else if (patch_method == 2) {
1224 warning() <<
"The patch method 2 is experimental!";
1225 CartesianMeshUniqueIdRenumberingV2 renumberer(
this, cmgi);
1226 renumberer.renumber();
1230 if (v.isSortAfterRenumbering()) {
1231 info() <<
"Compacting and Sorting after renumbering";
1232 m_mesh->nodeFamily()->compactItems(
true);
1233 m_mesh->faceFamily()->compactItems(
true);
1234 m_mesh->cellFamily()->compactItems(
true);
1252_createCartesianMeshCoarsening2()
1268 const char* name =
"CartesianMesh";
1277 ARCANE_FATAL(
"The mesh {0} is not yet created", h.meshName());
1284 mesh->_internalApi()->setMeshKind(mk);
1291 return adud->data();
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
File containing event management mechanisms.
Class allowing the definition of a mesh zone.
Integer size() const
Number of elements in the vector.
void add(ConstReferenceType val)
Adds element val to the end of the array.
UserData that self-destructs once detached.
Connectivity information of a Cartesian mesh.
Coarsens a Cartesian mesh by 2.
Coarsens a Cartesian mesh by 2.
Specific information for a Cartesian mesh.
void refinePatch3D(Real3 position, Real3 length) override
Refines a block of the Cartesian mesh in 3D.
Int32 nbPatch() const override
Number of patches in the mesh.
Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override
Method for deleting one or more layers of ghost cells at a defined refinement level.
void refinePatch(const AMRZonePosition &position) override
Refines a block of the Cartesian mesh.
ITraceMng * traceMng() const override
Associated trace manager.
CellDirectionMng cellDirection(Integer idir) override
List of cells in direction dir (0, 1 or 2).
void recreateFromDump() override
Recalculates Cartesian information after a restart.
void computeDirections() override
Calculates information for directional access.
FaceDirectionMng faceDirection(Integer idir) override
List of faces in direction dir (0, 1 or 2).
void coarseZone(const AMRZonePosition &position) override
Coarsens a block of the Cartesian mesh.
NodeDirectionMng nodeDirection(Integer idir) override
List of nodes in direction dir (0, 1 or 2).
void checkValid() const override
Performs checks on the validity of the instance.
IMesh * mesh() const override
Mesh associated with this Cartesian mesh.
FaceDirectionMng faceDirection(eMeshDirection dir) override
List of faces in direction dir.
NodeDirectionMng nodeDirection(eMeshDirection dir) override
List of nodes in direction dir.
void refinePatch2D(Real2 position, Real2 length) override
Refines a block of the Cartesian mesh in 2D.
ICartesianMeshPatch * patch(Int32 index) const override
Returns the index-th patch of the mesh.
void coarseZone2D(Real2 position, Real2 length) override
Coarsens a block of the Cartesian mesh in 2D.
void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v) override
Renumbers the uniqueId() of entities.
ICartesianMeshInternal * _internalApi() override
Internal API for Arcane.
void coarseZone3D(Real3 position, Real3 length) override
Coarsens a block of the Cartesian mesh in 3D.
Ref< CartesianMeshCoarsening > createCartesianMeshCoarsening() override
Creates an instance to manage mesh coarsening.
CartesianPatch amrPatch(Int32 index) const override
Returns the index-th patch of the mesh.
CellDirectionMng cellDirection(eMeshDirection dir) override
List of cells in direction dir.
CartesianMeshPatchListView patches() const override
View of the list of patches.
CartesianConnectivity connectivity() override
Connectivity information.
View of a list of patches.
Information for renumbering.
AMR Patch of a Cartesian mesh.
Info about the cells in a specific X, Y, or Z direction of a structured mesh.
View of cell information.
Face face(Int32 i) const
i-th face of the cell
Int32 nbFace() const
Number of faces of the cell.
Constant view of an array of type T.
Info on the faces of a specific direction X, Y, or Z of a structured mesh.
Interface of an AMR patch of a Cartesian mesh.
virtual void checkValid() const =0
Performs checks on the validity of the instance.
Interface of a Cartesian mesh.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Retrieves or creates the reference associated with mesh.
virtual IMesh * mesh() const =0
Mesh associated with this Cartesian mesh.
Interface of an entity family.
virtual ItemGroup allItems() const =0
Group of all entities.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Creates an entity group named name containing the entities local_ids.
virtual Int32 maxLocalId() const =0
virtual IItemFamily * cellFamily()=0
Returns the cell family.
virtual Int64 timestamp()=0
Counter indicating the time of the last mesh modification.
virtual EventObservable< const MeshEventArgs & > & eventObservable(eMeshEventType type)=0
Observable for an event.
Interface of a list that manages user data.
virtual void setData(const String &name, IUserData *ud)=0
Sets the user data associated with the name name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Data associated with name.
Interface for user data attached to another object.
Base class for a view on unstructured connectivity.
NodeGroup nodeGroup() const
Group of nodes of the elements of this group.
const String & name() const
Group name.
ItemVectorView view() const
View of the group entities.
Integer size() const
Number of elements in the group.
IItemFamily * itemFamily() const
Entity family to which this group belongs (0 for the null group).
void setItems(Int32ConstArrayView items_local_id)
Sets the entities of the group.
Utility class for printing information about an entity.
Int32ConstArrayView localIds() const
Array of local IDs of entities.
Node node(Int32 i) const
i-th node of the entity
Int32 nbNode() const
Number of nodes of the entity.
NodeLocalIdView nodeIds() const
List of nodes of the entity.
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
constexpr bool isOwn() const
true if the entity belongs to the subdomain
Arguments for mesh events.
Compatibility class to hold a MeshHandle or an IMesh*.
const MeshHandle & handle() const
Associated handle.
IMesh * meshOrNull() const
Returns the mesh associated with this instance.
IUserDataList * meshUserDataList() const
Associated user data.
Characteristics of a mesh.
Info about nodes in a specific direction X, Y, or Z of a structured mesh.
Class managing a 2-dimensional real vector.
Class managing a 3-dimensional real vector.
bool isNull() const
Indicates if the counter references a non-null instance.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
ItemGroupT< Cell > CellGroup
Group of cells.
ItemVectorViewT< Cell > CellVectorView
View over a vector of cells.
ItemGroupT< Node > NodeGroup
Group of nodes.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Coordinate type quantity at cell center.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
MeshVariableScalarRefT< Node, Int32 > VariableNodeInt32
Quantity at the node of 32-bit integer type.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Coordinate type quantity at face.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Quantity at the cell center of 32-bit integer type.
Int32 toInt32(Real r)
Converts a Real to Int32.
@ ReduceSum
Sum of values.
@ ReduceMax
Maximum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
bool arcaneIsCheck()
True if running in check mode.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
@ Cartesian
Cartesian mesh.
eMeshDirection
Direction type for a structured mesh.
@ EndPrepareDump
Event sent at the end of prepareForDump().
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
eMeshAMRKind
AMR mesh type.
@ Patch
The mesh is AMR by patch.
@ Cell
The mesh is AMR by cell.
@ PatchCartesianMeshOnly
The mesh is AMR by Cartesian patch (rectangular).
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet