24#include <boost/timer/timer.hpp>
26#include "dune/istl/bcrsmatrix.hh"
27#include "dune/istl/matrixindexset.hh"
42 template <
class Scalar,
class Entry>
44 Dune::BCRSMatrix<Entry>
const& A ,
45 bool onlyLowerTriangle =
false)
50 typedef Dune::BCRSMatrix<Entry> MatA;
51 typedef Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1> > MatP;
58 std::unique_ptr<Dune::MatrixIndexSet> nzC(
new Dune::MatrixIndexSet(P.M(),P.M()));
61 if(onlyLowerTriangle ==
false)
64 for (
int k=0; k<A.N(); ++k)
65 for (
typename MatA::ConstColIterator ca=A[k].begin(); ca!=A[k].end(); ++ca)
67 int const l = ca.index();
69 for (
typename MatP::ConstColIterator cpk=P[k].begin(); cpk!=P[k].end(); ++cpk)
70 for (
typename MatP::ConstColIterator cpl=P[l].begin(); cpl!=P[l].end(); ++cpl)
71 nzC->add(cpk.index(),cpl.index());
77 for (
int k=0; k<A.N(); ++k)
78 for (
typename MatA::ConstColIterator ca=A[k].begin(); ca!=A[k].end(); ++ca)
80 int const l = ca.index();
82 for (
typename MatP::ConstColIterator cpk=P[k].begin(); cpk!=P[k].end(); ++cpk)
83 for (
typename MatP::ConstColIterator cpl=P[l].begin(); cpl!=P[l].end(); ++cpl)
85 if( cpk.index() >= cpl.index() )
86 nzC->add(cpk.index(),cpl.index());
88 nzC->add(cpl.index(),cpk.index());
122 template <
class IndexP,
class EntryP,
class IndexA,
class EntryA>
124 bool onlyLowerTriangle =
false,
bool createDiagonal=
false)
126 assert(A.
N()==A.
M());
127 static_assert(EntryA::rows==EntryA::cols,
"central matrix entries in conjugation have to be square");
128 assert(A.
N()==P.
N());
134 timer.
start(
"conjugation pattern");
144 auto getColumnIndices = [] (
auto const& row, std::vector<IndexP>& ci)
147 for (
auto i=row.begin(); i!=row.end(); ++i)
148 ci.push_back(i.index());
150 std::vector<IndexP> is, js;
153 for (IndexA k=0; k<A.
N(); ++k)
155 getColumnIndices(P[k],is);
158 for (
auto ca=row.begin(); ca!=row.end(); ++ca)
160 IndexA
const l = ca.index();
161 getColumnIndices(P[l],js);
164 creator.
addElements(std::begin(is),std::end(is),std::begin(js),std::end(js));
165 if (onlyLowerTriangle && k>l)
167 creator.
addElements(std::begin(js),std::end(js),std::begin(is),std::end(is));
174 timer.
stop(
"conjugation pattern");
192 constexpr int entrySize = (EntryP::rows==1 && EntryP::cols==1)? (
int)EntryA::rows: (int)EntryP::cols;
195 timer.
start(
"matrix creation");
197 timer.
stop(
"matrix creation");
212 auto getEntryValues = [] (
auto const& row, std::vector<EntryP>& vi)
215 for (
auto i=row.begin(); i!=row.end(); ++i)
219 auto getColumnIndices = [] (
auto const& row,
auto& ci)
223 for (
auto i=row.begin(); i!=row.end(); ++i, ++idx)
224 ci.push_back(std::make_pair(i.index(),idx));
227 timer.
start(
"conjugation scatter");
232 std::vector<EntryP> pk, pl;
233 using SortedIndices = std::vector<std::pair<IndexP,int>>;
234 SortedIndices is, js;
236 for (IndexA k=rowStart; k<rowEnd; ++k)
239 getColumnIndices(Pk,is);
240 getEntryValues(Pk,pk);
243 for (
auto ca=row.begin(); ca!=row.end(); ++ca)
245 IndexA
const l = ca.index();
247 getColumnIndices(Pl,js);
248 getEntryValues(Pl,pl);
254 for (
int i=0; i<is.size(); ++i)
258 for (
int j=0; j<pl.size(); ++j)
261 localMatrices.
back()(i,j) = Pki_Akl * plj;
265 if (onlyLowerTriangle && k>l)
274 timer.
stop(
"conjugation scatter");
285 template <
class Scalar,
class Entry>
288 Dune::BCRSMatrix<Entry>
const& A,
289 bool onlyLowerTriangle =
false )
291 assert(A.N()==A.M());
292 assert(A.N()==P.N());
293 assert(C.N()==P.M());
294 assert(C.M()==P.M());
296 typedef Dune::BCRSMatrix<Entry> MatA;
297 typedef Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1> > MatP;
299 if(onlyLowerTriangle ==
false )
302 for (
int k=0; k<A.N(); ++k)
303 for (
typename MatA::ConstColIterator ca=A[k].begin(); ca!=A[k].end(); ++ca)
305 int const l = ca.index();
307 for (
typename MatP::ConstColIterator cpk=P[k].begin(); cpk!=P[k].end(); ++cpk)
308 for (
typename MatP::ConstColIterator cpl=P[l].begin(); cpl!=P[l].end(); ++cpl)
309 C[cpk.index()][cpl.index()].axpy((*cpl) * (*cpk),(*ca));
315 for (
int k=0; k<A.N(); ++k)
316 for (
typename MatA::ConstColIterator ca=A[k].begin(); ca!=A[k].end(); ++ca)
318 int const l = ca.index();
319 for (
typename MatP::ConstColIterator cpk=P[k].begin(); cpk!=P[k].end(); ++cpk)
320 for (
typename MatP::ConstColIterator cpl=P[l].begin(); cpl!=P[l].end(); ++cpl)
322 if( cpk.index() >= cpl.index() )
323 C[cpk.index()][cpl.index()].axpy((*cpl) * (*cpk), (*ca) );
327 for (
typename MatP::ConstColIterator cpl=P[l].begin(); cpl!=P[l].end(); ++cpl)
328 for (
typename MatP::ConstColIterator cpk=P[k].begin(); cpk!=P[k].end(); ++cpk)
329 if( cpl.index() >= cpk.index() )
330 C[cpl.index()][cpk.index()].axpy((*cpl) * (*cpk) , (*ca) );
A structure for holding a sequence of several local matrices to be filled sequentially and to be scat...
value_type & back()
A reference to the last pushed local matrix.
void push_back(SortedRowIdx const &ridx, SortedColIdx const &cidx)
Appends another (zero-initialized) local matrix.
A NUMA-aware compressed row storage matrix adhering mostly to the Dune ISTL interface (to complete....
Index M() const
The number of columns.
Index N() const
The number of rows.
A NUMA-aware creator for matrix sparsity patterns.
void addElements(IterRow const fromRow, IterRow const toRow, IterCol const fromCol, IterCol const toCol, bool colIsSorted=false)
Enters entries into the sparsity pattern.
void addDiagonal()
Enters the diagonal elements.
static NumaThreadPool & instance(int maxThreads=std::numeric_limits< int >::max())
Returns a globally unique thread pool instance.
int cpus() const
Reports the total number of CPUs (usually a multiple of nodes).
Supports gathering and reporting execution times information for nested program parts.
static Timings & instance()
Returns a reference to a single default instance.
void stop(std::string const &name)
Stops the timing of given section.
struct Times const * start(std::string const &name)
Starts or continues the timing of given section.
auto conjugation(NumaBCRSMatrix< EntryP, IndexP > const &P, NumaBCRSMatrix< EntryA, IndexA > const &A, bool onlyLowerTriangle=false, bool createDiagonal=false)
Creates the conjugation product .
Index uniformWeightRangeStart(BlockIndex i, BlockIndex n, Index m)
Computes partitioning points of ranges for uniform weight distributions.
void parallelFor(Func const &f, int maxTasks=std::numeric_limits< int >::max())
A parallel for loop that executes the given functor in parallel on different CPUs.
auto normalForm(Dune::FieldMatrix< T, n, m > const &A)
void conjugation(Dune::BCRSMatrix< Entry > &C, Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, 1, 1 > > const &P, Dune::BCRSMatrix< Entry > const &A, bool onlyLowerTriangle=false)
Computes the triple sparse matrix product .
std::unique_ptr< Dune::MatrixIndexSet > conjugationPattern(Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, 1, 1 > > const &P, Dune::BCRSMatrix< Entry > const &A, bool onlyLowerTriangle=false)
Creates the sparsity pattern of .