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(); }
126 void saveInfosInProperties()
override { m_cartesian_mesh->_saveInfosInProperties(); }
130 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
141 void build()
override;
151 return m_all_items_direction_info->cellDirection(dir);
156 return m_all_items_direction_info->cellDirection(idir);
161 return m_all_items_direction_info->faceDirection(dir);
166 return m_all_items_direction_info->faceDirection(idir);
171 return m_all_items_direction_info->nodeDirection(dir);
176 return m_all_items_direction_info->nodeDirection(idir);
185 return m_connectivity;
210 ICartesianMeshInternal*
_internalApi()
override {
return &m_internal_api; }
212 void computeDirectionsPatchV2(
Integer index)
override;
219 CartesianPatchGroup& _cartesianPatchGroup() {
return m_patch_group; }
220 void _computeDirectionsV2();
224 InternalApi m_internal_api;
227 Int32 m_local_face_direction[3] = { -1, -1, -1 };
228 IMesh* m_mesh =
nullptr;
229 Ref<CartesianMeshPatch> m_all_items_direction_info;
230 CartesianConnectivity m_connectivity;
231 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
232 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
233 UniqueArray<CartesianConnectivity::Permutation> m_permutation_storage;
234 bool m_is_amr =
false;
236 CartesianPatchGroup m_patch_group;
237 ScopedPtrT<Properties> m_properties;
239 EventObserverPool m_event_pool;
240 bool m_is_mesh_event_added =
false;
241 Int64 m_mesh_timestamp = 0;
246 void _computeMeshDirection(CartesianMeshPatch& cdi,
eMeshDirection dir,
251 void _computeMeshDirectionV2(CartesianMeshPatch& cdi,
eMeshDirection dir,
257 void _applyRefine(
const AMRZonePosition &position);
258 void _applyCoarse(
const AMRZonePosition& zone_position);
259 void _addPatch(ConstArrayView<Int32> parent_cells);
260 void _saveInfosInProperties();
262 std::tuple<CellGroup, NodeGroup>
264 void _checkNeedComputeDirections();
265 void _checkAddObservableMeshChanged();
272arcaneCreateCartesianMesh(
IMesh* mesh)
283CartesianMeshImpl(
IMesh* mesh)
285, m_internal_api(this)
291, m_amr_type(mesh->meshKind().meshAMRKind())
294 m_internal_api.initCartesianMeshNumberingMngInternal();
295 m_internal_api.initCartesianMeshAMRPatchMng();
297 m_all_items_direction_info = m_patch_group.groundPatch();
303void CartesianMeshImpl::
306 m_properties =
new Properties(*(
mesh()->properties()),
"CartesianMesh");
308 m_internal_api.cartesianMeshNumberingMngInternal()->build();
310 m_patch_group.build();
315const Int32 SERIALIZE_VERSION = 1;
321void CartesianMeshImpl::
322_checkNeedComputeDirections()
325 if (m_mesh_timestamp!=new_timestamp){
326 info() <<
"Mesh timestamp has changed (old=" << m_mesh_timestamp <<
" new=" << new_timestamp <<
")";
334void CartesianMeshImpl::
335_saveInfosInProperties()
338 m_properties->set(
"Version",SERIALIZE_VERSION);
340 m_patch_group.saveInfosInProperties();
343 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
354 info() <<
"Creating 'CartesianMesh' infos from dump";
357 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
358 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
362 Int32 v = m_properties->getInt32(
"Version");
363 if (v!=SERIALIZE_VERSION)
364 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
365 v,SERIALIZE_VERSION);
367 m_patch_group.recreateFromDump();
369 m_all_items_direction_info = m_patch_group.groundPatch();
377void CartesianMeshImpl::
378_checkAddObservableMeshChanged()
380 if (m_is_mesh_event_added)
382 m_is_mesh_event_added =
true;
385 auto f1 = [&](
const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
397 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
398 _computeDirectionsV2();
401 info() <<
"CartesianMesh: computeDirections()";
404 _checkAddObservableMeshChanged();
406 m_is_amr = m_mesh->isAmrActivated();
416 for( NodeLocalId inode : cell.
nodeIds() )
417 center += nodes_coord[inode];
419 cells_center[icell] = center;
424 for( NodeLocalId inode : face.
nodeIds() )
425 center += nodes_coord[inode];
427 faces_center[iface] = center;
432 Int32 next_face_x = -1;
433 Int32 next_face_y = -1;
434 Int32 next_face_z = -1;
437 Cell cell0 = cell_view[0];
440 Real3 cell_center = cells_center[cell0];
447 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
449 for(
Integer i=0; i<nb_node; ++i ){
451 info(4) <<
"Node I=" << i <<
" node=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
454 bool is_3d = m_mesh->dimension() == 3;
464 for (
Integer i = 0; i < nb_face; ++i) {
467 Real3 next_center = faces_center[f];
469 Real diff_x = next_center.
x - cell_center.
x;
470 Real diff_y = next_center.
y - cell_center.
y;
471 Real diff_z = next_center.
z - cell_center.
z;
473 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
475 if (diff_x > max_x) {
480 if (diff_y > max_y) {
485 if (diff_z > max_z) {
490 info(4) <<
"Advance in direction X -> " << next_face_x;
491 info(4) <<
"Advance in direction Y -> " << next_face_y;
492 info(4) <<
"Advance in direction Z -> " << next_face_z;
498 for (
Integer i = 0; i < nb_face; ++i) {
501 Real3 next_center = faces_center[f];
503 Real diff_x = next_center.
x - cell_center.
x;
504 Real diff_y = next_center.
y - cell_center.
y;
506 info(4) <<
"NEXT_FACE=" <<
ItemPrinter(f) <<
" center=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
508 if (diff_x > max_x) {
513 if (diff_y > max_y) {
518 info(4) <<
"Advance in direction X -> " << next_face_x;
519 info(4) <<
"Advance in direction Y -> " << next_face_y;
521 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
523 info() <<
"Informations from IMesh properties:";
525 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
527 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
528 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
529 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
530 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
535 auto x = _buildPatchGroups(
mesh()->allLevelCells(0),0);
536 all_cells = std::get<0>(x);
537 all_nodes = std::get<1>(x);
540 if (next_face_x!=(-1)){
541 m_local_face_direction[
MD_DirX] = next_face_x;
542 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
544 if (next_face_y!=(-1)){
545 m_local_face_direction[
MD_DirY] = next_face_y;
546 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
548 if (next_face_z != (-1)) {
549 m_local_face_direction[
MD_DirZ] = next_face_z;
550 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
554 for(
Integer idir=0, nb_dir=
mesh()->dimension(); idir<nb_dir; ++idir ){
556 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
557 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
560 info() <<
"Compute cartesian connectivity";
562 m_permutation_storage.resize(1);
563 m_permutation_storage[0].compute();
564 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
565 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
566 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
567 m_connectivity._computeInfos(
mesh(),nodes_coord,cells_center);
571 for (
Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
572 CellGroup cells = m_patch_group.allCells(patch_index);
574 info() <<
"AMR Patch name=" << cells.
name() <<
" size=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" << m_patch_group.nbPatch();
575 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
576 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
577 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
578 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
580 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
586 _saveInfosInProperties();
592std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
605 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
610 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
614 info(4) <<
"PATCH_CELLS name=" << patch_cells.
name() <<
" size=" << patch_cells.
size();
615 info(4) <<
"PATCH_NODES name=" << patch_nodes.
name() <<
" size=" << patch_nodes.
size();
616 return { patch_cells, patch_nodes };
622void CartesianMeshImpl::
626 IItemFamily* cell_family = m_mesh->cellFamily();
627 IItemFamily* face_family = m_mesh->faceFamily();
628 IItemFamily* node_family = m_mesh->nodeFamily();
631 Int32 max_face_id = face_family->maxLocalId();
632 Int32 max_node_id = node_family->maxLocalId();
634 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
635 cell_dm._internalResizeInfos(max_cell_id);
637 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
638 face_dm._internalResizeInfos(max_face_id);
640 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
641 node_dm._internalResizeInfos(max_node_id);
644 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
646 Int32 prev_local_face = -1;
647 Int32 next_local_face = m_local_face_direction[dir];
648 Integer mesh_dim = m_mesh->dimension();
651 prev_local_face = (next_local_face + 2) % 4;
652 else if (mesh_dim==3)
653 prev_local_face = (next_local_face + 3) % 6;
655 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
659 std::set<Int32> cells_set;
661 cells_set.insert(icell.itemLocalId());
668 Int32 my_level = cell.level();
669 Face next_face = cell.face(next_local_face);
670 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
671 if (cells_set.find(next_cell.localId()) == cells_set.end())
673 else if (next_cell.level() != my_level)
676 Face prev_face = cell.face(prev_local_face);
677 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
678 if (cells_set.find(prev_cell.localId()) == cells_set.end())
680 else if (prev_cell.level() != my_level)
682 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
684 cell_dm._internalComputeInnerAndOuterItems(all_cells);
685 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
686 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
692void CartesianMeshImpl::
693_computeDirectionsV2()
695 info() <<
"CartesianMesh: computeDirectionsV2()";
698 _checkAddObservableMeshChanged();
700 m_is_amr = m_mesh->isAmrActivated();
702 if (m_mesh->dimension() == 3) {
703 m_local_face_direction[
MD_DirX] = 4;
704 m_local_face_direction[
MD_DirY] = 5;
705 m_local_face_direction[
MD_DirZ] = 3;
708 m_local_face_direction[
MD_DirX] = 1;
709 m_local_face_direction[
MD_DirY] = 2;
712 info() <<
"Compute cartesian connectivity";
714 m_permutation_storage.resize(1);
715 m_permutation_storage[0].compute();
716 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
717 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
718 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
719 m_connectivity._computeInfos(
this);
722 for (
Integer patch_index = 0; patch_index < m_patch_group.nbPatch(); ++patch_index) {
723 computeDirectionsPatchV2(patch_index);
729 _saveInfosInProperties();
735void CartesianMeshImpl::
736computeDirectionsPatchV2(
Integer patch_index)
738 bool is_3d = m_mesh->dimension() == 3;
740 CellGroup cells = m_patch_group.allCells(patch_index);
741 Ref<CartesianMeshPatch>
patch = m_patch_group.patch(patch_index);
743 if (
patch->index() == -1) {
744 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
745 info() <<
"Informations from IMesh properties:";
746 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
747 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
748 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
749 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
751 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
752 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
753 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
754 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
758 info() <<
"AMR Patch name=" << cells.name() <<
" size=" << cells.size() <<
" index=" << patch_index <<
" trueindex=" <<
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.overlapCells(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.overlapCells(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.overlapCells(patch_index), patch_nodes);
774void CartesianMeshImpl::
777 IItemFamily* cell_family = m_mesh->cellFamily();
778 IItemFamily* face_family = m_mesh->faceFamily();
779 IItemFamily* node_family = m_mesh->nodeFamily();
781 Int32 max_cell_id = cell_family->maxLocalId();
782 Int32 max_face_id = face_family->maxLocalId();
783 Int32 max_node_id = node_family->maxLocalId();
785 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
786 cell_dm._internalResizeInfos(max_cell_id);
788 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
789 face_dm._internalResizeInfos(max_face_id);
791 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
792 node_dm._internalResizeInfos(max_node_id);
795 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
797 Int32 prev_local_face = -1;
798 Int32 next_local_face = m_local_face_direction[dir];
799 Integer mesh_dim = m_mesh->dimension();
802 prev_local_face = (next_local_face + 2) % 4;
803 else if (mesh_dim == 3)
804 prev_local_face = (next_local_face + 3) % 6;
806 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
810 std::set<Int32> cells_set;
812 cells_set.insert(icell.itemLocalId());
819 Int32 my_level = cell.level();
820 Face next_face = cell.face(next_local_face);
821 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
822 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
826 Face prev_face = cell.face(prev_local_face);
827 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
828 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
832 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
834 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
835 face_dm._internalComputeInfos(cell_dm);
836 node_dm._internalComputeInfos(cell_dm, all_nodes);
845 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
855 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
865 _applyRefine(position);
866 _saveInfosInProperties();
875 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
885 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
895 _applyCoarse(position);
896 _saveInfosInProperties();
906 ARCANE_FATAL(
"You cannot reduce number of ghost layer of level 0 with this method");
910 const Int32 max_nb_layer = 128;
914 level_max = std::max(level_max, icell->level());
922 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
925 if (level_0_nb_ghost_layer == 0) {
934 if (target_nb_ghost_layers % 2 != 0) {
935 target_nb_ghost_layers++;
938 if (target_nb_ghost_layers == nb_ghost_layer) {
939 return nb_ghost_layer;
944 Integer parent_level = level - 1;
945 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
951 std::function<void(
Cell)> children_list;
953 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
954 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
956 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
957 children_list(cell.hChild(i));
970 Cell front_cell = iface->frontCell();
971 Cell back_cell = iface->backCell();
973 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
974 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
975 for (
Node node : iface->nodes()) {
976 level_node[node] = 0;
982 bool is_modif =
true;
983 Int32 current_layer = 0;
988 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
992 Int32 min = max_nb_layer;
995 for (
Node node : icell->nodes()) {
996 Int32 nlevel = level_node[node];
998 min = std::min(min, nlevel);
999 max = std::max(max, nlevel);
1004 if (min != current_layer) {
1009 if (min == max_nb_layer && max == -1) {
1013 Integer new_level = ((min == max) ? min + 1 : max);
1015 for (
Node node : icell->nodes()) {
1016 Int32 nlevel = level_node[node];
1018 level_node[node] = new_level;
1024 level_cell[icell] = min;
1029 if (min >= parent_target_nb_ghost_layer) {
1030 children_list(*icell);
1034 if (current_layer >= max_nb_layer) {
1035 ARCANE_FATAL(
"Error in ghost layer counter algo. Report it plz.");
1040 for (
Integer i = level_max - 1; i >= 0; --i) {
1047 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1048 m_mesh->modifier()->coarsenItemsV2(
false);
1051 info() <<
"Nb ghost layer for level " << level <<
" : " << target_nb_ghost_layers;
1053 return target_nb_ghost_layers;
1059void CartesianMeshImpl::
1062 _addPatch(parent_cells_local_id);
1070void CartesianMeshImpl::
1071_addPatch(ConstArrayView<Int32> parent_cells)
1076 UniqueArray<Int32> children_local_id;
1077 CellInfoListView cells(m_mesh->
cellFamily());
1078 for (Int32 cell_local_id : parent_cells) {
1079 Cell c = cells[cell_local_id];
1080 for (
Integer k = 0; k < c.nbHChildren(); ++k) {
1081 Cell child = c.hChild(k);
1082 children_local_id.add(child.localId());
1086 m_patch_group.addPatch(children_local_id);
1092void CartesianMeshImpl::
1096 UniqueArray<Int32> cells_local_id;
1097 position.cellsInPatch(
mesh(), cells_local_id);
1099 Integer nb_cell = cells_local_id.size();
1100 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1102 IParallelMng* pm = m_mesh->parallelMng();
1104 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1105 if (total_nb_cell == 0)
1108 debug() <<
"Refine with modifier() (for all mesh types)";
1109 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1110 m_mesh->modifier()->adapt();
1112 _addPatch(cells_local_id);
1116 debug() <<
"Refine with specific refiner (for cartesian mesh only)";
1117 m_patch_group.addPatch(position);
1121 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1128 MeshStats ms(
traceMng(),m_mesh,m_mesh->parallelMng());
1136void CartesianMeshImpl::
1140 UniqueArray<Int32> cells_local_id;
1142 zone_position.cellsInPatch(
mesh(), cells_local_id);
1144 Integer nb_cell = cells_local_id.size();
1145 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1147 IParallelMng* pm = m_mesh->parallelMng();
1149 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1150 if (total_nb_cell == 0)
1153 debug() <<
"Coarse with modifier() (for all mesh types)";
1154 m_patch_group.removeCellsInAllPatches(cells_local_id);
1156 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1157 m_mesh->modifier()->coarsenItemsV2(
true);
1161 debug() <<
"Coarsen with specific coarser (for cartesian mesh only)";
1162 m_patch_group.removeCellsInZone(zone_position);
1166 ARCANE_FATAL(
"General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1173 MeshStats ms(
traceMng(), m_mesh, m_mesh->parallelMng());
1184 info(4) <<
"Check valid CartesianMesh";
1186 for(
Integer i=0; i<nb_patch; ++i ){
1198 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1201 Int32 face_method = v.renumberFaceMethod();
1202 if (face_method!=0 && face_method!=1)
1203 ARCANE_FATAL(
"Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1209 Int32 patch_method = v.renumberPatchMethod();
1210 if (patch_method < 0 || patch_method > 4) {
1211 ARCANE_FATAL(
"Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1215 ARCANE_FATAL(
"Mesh items renumbering is not compatible with this type of AMR");
1218 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1219 CartesianMeshUniqueIdRenumbering renumberer(
this, cmgi, v.parentPatch(), patch_method);
1220 renumberer.renumber();
1222 else if (patch_method == 2) {
1223 warning() <<
"The patch method 2 is experimental!";
1224 CartesianMeshUniqueIdRenumberingV2 renumberer(
this, cmgi);
1225 renumberer.renumber();
1229 if (v.isSortAfterRenumbering()){
1230 info() <<
"Compacting and Sorting after renumbering";
1231 m_mesh->nodeFamily()->compactItems(
true);
1232 m_mesh->faceFamily()->compactItems(
true);
1233 m_mesh->cellFamily()->compactItems(
true);
1251_createCartesianMeshCoarsening2()
1267 const char* name =
"CartesianMesh";
1276 ARCANE_FATAL(
"The mesh {0} is not yet created",h.meshName());
1283 mesh->_internalApi()->setMeshKind(mk);
1290 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