3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
scotchbackend.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
19
26#ifndef DUMUX_SCOTCH_BACKEND_HH
27#define DUMUX_SCOTCH_BACKEND_HH
28
29#include <string>
30#include <vector>
31#include <iostream>
32
33#include <dune/common/exceptions.hh>
34
35#if HAVE_PTSCOTCH
36#if HAVE_MPI
37#include <mpi.h>
38#endif
39extern "C"
40{
41#include <stdint.h>
42#include <ptscotch.h>
43}
44#else
45#warning "PTSCOTCH was not found on your system. Dumux::ScotchBackend won't do anything."
46#endif
47
48namespace Dumux {
49
50#if HAVE_PTSCOTCH
51
56template<class IndexType = int>
57class ScotchGraph
58{
59public:
61 using Graph = std::vector<std::vector<IndexType>>;
62
63 ScotchGraph(const Graph& graph)
64 {
65 // Number of local graph vertices
66 const SCOTCH_Num numNodes = graph.size();
67
68 // Data structures for graph input to SCOTCH
69 // add 1 for case that graph size is zero
70 vertTab_.reserve(numNodes + 1);
71 edgeTab_.reserve(20*numNodes);
72
73 // Build local graph input for SCOTCH
74 // (number of graph vertices (cells),
75 // number of edges connecting two vertices)
76 SCOTCH_Num numEdges = 0;
77 vertTab_.push_back(0);
78 for (auto vertex = graph.begin(); vertex != graph.end(); ++vertex)
79 {
80 numEdges += vertex->size();
81 vertTab_.push_back(vertTab_.back() + vertex->size());
82 edgeTab_.insert(edgeTab_.end(), vertex->begin(), vertex->end());
83 }
84
85 // Shrink vectors to hopefully recover any unused memory
86 vertTab_.shrink_to_fit();
87 edgeTab_.shrink_to_fit();
88
89 if (SCOTCH_graphInit(&scotchGraph_) != 0)
90 DUNE_THROW(Dune::Exception, "Error initializing SCOTCH graph!");
91
92 // check graph's consistency (recommended before building)
93 if (SCOTCH_graphCheck(&scotchGraph_) != 0)
94 DUNE_THROW(Dune::Exception, "Error within SCOTCH graph's consistency!");
95
96 // build graph
97 const SCOTCH_Num baseValue = 0; // C-style array indexing
98 if (SCOTCH_graphBuild(&scotchGraph_, baseValue, numNodes, vertTab_.data(), vertTab_.data()+1, NULL, NULL, numEdges, edgeTab_.data(), NULL))
99 DUNE_THROW(Dune::Exception, "Error building SCOTCH graph!");
100 }
101
103 ~ScotchGraph()
104 {
105 SCOTCH_graphExit(&scotchGraph_);
106 }
107
109 SCOTCH_Graph* data()
110 { return &scotchGraph_; }
111
112private:
113 SCOTCH_Graph scotchGraph_;
114 // we have to maintain these ourselves to keep the Scotch graph valid
115 std::vector<SCOTCH_Num> vertTab_;
116 std::vector<SCOTCH_Num> edgeTab_;
117};
118
123class ScotchGraphOrderStrategy
124{
125public:
126 ScotchGraphOrderStrategy(const std::string& strategy = "")
127 {
128 if (SCOTCH_stratInit(&strategy_) != 0)
129 DUNE_THROW(Dune::Exception, "Error initializing SCOTCH strategy!");
130
131 // Set SCOTCH strategy (if provided)
132 if (!strategy.empty())
133 SCOTCH_stratGraphOrder(&strategy_, strategy.c_str());
134 }
135
137 ~ScotchGraphOrderStrategy()
138 {
139 SCOTCH_stratExit(&strategy_);
140 }
141
143 SCOTCH_Strat* data()
144 { return &strategy_; }
145
146private:
147 SCOTCH_Strat strategy_;
148};
149
150#endif // HAVE_PTSCOTCH
151
157template<class IndexType>
159{
160public:
162 using Graph = std::vector<std::vector<IndexType>>;
163
166 static std::vector<int> computeGPSReordering(const Graph& graph,
167 std::size_t numPasses = 5)
168 {
169 // Create strategy string for Gibbs-Poole-Stockmeyer ordering
170 std::string strategy = "g{pass= " + std::to_string(numPasses) + "}";
171 return computeReordering(graph, strategy);
172 }
173
175 static std::vector<int> computeReordering(const Graph& graph,
176 std::string scotchStrategy = "")
177 {
178 std::vector<int> permutation, inversePermutation;
179 computeReordering(graph, permutation, inversePermutation, scotchStrategy);
180 return permutation;
181 }
182
184 static void computeReordering(const Graph& graph,
185 std::vector<int>& permutation,
186 std::vector<int>& inversePermutation,
187 std::string scotchStrategy = "")
188 {
189#if HAVE_PTSCOTCH
190 ScotchGraph<IndexType> scotchGraph(graph);
191 ScotchGraphOrderStrategy strategy(scotchStrategy);
192
193 // Vector to hold permutation vectors
194 const auto graphSize = graph.size();
195 std::vector<SCOTCH_Num> permutationIndices(graphSize);
196 std::vector<SCOTCH_Num> inversePermutationIndices(graphSize);
197
198 // Reset SCOTCH random number generator to produce deterministic partitions
199 SCOTCH_randomReset();
200
201 // Compute re-ordering
202 if (SCOTCH_graphOrder(
203 scotchGraph.data(), strategy.data(), permutationIndices.data(),
204 inversePermutationIndices.data(), NULL, NULL, NULL
205 ))
206 DUNE_THROW(Dune::Exception, "Error reordering SCOTCH graph!");
207
208 // Copy permutation vectors
209 permutation.resize(graphSize);
210 inversePermutation.resize(graphSize);
211 std::copy(permutationIndices.begin(), permutationIndices.end(),
212 permutation.begin());
213 std::copy(inversePermutationIndices.begin(), inversePermutationIndices.end(),
214 inversePermutation.begin());
215#endif // HAVE_PTSCOTCH
216 }
217};
218
219} // end namespace Dumux
220
221#endif
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
A reordering backend using the scotch library.
Definition: scotchbackend.hh:159
static std::vector< int > computeReordering(const Graph &graph, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:175
std::vector< std::vector< IndexType > > Graph
the graph type
Definition: scotchbackend.hh:162
static std::vector< int > computeGPSReordering(const Graph &graph, std::size_t numPasses=5)
Definition: scotchbackend.hh:166
static void computeReordering(const Graph &graph, std::vector< int > &permutation, std::vector< int > &inversePermutation, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:184