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"
77class CartesianMeshImpl
86 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
87 : m_cartesian_mesh(cartesian_mesh)
95 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
99 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
103 if (m_numbering_mng.isNull()) {
106 if (m_amr_mng.isNull()) {
116 if (m_numbering_mng.isNull()) {
122 return m_numbering_mng;
128 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
139 void build()
override;
149 return m_all_items_direction_info->cellDirection(dir);
154 return m_all_items_direction_info->cellDirection(idir);
159 return m_all_items_direction_info->faceDirection(dir);
164 return m_all_items_direction_info->faceDirection(idir);
169 return m_all_items_direction_info->nodeDirection(dir);
174 return m_all_items_direction_info->nodeDirection(idir);
183 return m_connectivity;
210 void computeDirectionsPatchV2(
Integer index)
override;
218 void _computeDirectionsV2();
222 InternalApi m_internal_api;
226 IMesh* m_mesh =
nullptr;
232 bool m_is_amr =
false;
238 bool m_is_mesh_event_added =
false;
239 Int64 m_mesh_timestamp = 0;
258 void _saveInfosInProperties();
260 std::tuple<CellGroup, NodeGroup>
262 void _checkNeedComputeDirections();
263 void _checkAddObservableMeshChanged();
281CartesianMeshImpl(IMesh* mesh)
282: TraceAccessor(mesh->traceMng())
283, m_internal_api(this)
285, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
286, m_cells_to_node_storage(platform::getDefaultDataAllocator())
287, m_permutation_storage(platform::getDefaultDataAllocator())
289, m_amr_type(mesh->meshKind().meshAMRKind())
292 m_internal_api.initCartesianMeshNumberingMngInternal();
293 m_internal_api.initCartesianMeshAMRPatchMng();
295 m_all_items_direction_info = m_patch_group.groundPatch();
301void CartesianMeshImpl::
304 m_properties =
new Properties(*(mesh()->properties()),
"CartesianMesh");
305 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
306 m_internal_api.cartesianMeshNumberingMngInternal()->build();
308 m_patch_group.build();
313const Int32 SERIALIZE_VERSION = 1;
319void CartesianMeshImpl::
320_checkNeedComputeDirections()
322 Int64 new_timestamp = mesh()->timestamp();
323 if (m_mesh_timestamp!=new_timestamp){
324 info() <<
"Mesh timestamp has changed (old=" << m_mesh_timestamp <<
" new=" << new_timestamp <<
")";
332void CartesianMeshImpl::
333_saveInfosInProperties()
336 m_properties->set(
"Version",SERIALIZE_VERSION);
338 m_patch_group.saveInfosInProperties();
340 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
341 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
349void CartesianMeshImpl::
352 info() <<
"Creating 'CartesianMesh' infos from dump";
355 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
356 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
360 Int32 v = m_properties->getInt32(
"Version");
361 if (v!=SERIALIZE_VERSION)
362 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
363 v,SERIALIZE_VERSION);
375void CartesianMeshImpl::
376_checkAddObservableMeshChanged()
378 if (m_is_mesh_event_added)
380 m_is_mesh_event_added =
true;
383 auto f1 = [&](
const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
384 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool,f1);
390void CartesianMeshImpl::
395 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
396 _computeDirectionsV2();
399 info() <<
"CartesianMesh: computeDirections()";
401 m_mesh_timestamp =
mesh()->timestamp();
402 _checkAddObservableMeshChanged();
404 m_is_amr = m_mesh->isAmrActivated();
414 for( NodeLocalId inode : cell.
nodeIds() )
415 center += nodes_coord[inode];
417 cells_center[icell] = center;
422 for( NodeLocalId inode : face.
nodeIds() )
423 center += nodes_coord[inode];
425 faces_center[iface] = center;
430 Int32 next_face_x = -1;
431 Int32 next_face_y = -1;
432 Int32 next_face_z = -1;
435 Cell cell0 = cell_view[0];
438 Real3 cell_center = cells_center[cell0];
445 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
447 for(
Integer i=0; i<nb_node; ++i ){
449 info(4) <<
"Node I=" << i <<
" node=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
452 bool is_3d = m_mesh->dimension() == 3;
462 for (
Integer i = 0; i < nb_face; ++i) {
465 Real3 next_center = faces_center[f];
467 Real diff_x = next_center.
x - cell_center.
x;
468 Real diff_y = next_center.
y - cell_center.
y;
469 Real diff_z = next_center.
z - cell_center.
z;
471 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
473 if (diff_x > max_x) {
478 if (diff_y > max_y) {
483 if (diff_z > max_z) {
488 info(4) <<
"Advance in direction X -> " << next_face_x;
489 info(4) <<
"Advance in direction Y -> " << next_face_y;
490 info(4) <<
"Advance in direction Z -> " << next_face_z;
496 for (
Integer i = 0; i < nb_face; ++i) {
499 Real3 next_center = faces_center[f];
501 Real diff_x = next_center.
x - cell_center.
x;
502 Real diff_y = next_center.
y - cell_center.
y;
504 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
506 if (diff_x > max_x) {
511 if (diff_y > max_y) {
516 info(4) <<
"Advance in direction X -> " << next_face_x;
517 info(4) <<
"Advance in direction Y -> " << next_face_y;
519 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
521 info() <<
"Informations from IMesh properties:";
523 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
525 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
526 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
527 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
528 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
533 auto x = _buildPatchGroups(
mesh()->allLevelCells(0),0);
534 all_cells = std::get<0>(x);
535 all_nodes = std::get<1>(x);
538 if (next_face_x!=(-1)){
540 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
542 if (next_face_y!=(-1)){
544 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
546 if (next_face_z != (-1)) {
548 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
552 for(
Integer idir=0, nb_dir=
mesh()->dimension(); idir<nb_dir; ++idir ){
554 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
555 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
558 info() <<
"Compute cartesian connectivity";
560 m_permutation_storage.resize(1);
561 m_permutation_storage[0].compute();
562 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
563 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
564 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
565 m_connectivity._computeInfos(
mesh(),nodes_coord,cells_center);
572 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" <<
m_patch_group.nbPatch();
573 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
574 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
575 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
576 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
578 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
584 _saveInfosInProperties();
590std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
603 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
608 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
612 info(4) <<
"PATCH_CELLS name=" << patch_cells.
name() <<
" size=" << patch_cells.
size();
613 info(4) <<
"PATCH_NODES name=" << patch_nodes.
name() <<
" size=" << patch_nodes.
size();
614 return { patch_cells, patch_nodes };
620void CartesianMeshImpl::
621_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center,
622 VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes)
624 IItemFamily* cell_family = m_mesh->cellFamily();
625 IItemFamily* face_family = m_mesh->faceFamily();
626 IItemFamily* node_family = m_mesh->nodeFamily();
628 Int32 max_cell_id = cell_family->
maxLocalId();
629 Int32 max_face_id = face_family->maxLocalId();
630 Int32 max_node_id = node_family->maxLocalId();
632 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
633 cell_dm._internalResizeInfos(max_cell_id);
635 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
636 face_dm._internalResizeInfos(max_face_id);
638 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
639 node_dm._internalResizeInfos(max_node_id);
642 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
644 Int32 prev_local_face = -1;
645 Int32 next_local_face = m_local_face_direction[dir];
646 Integer mesh_dim = m_mesh->dimension();
649 prev_local_face = (next_local_face + 2) % 4;
650 else if (mesh_dim==3)
651 prev_local_face = (next_local_face + 3) % 6;
653 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
657 std::set<Int32> cells_set;
659 cells_set.insert(icell.itemLocalId());
666 Int32 my_level = cell.level();
667 Face next_face = cell.face(next_local_face);
668 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
669 if (cells_set.find(next_cell.localId()) == cells_set.end())
671 else if (next_cell.level() != my_level)
674 Face prev_face = cell.face(prev_local_face);
675 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
676 if (cells_set.find(prev_cell.localId()) == cells_set.end())
678 else if (prev_cell.level() != my_level)
680 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
682 cell_dm._internalComputeInnerAndOuterItems(all_cells);
683 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
684 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
690void CartesianMeshImpl::
691_computeDirectionsV2()
693 info() <<
"CartesianMesh: computeDirectionsV2()";
695 m_mesh_timestamp = mesh()->timestamp();
696 _checkAddObservableMeshChanged();
698 m_is_amr = m_mesh->isAmrActivated();
700 IItemFamily* cell_family = m_mesh->cellFamily();
701 IItemFamily* node_family = m_mesh->nodeFamily();
703 bool is_3d = m_mesh->dimension() == 3;
705 m_all_items_direction_info->_internalComputeNodeCellInformations();
707 info() <<
"Informations from IMesh properties:";
709 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
711 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
712 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
713 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
714 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
716 CellGroup all_cells = cell_family->allItems();
717 NodeGroup all_nodes = node_family->allItems();
719 auto x = _buildPatchGroups(mesh()->allLevelCells(0), 0);
720 all_cells = std::get<0>(x);
721 all_nodes = std::get<1>(x);
724 m_local_face_direction[
MD_DirX] = 4;
725 m_local_face_direction[
MD_DirY] = 5;
726 m_local_face_direction[
MD_DirZ] = 3;
729 m_local_face_direction[
MD_DirX] = 1;
730 m_local_face_direction[
MD_DirY] = 2;
733 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells,
CellGroup(), all_nodes);
734 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells,
CellGroup(), all_nodes);
736 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells,
CellGroup(), all_nodes);
740 for (Integer idir = 0, nb_dir = mesh()->dimension(); idir < nb_dir; ++idir) {
741 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
742 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
743 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
746 info() <<
"Compute cartesian connectivity";
748 m_permutation_storage.resize(1);
749 m_permutation_storage[0].compute();
750 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
751 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
752 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
753 m_connectivity._computeInfos(
this);
756 for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
757 computeDirectionsPatchV2(patch_index);
764 _saveInfosInProperties();
770void CartesianMeshImpl::
771computeDirectionsPatchV2(Integer patch_index)
773 bool is_3d = m_mesh->dimension() == 3;
775 CellGroup cells = m_patch_group.allCells(patch_index);
776 Ref<CartesianMeshPatch> patch = m_patch_group.patch(patch_index);
777 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
779 const AMRPatchPosition position = patch->position();
780 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
782 patch->_internalComputeNodeCellInformations();
783 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
784 _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);
785 _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);
787 _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);
793void CartesianMeshImpl::
794_computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overlap_cells, NodeGroup all_nodes)
796 IItemFamily* cell_family = m_mesh->cellFamily();
797 IItemFamily* face_family = m_mesh->faceFamily();
798 IItemFamily* node_family = m_mesh->nodeFamily();
800 Int32 max_cell_id = cell_family->maxLocalId();
801 Int32 max_face_id = face_family->maxLocalId();
802 Int32 max_node_id = node_family->maxLocalId();
804 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
805 cell_dm._internalResizeInfos(max_cell_id);
807 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
808 face_dm._internalResizeInfos(max_face_id);
810 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
811 node_dm._internalResizeInfos(max_node_id);
814 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
816 Int32 prev_local_face = -1;
817 Int32 next_local_face = m_local_face_direction[dir];
818 Integer mesh_dim = m_mesh->dimension();
821 prev_local_face = (next_local_face + 2) % 4;
822 else if (mesh_dim == 3)
823 prev_local_face = (next_local_face + 3) % 6;
825 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
829 std::set<Int32> cells_set;
831 cells_set.insert(icell.itemLocalId());
838 Int32 my_level = cell.level();
839 Face next_face = cell.face(next_local_face);
840 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
841 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
845 Face prev_face = cell.face(prev_local_face);
846 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
847 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
851 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
853 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
854 face_dm._internalComputeInfos(cell_dm);
855 node_dm._internalComputeInfos(cell_dm, all_nodes);
861void CartesianMeshImpl::
864 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
871void CartesianMeshImpl::
874 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
881void CartesianMeshImpl::
884 _applyRefine(position);
885 _saveInfosInProperties();
891void CartesianMeshImpl::
894 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
901void CartesianMeshImpl::
904 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
911void CartesianMeshImpl::
914 _applyCoarse(position);
915 _saveInfosInProperties();
925 ARCANE_FATAL(
"You cannot reduce number of ghost layer of level 0 with this method");
929 const Int32 max_nb_layer = 128;
933 level_max = std::max(level_max, icell->level());
941 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
944 if (level_0_nb_ghost_layer == 0) {
953 if (target_nb_ghost_layers % 2 != 0) {
954 target_nb_ghost_layers++;
957 if (target_nb_ghost_layers == nb_ghost_layer) {
958 return nb_ghost_layer;
963 Integer parent_level = level - 1;
964 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
970 std::function<void(
Cell)> children_list;
972 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
973 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
975 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
976 children_list(cell.hChild(i));
989 Cell front_cell = iface->frontCell();
990 Cell back_cell = iface->backCell();
992 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
993 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
994 for (
Node node : iface->nodes()) {
995 level_node[node] = 0;
1001 bool is_modif =
true;
1002 Int32 current_layer = 0;
1007 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
1011 Int32 min = max_nb_layer;
1014 for (
Node node : icell->nodes()) {
1015 Int32 nlevel = level_node[node];
1017 min = std::min(min, nlevel);
1018 max = std::max(max, nlevel);
1023 if (min != current_layer) {
1028 if (min == max_nb_layer && max == -1) {
1032 Integer new_level = ((min == max) ? min + 1 : max);
1034 for (
Node node : icell->nodes()) {
1035 Int32 nlevel = level_node[node];
1037 level_node[node] = new_level;
1043 level_cell[icell] = min;
1048 if (min >= parent_target_nb_ghost_layer) {
1049 children_list(*icell);
1053 if (current_layer >= max_nb_layer) {
1054 ARCANE_FATAL(
"Error in ghost layer counter algo. Report it plz.");
1059 for (
Integer i = level_max - 1; i >= 0; --i) {
1066 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1067 m_mesh->modifier()->coarsenItemsV2(
false);
1070 info() <<
"Nb ghost layer for level " << level <<
" : " << target_nb_ghost_layers;
1072 return target_nb_ghost_layers;
1078void CartesianMeshImpl::
1081 _addPatch(parent_cells_local_id);
1089void CartesianMeshImpl::
1097 for (
Int32 cell_local_id : parent_cells) {
1098 Cell c = cells[cell_local_id];
1111void CartesianMeshImpl::
1119 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1123 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1124 if (total_nb_cell == 0)
1127 debug() <<
"Refine with modifier() (for all mesh types)";
1128 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1129 m_mesh->modifier()->adapt();
1131 _addPatch(cells_local_id);
1134 else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1135 debug() <<
"Refine with specific refiner (for cartesian mesh only)";
1136 m_patch_group.addPatch(position);
1139 else if (m_amr_type == eMeshAMRKind::Patch) {
1140 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1147 MeshStats ms(traceMng(),m_mesh,m_mesh->parallelMng());
1155void CartesianMeshImpl::
1156_applyCoarse(
const AMRZonePosition& zone_position)
1158 if (m_amr_type == eMeshAMRKind::Cell) {
1159 UniqueArray<Int32> cells_local_id;
1161 zone_position.cellsInPatch(mesh(), cells_local_id);
1163 Integer nb_cell = cells_local_id.size();
1164 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1166 IParallelMng* pm = m_mesh->parallelMng();
1167 Int64 total_nb_cell = pm->
reduce(Parallel::ReduceSum, nb_cell);
1168 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1169 if (total_nb_cell == 0)
1172 debug() <<
"Coarse with modifier() (for all mesh types)";
1173 m_patch_group.removeCellsInAllPatches(cells_local_id);
1174 m_patch_group.applyPatchEdit(
true);
1176 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1177 m_mesh->modifier()->coarsenItemsV2(
true);
1180 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1181 debug() <<
"Coarsen with specific coarser (for cartesian mesh only)";
1182 m_patch_group.removeCellsInZone(zone_position);
1185 else if (m_amr_type == eMeshAMRKind::Patch) {
1186 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1193 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1201void CartesianMeshImpl::
1204 info(4) <<
"Check valid CartesianMesh";
1206 for(
Integer i=0; i<nb_patch; ++i ){
1215void CartesianMeshImpl::
1218 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1221 Int32 face_method = v.renumberFaceMethod();
1222 if (face_method!=0 && face_method!=1)
1223 ARCANE_FATAL(
"Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1229 Int32 patch_method = v.renumberPatchMethod();
1230 if (patch_method < 0 || patch_method > 4) {
1231 ARCANE_FATAL(
"Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1235 ARCANE_FATAL(
"Mesh items renumbering is not compatible with this type of AMR");
1238 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1240 renumberer.renumber();
1242 else if (patch_method == 2) {
1243 warning() <<
"The patch method 2 is experimental!";
1245 renumberer.renumber();
1249 if (v.isSortAfterRenumbering()){
1250 info() <<
"Compacting and Sorting after renumbering";
1251 m_mesh->nodeFamily()->compactItems(
true);
1252 m_mesh->faceFamily()->compactItems(
true);
1253 m_mesh->cellFamily()->compactItems(
true);
1262createCartesianMeshCoarsening()
1271_createCartesianMeshCoarsening2()
1287 const char* name =
"CartesianMesh";
1296 ARCANE_FATAL(
"The mesh {0} is not yet created",h.meshName());
1303 mesh->_internalApi()->setMeshKind(mk);
1310 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.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Méthode permettant de retrouver les mailles incluses dans la zone.
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.
void initCartesianMeshNumberingMngInternal() override
Méthode permettant de créer une instance de CartesianMeshNumberingMngInternal.
Ref< ICartesianMeshNumberingMngInternal > cartesianMeshNumberingMngInternal() override
Méthode permettant de récupérer l'instance de CartesianMeshNumberingMngInternal.
void addPatchFromExistingChildren(ConstArrayView< Int32 > parent_cells_local_id) override
Créé un patch avec tous les enfants des mailles parent_cells_local_id.
Ref< ICartesianMeshAMRPatchMng > cartesianMeshAMRPatchMng() override
Méthode permettant de récupérer l'instance de CartesianMeshAMRPatchMng.
Ref< CartesianMeshCoarsening2 > createCartesianMeshCoarsening2() override
Créé une instance pour gérer le déraffinement du maillage (V2).
void initCartesianMeshAMRPatchMng() override
Méthode permettant de créer une instance de CartesianMeshAMRPatchMng.
CartesianPatchGroup & cartesianPatchGroup() override
Méthode permettant de récupérer le CartesianPatchGroup.
Infos spécifiques à 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...
CartesianPatchGroup m_patch_group
Groupe de mailles pour chaque patch AMR.
void refinePatch(const AMRZonePosition &position) override
Raffine un bloc du maillage cartésien.
ITraceMng * traceMng() const override
Gestionnaire de trace 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)
Int32 m_local_face_direction[3]
Indice dans la numérotation locale de la maille, de la face dans.
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.
void _addPatch(ConstArrayView< Int32 > parent_cells)
Créé un patch avec tous les enfants du groupe parent_cells.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
Vue sur une liste de patchs.
Informations par direction pour chaque genre d'entité du maillage.
Informations pour la renumérotation.
Renumérotation des uniqueId() pour les maillages cartésiens.
Renumérotation des uniqueId() pour les maillages cartésiens.
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.
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Cell hChild(Int32 i) const
i-ème enfant AMR
Vue constante d'un tableau de type T.
Conserve des références d'observateurs.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Partie interne de ICartesianMesh.
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.
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
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
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 Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
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é.
Exception lorsqu'une fonction n'est pas implémentée.
Classe gérant un vecteur de réel de dimension 2.
Classe gérant un vecteur de réel de dimension 3.
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
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)
Converti 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é
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
ICartesianMesh * arcaneCreateCartesianMesh(IMesh *mesh)
eMeshAMRKind
Type de maillage AMR.
@ 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