Arcane  v4.1.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AMRPatchPositionLevelGroup.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* AMRPatchPositionLevelGroup.cc (C) 2000-2025 */
9/* */
10/* Groupe de position de patch AMR réparti par niveau. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h"
15
16#include "arcane/cartesianmesh/AMRPatchPosition.h"
17
18#include <algorithm>
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29AMRPatchPositionLevelGroup::
30AMRPatchPositionLevelGroup(Integer max_level)
31: m_max_level(max_level)
32, m_patches(max_level+1)
33{}
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38AMRPatchPositionLevelGroup::
39~AMRPatchPositionLevelGroup()
40= default;
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45Integer AMRPatchPositionLevelGroup::
46maxLevel()
47{
48 return m_max_level;
49}
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54ConstArrayView<AMRPatchPosition> AMRPatchPositionLevelGroup::
55patches(Integer level)
56{
57 return m_patches[level];
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63void AMRPatchPositionLevelGroup::
64addPatch(AMRPatchPosition patch)
65{
66 m_patches[patch.level()].add(patch);
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void AMRPatchPositionLevelGroup::
73fusionPatches(Integer level)
74{
75 fusionPatches(m_patches[level], true);
76}
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81void AMRPatchPositionLevelGroup::
82fusionPatches(UniqueArray<AMRPatchPosition>& patch_position, bool remove_null)
83{
84 // Algo de fusion.
85 // D'abord, on trie les patchs du plus petit nb de mailles au plus grand nb de mailles (optionnel).
86 // Ensuite, pour chaque patch, on regarde si l'on peut le fusionner avec un autre.
87 // Si on arrive à faire une fusion, on recommence l'algo jusqu'à ne plus pouvoir fusionner.
88 bool fusion = true;
89 while (fusion) {
90 fusion = false;
91
92 // Le sort permet de fusionner les patchs les plus petits d'abord, ce qui
93 // permet d'équilibrer (un peu) la taille des patchs.
94 // Attention : retirer le sort change les hashs des tests.
95 std::stable_sort(patch_position.begin(), patch_position.end(),
96 [](const AMRPatchPosition& a, const AMRPatchPosition& b) {
97 return a.nbCells() < b.nbCells();
98 });
99
100 for (Integer p0 = 0; p0 < patch_position.size(); ++p0) {
101 AMRPatchPosition& patch_fusion_0 = patch_position[p0];
102 if (patch_fusion_0.isNull())
103 continue;
104
105 for (Integer p1 = p0 + 1; p1 < patch_position.size(); ++p1) {
106 AMRPatchPosition& patch_fusion_1 = patch_position[p1];
107 if (patch_fusion_1.isNull())
108 continue;
109
110 // if (tm) {
111 // tm->info() << "Check fusion";
112 // tm->info() << " 0 -- Min point : " << patch_fusion_0.minPoint()
113 // << " -- Max point : " << patch_fusion_0.maxPoint()
114 // << " -- Level : " << patch_fusion_0.level()
115 // << " -- NbCells : " << patch_fusion_0.nbCells();
116 // tm->info() << " 1 -- Min point : " << patch_fusion_1.minPoint()
117 // << " -- Max point : " << patch_fusion_1.maxPoint()
118 // << " -- Level : " << patch_fusion_1.level()
119 // << " -- NbCells : " << patch_fusion_1.nbCells();
120 // }
121 if (patch_fusion_0.fusion(patch_fusion_1)) {
122 // if (tm)
123 // tm->info() << "Fusion OK";
124 patch_fusion_1.setLevel(-2); // Devient null.
125 fusion = true;
126 break;
127 }
128 }
129 if (fusion) {
130 break;
131 }
132 }
133 }
134 if (remove_null) {
135 for (Integer i = 0; i < patch_position.size(); ++i) {
136 if (patch_position[i].isNull()) {
137 patch_position.remove(i);
138 i--;
139 }
140 }
141 }
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
147} // End namespace Arcane
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.