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;
216 void _computeDirectionsV2();
220 InternalApi m_internal_api;
224 IMesh* m_mesh =
nullptr;
230 bool m_is_amr =
false;
236 bool m_is_mesh_event_added =
false;
237 Int64 m_mesh_timestamp = 0;
256 void _saveInfosInProperties();
258 std::tuple<CellGroup, NodeGroup>
260 void _checkNeedComputeDirections();
261 void _checkAddObservableMeshChanged();
279CartesianMeshImpl(IMesh* mesh)
280: TraceAccessor(mesh->traceMng())
281, m_internal_api(this)
283, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
284, m_cells_to_node_storage(platform::getDefaultDataAllocator())
285, m_permutation_storage(platform::getDefaultDataAllocator())
287, m_amr_type(mesh->meshKind().meshAMRKind())
290 m_internal_api.initCartesianMeshNumberingMngInternal();
291 m_internal_api.initCartesianMeshAMRPatchMng();
293 m_all_items_direction_info = m_patch_group.groundPatch();
299void CartesianMeshImpl::
302 m_properties =
new Properties(*(mesh()->properties()),
"CartesianMesh");
303 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
304 m_internal_api.cartesianMeshNumberingMngInternal()->_build();
310const Int32 SERIALIZE_VERSION = 1;
316void CartesianMeshImpl::
317_checkNeedComputeDirections()
319 Int64 new_timestamp = mesh()->timestamp();
320 if (m_mesh_timestamp!=new_timestamp){
321 info() <<
"Mesh timestamp has changed (old=" << m_mesh_timestamp <<
" new=" << new_timestamp <<
")";
329void CartesianMeshImpl::
330_saveInfosInProperties()
333 m_properties->set(
"Version",SERIALIZE_VERSION);
336 UniqueArray<String> patch_group_names;
337 for (Integer i = 1; i < m_patch_group.nbPatch(); ++i) {
338 patch_group_names.add(m_patch_group.allCells(i).name());
340 m_properties->set(
"PatchGroupNames",patch_group_names);
347 m_properties->set(
"PatchGroupNamesAvailable", m_patch_group.availableGroupIndex());
349 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
350 m_internal_api.cartesianMeshNumberingMngInternal()->_saveInfosInProperties();
358void CartesianMeshImpl::
361 info() <<
"Creating 'CartesianMesh' infos from dump";
364 m_internal_api.cartesianMeshNumberingMngInternal()->_recreateFromDump();
365 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
369 Int32 v = m_properties->getInt32(
"Version");
370 if (v!=SERIALIZE_VERSION)
371 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
372 v,SERIALIZE_VERSION);
376 m_properties->get(
"PatchGroupNames",patch_group_names);
377 info(4) <<
"Found n=" << patch_group_names.
size() <<
" patchs";
381 for (
const String& x : patch_group_names) {
388 m_properties->get(
"PatchGroupNamesAvailable", available_index);
397void CartesianMeshImpl::
398_checkAddObservableMeshChanged()
400 if (m_is_mesh_event_added)
402 m_is_mesh_event_added =
true;
405 auto f1 = [&](
const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
406 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool,f1);
412void CartesianMeshImpl::
417 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
418 _computeDirectionsV2();
421 info() <<
"CartesianMesh: computeDirections()";
423 m_mesh_timestamp =
mesh()->timestamp();
424 _checkAddObservableMeshChanged();
426 m_is_amr = m_mesh->isAmrActivated();
436 for( NodeLocalId inode : cell.
nodeIds() )
437 center += nodes_coord[inode];
439 cells_center[icell] = center;
444 for( NodeLocalId inode : face.
nodeIds() )
445 center += nodes_coord[inode];
447 faces_center[iface] = center;
452 Int32 next_face_x = -1;
453 Int32 next_face_y = -1;
454 Int32 next_face_z = -1;
457 Cell cell0 = cell_view[0];
460 Real3 cell_center = cells_center[cell0];
467 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
469 for(
Integer i=0; i<nb_node; ++i ){
471 info(4) <<
"Node I=" << i <<
" node=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
474 bool is_3d = m_mesh->dimension() == 3;
484 for (
Integer i = 0; i < nb_face; ++i) {
487 Real3 next_center = faces_center[f];
489 Real diff_x = next_center.
x - cell_center.
x;
490 Real diff_y = next_center.
y - cell_center.
y;
491 Real diff_z = next_center.
z - cell_center.
z;
493 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
495 if (diff_x > max_x) {
500 if (diff_y > max_y) {
505 if (diff_z > max_z) {
510 info(4) <<
"Advance in direction X -> " << next_face_x;
511 info(4) <<
"Advance in direction Y -> " << next_face_y;
512 info(4) <<
"Advance in direction Z -> " << next_face_z;
518 for (
Integer i = 0; i < nb_face; ++i) {
521 Real3 next_center = faces_center[f];
523 Real diff_x = next_center.
x - cell_center.
x;
524 Real diff_y = next_center.
y - cell_center.
y;
526 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
528 if (diff_x > max_x) {
533 if (diff_y > max_y) {
538 info(4) <<
"Advance in direction X -> " << next_face_x;
539 info(4) <<
"Advance in direction Y -> " << next_face_y;
541 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
543 info() <<
"Informations from IMesh properties:";
545 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
547 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
548 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
549 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
550 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
555 auto x = _buildPatchGroups(
mesh()->allLevelCells(0),0);
556 all_cells = std::get<0>(x);
557 all_nodes = std::get<1>(x);
560 if (next_face_x!=(-1)){
562 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
564 if (next_face_y!=(-1)){
566 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
568 if (next_face_z != (-1)) {
570 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
574 for(
Integer idir=0, nb_dir=
mesh()->dimension(); idir<nb_dir; ++idir ){
576 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
577 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
580 info() <<
"Compute cartesian connectivity";
582 m_permutation_storage.resize(1);
583 m_permutation_storage[0].compute();
584 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
585 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
586 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
587 m_connectivity._computeInfos(
mesh(),nodes_coord,cells_center);
594 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" <<
m_patch_group.nbPatch();
595 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
596 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
597 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
598 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
600 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
606 _saveInfosInProperties();
612std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
625 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
630 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
634 info(4) <<
"PATCH_CELLS name=" << patch_cells.
name() <<
" size=" << patch_cells.
size();
635 info(4) <<
"PATCH_NODES name=" << patch_nodes.
name() <<
" size=" << patch_nodes.
size();
636 return { patch_cells, patch_nodes };
642void CartesianMeshImpl::
643_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center,
644 VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes)
646 IItemFamily* cell_family = m_mesh->cellFamily();
647 IItemFamily* face_family = m_mesh->faceFamily();
648 IItemFamily* node_family = m_mesh->nodeFamily();
650 Int32 max_cell_id = cell_family->
maxLocalId();
651 Int32 max_face_id = face_family->maxLocalId();
652 Int32 max_node_id = node_family->maxLocalId();
654 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
655 cell_dm._internalResizeInfos(max_cell_id);
657 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
658 face_dm._internalResizeInfos(max_face_id);
660 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
661 node_dm._internalResizeInfos(max_node_id);
664 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
666 Int32 prev_local_face = -1;
667 Int32 next_local_face = m_local_face_direction[dir];
668 Integer mesh_dim = m_mesh->dimension();
671 prev_local_face = (next_local_face + 2) % 4;
672 else if (mesh_dim==3)
673 prev_local_face = (next_local_face + 3) % 6;
675 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
679 std::set<Int32> cells_set;
681 cells_set.insert(icell.itemLocalId());
688 Int32 my_level = cell.level();
689 Face next_face = cell.face(next_local_face);
690 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
691 if (cells_set.find(next_cell.localId()) == cells_set.end())
693 else if (next_cell.level() != my_level)
696 Face prev_face = cell.face(prev_local_face);
697 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
698 if (cells_set.find(prev_cell.localId()) == cells_set.end())
700 else if (prev_cell.level() != my_level)
702 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
704 cell_dm._internalComputeInnerAndOuterItems(all_cells);
705 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
706 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
712void CartesianMeshImpl::
713_computeDirectionsV2()
715 info() <<
"CartesianMesh: computeDirectionsV2()";
717 m_mesh_timestamp = mesh()->timestamp();
718 _checkAddObservableMeshChanged();
720 m_is_amr = m_mesh->isAmrActivated();
722 IItemFamily* cell_family = m_mesh->cellFamily();
723 IItemFamily* node_family = m_mesh->nodeFamily();
725 bool is_3d = m_mesh->dimension() == 3;
727 m_all_items_direction_info->_internalComputeNodeCellInformations();
729 info() <<
"Informations from IMesh properties:";
731 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
733 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
734 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
735 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
736 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
738 CellGroup all_cells = cell_family->allItems();
739 NodeGroup all_nodes = node_family->allItems();
741 auto x = _buildPatchGroups(mesh()->allLevelCells(0), 0);
742 all_cells = std::get<0>(x);
743 all_nodes = std::get<1>(x);
746 m_local_face_direction[
MD_DirX] = 4;
747 m_local_face_direction[
MD_DirY] = 5;
748 m_local_face_direction[
MD_DirZ] = 3;
751 m_local_face_direction[
MD_DirX] = 1;
752 m_local_face_direction[
MD_DirY] = 2;
755 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells,
CellGroup(), all_nodes);
756 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells,
CellGroup(), all_nodes);
758 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells,
CellGroup(), all_nodes);
762 for (Integer idir = 0, nb_dir = mesh()->dimension(); idir < nb_dir; ++idir) {
763 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
764 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
765 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
768 info() <<
"Compute cartesian connectivity";
770 m_permutation_storage.resize(1);
771 m_permutation_storage[0].compute();
772 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
773 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
774 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
775 m_connectivity._computeInfos(
this);
779 for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
780 CellGroup cells = m_patch_group.allCells(patch_index);
781 Ref<CartesianMeshPatch> patch = m_patch_group.patch(patch_index);
782 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
784 const AMRPatchPosition position = patch->position();
785 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
787 patch->_internalComputeNodeCellInformations();
788 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
789 _computeMeshDirectionV2(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes);
790 _computeMeshDirectionV2(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes);
792 _computeMeshDirectionV2(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overallCells(patch_index), patch_nodes);
799 _saveInfosInProperties();
805void CartesianMeshImpl::
806_computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overall_cells, NodeGroup all_nodes)
808 IItemFamily* cell_family = m_mesh->cellFamily();
809 IItemFamily* face_family = m_mesh->faceFamily();
810 IItemFamily* node_family = m_mesh->nodeFamily();
812 Int32 max_cell_id = cell_family->maxLocalId();
813 Int32 max_face_id = face_family->maxLocalId();
814 Int32 max_node_id = node_family->maxLocalId();
816 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
817 cell_dm._internalResizeInfos(max_cell_id);
819 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
820 face_dm._internalResizeInfos(max_face_id);
822 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
823 node_dm._internalResizeInfos(max_node_id);
826 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
828 Int32 prev_local_face = -1;
829 Int32 next_local_face = m_local_face_direction[dir];
830 Integer mesh_dim = m_mesh->dimension();
833 prev_local_face = (next_local_face + 2) % 4;
834 else if (mesh_dim == 3)
835 prev_local_face = (next_local_face + 3) % 6;
837 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
841 std::set<Int32> cells_set;
843 cells_set.insert(icell.itemLocalId());
850 Int32 my_level = cell.level();
851 Face next_face = cell.face(next_local_face);
852 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
853 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
857 Face prev_face = cell.face(prev_local_face);
858 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
859 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
863 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
865 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overall_cells);
866 face_dm._internalComputeInfos(cell_dm);
867 node_dm._internalComputeInfos(cell_dm, all_nodes);
873void CartesianMeshImpl::
876 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
883void CartesianMeshImpl::
886 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
893void CartesianMeshImpl::
896 _applyRefine(position);
897 _saveInfosInProperties();
903void CartesianMeshImpl::
906 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
913void CartesianMeshImpl::
916 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
923void CartesianMeshImpl::
926 _applyCoarse(position);
927 _saveInfosInProperties();
937 ARCANE_FATAL(
"You cannot reduce number of ghost layer of level 0 with this method");
941 const Int32 max_nb_layer = 128;
945 level_max = std::max(level_max, icell->level());
953 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
956 if (level_0_nb_ghost_layer == 0) {
965 if (target_nb_ghost_layers % 2 != 0) {
966 target_nb_ghost_layers++;
969 if (target_nb_ghost_layers == nb_ghost_layer) {
970 return nb_ghost_layer;
975 Integer parent_level = level - 1;
976 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
982 std::function<void(
Cell)> children_list;
984 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
985 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
987 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
988 children_list(cell.hChild(i));
1001 Cell front_cell = iface->frontCell();
1002 Cell back_cell = iface->backCell();
1004 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
1005 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
1006 for (
Node node : iface->nodes()) {
1007 level_node[node] = 0;
1013 bool is_modif =
true;
1014 Int32 current_layer = 0;
1019 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
1023 Int32 min = max_nb_layer;
1026 for (
Node node : icell->nodes()) {
1027 Int32 nlevel = level_node[node];
1029 min = std::min(min, nlevel);
1030 max = std::max(max, nlevel);
1035 if (min != current_layer) {
1040 if (min == max_nb_layer && max == -1) {
1044 Integer new_level = ((min == max) ? min + 1 : max);
1046 for (
Node node : icell->nodes()) {
1047 Int32 nlevel = level_node[node];
1049 level_node[node] = new_level;
1055 level_cell[icell] = min;
1060 if (min >= parent_target_nb_ghost_layer) {
1061 children_list(*icell);
1065 if (current_layer >= max_nb_layer) {
1066 ARCANE_FATAL(
"Error in ghost layer counter algo. Report it plz.");
1071 for (
Integer i = level_max - 1; i >= 0; --i) {
1078 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1079 m_mesh->modifier()->coarsenItemsV2(
false);
1082 info() <<
"Nb ghost layer for level " << level <<
" : " << target_nb_ghost_layers;
1084 return target_nb_ghost_layers;
1090void CartesianMeshImpl::
1093 m_patch_group.updateLevelsBeforeAddGroundPatch();
1094 _addPatch(parent_cells_local_id);
1102void CartesianMeshImpl::
1110 for (
Int32 cell_local_id : parent_cells) {
1111 Cell c = cells[cell_local_id];
1124void CartesianMeshImpl::
1131 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1135 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1136 if (total_nb_cell==0)
1140 debug() <<
"Refine with modifier() (for all mesh types)";
1141 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1142 m_mesh->modifier()->adapt();
1144 else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1145 debug() <<
"Refine with specific refiner (for cartesian mesh only)";
1146 computeDirections();
1147 m_internal_api.cartesianMeshAMRPatchMng()->flagCellToRefine(cells_local_id,
true);
1148 m_internal_api.cartesianMeshAMRPatchMng()->refine();
1150 else if(m_amr_type == eMeshAMRKind::Patch) {
1151 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1158 MeshStats ms(traceMng(),m_mesh,m_mesh->parallelMng());
1161 _addPatch(cells_local_id);
1167void CartesianMeshImpl::
1168_applyCoarse(
const AMRZonePosition& zone_position)
1170 UniqueArray<Int32> cells_local_id;
1171 AMRPatchPosition patch_position;
1172 if (m_amr_type == eMeshAMRKind::Cell) {
1173 zone_position.cellsInPatch(mesh(), cells_local_id);
1175 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1176 zone_position.cellsInPatch(
this, cells_local_id, patch_position);
1179 Integer nb_cell = cells_local_id.size();
1180 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1182 IParallelMng* pm = m_mesh->parallelMng();
1183 Int64 total_nb_cell = pm->
reduce(Parallel::ReduceSum, nb_cell);
1184 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1185 if (total_nb_cell == 0)
1188 if (m_amr_type == eMeshAMRKind::Cell) {
1189 debug() <<
"Coarse with modifier() (for all mesh types)";
1190 m_patch_group.removeCellsInAllPatches(cells_local_id);
1191 m_patch_group.applyPatchEdit(
true);
1193 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1194 m_mesh->modifier()->coarsenItemsV2(
true);
1196 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1197 debug() <<
"Coarsen with specific coarser (for cartesian mesh only)";
1198 m_patch_group.removeCellsInAllPatches(patch_position);
1199 m_patch_group.applyPatchEdit(
false);
1201 computeDirections();
1202 m_internal_api.cartesianMeshAMRPatchMng()->flagCellToCoarsen(cells_local_id,
true);
1203 m_internal_api.cartesianMeshAMRPatchMng()->coarsen(
true);
1205 else if (m_amr_type == eMeshAMRKind::Patch) {
1206 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1213 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1221void CartesianMeshImpl::
1224 info(4) <<
"Check valid CartesianMesh";
1226 for(
Integer i=0; i<nb_patch; ++i ){
1235void CartesianMeshImpl::
1238 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1241 Int32 face_method = v.renumberFaceMethod();
1242 if (face_method!=0 && face_method!=1)
1243 ARCANE_FATAL(
"Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1249 ARCANE_FATAL(
"Face renumbering is not compatible with this type of AMR");
1253 Int32 patch_method = v.renumberPatchMethod();
1254 if (patch_method < 0 || patch_method > 4)
1255 ARCANE_FATAL(
"Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1258 else if (patch_method == 1 || patch_method == 3 || patch_method == 4){
1260 renumberer.renumber();
1262 else if (patch_method == 2){
1263 warning() <<
"The patch method 2 is experimental!";
1265 renumberer.renumber();
1269 if (v.isSortAfterRenumbering()){
1270 info() <<
"Compacting and Sorting after renumbering";
1271 m_mesh->nodeFamily()->compactItems(
true);
1272 m_mesh->faceFamily()->compactItems(
true);
1273 m_mesh->cellFamily()->compactItems(
true);
1282createCartesianMeshCoarsening()
1291_createCartesianMeshCoarsening2()
1307 const char* name =
"CartesianMesh";
1316 ARCANE_FATAL(
"The mesh {0} is not yet created",h.meshName());
1323 mesh->_internalApi()->setMeshKind(mk);
1330 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 findGroup(const String &name) const =0
Recherche un groupe.
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.
bool null() const
true is le groupe est le groupe nul
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