12#ifndef DUMUX_ASSEMBLY_COLORING_HH
13#define DUMUX_ASSEMBLY_COLORING_HH
21#include <dune/common/timer.hh>
22#include <dune/common/exceptions.hh>
31template <
class Gr
idGeometry>
32std::vector<std::vector<std::size_t>>
33computeConnectedElements(
const GridGeometry& gg)
35 std::vector<std::vector<std::size_t>> connectedElements;
39 connectedElements.resize(gg.gridView().size(0));
40 const auto& eMapper = gg.elementMapper();
41 for (
const auto& element : elements(gg.gridView()))
43 const auto eIdx = eMapper.index(element);
44 for (
const auto& intersection : intersections(gg.gridView(), element))
45 if (intersection.neighbor())
46 connectedElements[eMapper.index(intersection.outside())].push_back(eIdx);
55 static constexpr int dim = GridGeometry::GridView::dimension;
56 connectedElements.resize(gg.gridView().size(dim));
57 const auto& vMapper = gg.vertexMapper();
58 for (
const auto& element : elements(gg.gridView()))
60 const auto eIdx = gg.elementMapper().index(element);
61 for (
int i = 0; i <
element.subEntities(dim); i++)
62 connectedElements[vMapper.subIndex(element, i, dim)].push_back(eIdx);
74 std::vector<std::vector<std::size_t>> vToElements;
75 static constexpr int dim = GridGeometry::GridView::dimension;
76 vToElements.resize(gg.gridView().size(dim));
77 const auto& vMapper = gg.vertexMapper();
78 for (
const auto& element : elements(gg.gridView()))
80 const auto eIdx = gg.elementMapper().index(element);
81 for (
int i = 0; i <
element.subEntities(dim); i++)
82 vToElements[vMapper.subIndex(element, i, dim)].push_back(eIdx);
85 connectedElements.resize(gg.gridView().size(0));
86 for (
const auto& element : elements(gg.gridView()))
88 const auto eIdx = gg.elementMapper().index(element);
89 for (
int i = 0; i <
element.subEntities(dim); i++)
91 const auto& e = vToElements[vMapper.subIndex(element, i, dim)];
92 connectedElements[eIdx].insert(connectedElements[eIdx].end(), e.begin(), e.end());
96 std::sort(connectedElements[eIdx].begin(), connectedElements[eIdx].end());
97 connectedElements[eIdx].erase(
98 std::unique(connectedElements[eIdx].begin(), connectedElements[eIdx].end()),
99 connectedElements[eIdx].end()
106 return connectedElements;
109 DUNE_THROW(Dune::NotImplemented,
110 "Missing coloring scheme implementation for this discretization method"
113 return connectedElements;
128template<
class Gr
idGeometry,
class ConnectedElements>
129void addNeighborColors(
const GridGeometry& gg,
130 const typename GridGeometry::LocalView::Element& element,
131 const std::vector<int>& colors,
132 const ConnectedElements& connectedElements,
133 std::vector<int>& neighborColors)
143 const auto& eMapper = gg.elementMapper();
144 for (
const auto& intersection : intersections(gg.gridView(), element))
146 if (intersection.neighbor())
149 const auto nIdx = eMapper.index(intersection.outside());
150 neighborColors.push_back(colors[nIdx]);
153 for (
const auto nnIdx : connectedElements[eMapper.index(intersection.outside())])
154 neighborColors.push_back(colors[nnIdx]);
166 const auto& vMapper = gg.vertexMapper();
167 static constexpr int dim = GridGeometry::GridView::dimension;
169 for (
int i = 0; i <
element.subEntities(dim); i++)
170 for (
auto eIdx : connectedElements[vMapper.subIndex(element, i, dim)])
171 neighborColors.push_back(colors[eIdx]);
178 const auto& eMapper = gg.elementMapper();
179 for (
const auto& intersection : intersections(gg.gridView(), element))
180 if (intersection.neighbor())
181 neighborColors.push_back(colors[eMapper.index(intersection.outside())]);
185 DUNE_THROW(Dune::NotImplemented,
186 "Missing coloring scheme implementation for this discretization method"
195int smallestAvailableColor(
const std::vector<int>& colors,
196 std::vector<bool>& colorUsed)
198 const int numColors = colors.size();
199 colorUsed.assign(numColors,
false);
205 for (
int i = 0; i < numColors; i++)
206 if (colors[i] >= 0 && colors[i] < numColors)
207 colorUsed[colors[i]] =
true;
210 for (
int i = 0; i < numColors; i++)
242template<
class Gr
idGeometry>
247 using ElementSeed =
typename GridGeometry::GridView::Grid::template Codim<0>::EntitySeed;
250 using Sets = std::deque<std::vector<ElementSeed>>;
251 using Colors = std::vector<int>;
253 Coloring(std::size_t size) : sets{}, colors(size, -1) {}
259 Coloring coloring(gg.gridView().size(0));
262 std::vector<int> neighborColors; neighborColors.reserve(30);
263 std::vector<bool> colorUsed; colorUsed.reserve(30);
266 const auto connectedElements = Detail::computeConnectedElements(gg);
268 for (
const auto& element : elements(gg.gridView()))
271 neighborColors.clear();
272 Detail::addNeighborColors(gg, element, coloring.colors, connectedElements, neighborColors);
275 const auto color = Detail::smallestAvailableColor(neighborColors, colorUsed);
278 coloring.colors[gg.elementMapper().index(element)] = color;
281 if (color < coloring.sets.size())
282 coloring.sets[color].push_back(element.seed());
284 coloring.sets.push_back(std::vector<ElementSeed>{ element.seed() });
288 std::cout << Fmt::format(
"Colored {} elements with {} colors in {} seconds.\n",
289 gg.gridView().size(0), coloring.sets.size(), timer.elapsed());
295template<
class DiscretizationMethod>
The available discretization methods in Dumux.
Definition cellcentered/mpfa/elementvolumevariables.hh:24
Definition cvfelocalresidual.hh:25
constexpr CCMpfa ccmpfa
Definition method.hh:165
constexpr FCDiamond fcdiamond
Definition method.hh:173
constexpr PQ2 pq2
Definition method.hh:167
constexpr CCTpfa cctpfa
Definition method.hh:164
constexpr Box box
Definition method.hh:166
constexpr PQ3 pq3
Definition method.hh:168
constexpr PQ1Bubble pq1bubble
Definition method.hh:169
constexpr FCStaggered fcstaggered
Definition method.hh:172
auto computeColoring(const GridGeometry &gg, int verbosity=1)
Compute iterable lists of element seeds partitioned by color.
Definition coloring.hh:243
Traits specifying if a given discretization tag supports coloring.
Definition coloring.hh:296