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"
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IParallelMng.h"
21#include "arcane/core/MeshKind.h"
23#include "arcane/cartesianmesh/ICartesianMesh.h"
25#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
26#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
27#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h"
28#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h"
29#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h"
30#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h"
52, m_index_new_patches(1)
53, m_size_of_overlap_layer_sub_top_level(0)
60Ref<CartesianMeshPatch> CartesianPatchGroup::
70void CartesianPatchGroup::
71addPatch(ConstArrayView<Int32> cells_local_id)
73 Integer index = _nextIndexForNewPatch();
74 String children_group_name = String(
"CartesianMeshPatchCells") + index;
75 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
76 CellGroup children_cells = cell_family->createGroup(children_group_name, cells_local_id,
true);
77 addPatch(children_cells, index);
85addPatchAfterRestore(CellGroup cell_group)
87 const String& name = cell_group.name();
89 if (name.startsWith(
"CartesianMeshPatchCells")) {
90 String index_str = name.substring(23);
91 group_index = std::stoi(index_str.localstr());
97 addPatch(cell_group, group_index);
104void CartesianPatchGroup::
105addPatch(CellGroup cell_group, Integer group_index)
107 _createGroundPatch();
108 if (cell_group.null())
111 AMRPatchPosition position;
113 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
114 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
115 FixedArray<Int64, 6> min_n_max;
116 min_n_max[0] = INT64_MAX;
117 min_n_max[1] = INT64_MAX;
118 min_n_max[2] = INT64_MAX;
122 ArrayView
min(min_n_max.view().subView(0, 3));
123 ArrayView
max(min_n_max.view().subView(3, 3));
130 level = icell->level();
132 if (level != icell->level()) {
133 ARCANE_FATAL(
"Level pb -- Zone with cells to different levels -- Level recorded before : {0} -- Cell Level : {1} -- CellUID : {2}", level, icell->level(), icell->uniqueId());
135 Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell);
136 if (pos_x < min[MD_DirX])
138 if (pos_x > max[MD_DirX])
141 Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell);
142 if (pos_y < min[MD_DirY])
144 if (pos_y > max[MD_DirY])
147 Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell);
148 if (pos_z < min[MD_DirZ])
150 if (pos_z > max[MD_DirZ])
153 m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMin, min);
154 m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max);
155 nb_cells = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceSum, nb_cells);
156 Integer level_r = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, level);
158 if (level != -1 && level != level_r) {
168 if (nb_cells != nb_cells_patch) {
169 ARCANE_FATAL(
"Not regular patch -- NbCellsInGroup : {0} -- NbCellsInPatch : {1}", nb_cells, nb_cells_patch);
175 position.setLevel(level_r);
177 if (level_r > m_higher_level)
178 m_higher_level = level_r;
181 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, position);
182 _addPatchInstance(
makeRef(cdi));
183 _addCellGroup(cell_group, cdi);
204 return m_amr_patches.size();
210Ref<CartesianMeshPatch> CartesianPatchGroup::
211patch(
const Integer index)
const
213 return m_amr_patches[index];
219CartesianMeshPatchListView CartesianPatchGroup::
222 return CartesianMeshPatchListView{ m_amr_patches_pointer };
229allCells(
const Integer index)
232 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
234 return m_amr_patch_cell_groups_all[index - 1];
241inPatchCells(Integer index)
243 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
244 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
247 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
249 return m_amr_patch_cell_groups_inpatch[index - 1];
256overallCells(Integer index)
258 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
259 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
262 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
264 return m_amr_patch_cell_groups_overall[index - 1];
271void CartesianPatchGroup::
275 _createGroundPatch();
281void CartesianPatchGroup::
282removePatch(
const Integer index)
284 if (m_patches_to_delete.contains(index)) {
290 if (index < 1 || index >= m_amr_patches.size()) {
294 m_patches_to_delete.add(index);
300void CartesianPatchGroup::
301removeCellsInAllPatches(ConstArrayView<Int32> cells_local_id)
303 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
306 for (CellGroup cells : m_amr_patch_cell_groups_all) {
307 cells.removeItems(cells_local_id);
314void CartesianPatchGroup::
315removeCellsInAllPatches(
const AMRPatchPosition& zone_to_delete)
317 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
318 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
322 const Integer nb_patchs = m_amr_patches_pointer.size();
323 for (Integer i = 1; i < nb_patchs; ++i) {
324 ICartesianMeshPatch* patch = m_amr_patches_pointer[i];
333 if (_isPatchInContact(patch->position(), zone_to_delete)) {
334 _splitPatch(i, zone_to_delete);
342void CartesianPatchGroup::
343applyPatchEdit(
bool remove_empty_patches)
347 std::sort(m_patches_to_delete.begin(), m_patches_to_delete.end(),
348 [](
const Integer a,
const Integer b) {
352 _removeMultiplePatches(m_patches_to_delete);
353 m_patches_to_delete.clear();
355 if (remove_empty_patches) {
356 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
357 ARCANE_FATAL(
"remove_empty_patches=true available only with AMR Cell");
359 UniqueArray<Integer> size_of_patches(m_amr_patch_cell_groups_all.size());
360 for (Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) {
361 size_of_patches[i] = m_amr_patch_cell_groups_all[i].size();
363 m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches);
364 for (Integer i = 0; i < size_of_patches.size(); ++i) {
365 if (size_of_patches[i] == 0) {
366 m_patches_to_delete.add(i + 1);
369 _removeMultiplePatches(m_patches_to_delete);
370 m_patches_to_delete.clear();
374 for (
const auto patch : m_amr_patches_pointer) {
375 const Integer level = patch->_internalApi()->positionRef().level();
376 if (level > m_higher_level) {
377 m_higher_level = level;
385void CartesianPatchGroup::
386updateLevelsBeforeAddGroundPatch()
388 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
391 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
392 for (ICartesianMeshPatch* patch : m_amr_patches_pointer) {
393 Integer level = patch->position().level();
396 Int64x3 max_point = patch->position().maxPoint();
397 if (m_cmesh->mesh()->dimension() == 2) {
398 patch->_internalApi()->positionRef().setMaxPoint({
399 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
400 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
405 patch->_internalApi()->positionRef().setMaxPoint({
406 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
407 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
408 numbering->offsetLevelToLevel(max_point.z, level, level - 1),
414 patch->_internalApi()->positionRef().setLevel(level + 1);
415 if (level + 1 > m_higher_level) {
416 m_higher_level = level + 1;
426_nextIndexForNewPatch()
428 if (!m_available_group_index.empty()) {
429 const Integer elem = m_available_group_index.back();
430 m_available_group_index.popBack();
433 return m_index_new_patches++;
439void CartesianPatchGroup::
442 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
446 UniqueArray<std::pair<Integer, Int64>> index_n_nb_cells;
449 for (
auto patch : m_amr_patches_pointer) {
450 index_n_nb_cells.add({ index++, patch->position().nbCells() });
462 std::sort(index_n_nb_cells.begin(), index_n_nb_cells.end(),
463 [](
const std::pair<Integer, Int64>& a,
const std::pair<Integer, Int64>& b) {
464 return a.second < b.second;
467 for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) {
468 auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0];
470 AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef();
471 if (patch_fusion_0.isNull())
478 Integer p1 = (fusion ? 0 : p0 + 1);
479 for (; p1 < m_amr_patches_pointer.size(); ++p1) {
482 auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1];
484 AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef();
486 if (patch_fusion_1.isNull())
497 if (patch_fusion_0.fusion(patch_fusion_1)) {
499 patch_fusion_1.setLevel(-2);
500 index_n_nb_cells[p0].second = patch_fusion_0.nbCells();
502 UniqueArray<Int32> local_ids;
503 allCells(index_p1).view().fillLocalIds(local_ids);
504 allCells(index_p0).addItems(local_ids,
false);
507 removePatch(index_p1);
520void CartesianPatchGroup::
521refine(
bool clear_refine_flag)
529 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
530 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
532 Integer dimension = m_cmesh->mesh()->dimension();
533 Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
537 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
539 amr->_syncFlagCell();
541 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
542 Integer level = icell->level();
543 if (icell->hasFlags(ItemFlags::II_Refine)) {
544 if (level > future_max_level)
545 future_max_level = level;
547 if (level > old_max_level)
548 old_max_level = level;
550 future_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, future_max_level);
551 old_max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, old_max_level);
554 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
556 AMRPatchPositionLevelGroup all_patches(future_max_level);
558 for (Integer level = future_max_level; level >= min_level; --level) {
560 if (level != future_max_level) {
561 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
562 if (icell->level() == level && icell->hasFlags(ItemFlags::II_Refine)) {
563 Integer pos_x = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordX(*icell), level, level + 1);
564 Integer pos_y = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordY(*icell), level, level + 1);
565 Integer pos_z = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoordZ(*icell), level, level + 1);
567 for (
auto patch : all_patches.patches(level)) {
568 if (patch.isInWithOverlap(pos_x, pos_y, pos_z, patch.overlapLayerSize() + 1)) {
569 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
580 AMRPatchPosition all_level;
581 all_level.setLevel(level);
582 all_level.setMinPoint({ 0, 0, 0 });
583 all_level.setMaxPoint({ numbering->globalNbCellsX(level), numbering->globalNbCellsY(level), numbering->globalNbCellsZ(level) });
584 all_level.setOverlapLayerSize(nb_overlap_cells);
586 AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches);
587 UniqueArray<AMRPatchPositionSignature> sig_array;
590 AMRPatchPositionSignatureCut::cut(sig_array);
592 for (
const auto& elem : sig_array) {
593 all_patches.addPatch(elem.patch());
595 nb_overlap_cells /= 2;
596 nb_overlap_cells += 1;
663 clearRefineRelatedFlags();
667 applyPatchEdit(
false);
669 for (Integer level = min_level; level <= future_max_level; ++level) {
670 all_patches.fusionPatches(level);
672 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
673 if (!icell->hasHChildren()) {
674 Integer pos_x = numbering->cellUniqueIdToCoordX(*icell);
675 Integer pos_y = numbering->cellUniqueIdToCoordY(*icell);
676 Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell);
677 for (
const AMRPatchPosition& patch : all_patches.patches(level)) {
678 if (patch.isInWithOverlap(pos_x, pos_y, pos_z)) {
679 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
730 for (
const AMRPatchPosition& patch : all_patches.patches(level)) {
731 _addPatch(patch.patchUp(dimension));
747 for (Integer level = old_max_level; level > future_max_level + 1; --level) {
748 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
749 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
755 for (Integer level = future_max_level + 1; level > min_level; --level) {
756 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
757 Integer pos_x = numbering->cellUniqueIdToCoordX(*icell);
758 Integer pos_y = numbering->cellUniqueIdToCoordY(*icell);
759 Integer pos_z = numbering->cellUniqueIdToCoordZ(*icell);
762 for (
const AMRPatchPosition& patch : all_patches.patches(level - 1)) {
763 if (patch.patchUp(dimension).isInWithOverlap(pos_x, pos_y, pos_z)) {
769 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
809 m_cmesh->computeDirections();
811 if (clear_refine_flag) {
812 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
813 if (icell->hasFlags(ItemFlags::II_Coarsen)) {
816 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
836void CartesianPatchGroup::
837clearRefineRelatedFlags()
const
839 constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine |
840 ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined |
841 ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive);
842 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
843 icell->mutableItemBase().removeFlags(flags_to_remove);
850void CartesianPatchGroup::
851rebuildAvailableGroupIndex(ConstArrayView<Integer> available_group_index)
853 m_available_group_index = available_group_index;
859ConstArrayView<Int32> CartesianPatchGroup::
862 return m_available_group_index;
868void CartesianPatchGroup::
869setOverlapLayerSizeTopLevel(Integer size_of_overlap_layer_top_level)
871 m_size_of_overlap_layer_sub_top_level = (size_of_overlap_layer_top_level + 1) / 2;
878overlapLayerSize(Integer level)
880 if (level < 0 || level > m_higher_level) {
883 if (level == m_higher_level) {
884 return m_size_of_overlap_layer_sub_top_level * 2;
886 Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
887 for (Integer i = m_higher_level - 1; i > level; --i) {
888 nb_overlap_cells /= 2;
889 nb_overlap_cells += 1;
891 return nb_overlap_cells;
897void CartesianPatchGroup::
898_addPatchInstance(Ref<CartesianMeshPatch> v)
900 m_amr_patches.add(v);
901 m_amr_patches_pointer.add(v.get());
907void CartesianPatchGroup::
908_removeOnePatch(Integer index)
910 m_available_group_index.add(m_amr_patches[index]->index());
913 m_amr_patch_cell_groups_all[index - 1].clear();
914 m_amr_patch_cell_groups_all.remove(index - 1);
916 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
917 m_amr_patch_cell_groups_inpatch[index - 1].clear();
918 m_amr_patch_cell_groups_inpatch.remove(index - 1);
919 m_amr_patch_cell_groups_overall[index - 1].clear();
920 m_amr_patch_cell_groups_overall.remove(index - 1);
923 m_amr_patches_pointer.remove(index);
924 m_amr_patches.remove(index);
931void CartesianPatchGroup::
932_removeMultiplePatches(ConstArrayView<Integer> indexes)
935 for (
const Integer index : indexes) {
936 _removeOnePatch(index - count);
944void CartesianPatchGroup::
947 Ref<CartesianMeshPatch> ground_patch = m_amr_patches.front();
949 for (CellGroup cell_group : m_amr_patch_cell_groups_all) {
952 m_amr_patch_cell_groups_all.clear();
954 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
955 for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) {
958 for (CellGroup cell_group : m_amr_patch_cell_groups_overall) {
961 m_amr_patch_cell_groups_inpatch.clear();
962 m_amr_patch_cell_groups_overall.clear();
965 m_amr_patches_pointer.clear();
966 m_amr_patches.clear();
967 m_available_group_index.clear();
968 m_patches_to_delete.clear();
969 m_index_new_patches = 1;
971 m_amr_patches.add(ground_patch);
972 m_amr_patches_pointer.add(ground_patch.get());
978void CartesianPatchGroup::
981 if (!m_amr_patches.empty())
983 auto patch =
makeRef(
new CartesianMeshPatch(m_cmesh, -1));
984 _addPatchInstance(patch);
986 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
987 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
988 patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 });
989 patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) });
990 patch->_internalApi()->positionRef().setLevel(0);
997void CartesianPatchGroup::
998_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch)
1000 m_amr_patch_cell_groups_all.add(cell_group);
1002 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
1009 AMRPatchPosition patch_position = patch->position();
1010 Ref<ICartesianMeshNumberingMngInternal> numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1012 UniqueArray<Int32> inpatch_items_lid;
1013 UniqueArray<Int32> overall_items_lid;
1017 Int64 pos_x = numbering->cellUniqueIdToCoordX(cell);
1018 Int64 pos_y = numbering->cellUniqueIdToCoordY(cell);
1019 Int64 pos_z = numbering->cellUniqueIdToCoordZ(cell);
1021 if (cell.isOwn() && patch_position.isIn(pos_x, pos_y, pos_z)) {
1022 inpatch_items_lid.add(cell.localId());
1025 overall_items_lid.add(cell.localId());
1030 m_amr_patch_cell_groups_inpatch.add(own);
1033 m_amr_patch_cell_groups_overall.add(overall);
1042bool CartesianPatchGroup::
1043_isPatchInContact(
const AMRPatchPosition& patch_position0,
const AMRPatchPosition& patch_position1)
1046 (patch_position0.level() == patch_position1.level()) &&
1047 (patch_position0.maxPoint().x > patch_position1.minPoint().x && patch_position1.maxPoint().x > patch_position0.minPoint().x) &&
1048 (patch_position0.maxPoint().y > patch_position1.minPoint().y && patch_position1.maxPoint().y > patch_position0.minPoint().y) &&
1049 (m_cmesh->mesh()->dimension() == 2 || (patch_position0.maxPoint().z > patch_position1.minPoint().z && patch_position1.maxPoint().z > patch_position0.minPoint().z)));
1057void CartesianPatchGroup::
1058_splitPatch(Integer index_patch,
const AMRPatchPosition& part_to_remove)
1088 auto cut_points_p0 = [](Int64 p0_min, Int64 p0_max, Int64 p1_min, Int64 p1_max) -> std::pair<Int64, Int64> {
1089 std::pair<Int64, Int64> to_return{ -1, -1 };
1090 if (p1_min > p0_min && p1_min < p0_max) {
1091 to_return.first = p1_min;
1093 if (p1_max > p0_min && p1_max < p0_max) {
1094 to_return.second = p1_max;
1099 ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch];
1100 AMRPatchPosition patch_position = patch->position();
1102 UniqueArray<AMRPatchPosition> new_patch_out;
1104 Int64x3 min_point_of_patch_to_exclude(-1, -1, -1);
1108 UniqueArray<AMRPatchPosition> new_patch_in;
1112 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);
1116 if (cut_point_x.first == -1 && cut_point_x.second == -1) {
1117 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1118 new_patch_out.add(patch_position);
1122 else if (cut_point_x.second == -1) {
1123 min_point_of_patch_to_exclude.x = cut_point_x.first;
1124 auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX);
1125 new_patch_out.add(fst);
1126 new_patch_out.add(snd);
1130 else if (cut_point_x.first == -1) {
1131 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1132 auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX);
1133 new_patch_out.add(fst);
1134 new_patch_out.add(snd);
1139 min_point_of_patch_to_exclude.x = cut_point_x.first;
1140 auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX);
1141 new_patch_out.add(fst);
1142 auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX);
1143 new_patch_out.add(snd);
1144 new_patch_out.add(thr);
1150 std::swap(new_patch_out, new_patch_in);
1152 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);
1156 if (cut_point_y.first == -1 && cut_point_y.second == -1) {
1157 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1158 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1159 new_patch_out.add(patch_x);
1164 else if (cut_point_y.second == -1) {
1165 min_point_of_patch_to_exclude.y = cut_point_y.first;
1166 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1167 auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY);
1168 new_patch_out.add(fst);
1169 new_patch_out.add(snd);
1174 else if (cut_point_y.first == -1) {
1175 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1176 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1177 auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY);
1178 new_patch_out.add(fst);
1179 new_patch_out.add(snd);
1185 min_point_of_patch_to_exclude.y = cut_point_y.first;
1186 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1187 auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY);
1188 new_patch_out.add(fst);
1189 auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY);
1190 new_patch_out.add(snd);
1191 new_patch_out.add(thr);
1197 if (m_cmesh->mesh()->dimension() == 3) {
1198 std::swap(new_patch_out, new_patch_in);
1199 new_patch_out.clear();
1201 std::pair<Int64, Int64> cut_point_z = cut_points_p0(patch_position.minPoint().z, patch_position.maxPoint().z, part_to_remove.minPoint().z, part_to_remove.maxPoint().z);
1205 if (cut_point_z.first == -1 && cut_point_z.second == -1) {
1206 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1207 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
1208 new_patch_out.add(patch_y);
1213 else if (cut_point_z.second == -1) {
1214 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1215 min_point_of_patch_to_exclude.z = cut_point_z.first;
1216 auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ);
1217 new_patch_out.add(fst);
1218 new_patch_out.add(snd);
1223 else if (cut_point_z.first == -1) {
1224 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1225 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
1226 auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ);
1227 new_patch_out.add(fst);
1228 new_patch_out.add(snd);
1234 for (
const AMRPatchPosition& patch_y : new_patch_in) {
1235 min_point_of_patch_to_exclude.z = cut_point_z.first;
1236 auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ);
1237 new_patch_out.add(fst);
1238 auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ);
1239 new_patch_out.add(snd);
1240 new_patch_out.add(thr);
1248 if (m_cmesh->mesh()->dimension() == 2) {
1249 min_point_of_patch_to_exclude.z = 0;
1255 for (AMRPatchPosition& new_patch : new_patch_out) {
1256 if (new_patch.minPoint() == min_point_of_patch_to_exclude) {
1257 new_patch.setLevel(-2);
1267 AMRPatchPositionLevelGroup::fusionPatches(new_patch_out,
false);
1271 for (
const auto& new_patch : new_patch_out) {
1272 if (!new_patch.isNull()) {
1277 _addCutPatch(new_patch, m_amr_patch_cell_groups_all[index_patch - 1]);
1284 removePatch(index_patch);
1290void CartesianPatchGroup::
1291_addCutPatch(
const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
1296 if (parent_patch_cell_group.null())
1299 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
1300 Integer group_index = _nextIndexForNewPatch();
1301 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
1303 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
1304 _addPatchInstance(
makeRef(cdi));
1306 UniqueArray<Int32> cells_local_id;
1308 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1309 ENUMERATE_ (Cell, icell, parent_patch_cell_group) {
1310 Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell);
1311 Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell);
1312 Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell);
1313 if (new_patch_position.isIn(pos_x, pos_y, pos_z)) {
1314 cells_local_id.add(icell.localId());
1318 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
1319 _addCellGroup(parent_cells, cdi);
1331void CartesianPatchGroup::
1332_addPatch(
const AMRPatchPosition& new_patch_position)
1334 UniqueArray<Int32> cells_local_id;
1336 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1337 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) {
1338 Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell);
1339 Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell);
1340 Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell);
1341 if (new_patch_position.isInWithOverlap(pos_x, pos_y, pos_z)) {
1342 cells_local_id.add(icell.localId());
1346 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
1347 Integer group_index = _nextIndexForNewPatch();
1348 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
1350 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
1352 _addPatchInstance(
makeRef(cdi));
1353 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
1354 _addCellGroup(parent_cells, cdi);
1356 if (new_patch_position.level() > m_higher_level) {
1357 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.