mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
commit
4ccc5cddc7
@ -19,38 +19,34 @@
|
||||
#ifndef OPM_GRAPHCOLORING_HEADER_INCLUDED
|
||||
#define OPM_GRAPHCOLORING_HEADER_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <queue>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
namespace Opm {
|
||||
namespace Detail {
|
||||
template <class Graph>
|
||||
std::size_t colorGraphWelshPowell(const Graph& graph,
|
||||
std::deque<typename Graph::VertexDescriptor>& orderedVertices,
|
||||
std::vector<int>& colors,
|
||||
int color, int noVertices)
|
||||
int color,
|
||||
int noVertices)
|
||||
{
|
||||
std::vector<int> forbidden(noVertices, false);
|
||||
std::size_t noColored = 0;
|
||||
|
||||
for (auto vertex = orderedVertices.begin(),
|
||||
vertexEnd = orderedVertices.end();
|
||||
vertex != vertexEnd; ++vertex)
|
||||
{
|
||||
vertexEnd = orderedVertices.end(); vertex != vertexEnd; ++vertex) {
|
||||
// Skip forbidden vertices
|
||||
while (vertex != vertexEnd && forbidden[*vertex])
|
||||
++vertex;
|
||||
if ( vertex == vertexEnd )
|
||||
{
|
||||
if (vertex == vertexEnd) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -58,24 +54,23 @@ std::size_t colorGraphWelshPowell(const Graph& graph,
|
||||
colors[*vertex] = color;
|
||||
++noColored;
|
||||
// Forbid neighors
|
||||
for(auto edge = graph.beginEdges(*vertex), endEdge = graph.endEdges(*vertex);
|
||||
edge != endEdge; ++edge)
|
||||
{
|
||||
for (auto edge = graph.beginEdges(*vertex),
|
||||
endEdge = graph.endEdges(*vertex); edge != endEdge; ++edge) {
|
||||
forbidden[edge.target()] = true;
|
||||
}
|
||||
}
|
||||
// forbidden vertices will be colored next for coloring
|
||||
using Vertex = typename Graph::VertexDescriptor;
|
||||
auto newEnd = std::remove_if(orderedVertices.begin(), orderedVertices.end(),
|
||||
[&forbidden](const Vertex& vertex)
|
||||
{
|
||||
return !forbidden[vertex];
|
||||
});
|
||||
auto newEnd = std::remove_if(orderedVertices.begin(),
|
||||
orderedVertices.end(),
|
||||
[&forbidden](const Vertex& vertex) { return !forbidden[vertex]; });
|
||||
orderedVertices.resize(newEnd - orderedVertices.begin());
|
||||
return noColored;
|
||||
}
|
||||
|
||||
template <class Graph, class Functor>
|
||||
std::size_t breadthFirstSearch(const Graph& graph, typename Graph::VertexDescriptor root,
|
||||
std::size_t breadthFirstSearch(const Graph& graph,
|
||||
typename Graph::VertexDescriptor root,
|
||||
Functor functor)
|
||||
{
|
||||
std::vector<int> visited(graph.maxVertex() + 1, false);
|
||||
@ -85,15 +80,11 @@ std::size_t breadthFirstSearch(const Graph& graph, typename Graph::VertexDescrip
|
||||
nextVertices.push(root);
|
||||
visited[root] = true; // We do not visit root.
|
||||
|
||||
while( !nextVertices.empty() )
|
||||
{
|
||||
while (!nextVertices.empty()) {
|
||||
auto current = nextVertices.front();
|
||||
for (auto edge = graph.beginEdges(current),
|
||||
endEdge = graph.endEdges(current);
|
||||
edge != endEdge; ++edge)
|
||||
{
|
||||
if ( ! visited[edge.target()] )
|
||||
{
|
||||
endEdge = graph.endEdges(current); edge != endEdge; ++edge) {
|
||||
if (!visited[edge.target()]) {
|
||||
visited[edge.target()] = true;
|
||||
nextVertices.push(edge.target());
|
||||
functor(edge.target());
|
||||
@ -125,32 +116,24 @@ colorVerticesWelshPowell(const Graph& graph)
|
||||
std::ptrdiff_t firstDegreeChange = 0;
|
||||
|
||||
// populate deque
|
||||
for( auto vertex = graph.begin(), endVertex = graph.end();
|
||||
vertex != endVertex; ++vertex)
|
||||
{
|
||||
for (auto vertex = graph.begin(),
|
||||
endVertex = graph.end(); vertex != endVertex; ++vertex) {
|
||||
auto currentVertex = *vertex;
|
||||
auto& degree = degrees[currentVertex];
|
||||
|
||||
for (auto edge = graph.beginEdges(currentVertex),
|
||||
endEdge = graph.endEdges(currentVertex);
|
||||
edge != endEdge; ++edge)
|
||||
{
|
||||
endEdge = graph.endEdges(currentVertex); edge != endEdge; ++edge) {
|
||||
++degree;
|
||||
}
|
||||
|
||||
|
||||
if( degree >= maxDegree )
|
||||
{
|
||||
if (degree >= maxDegree) {
|
||||
orderedVertices.emplace_front(currentVertex);
|
||||
++firstDegreeChange;
|
||||
if(degree > maxDegree)
|
||||
{
|
||||
if (degree > maxDegree) {
|
||||
firstDegreeChange = 1;
|
||||
maxDegree = degree;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
orderedVertices.emplace_back(currentVertex);
|
||||
}
|
||||
}
|
||||
@ -159,9 +142,7 @@ colorVerticesWelshPowell(const Graph& graph)
|
||||
std::stable_sort(orderedVertices.begin() + firstDegreeChange,
|
||||
orderedVertices.end(),
|
||||
[°rees](const Vertex& v1, const Vertex& v2)
|
||||
{
|
||||
return degrees[v1] > degrees[v2];
|
||||
});
|
||||
{ return degrees[v1] > degrees[v2]; });
|
||||
|
||||
// Overwrite degree with color
|
||||
auto& colors = degrees;
|
||||
@ -171,11 +152,9 @@ colorVerticesWelshPowell(const Graph& graph)
|
||||
std::vector<std::size_t> verticesPerColor;
|
||||
verticesPerColor.reserve(10);
|
||||
|
||||
while(!orderedVertices.empty())
|
||||
{
|
||||
verticesPerColor
|
||||
.push_back(Detail::colorGraphWelshPowell(graph, orderedVertices, colors,
|
||||
color++, noVertices));
|
||||
while (!orderedVertices.empty()) {
|
||||
verticesPerColor.push_back(Detail::colorGraphWelshPowell(graph, orderedVertices,
|
||||
colors, color++, noVertices));
|
||||
}
|
||||
return std::make_tuple(colors, color, verticesPerColor);
|
||||
}
|
||||
@ -183,7 +162,8 @@ colorVerticesWelshPowell(const Graph& graph)
|
||||
/// \! Reorder colored graph preserving order of vertices with the same color.
|
||||
template <class Graph>
|
||||
std::vector<std::size_t>
|
||||
reorderVerticesPreserving(const std::vector<int>& colors, int noColors,
|
||||
reorderVerticesPreserving(const std::vector<int>& colors,
|
||||
int noColors,
|
||||
const std::vector<std::size_t>& verticesPerColor,
|
||||
const Graph& graph)
|
||||
{
|
||||
@ -193,8 +173,7 @@ reorderVerticesPreserving(const std::vector<int>& colors, int noColors,
|
||||
verticesPerColor.begin() + verticesPerColor.size() - 1,
|
||||
colorIndex.begin() + 1);
|
||||
|
||||
for(const auto& vertex: graph)
|
||||
{
|
||||
for (const auto& vertex : graph) {
|
||||
indices[vertex] = colorIndex[colors[vertex]]++;
|
||||
}
|
||||
return indices;
|
||||
@ -203,7 +182,8 @@ reorderVerticesPreserving(const std::vector<int>& colors, int noColors,
|
||||
/// \! Reorder Vetrices in spheres
|
||||
template <class Graph>
|
||||
std::vector<std::size_t>
|
||||
reorderVerticesSpheres(const std::vector<int>& colors, int noColors,
|
||||
reorderVerticesSpheres(const std::vector<int>& colors,
|
||||
int noColors,
|
||||
const std::vector<std::size_t>& verticesPerColor,
|
||||
const Graph& graph,
|
||||
typename Graph::VertexDescriptor root)
|
||||
@ -221,18 +201,14 @@ reorderVerticesSpheres(const std::vector<int>& colors, int noColors,
|
||||
indices[vertex] = colorIndex[colors[vertex]]++;
|
||||
};
|
||||
|
||||
while ( noVisited < graph.maxVertex() + 1 )
|
||||
{
|
||||
while (noVisited < graph.maxVertex() + 1) {
|
||||
numberer(root);
|
||||
++noVisited; // root node already visited and not visited in BFS
|
||||
noVisited += Detail::breadthFirstSearch(graph, root, numberer);
|
||||
if ( noVisited < graph.maxVertex() + 1 )
|
||||
{
|
||||
if (noVisited < graph.maxVertex() + 1) {
|
||||
// Graph is disconnected search for not yet visited node
|
||||
for(auto vertex: graph)
|
||||
{
|
||||
if ( indices[vertex] == notVisitedTag )
|
||||
{
|
||||
for (auto vertex : graph) {
|
||||
if (indices[vertex] == notVisitedTag) {
|
||||
// \todo make sure that this is a peripheral node!
|
||||
root = vertex;
|
||||
break;
|
||||
|
@ -504,36 +504,61 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(SeqDILUDiagIsCorrect3x3, T, NumericTypes)
|
||||
for (auto row = A.createbegin(); row != A.createend(); ++row) {
|
||||
if (row.index() == 0) {
|
||||
row.insert(row.index());
|
||||
}
|
||||
else if (row.index() == 1) {
|
||||
} else if (row.index() == 1) {
|
||||
row.insert(row.index());
|
||||
row.insert(row.index() + 1);
|
||||
}
|
||||
else if (row.index() == 2) {
|
||||
} else if (row.index() == 2) {
|
||||
row.insert(row.index() - 1);
|
||||
row.insert(row.index());
|
||||
}
|
||||
}
|
||||
|
||||
A[0][0][0][0]=3.0; A[1][1][0][0]=1.0; A[1][2][0][0]=1.0;
|
||||
A[0][0][0][1]=1.0; A[1][1][0][1]=0.0; A[1][2][0][1]=0.0;
|
||||
A[0][0][0][2]=2.0; A[1][1][0][2]=1.0; A[1][2][0][2]=2.0;
|
||||
A[0][0][1][0]=2.0; A[1][1][1][0]=4.0; A[1][2][1][0]=0.0;
|
||||
A[0][0][1][1]=3.0; A[1][1][1][1]=1.0; A[1][2][1][1]=1.0;
|
||||
A[0][0][1][2]=1.0; A[1][1][1][2]=0.0; A[1][2][1][2]=1.0;
|
||||
A[0][0][2][0]=2.0; A[1][1][2][0]=3.0; A[1][2][2][0]=0.0;
|
||||
A[0][0][2][1]=1.0; A[1][1][2][1]=1.0; A[1][2][2][1]=1.0;
|
||||
A[0][0][2][2]=0.0; A[1][1][2][2]=3.0; A[1][2][2][2]=3.0;
|
||||
A[0][0][0][0] = 3.0;
|
||||
A[1][1][0][0] = 1.0;
|
||||
A[1][2][0][0] = 1.0;
|
||||
A[0][0][0][1] = 1.0;
|
||||
A[1][1][0][1] = 0.0;
|
||||
A[1][2][0][1] = 0.0;
|
||||
A[0][0][0][2] = 2.0;
|
||||
A[1][1][0][2] = 1.0;
|
||||
A[1][2][0][2] = 2.0;
|
||||
A[0][0][1][0] = 2.0;
|
||||
A[1][1][1][0] = 4.0;
|
||||
A[1][2][1][0] = 0.0;
|
||||
A[0][0][1][1] = 3.0;
|
||||
A[1][1][1][1] = 1.0;
|
||||
A[1][2][1][1] = 1.0;
|
||||
A[0][0][1][2] = 1.0;
|
||||
A[1][1][1][2] = 0.0;
|
||||
A[1][2][1][2] = 1.0;
|
||||
A[0][0][2][0] = 2.0;
|
||||
A[1][1][2][0] = 3.0;
|
||||
A[1][2][2][0] = 0.0;
|
||||
A[0][0][2][1] = 1.0;
|
||||
A[1][1][2][1] = 1.0;
|
||||
A[1][2][2][1] = 1.0;
|
||||
A[0][0][2][2] = 0.0;
|
||||
A[1][1][2][2] = 3.0;
|
||||
A[1][2][2][2] = 3.0;
|
||||
|
||||
A[2][1][0][0]=1.0; A[2][2][0][0]=1.0;
|
||||
A[2][1][0][1]=0.0; A[2][2][0][1]=3.0;
|
||||
A[2][1][0][2]=2.0; A[2][2][0][2]=2.0;
|
||||
A[2][1][1][0]=0.0; A[2][2][1][0]=2.0;
|
||||
A[2][1][1][1]=1.0; A[2][2][1][1]=1.0;
|
||||
A[2][1][1][2]=4.0; A[2][2][1][2]=3.0;
|
||||
A[2][1][2][0]=5.0; A[2][2][2][0]=3.0;
|
||||
A[2][1][2][1]=1.0; A[2][2][2][1]=1.0;
|
||||
A[2][1][2][2]=1.0; A[2][2][2][2]=2.0;
|
||||
A[2][1][0][0] = 1.0;
|
||||
A[2][2][0][0] = 1.0;
|
||||
A[2][1][0][1] = 0.0;
|
||||
A[2][2][0][1] = 3.0;
|
||||
A[2][1][0][2] = 2.0;
|
||||
A[2][2][0][2] = 2.0;
|
||||
A[2][1][1][0] = 0.0;
|
||||
A[2][2][1][0] = 2.0;
|
||||
A[2][1][1][1] = 1.0;
|
||||
A[2][2][1][1] = 1.0;
|
||||
A[2][1][1][2] = 4.0;
|
||||
A[2][2][1][2] = 3.0;
|
||||
A[2][1][2][0] = 5.0;
|
||||
A[2][2][2][0] = 3.0;
|
||||
A[2][1][2][1] = 1.0;
|
||||
A[2][2][2][1] = 1.0;
|
||||
A[2][1][2][2] = 1.0;
|
||||
A[2][2][2][2] = 2.0;
|
||||
|
||||
|
||||
auto D_00 = A[0][0];
|
||||
@ -602,46 +627,83 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(SeqDILUApplyIsCorrect3, T, NumericTypes)
|
||||
for (auto row = A.createbegin(); row != A.createend(); ++row) {
|
||||
if (row.index() == 0) {
|
||||
row.insert(row.index());
|
||||
}
|
||||
else if (row.index() == 1) {
|
||||
} else if (row.index() == 1) {
|
||||
row.insert(row.index());
|
||||
row.insert(row.index() + 1);
|
||||
}
|
||||
else if (row.index() == 2) {
|
||||
} else if (row.index() == 2) {
|
||||
row.insert(row.index() - 1);
|
||||
row.insert(row.index());
|
||||
}
|
||||
}
|
||||
|
||||
A[0][0][0][0]=3.0; A[1][1][0][0]=1.0; A[1][2][0][0]=1.0;
|
||||
A[0][0][0][1]=1.0; A[1][1][0][1]=0.0; A[1][2][0][1]=0.0;
|
||||
A[0][0][0][2]=2.0; A[1][1][0][2]=1.0; A[1][2][0][2]=2.0;
|
||||
A[0][0][1][0]=2.0; A[1][1][1][0]=4.0; A[1][2][1][0]=0.0;
|
||||
A[0][0][1][1]=3.0; A[1][1][1][1]=1.0; A[1][2][1][1]=1.0;
|
||||
A[0][0][1][2]=1.0; A[1][1][1][2]=0.0; A[1][2][1][2]=1.0;
|
||||
A[0][0][2][0]=2.0; A[1][1][2][0]=3.0; A[1][2][2][0]=0.0;
|
||||
A[0][0][2][1]=1.0; A[1][1][2][1]=1.0; A[1][2][2][1]=1.0;
|
||||
A[0][0][2][2]=0.0; A[1][1][2][2]=3.0; A[1][2][2][2]=3.0;
|
||||
A[0][0][0][0] = 3.0;
|
||||
A[1][1][0][0] = 1.0;
|
||||
A[1][2][0][0] = 1.0;
|
||||
A[0][0][0][1] = 1.0;
|
||||
A[1][1][0][1] = 0.0;
|
||||
A[1][2][0][1] = 0.0;
|
||||
A[0][0][0][2] = 2.0;
|
||||
A[1][1][0][2] = 1.0;
|
||||
A[1][2][0][2] = 2.0;
|
||||
A[0][0][1][0] = 2.0;
|
||||
A[1][1][1][0] = 4.0;
|
||||
A[1][2][1][0] = 0.0;
|
||||
A[0][0][1][1] = 3.0;
|
||||
A[1][1][1][1] = 1.0;
|
||||
A[1][2][1][1] = 1.0;
|
||||
A[0][0][1][2] = 1.0;
|
||||
A[1][1][1][2] = 0.0;
|
||||
A[1][2][1][2] = 1.0;
|
||||
A[0][0][2][0] = 2.0;
|
||||
A[1][1][2][0] = 3.0;
|
||||
A[1][2][2][0] = 0.0;
|
||||
A[0][0][2][1] = 1.0;
|
||||
A[1][1][2][1] = 1.0;
|
||||
A[1][2][2][1] = 1.0;
|
||||
A[0][0][2][2] = 0.0;
|
||||
A[1][1][2][2] = 3.0;
|
||||
A[1][2][2][2] = 3.0;
|
||||
|
||||
A[2][1][0][0]=1.0; A[2][2][0][0]=1.0;
|
||||
A[2][1][0][1]=0.0; A[2][2][0][1]=3.0;
|
||||
A[2][1][0][2]=2.0; A[2][2][0][2]=2.0;
|
||||
A[2][1][1][0]=0.0; A[2][2][1][0]=2.0;
|
||||
A[2][1][1][1]=1.0; A[2][2][1][1]=1.0;
|
||||
A[2][1][1][2]=4.0; A[2][2][1][2]=3.0;
|
||||
A[2][1][2][0]=5.0; A[2][2][2][0]=3.0;
|
||||
A[2][1][2][1]=1.0; A[2][2][2][1]=1.0;
|
||||
A[2][1][2][2]=1.0; A[2][2][2][2]=2.0;
|
||||
A[2][1][0][0] = 1.0;
|
||||
A[2][2][0][0] = 1.0;
|
||||
A[2][1][0][1] = 0.0;
|
||||
A[2][2][0][1] = 3.0;
|
||||
A[2][1][0][2] = 2.0;
|
||||
A[2][2][0][2] = 2.0;
|
||||
A[2][1][1][0] = 0.0;
|
||||
A[2][2][1][0] = 2.0;
|
||||
A[2][1][1][1] = 1.0;
|
||||
A[2][2][1][1] = 1.0;
|
||||
A[2][1][1][2] = 4.0;
|
||||
A[2][2][1][2] = 3.0;
|
||||
A[2][1][2][0] = 5.0;
|
||||
A[2][2][2][0] = 3.0;
|
||||
A[2][1][2][1] = 1.0;
|
||||
A[2][2][2][1] = 1.0;
|
||||
A[2][1][2][2] = 1.0;
|
||||
A[2][2][2][2] = 2.0;
|
||||
|
||||
Vector x(3);
|
||||
x[0][0] = 1.0; x[1][0] = 1.0; x[2][0] = 1.0;
|
||||
x[0][1] = 2.0; x[1][1] = 3.0; x[2][1] = 0.0;
|
||||
x[0][2] = 3.0; x[1][2] = 2.0; x[2][2] = 2.0;
|
||||
x[0][0] = 1.0;
|
||||
x[1][0] = 1.0;
|
||||
x[2][0] = 1.0;
|
||||
x[0][1] = 2.0;
|
||||
x[1][1] = 3.0;
|
||||
x[2][1] = 0.0;
|
||||
x[0][2] = 3.0;
|
||||
x[1][2] = 2.0;
|
||||
x[2][2] = 2.0;
|
||||
|
||||
Vector b(3);
|
||||
b[0][0] = 2.0; b[1][0] = 2.0; b[2][0] = 0.0;
|
||||
b[0][1] = 1.0; b[1][1] = 3.0; b[2][1] = 2.0;
|
||||
b[0][2] = 2.0; b[1][2] = 2.0; b[2][2] = 1.0;
|
||||
b[0][0] = 2.0;
|
||||
b[1][0] = 2.0;
|
||||
b[2][0] = 0.0;
|
||||
b[0][1] = 1.0;
|
||||
b[1][1] = 3.0;
|
||||
b[2][1] = 2.0;
|
||||
b[0][2] = 2.0;
|
||||
b[1][2] = 2.0;
|
||||
b[2][2] = 1.0;
|
||||
|
||||
|
||||
// D_00 = A_00
|
||||
|
Loading…
Reference in New Issue
Block a user