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
82 :
public ICartesianMeshInternal
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);
101 void initCartesianMeshAMRPatchMng()
override
103 if (m_numbering_mng.
isNull()) {
104 initCartesianMeshNumberingMngInternal();
107 m_amr_mng =
makeRef(
new CartesianMeshAMRPatchMng(m_cartesian_mesh, m_numbering_mng.
get()));
114 void initCartesianMeshNumberingMngInternal()
override
116 if (m_numbering_mng.
isNull()) {
117 m_numbering_mng =
makeRef(
new CartesianMeshNumberingMngInternal(m_cartesian_mesh->
mesh()));
122 return m_numbering_mng;
124 CartesianPatchGroup& cartesianPatchGroup()
override {
return m_cartesian_mesh->_cartesianPatchGroup(); }
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;
208 ICartesianMeshInternal*
_internalApi()
override {
return &m_internal_api; }
215 CartesianPatchGroup& _cartesianPatchGroup() {
return m_patch_group; }
216 void _computeDirectionsV2();
220 InternalApi m_internal_api;
223 Int32 m_local_face_direction[3] = { -1, -1, -1 };
224 IMesh* m_mesh =
nullptr;
225 Ref<CartesianMeshPatch> m_all_items_direction_info;
226 CartesianConnectivity m_connectivity;
227 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
228 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
229 UniqueArray<CartesianConnectivity::Permutation> m_permutation_storage;
230 bool m_is_amr =
false;
232 CartesianPatchGroup m_patch_group;
233 ScopedPtrT<Properties> m_properties;
235 EventObserverPool m_event_pool;
236 bool m_is_mesh_event_added =
false;
237 Int64 m_mesh_timestamp = 0;
242 void _computeMeshDirection(CartesianMeshPatch& cdi,
eMeshDirection dir,
247 void _computeMeshDirectionV2(CartesianMeshPatch& cdi,
eMeshDirection dir,
253 void _applyRefine(
const AMRZonePosition &position);
254 void _applyCoarse(
const AMRZonePosition& zone_position);
255 void _addPatch(ConstArrayView<Int32> parent_cells);
256 void _saveInfosInProperties();
258 std::tuple<CellGroup, NodeGroup>
260 void _checkNeedComputeDirections();
261 void _checkAddObservableMeshChanged();
268arcaneCreateCartesianMesh(
IMesh* mesh)
279CartesianMeshImpl(
IMesh* mesh)
281, m_internal_api(this)
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");
304 m_internal_api.cartesianMeshNumberingMngInternal()->build();
306 m_patch_group.build();
311const Int32 SERIALIZE_VERSION = 1;
317void CartesianMeshImpl::
318_checkNeedComputeDirections()
321 if (m_mesh_timestamp!=new_timestamp){
322 info() <<
"Mesh timestamp has changed (old=" << m_mesh_timestamp <<
" new=" << new_timestamp <<
")";
330void CartesianMeshImpl::
331_saveInfosInProperties()
334 m_properties->set(
"Version",SERIALIZE_VERSION);
336 m_patch_group.saveInfosInProperties();
339 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
350 info() <<
"Creating 'CartesianMesh' infos from dump";
353 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
354 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
358 Int32 v = m_properties->getInt32(
"Version");
359 if (v!=SERIALIZE_VERSION)
360 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
361 v,SERIALIZE_VERSION);
363 m_patch_group.recreateFromDump();
365 m_all_items_direction_info = m_patch_group.groundPatch();
373void CartesianMeshImpl::
374_checkAddObservableMeshChanged()
376 if (m_is_mesh_event_added)
378 m_is_mesh_event_added =
true;
381 auto f1 = [&](
const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
393 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
394 _computeDirectionsV2();
397 info() <<
"CartesianMesh: computeDirections()";
400 _checkAddObservableMeshChanged();
402 m_is_amr = m_mesh->isAmrActivated();
412 for( NodeLocalId inode : cell.
nodeIds() )
413 center += nodes_coord[inode];
415 cells_center[icell] = center;
420 for( NodeLocalId inode : face.
nodeIds() )
421 center += nodes_coord[inode];
423 faces_center[iface] = center;
428 Int32 next_face_x = -1;
429 Int32 next_face_y = -1;
430 Int32 next_face_z = -1;
433 Cell cell0 = cell_view[0];
436 Real3 cell_center = cells_center[cell0];
443 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
445 for(
Integer i=0; i<nb_node; ++i ){
447 info(4) <<
"Node I=" << i <<
" node=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
450 bool is_3d = m_mesh->dimension() == 3;
460 for (
Integer i = 0; i < nb_face; ++i) {
463 Real3 next_center = faces_center[f];
465 Real diff_x = next_center.
x - cell_center.
x;
466 Real diff_y = next_center.
y - cell_center.
y;
467 Real diff_z = next_center.
z - cell_center.
z;
469 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
471 if (diff_x > max_x) {
476 if (diff_y > max_y) {
481 if (diff_z > max_z) {
486 info(4) <<
"Advance in direction X -> " << next_face_x;
487 info(4) <<
"Advance in direction Y -> " << next_face_y;
488 info(4) <<
"Advance in direction Z -> " << next_face_z;
494 for (
Integer i = 0; i < nb_face; ++i) {
497 Real3 next_center = faces_center[f];
499 Real diff_x = next_center.
x - cell_center.
x;
500 Real diff_y = next_center.
y - cell_center.
y;
502 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
504 if (diff_x > max_x) {
509 if (diff_y > max_y) {
514 info(4) <<
"Advance in direction X -> " << next_face_x;
515 info(4) <<
"Advance in direction Y -> " << next_face_y;
517 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
519 info() <<
"Informations from IMesh properties:";
521 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
523 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
524 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
525 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
526 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
531 auto x = _buildPatchGroups(
mesh()->allLevelCells(0),0);
532 all_cells = std::get<0>(x);
533 all_nodes = std::get<1>(x);
536 if (next_face_x!=(-1)){
537 m_local_face_direction[
MD_DirX] = next_face_x;
538 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
540 if (next_face_y!=(-1)){
541 m_local_face_direction[
MD_DirY] = next_face_y;
542 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
544 if (next_face_z != (-1)) {
545 m_local_face_direction[
MD_DirZ] = next_face_z;
546 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
550 for(
Integer idir=0, nb_dir=
mesh()->dimension(); idir<nb_dir; ++idir ){
552 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
553 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
556 info() <<
"Compute cartesian connectivity";
558 m_permutation_storage.resize(1);
559 m_permutation_storage[0].compute();
560 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
561 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
562 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
563 m_connectivity._computeInfos(
mesh(),nodes_coord,cells_center);
567 for (
Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
568 CellGroup cells = m_patch_group.allCells(patch_index);
570 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
571 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
572 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
573 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
574 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
576 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
582 _saveInfosInProperties();
588std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
601 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
606 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
610 info(4) <<
"PATCH_CELLS name=" << patch_cells.
name() <<
" size=" << patch_cells.
size();
611 info(4) <<
"PATCH_NODES name=" << patch_nodes.
name() <<
" size=" << patch_nodes.
size();
612 return { patch_cells, patch_nodes };
618void CartesianMeshImpl::
622 IItemFamily* cell_family = m_mesh->cellFamily();
623 IItemFamily* face_family = m_mesh->faceFamily();
624 IItemFamily* node_family = m_mesh->nodeFamily();
627 Int32 max_face_id = face_family->maxLocalId();
628 Int32 max_node_id = node_family->maxLocalId();
630 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
631 cell_dm._internalResizeInfos(max_cell_id);
633 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
634 face_dm._internalResizeInfos(max_face_id);
636 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
637 node_dm._internalResizeInfos(max_node_id);
640 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
642 Int32 prev_local_face = -1;
643 Int32 next_local_face = m_local_face_direction[dir];
644 Integer mesh_dim = m_mesh->dimension();
647 prev_local_face = (next_local_face + 2) % 4;
648 else if (mesh_dim==3)
649 prev_local_face = (next_local_face + 3) % 6;
651 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
655 std::set<Int32> cells_set;
657 cells_set.insert(icell.itemLocalId());
664 Int32 my_level = cell.level();
665 Face next_face = cell.face(next_local_face);
666 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
667 if (cells_set.find(next_cell.localId()) == cells_set.end())
669 else if (next_cell.level() != my_level)
672 Face prev_face = cell.face(prev_local_face);
673 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
674 if (cells_set.find(prev_cell.localId()) == cells_set.end())
676 else if (prev_cell.level() != my_level)
678 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
680 cell_dm._internalComputeInnerAndOuterItems(all_cells);
681 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
682 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
688void CartesianMeshImpl::
689_computeDirectionsV2()
691 info() <<
"CartesianMesh: computeDirectionsV2()";
694 _checkAddObservableMeshChanged();
696 m_is_amr = m_mesh->isAmrActivated();
698 IItemFamily* cell_family = m_mesh->cellFamily();
699 IItemFamily* node_family = m_mesh->nodeFamily();
701 bool is_3d = m_mesh->dimension() == 3;
703 m_all_items_direction_info->_internalComputeNodeCellInformations();
705 info() <<
"Informations from IMesh properties:";
707 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
709 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
710 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
711 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
712 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
714 CellGroup all_cells = cell_family->allItems();
715 NodeGroup all_nodes = node_family->allItems();
717 auto x = _buildPatchGroups(
mesh()->allLevelCells(0), 0);
718 all_cells = std::get<0>(x);
719 all_nodes = std::get<1>(x);
722 m_local_face_direction[
MD_DirX] = 4;
723 m_local_face_direction[
MD_DirY] = 5;
724 m_local_face_direction[
MD_DirZ] = 3;
727 m_local_face_direction[
MD_DirX] = 1;
728 m_local_face_direction[
MD_DirY] = 2;
731 _computeMeshDirectionV2(*m_all_items_direction_info.get(),
MD_DirX, all_cells, all_cells,
CellGroup(), all_nodes);
732 _computeMeshDirectionV2(*m_all_items_direction_info.get(),
MD_DirY, all_cells, all_cells,
CellGroup(), all_nodes);
734 _computeMeshDirectionV2(*m_all_items_direction_info.get(),
MD_DirZ, all_cells, all_cells,
CellGroup(), all_nodes);
738 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
739 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
740 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
741 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
744 info() <<
"Compute cartesian connectivity";
746 m_permutation_storage.resize(1);
747 m_permutation_storage[0].compute();
748 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
749 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
750 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
751 m_connectivity._computeInfos(
this);
755 for (
Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
756 CellGroup cells = m_patch_group.allCells(patch_index);
757 Ref<CartesianMeshPatch>
patch = m_patch_group.patch(patch_index);
758 info() <<
"AMR Patch name=" << cells.name() <<
" size=" << cells.size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
760 const AMRPatchPosition position =
patch->position();
761 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
763 patch->_internalComputeNodeCellInformations();
764 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
765 _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);
766 _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);
768 _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);
775 _saveInfosInProperties();
781void CartesianMeshImpl::
784 IItemFamily* cell_family = m_mesh->cellFamily();
785 IItemFamily* face_family = m_mesh->faceFamily();
786 IItemFamily* node_family = m_mesh->nodeFamily();
788 Int32 max_cell_id = cell_family->maxLocalId();
789 Int32 max_face_id = face_family->maxLocalId();
790 Int32 max_node_id = node_family->maxLocalId();
792 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
793 cell_dm._internalResizeInfos(max_cell_id);
795 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
796 face_dm._internalResizeInfos(max_face_id);
798 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
799 node_dm._internalResizeInfos(max_node_id);
802 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
804 Int32 prev_local_face = -1;
805 Int32 next_local_face = m_local_face_direction[dir];
806 Integer mesh_dim = m_mesh->dimension();
809 prev_local_face = (next_local_face + 2) % 4;
810 else if (mesh_dim == 3)
811 prev_local_face = (next_local_face + 3) % 6;
813 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
817 std::set<Int32> cells_set;
819 cells_set.insert(icell.itemLocalId());
826 Int32 my_level = cell.level();
827 Face next_face = cell.face(next_local_face);
828 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
829 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
833 Face prev_face = cell.face(prev_local_face);
834 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
835 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
839 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
841 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overall_cells);
842 face_dm._internalComputeInfos(cell_dm);
843 node_dm._internalComputeInfos(cell_dm, all_nodes);
852 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
862 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
872 _applyRefine(position);
873 _saveInfosInProperties();
882 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
892 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
902 _applyCoarse(position);
903 _saveInfosInProperties();
913 ARCANE_FATAL(
"You cannot reduce number of ghost layer of level 0 with this method");
917 const Int32 max_nb_layer = 128;
921 level_max = std::max(level_max, icell->level());
929 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
932 if (level_0_nb_ghost_layer == 0) {
941 if (target_nb_ghost_layers % 2 != 0) {
942 target_nb_ghost_layers++;
945 if (target_nb_ghost_layers == nb_ghost_layer) {
946 return nb_ghost_layer;
951 Integer parent_level = level - 1;
952 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
958 std::function<void(
Cell)> children_list;
960 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
961 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
963 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
964 children_list(cell.hChild(i));
977 Cell front_cell = iface->frontCell();
978 Cell back_cell = iface->backCell();
980 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
981 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
982 for (
Node node : iface->nodes()) {
983 level_node[node] = 0;
989 bool is_modif =
true;
990 Int32 current_layer = 0;
995 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
999 Int32 min = max_nb_layer;
1002 for (
Node node : icell->nodes()) {
1003 Int32 nlevel = level_node[node];
1005 min = std::min(min, nlevel);
1006 max = std::max(max, nlevel);
1011 if (min != current_layer) {
1016 if (min == max_nb_layer && max == -1) {
1020 Integer new_level = ((min == max) ? min + 1 : max);
1022 for (
Node node : icell->nodes()) {
1023 Int32 nlevel = level_node[node];
1025 level_node[node] = new_level;
1031 level_cell[icell] = min;
1036 if (min >= parent_target_nb_ghost_layer) {
1037 children_list(*icell);
1041 if (current_layer >= max_nb_layer) {
1042 ARCANE_FATAL(
"Error in ghost layer counter algo. Report it plz.");
1047 for (
Integer i = level_max - 1; i >= 0; --i) {
1054 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1055 m_mesh->modifier()->coarsenItemsV2(
false);
1058 info() <<
"Nb ghost layer for level " << level <<
" : " << target_nb_ghost_layers;
1060 return target_nb_ghost_layers;
1066void CartesianMeshImpl::
1069 _addPatch(parent_cells_local_id);
1077void CartesianMeshImpl::
1078_addPatch(ConstArrayView<Int32> parent_cells)
1083 UniqueArray<Int32> children_local_id;
1084 CellInfoListView cells(m_mesh->
cellFamily());
1085 for (Int32 cell_local_id : parent_cells) {
1086 Cell c = cells[cell_local_id];
1087 for (
Integer k = 0; k < c.nbHChildren(); ++k) {
1088 Cell child = c.hChild(k);
1089 children_local_id.add(child.localId());
1093 m_patch_group.addPatch(children_local_id);
1099void CartesianMeshImpl::
1103 UniqueArray<Int32> cells_local_id;
1104 position.cellsInPatch(
mesh(), cells_local_id);
1106 Integer nb_cell = cells_local_id.size();
1107 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1109 IParallelMng* pm = m_mesh->parallelMng();
1111 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1112 if (total_nb_cell == 0)
1115 debug() <<
"Refine with modifier() (for all mesh types)";
1116 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1117 m_mesh->modifier()->adapt();
1119 _addPatch(cells_local_id);
1123 debug() <<
"Refine with specific refiner (for cartesian mesh only)";
1124 m_patch_group.addPatch(position);
1128 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1135 MeshStats ms(
traceMng(),m_mesh,m_mesh->parallelMng());
1143void CartesianMeshImpl::
1147 UniqueArray<Int32> cells_local_id;
1149 zone_position.cellsInPatch(
mesh(), cells_local_id);
1151 Integer nb_cell = cells_local_id.size();
1152 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1154 IParallelMng* pm = m_mesh->parallelMng();
1156 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1157 if (total_nb_cell == 0)
1160 debug() <<
"Coarse with modifier() (for all mesh types)";
1161 m_patch_group.removeCellsInAllPatches(cells_local_id);
1162 m_patch_group.applyPatchEdit(
true);
1164 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1165 m_mesh->modifier()->coarsenItemsV2(
true);
1169 debug() <<
"Coarsen with specific coarser (for cartesian mesh only)";
1170 m_patch_group.removeCellsInZone(zone_position);
1174 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1181 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1192 info(4) <<
"Check valid CartesianMesh";
1194 for(
Integer i=0; i<nb_patch; ++i ){
1206 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1209 Int32 face_method = v.renumberFaceMethod();
1210 if (face_method!=0 && face_method!=1)
1211 ARCANE_FATAL(
"Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1217 Int32 patch_method = v.renumberPatchMethod();
1218 if (patch_method < 0 || patch_method > 4) {
1219 ARCANE_FATAL(
"Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1223 ARCANE_FATAL(
"Mesh items renumbering is not compatible with this type of AMR");
1226 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1227 CartesianMeshUniqueIdRenumbering renumberer(
this, cmgi, v.parentPatch(), patch_method);
1228 renumberer.renumber();
1230 else if (patch_method == 2) {
1231 warning() <<
"The patch method 2 is experimental!";
1232 CartesianMeshUniqueIdRenumberingV2 renumberer(
this, cmgi);
1233 renumberer.renumber();
1237 if (v.isSortAfterRenumbering()){
1238 info() <<
"Compacting and Sorting after renumbering";
1239 m_mesh->nodeFamily()->compactItems(
true);
1240 m_mesh->faceFamily()->compactItems(
true);
1241 m_mesh->cellFamily()->compactItems(
true);
1259_createCartesianMeshCoarsening2()
1275 const char* name =
"CartesianMesh";
1284 ARCANE_FATAL(
"The mesh {0} is not yet created",h.meshName());
1291 mesh->_internalApi()->setMeshKind(mk);
1298 return adud->data();
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les mécanismes de gestion des évènements.
Classe permettant de définir une zone d'un maillage.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Informations de connectivité d'un maillage cartésien.
Déraffine un maillage cartésien par 2.
Déraffine un maillage cartésien par 2.
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...
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)
void checkValid() const override
Effectue des vérifications sur la validité de l'instance.
IMesh * mesh() const override
Maillage associé à ce maillage cartésien.
FaceDirectionMng faceDirection(eMeshDirection dir) override
Liste des faces dans la direction dir.
NodeDirectionMng nodeDirection(eMeshDirection dir) override
Liste des noeuds dans la direction dir.
void refinePatch2D(Real2 position, Real2 length) override
Raffine en 2D un bloc du maillage cartésien.
ICartesianMeshPatch * patch(Int32 index) const override
Retourne le index-ième patch du maillage.
void coarseZone2D(Real2 position, Real2 length) override
Dé-raffine en 2D un bloc du maillage cartésien.
void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v) override
Renumérote les uniqueId() des entités.
ICartesianMeshInternal * _internalApi() override
API interne à Arcane.
void coarseZone3D(Real3 position, Real3 length) override
Dé-raffine en 3D un bloc du maillage cartésien.
Ref< CartesianMeshCoarsening > createCartesianMeshCoarsening() override
Créé une instance pour gérer le déraffinement du maillage.
CartesianPatch amrPatch(Int32 index) const override
Retourne le index-ième patch du maillage.
CellDirectionMng cellDirection(eMeshDirection dir) override
Liste des mailles dans la direction dir.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
Vue sur une liste de patchs.
Informations pour la renumérotation.
Patch AMR d'un maillage cartésien.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Vue sur les informations des mailles.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Vue constante d'un tableau de type T.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Interface d'un patch AMR d'un maillage cartésien.
virtual void checkValid() const =0
Effectue des vérifications sur la validité de l'instance.
Interface d'un maillage cartésien.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Récupère ou créé la référence associée à mesh.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
Interface d'une famille d'entités.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual Int32 maxLocalId() const =0
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual Int64 timestamp()=0
Compteur indiquant le temps de dernière modification du maillage.
virtual EventObservable< const MeshEventArgs & > & eventObservable(eMeshEventType type)=0
Observable pour un évènement.
Interface du gestionnaire de traces.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Classe de base d'une vue sur une connectivité non structurée.
NodeGroup nodeGroup() const
Groupe des noeuds des éléments de ce groupe.
const String & name() const
Nom du groupe.
ItemVectorView view() const
Vue sur les entités du groupe.
Integer size() const
Nombre d'éléments du groupe.
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul)
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe.
Classe utilitaire pour imprimer les infos sur une entité.
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
Node node(Int32 i) const
i-ème noeud de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
Arguments des évènements sur le maillage.
Classe de compatibilité pour contenir un MeshHandle ou un IMesh*.
const MeshHandle & handle() const
handle associé.
IMesh * meshOrNull() const
Retourne le maillage associé à cette instance.
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Caractéristiques d'un maillage.
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Classe gérant un vecteur de réel de dimension 2.
Classe gérant un vecteur de réel de dimension 3.
Référence à une instance.
Chaîne de caractères unicode.
Classe d'accès aux traces.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
bool isNull() const
Indique si le compteur référence une instance non nulle.
InstanceType * get() const
Instance associée ou nullptr si aucune.
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é
@ EndPrepareDump
Evènement envoyé à la fin de prepareForDump()
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
eMeshAMRKind
Type de maillage AMR.
@ Patch
Le maillage est AMR par patch.
@ Cell
Le maillage est AMR par maille.
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire)
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet