13#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
15#include "arcane/utils/FixedArray.h"
16#include "arcane/utils/Vector3.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/ITraceMng.h"
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/MeshKind.h"
23#include "arcane/core/Properties.h"
25#include "arcane/cartesianmesh/ICartesianMesh.h"
26#include "arcane/cartesianmesh/AMRZonePosition.h"
28#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
29#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
30#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h"
31#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h"
32#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h"
33#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h"
55, m_index_new_patches(1)
56, m_size_of_overlap_layer_sub_top_level(0)
63void CartesianPatchGroup::
66 m_properties =
makeRef(
new Properties(*(m_cmesh->mesh()->properties()),
"CartesianPatchGroup"));
72void CartesianPatchGroup::
73saveInfosInProperties()
75 m_properties->set(
"Version", 1);
77 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
78 UniqueArray<String> patch_group_names;
79 for (Integer i = 1; i < m_amr_patches_pointer.size(); ++i) {
80 patch_group_names.add(allCells(i).name());
82 m_properties->set(
"PatchGroupNames", patch_group_names);
86 UniqueArray<String> patch_group_names(m_amr_patches_pointer.size() - 1);
87 UniqueArray<Int32> level(m_amr_patches_pointer.size());
88 UniqueArray<Int32> overlap(m_amr_patches_pointer.size());
89 UniqueArray<Int32> index(m_amr_patches_pointer.size());
90 UniqueArray<CartCoordType> min_point(m_amr_patches_pointer.size() * 3);
91 UniqueArray<CartCoordType> max_point(m_amr_patches_pointer.size() * 3);
93 for (Integer i = 0; i < m_amr_patches_pointer.size(); ++i) {
94 const AMRPatchPosition& position = m_amr_patches_pointer[i]->_internalApi()->positionRef();
95 level[i] = position.level();
96 overlap[i] = position.overlapLayerSize();
97 index[i] = m_amr_patches_pointer[i]->index();
100 min_point[pos + 0] = position.minPoint().x;
101 min_point[pos + 1] = position.minPoint().y;
102 min_point[pos + 2] = position.minPoint().z;
103 max_point[pos + 0] = position.maxPoint().x;
104 max_point[pos + 1] = position.maxPoint().y;
105 max_point[pos + 2] = position.maxPoint().z;
108 patch_group_names[i - 1] = allCells(i).name();
111 m_properties->set(
"LevelPatches", level);
112 m_properties->set(
"OverlapSizePatches", overlap);
113 m_properties->set(
"IndexPatches", index);
114 m_properties->set(
"MinPointPatches", min_point);
115 m_properties->set(
"MaxPointPatches", max_point);
122 m_properties->set(
"PatchGroupNamesAvailable", m_available_group_index);
123 m_properties->set(
"PatchGroupNames", patch_group_names);
130void CartesianPatchGroup::
134 Int32 v = m_properties->getInt32(
"Version");
136 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1);
142 UniqueArray<String> patch_group_names;
143 m_properties->get(
"PatchGroupNames", patch_group_names);
145 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
146 m_cmesh->traceMng()->info(4) <<
"Found n=" << patch_group_names.size() <<
" patchs";
148 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
149 for (
const String& x : patch_group_names) {
150 CellGroup group = cell_family->findGroup(x);
153 addPatchAfterRestore(group);
157 UniqueArray<Int32> level;
158 UniqueArray<Int32> overlap;
159 UniqueArray<Int32> index;
160 UniqueArray<CartCoordType> min_point;
161 UniqueArray<CartCoordType> max_point;
163 m_properties->get(
"LevelPatches", level);
164 m_properties->get(
"OverlapSizePatches", overlap);
165 m_properties->get(
"IndexPatches", index);
166 m_properties->get(
"MinPointPatches", min_point);
167 m_properties->get(
"MaxPointPatches", max_point);
169 if (index.size() < 1) {
174 ConstArrayView
min(min_point.subConstView(0, 3));
175 ConstArrayView
max(max_point.subConstView(0, 3));
177 AMRPatchPosition position(
183 m_amr_patches_pointer[0]->_internalApi()->setPosition(position);
186 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
188 for (Integer i = 1; i < index.size(); ++i) {
189 ConstArrayView
min(min_point.subConstView(i * 3, 3));
190 ConstArrayView
max(max_point.subConstView(i * 3, 3));
192 AMRPatchPosition position(
198 const String& x = patch_group_names[i - 1];
199 CellGroup cell_group = cell_family->findGroup(x);
200 if (cell_group.null())
203 auto* cdi =
new CartesianMeshPatch(m_cmesh, index[i], position);
204 _addPatchInstance(
makeRef(cdi));
205 _addCellGroup(cell_group, cdi);
208 UniqueArray<Int32> available_index;
209 m_properties->get(
"PatchGroupNamesAvailable", available_index);
210 rebuildAvailableGroupIndex(available_index);
217Ref<CartesianMeshPatch> CartesianPatchGroup::
220 _createGroundPatch();
227void CartesianPatchGroup::
228addPatch(ConstArrayView<Int32> cells_local_id)
230 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
234 Integer index = _nextIndexForNewPatch();
235 String children_group_name = String(
"CartesianMeshPatchCells") + index;
236 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
237 CellGroup children_cells = cell_family->createGroup(children_group_name, cells_local_id,
true);
238 addPatch(children_cells, index);
246addPatchAfterRestore(CellGroup cell_group)
248 const String& name = cell_group.name();
250 if (name.startsWith(
"CartesianMeshPatchCells")) {
251 String index_str = name.substring(23);
252 group_index = std::stoi(index_str.localstr());
258 addPatch(cell_group, group_index);
265void CartesianPatchGroup::
266addPatch(CellGroup cell_group, Integer group_index)
268 _createGroundPatch();
269 if (cell_group.null())
272 AMRPatchPosition position;
274 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, position);
275 _addPatchInstance(
makeRef(cdi));
276 _addCellGroup(cell_group, cdi);
282void CartesianPatchGroup::
283addPatch(
const AMRZonePosition& zone_position)
285 clearRefineRelatedFlags();
287 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
288 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
290 auto position = zone_position.toAMRPatchPosition(m_cmesh);
291 Int32 level = position.level();
293 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
294 if (!icell->hasHChildren()) {
295 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
296 if (position.isInWithOverlap(pos)) {
297 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
304 _addPatch(position.patchUp(m_cmesh->mesh()->dimension()));
314 return m_amr_patches.size();
320Ref<CartesianMeshPatch> CartesianPatchGroup::
321patch(
const Integer index)
const
323 return m_amr_patches[index];
329CartesianMeshPatchListView CartesianPatchGroup::
332 return CartesianMeshPatchListView{ m_amr_patches_pointer };
339allCells(
const Integer index)
342 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
344 return m_amr_patch_cell_groups_all[index - 1];
351inPatchCells(Integer index)
353 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
354 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
357 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
359 return m_amr_patch_cell_groups_inpatch[index - 1];
366overallCells(Integer index)
368 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
369 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
372 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
374 return m_amr_patch_cell_groups_overall[index - 1];
381void CartesianPatchGroup::
385 _createGroundPatch();
391void CartesianPatchGroup::
392removePatch(
const Integer index)
394 if (m_patches_to_delete.contains(index)) {
400 if (index < 1 || index >= m_amr_patches.size()) {
404 m_patches_to_delete.add(index);
410void CartesianPatchGroup::
411removeCellsInAllPatches(ConstArrayView<Int32> cells_local_id)
413 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
416 for (CellGroup cells : m_amr_patch_cell_groups_all) {
417 cells.removeItems(cells_local_id);
424void CartesianPatchGroup::
425_removeCellsInAllPatches(
const AMRPatchPosition& zone_to_delete)
429 const Integer nb_patchs = m_amr_patches_pointer.size();
430 for (Integer i = 1; i < nb_patchs; ++i) {
431 ICartesianMeshPatch* patch = m_amr_patches_pointer[i];
440 if (zone_to_delete.haveIntersection(patch->position())) {
441 _splitPatch(i, zone_to_delete);
449void CartesianPatchGroup::
450removeCellsInZone(
const AMRZonePosition& zone_to_delete)
452 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
453 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
455 clearRefineRelatedFlags();
457 UniqueArray<Int32> cells_local_id;
459 AMRPatchPosition patch_position;
460 zone_to_delete.cellsInPatch(m_cmesh, cells_local_id, patch_position);
462 _removeCellsInAllPatches(patch_position);
463 applyPatchEdit(
false);
464 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
465 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
467 Int32 level = patch_position.level();
469 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
470 if (!icell->hasHChildren()) {
471 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
472 if (patch_position.isIn(pos)) {
473 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
484void CartesianPatchGroup::
485applyPatchEdit(
bool remove_empty_patches)
489 std::stable_sort(m_patches_to_delete.begin(), m_patches_to_delete.end(),
490 [](
const Integer a,
const Integer b) {
494 _removeMultiplePatches(m_patches_to_delete);
495 m_patches_to_delete.clear();
497 if (remove_empty_patches) {
498 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
499 ARCANE_FATAL(
"remove_empty_patches=true available only with AMR Cell");
501 UniqueArray<Integer> size_of_patches(m_amr_patch_cell_groups_all.size());
502 for (Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) {
503 size_of_patches[i] = m_amr_patch_cell_groups_all[i].size();
505 m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches);
506 for (Integer i = 0; i < size_of_patches.size(); ++i) {
507 if (size_of_patches[i] == 0) {
508 m_patches_to_delete.add(i + 1);
511 _removeMultiplePatches(m_patches_to_delete);
512 m_patches_to_delete.clear();
516 for (
const auto patch : m_amr_patches_pointer) {
517 const Int32 level = patch->_internalApi()->positionRef().level();
518 if (level > m_higher_level) {
519 m_higher_level = level;
527void CartesianPatchGroup::
528updateLevelsAndAddGroundPatch()
530 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
533 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
539 for (ICartesianMeshPatch* patch : m_amr_patches_pointer) {
540 const Int32 level = patch->position().level();
543 const CartCoord3Type max_point = patch->position().maxPoint();
544 if (m_cmesh->mesh()->dimension() == 2) {
545 patch->_internalApi()->positionRef().setMaxPoint({
546 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
547 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
552 patch->_internalApi()->positionRef().setMaxPoint({
553 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
554 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
555 numbering->offsetLevelToLevel(max_point.z, level, level - 1),
561 patch->_internalApi()->positionRef().setLevel(level + 1);
562 if (level + 1 > m_higher_level) {
563 m_higher_level = level + 1;
568 AMRPatchPosition old_ground;
569 old_ground.setLevel(1);
570 old_ground.setMinPoint({ 0, 0, 0 });
571 old_ground.setMaxPoint({ numbering->globalNbCellsX(1), numbering->globalNbCellsY(1), numbering->globalNbCellsZ(1) });
572 old_ground.setOverlapLayerSize(0);
574 _addPatch(old_ground);
581_nextIndexForNewPatch()
583 if (!m_available_group_index.empty()) {
584 const Integer elem = m_available_group_index.back();
585 m_available_group_index.popBack();
588 return m_index_new_patches++;
594void CartesianPatchGroup::
597 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
601 UniqueArray<std::pair<Integer, Int64>> index_n_nb_cells;
604 for (
auto patch : m_amr_patches_pointer) {
605 index_n_nb_cells.add({ index++, patch->position().nbCells() });
617 std::stable_sort(index_n_nb_cells.begin(), index_n_nb_cells.end(),
618 [](
const std::pair<Integer, Int64>& a,
const std::pair<Integer, Int64>& b) {
619 return a.second < b.second;
622 for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) {
623 auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0];
625 AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef();
626 if (patch_fusion_0.isNull())
633 for (Integer p1 = p0 + 1; p1 < m_amr_patches_pointer.size(); ++p1) {
634 auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1];
636 AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef();
637 if (patch_fusion_1.isNull())
648 if (patch_fusion_0.fusion(patch_fusion_1)) {
650 patch_fusion_1.setLevel(-2);
651 index_n_nb_cells[p0].second = patch_fusion_0.nbCells();
653 UniqueArray<Int32> local_ids;
654 allCells(index_p1).view().fillLocalIds(local_ids);
655 allCells(index_p0).addItems(local_ids,
false);
658 removePatch(index_p1);
674void CartesianPatchGroup::
675refine(
bool clear_refine_flag)
683 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
684 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
686 Integer dimension = m_cmesh->mesh()->dimension();
687 Int32 nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
689 Int32 future_max_level = -1;
690 Int32 old_max_level = -1;
691 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
693 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
694 Integer level = icell->level();
695 if (icell->hasFlags(ItemFlags::II_Refine)) {
696 if (level > future_max_level)
697 future_max_level = level;
699 if (level > old_max_level)
700 old_max_level = level;
702 future_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, future_max_level);
703 old_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, old_max_level);
706 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
708 AMRPatchPositionLevelGroup all_patches(future_max_level);
710 for (Int32 level = future_max_level; level >= min_level; --level) {
712 if (level != future_max_level) {
713 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
714 if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) {
715 const CartCoord3Type pos = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoord(*icell), level, level + 1);
716 for (
const auto& patch : all_patches.patches(level)) {
717 if (patch.isInWithOverlap(pos, patch.overlapLayerSize() + 1)) {
718 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
729 AMRPatchPosition all_level;
730 all_level.setLevel(level);
731 all_level.setMinPoint({ 0, 0, 0 });
732 all_level.setMaxPoint({ numbering->globalNbCellsX(level), numbering->globalNbCellsY(level), numbering->globalNbCellsZ(level) });
733 all_level.setOverlapLayerSize(nb_overlap_cells);
735 AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches);
736 UniqueArray<AMRPatchPositionSignature> sig_array;
739 AMRPatchPositionSignatureCut::cut(sig_array);
741 for (
const auto& elem : sig_array) {
742 all_patches.addPatch(elem.patch());
744 nb_overlap_cells /= 2;
745 nb_overlap_cells += 1;
812 clearRefineRelatedFlags();
816 applyPatchEdit(
false);
818 for (Int32 level = min_level; level <= future_max_level; ++level) {
819 all_patches.fusionPatches(level);
821 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
822 if (!icell->hasHChildren()) {
823 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
824 for (
const AMRPatchPosition& patch : all_patches.patches(level)) {
825 if (patch.isInWithOverlap(pos)) {
826 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
877 for (
const AMRPatchPosition& patch : all_patches.patches(level)) {
878 _addPatch(patch.patchUp(dimension));
894 for (Int32 level = old_max_level; level > future_max_level + 1; --level) {
895 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
896 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
902 for (Int32 level = future_max_level + 1; level > min_level; --level) {
903 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
904 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
907 for (
const AMRPatchPosition& patch : all_patches.patches(level - 1)) {
908 if (patch.patchUp(dimension).isInWithOverlap(pos)) {
914 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
954 m_cmesh->computeDirections();
956 if (clear_refine_flag) {
957 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
958 if (icell->hasFlags(ItemFlags::II_Coarsen)) {
961 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
981void CartesianPatchGroup::
982clearRefineRelatedFlags()
const
984 constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine |
985 ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined |
986 ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive);
987 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
988 icell->mutableItemBase().removeFlags(flags_to_remove);
995void CartesianPatchGroup::
996rebuildAvailableGroupIndex(ConstArrayView<Integer> available_group_index)
998 m_available_group_index = available_group_index;
1004ConstArrayView<Int32> CartesianPatchGroup::
1005availableGroupIndex()
1007 return m_available_group_index;
1013void CartesianPatchGroup::
1014setOverlapLayerSizeTopLevel(Int32 size_of_overlap_layer_top_level)
1016 m_size_of_overlap_layer_sub_top_level = (size_of_overlap_layer_top_level + 1) / 2;
1022Int32 CartesianPatchGroup::
1023overlapLayerSize(Int32 level)
1025 if (level < 0 || level > m_higher_level) {
1028 if (level == m_higher_level) {
1029 return m_size_of_overlap_layer_sub_top_level * 2;
1031 Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
1032 for (Integer i = m_higher_level - 1; i > level; --i) {
1033 nb_overlap_cells /= 2;
1034 nb_overlap_cells += 1;
1036 return nb_overlap_cells;
1042void CartesianPatchGroup::
1043_addPatchInstance(Ref<CartesianMeshPatch> v)
1045 m_amr_patches.add(v);
1046 m_amr_patches_pointer.add(v.get());
1052void CartesianPatchGroup::
1053_removeOnePatch(Integer index)
1055 m_available_group_index.add(m_amr_patches[index]->index());
1058 m_amr_patch_cell_groups_all[index - 1].clear();
1059 m_amr_patch_cell_groups_all.remove(index - 1);
1061 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1062 m_amr_patch_cell_groups_inpatch[index - 1].clear();
1063 m_amr_patch_cell_groups_inpatch.remove(index - 1);
1064 m_amr_patch_cell_groups_overall[index - 1].clear();
1065 m_amr_patch_cell_groups_overall.remove(index - 1);
1068 m_amr_patches_pointer.remove(index);
1069 m_amr_patches.remove(index);
1076void CartesianPatchGroup::
1077_removeMultiplePatches(ConstArrayView<Integer> indexes)
1080 for (
const Integer index : indexes) {
1081 _removeOnePatch(index - count);
1089void CartesianPatchGroup::
1092 Ref<CartesianMeshPatch> ground_patch = m_amr_patches.front();
1094 for (CellGroup cell_group : m_amr_patch_cell_groups_all) {
1097 m_amr_patch_cell_groups_all.clear();
1099 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1100 for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) {
1103 for (CellGroup cell_group : m_amr_patch_cell_groups_overall) {
1106 m_amr_patch_cell_groups_inpatch.clear();
1107 m_amr_patch_cell_groups_overall.clear();
1110 m_amr_patches_pointer.clear();
1111 m_amr_patches.clear();
1112 m_available_group_index.clear();
1113 m_patches_to_delete.clear();
1114 m_index_new_patches = 1;
1116 m_amr_patches.add(ground_patch);
1117 m_amr_patches_pointer.add(ground_patch.get());
1123void CartesianPatchGroup::
1126 if (!m_amr_patches.empty())
1128 auto patch =
makeRef(
new CartesianMeshPatch(m_cmesh, -1));
1129 _addPatchInstance(patch);
1131 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1132 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1133 patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 });
1134 patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) });
1135 patch->_internalApi()->positionRef().setLevel(0);
1142void CartesianPatchGroup::
1143_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch)
1145 m_amr_patch_cell_groups_all.add(cell_group);
1147 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
1154 AMRPatchPosition patch_position = patch->position();
1155 Ref<ICartesianMeshNumberingMngInternal> numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1157 UniqueArray<Int32> inpatch_items_lid;
1158 UniqueArray<Int32> overall_items_lid;
1162 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(cell);
1164 if (cell.isOwn() && patch_position.isIn(pos)) {
1165 inpatch_items_lid.add(cell.localId());
1168 overall_items_lid.add(cell.localId());
1173 m_amr_patch_cell_groups_inpatch.add(own);
1176 m_amr_patch_cell_groups_overall.add(overall);
1187void CartesianPatchGroup::
1188_splitPatch(Integer index_patch,
const AMRPatchPosition& part_to_remove)
1218 auto cut_points_p0 = [](CartCoordType p0_min, CartCoordType p0_max, CartCoordType p1_min, CartCoordType p1_max) -> std::pair<CartCoordType, CartCoordType> {
1219 std::pair to_return{ -1, -1 };
1220 if (p1_min > p0_min && p1_min < p0_max) {
1221 to_return.first = p1_min;
1223 if (p1_max > p0_min && p1_max < p0_max) {
1224 to_return.second = p1_max;
1229 ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch];
1230 AMRPatchPosition patch_position = patch->position();
1232 UniqueArray<AMRPatchPosition> new_patch_out;
1234 CartCoord3Type min_point_of_patch_to_exclude(-1, -1, -1);
1238 UniqueArray<AMRPatchPosition> new_patch_in;
1242 auto cut_point_x = cut_points_p0(patch_position.minPoint().x, patch_position.maxPoint().x, part_to_remove.minPoint().x, part_to_remove.maxPoint().x);
1246 if (cut_point_x.first == -1 && cut_point_x.second == -1) {
1247 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1248 new_patch_out.add(patch_position);
1252 else if (cut_point_x.second == -1) {
1253 min_point_of_patch_to_exclude.x = cut_point_x.first;
1254 auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX);
1255 new_patch_out.add(fst);
1256 new_patch_out.add(snd);
1260 else if (cut_point_x.first == -1) {
1261 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1262 auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX);
1263 new_patch_out.add(fst);
1264 new_patch_out.add(snd);
1269 min_point_of_patch_to_exclude.x = cut_point_x.first;
1270 auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX);
1271 new_patch_out.add(fst);
1272 auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX);
1273 new_patch_out.add(snd);
1274 new_patch_out.add(thr);
1280 std::swap(new_patch_out, new_patch_in);
1282 auto cut_point_y = cut_points_p0(patch_position.minPoint().y, patch_position.maxPoint().y, part_to_remove.minPoint().y, part_to_remove.maxPoint().y);
1286 if (cut_point_y.first == -1 && cut_point_y.second == -1) {
1287 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1288 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1289 new_patch_out.add(patch_x);
1294 else if (cut_point_y.second == -1) {
1295 min_point_of_patch_to_exclude.y = cut_point_y.first;
1296 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1297 auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY);
1298 new_patch_out.add(fst);
1299 new_patch_out.add(snd);
1304 else if (cut_point_y.first == -1) {
1305 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1306 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1307 auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY);
1308 new_patch_out.add(fst);
1309 new_patch_out.add(snd);
1315 min_point_of_patch_to_exclude.y = cut_point_y.first;
1316 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1317 auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY);
1318 new_patch_out.add(fst);
1319 auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY);
1320 new_patch_out.add(snd);
1321 new_patch_out.add(thr);
1327 if (m_cmesh->mesh()->dimension() == 3) {
1328 std::swap(new_patch_out, new_patch_in);
1329 new_patch_out.clear();
1331 auto cut_point_z = cut_points_p0(patch_position.minPoint().z, patch_position.maxPoint().z, part_to_remove.minPoint().z, part_to_remove.maxPoint().z);
1335 if (cut_point_z.first == -1 && cut_point_z.second == -1) {
1336 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1337 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
1338 new_patch_out.add(patch_y);
1343 else if (cut_point_z.second == -1) {
1344 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1345 min_point_of_patch_to_exclude.z = cut_point_z.first;
1346 auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ);
1347 new_patch_out.add(fst);
1348 new_patch_out.add(snd);
1353 else if (cut_point_z.first == -1) {
1354 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1355 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
1356 auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ);
1357 new_patch_out.add(fst);
1358 new_patch_out.add(snd);
1364 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1365 min_point_of_patch_to_exclude.z = cut_point_z.first;
1366 auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ);
1367 new_patch_out.add(fst);
1368 auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ);
1369 new_patch_out.add(snd);
1370 new_patch_out.add(thr);
1378 if (m_cmesh->mesh()->dimension() == 2) {
1379 min_point_of_patch_to_exclude.z = 0;
1385 for (AMRPatchPosition& new_patch : new_patch_out) {
1386 if (new_patch.minPoint() == min_point_of_patch_to_exclude) {
1387 new_patch.setLevel(-2);
1397 AMRPatchPositionLevelGroup::fusionPatches(new_patch_out,
false);
1401 for (
const auto& new_patch : new_patch_out) {
1402 if (!new_patch.isNull()) {
1407 _addCutPatch(new_patch, m_amr_patch_cell_groups_all[index_patch - 1]);
1414 removePatch(index_patch);
1420void CartesianPatchGroup::
1421_addCutPatch(
const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
1426 if (parent_patch_cell_group.null())
1429 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
1430 Integer group_index = _nextIndexForNewPatch();
1431 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
1433 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
1434 _addPatchInstance(
makeRef(cdi));
1436 UniqueArray<Int32> cells_local_id;
1438 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1439 ENUMERATE_ (Cell, icell, parent_patch_cell_group) {
1440 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
1441 if (new_patch_position.isIn(pos)) {
1442 cells_local_id.add(icell.localId());
1446 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
1447 _addCellGroup(parent_cells, cdi);
1459void CartesianPatchGroup::
1460_addPatch(
const AMRPatchPosition& new_patch_position)
1462 UniqueArray<Int32> cells_local_id;
1464 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1465 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) {
1466 const CartCoord3Type pos = numbering->cellUniqueIdToCoord(*icell);
1467 if (new_patch_position.isInWithOverlap(pos)) {
1468 cells_local_id.add(icell.localId());
1472 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
1473 Integer group_index = _nextIndexForNewPatch();
1474 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
1476 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
1478 _addPatchInstance(
makeRef(cdi));
1479 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
1480 _addCellGroup(parent_cells, cdi);
1482 if (new_patch_position.level() > m_higher_level) {
1483 m_higher_level = new_patch_position.level();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Interface d'un maillage cartésien.
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 IItemFamily * cellFamily()=0
Retourne la famille des mailles.
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
@ Cell
Le maillage est AMR par maille.