Dune Core Modules (2.3.1)

galerkin.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// $Id$
4#ifndef DUNE_GALERKIN_HH
5#define DUNE_GALERKIN_HH
6
7#include "aggregates.hh"
8#include "pinfo.hh"
11#include <dune/common/unused.hh>
12#include <set>
13#include <limits>
14#include <algorithm>
15
16namespace Dune
17{
18 namespace Amg
19 {
31 template<class T>
32 struct OverlapVertex
33 {
37 typedef T Aggregate;
38
42 typedef T Vertex;
43
48
53 };
54
55
56
61 template<class M>
63 {
64 public:
70 SparsityBuilder(M& matrix);
71
72 void insert(const typename M::size_type& index);
73
74 void operator++();
75
76 std::size_t minRowSize();
77
78 std::size_t maxRowSize();
79
80 std::size_t sumRowSize();
81 std::size_t index()
82 {
83 return row_.index();
84 }
85 private:
87 typename M::CreateIterator row_;
89 std::size_t minRowSize_;
91 std::size_t maxRowSize_;
92 std::size_t sumRowSize_;
93#ifdef DUNE_ISTL_WITH_CHECKING
94 bool diagonalInserted;
95#endif
96 };
97
98 class BaseGalerkinProduct
99 {
100 public:
109 template<class M, class V, class I, class O>
110 void calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
111 const I& pinfo, const O& copy);
112
113 };
114
115 template<class T>
116 class GalerkinProduct
117 : public BaseGalerkinProduct
118 {
119 public:
120 typedef T ParallelInformation;
121
131 template<class G, class V, class Set>
132 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
133 const ParallelInformation& pinfo,
135 const typename G::Matrix::size_type& size,
136 const Set& copy);
137 private:
138
145 template<class G, class I, class Set>
146 const OverlapVertex<typename G::VertexDescriptor>*
147 buildOverlapVertices(const G& graph, const I& pinfo,
149 const Set& overlap,
150 std::size_t& overlapCount);
151
152 template<class A>
153 struct OVLess
154 {
155 bool operator()(const OverlapVertex<A>& o1, const OverlapVertex<A>& o2)
156 {
157 return *o1.aggregate < *o2.aggregate;
158 }
159 };
160 };
161
162 template<>
163 class GalerkinProduct<SequentialInformation>
164 : public BaseGalerkinProduct
165 {
166 public:
176 template<class G, class V, class Set>
177 typename G::MutableMatrix* build(G& fineGraph, V& visitedMap,
178 const SequentialInformation& pinfo,
179 const AggregatesMap<typename G::VertexDescriptor>& aggregates,
180 const typename G::Matrix::size_type& size,
181 const Set& copy);
182 };
183
184 struct BaseConnectivityConstructor
185 {
186 template<class R, class G, class V>
187 static void constructOverlapConnectivity(R& row, G& graph, V& visitedMap,
188 const AggregatesMap<typename G::VertexDescriptor>& aggregates,
189 const OverlapVertex<typename G::VertexDescriptor>*& seed,
190 const OverlapVertex<typename G::VertexDescriptor>* overlapEnd);
191
195 template<class R, class G, class V>
196 static void constructNonOverlapConnectivity(R& row, G& graph, V& visitedMap,
197 const AggregatesMap<typename G::VertexDescriptor>& aggregates,
198 const typename G::VertexDescriptor& seed);
199
200
204 template<class G, class S, class V>
206 {
207 public:
211 typedef G Graph;
215 typedef typename Graph::ConstEdgeIterator ConstEdgeIterator;
216
220 typedef S Set;
221
225 typedef V VisitedMap;
226
230 typedef typename Graph::VertexDescriptor Vertex;
231
239 ConnectedBuilder(const AggregatesMap<Vertex>& aggregates, Graph& graph,
240 VisitedMap& visitedMap, Set& connected);
241
246 void operator()(const ConstEdgeIterator& edge);
247
248 private:
252 const AggregatesMap<Vertex>& aggregates_;
253
254 Graph& graph_;
255
259 VisitedMap& visitedMap_;
260
264 Set& connected_;
265 };
266
267 };
268
269 template<class G, class T>
270 struct ConnectivityConstructor : public BaseConnectivityConstructor
271 {
272 typedef typename G::VertexDescriptor Vertex;
273
274 template<class V, class O, class R>
275 static void examine(G& graph,
276 V& visitedMap,
277 const T& pinfo,
278 const AggregatesMap<Vertex>& aggregates,
279 const O& overlap,
280 const OverlapVertex<Vertex>* overlapVertices,
281 const OverlapVertex<Vertex>* overlapEnd,
282 R& row);
283 };
284
285 template<class G>
286 struct ConnectivityConstructor<G,SequentialInformation> : public BaseConnectivityConstructor
287 {
288 typedef typename G::VertexDescriptor Vertex;
289
290 template<class V, class R>
291 static void examine(G& graph,
292 V& visitedMap,
293 const SequentialInformation& pinfo,
294 const AggregatesMap<Vertex>& aggregates,
295 R& row);
296 };
297
298 template<class T>
299 struct DirichletBoundarySetter
300 {
301 template<class M, class O>
302 static void set(M& coarse, const T& pinfo, const O& copy);
303 };
304
305 template<>
306 struct DirichletBoundarySetter<SequentialInformation>
307 {
308 template<class M, class O>
309 static void set(M& coarse, const SequentialInformation& pinfo, const O& copy);
310 };
311
312 template<class R, class G, class V>
313 void BaseConnectivityConstructor::constructNonOverlapConnectivity(R& row, G& graph, V& visitedMap,
315 const typename G::VertexDescriptor& seed)
316 {
317 assert(row.index()==aggregates[seed]);
318 row.insert(aggregates[seed]);
319 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
320 typedef typename G::VertexDescriptor Vertex;
321 typedef std::allocator<Vertex> Allocator;
322 typedef SLList<Vertex,Allocator> VertexList;
323 typedef typename AggregatesMap<Vertex>::DummyEdgeVisitor DummyVisitor;
324 VertexList vlist;
325 DummyVisitor dummy;
326 aggregates.template breadthFirstSearch<true,false>(seed,aggregates[seed], graph, vlist, dummy,
327 conBuilder, visitedMap);
328 }
329
330 template<class R, class G, class V>
331 void BaseConnectivityConstructor::constructOverlapConnectivity(R& row, G& graph, V& visitedMap,
333 const OverlapVertex<typename G::VertexDescriptor>*& seed,
334 const OverlapVertex<typename G::VertexDescriptor>* overlapEnd)
335 {
336 ConnectedBuilder<G,R,V> conBuilder(aggregates, graph, visitedMap, row);
337 const typename G::VertexDescriptor aggregate=*seed->aggregate;
338
339 if (row.index()==*seed->aggregate) {
340 while(seed != overlapEnd && aggregate == *seed->aggregate) {
341 row.insert(*seed->aggregate);
342 // Walk over all neighbours and add them to the connected array.
343 visitNeighbours(graph, seed->vertex, conBuilder);
344 // Mark vertex as visited
345 put(visitedMap, seed->vertex, true);
346 ++seed;
347 }
348 }
349 }
350
351 template<class G, class S, class V>
353 Graph& graph, VisitedMap& visitedMap,
354 Set& connected)
355 : aggregates_(aggregates), graph_(graph), visitedMap_(visitedMap), connected_(connected)
356 {}
357
358 template<class G, class S, class V>
360 {
361 typedef typename G::VertexDescriptor Vertex;
362 const Vertex& vertex = aggregates_[edge.target()];
365 connected_.insert(vertex);
366 }
367
368 template<class T>
369 template<class G, class I, class Set>
370 const OverlapVertex<typename G::VertexDescriptor>*
371 GalerkinProduct<T>::buildOverlapVertices(const G& graph, const I& pinfo,
373 const Set& overlap,
374 std::size_t& overlapCount)
375 {
376 // count the overlap vertices.
377 typedef typename G::ConstVertexIterator ConstIterator;
378 typedef typename I::GlobalLookupIndexSet GlobalLookup;
379 typedef typename GlobalLookup::IndexPair IndexPair;
380
381 const ConstIterator end = graph.end();
382 overlapCount = 0;
383
384 const GlobalLookup& lookup=pinfo.globalLookup();
385
386 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
387 const IndexPair* pair = lookup.pair(*vertex);
388
389 if(pair!=0 && overlap.contains(pair->local().attribute()))
390 ++overlapCount;
391 }
392 // Allocate space
393 typedef typename G::VertexDescriptor Vertex;
394
395 OverlapVertex<Vertex>* overlapVertices = new OverlapVertex<Vertex>[overlapCount=0 ? 1 : overlapCount];
396 if(overlapCount==0)
397 return overlapVertices;
398
399 // Initialize them
400 overlapCount=0;
401 for(ConstIterator vertex=graph.begin(); vertex != end; ++vertex) {
402 const IndexPair* pair = lookup.pair(*vertex);
403
404 if(pair!=0 && overlap.contains(pair->local().attribute())) {
405 overlapVertices[overlapCount].aggregate = &aggregates[pair->local()];
406 overlapVertices[overlapCount].vertex = pair->local();
407 ++overlapCount;
408 }
409 }
410
411 dverb << overlapCount<<" overlap vertices"<<std::endl;
412
413 std::sort(overlapVertices, overlapVertices+overlapCount, OVLess<Vertex>());
414 // due to the sorting the isolated aggregates (to be skipped) are at the end.
415
416 return overlapVertices;
417 }
418
419 template<class G, class T>
420 template<class V, class O, class R>
421 void ConnectivityConstructor<G,T>::examine(G& graph,
422 V& visitedMap,
423 const T& pinfo,
424 const AggregatesMap<Vertex>& aggregates,
425 const O& overlap,
426 const OverlapVertex<Vertex>* overlapVertices,
427 const OverlapVertex<Vertex>* overlapEnd,
428 R& row)
429 {
430 typedef typename T::GlobalLookupIndexSet GlobalLookup;
431 const GlobalLookup& lookup = pinfo.globalLookup();
432
433 typedef typename G::VertexIterator VertexIterator;
434
435 VertexIterator vend=graph.end();
436
437#ifdef DUNE_ISTL_WITH_CHECKING
438 std::set<Vertex> examined;
439#endif
440
441 // The aggregates owned by the process have lower local indices
442 // then those not owned. We process them in the first pass.
443 // They represent the rows 0, 1, ..., n of the coarse matrix
444 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex)
445 if(!get(visitedMap, *vertex)) {
446 // In the first pass we only process owner nodes
447 typedef typename GlobalLookup::IndexPair IndexPair;
448 const IndexPair* pair = lookup.pair(*vertex);
449 if(pair==0 || !overlap.contains(pair->local().attribute())) {
450#ifdef DUNE_ISTL_WITH_CHECKING
451 assert(examined.find(aggregates[*vertex])==examined.end());
452 examined.insert(aggregates[*vertex]);
453#endif
454 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
455
456 // only needed for ALU
457 // (ghosts with same global id as owners on the same process)
458 if (pinfo.getSolverCategory() == static_cast<int>(SolverCategory::nonoverlapping)) {
459 if(overlapVertices != overlapEnd) {
460 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
461 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
462 }
463 else{
464 ++overlapVertices;
465 }
466 }
467 }
468 ++row;
469 }
470 }
471
472 dvverb<<"constructed "<<row.index()<<" non-overlapping rows"<<std::endl;
473
474 // Now come the aggregates not owned by use.
475 // They represent the rows n+1, ..., N
476 while(overlapVertices != overlapEnd)
477 if(*overlapVertices->aggregate!=AggregatesMap<Vertex>::ISOLATED) {
478
479#ifdef DUNE_ISTL_WITH_CHECKING
480 typedef typename GlobalLookup::IndexPair IndexPair;
481 const IndexPair* pair = lookup.pair(overlapVertices->vertex);
482 assert(pair!=0 && overlap.contains(pair->local().attribute()));
483 assert(examined.find(aggregates[overlapVertices->vertex])==examined.end());
484 examined.insert(aggregates[overlapVertices->vertex]);
485#endif
486 constructOverlapConnectivity(row, graph, visitedMap, aggregates, overlapVertices, overlapEnd);
487 ++row;
488 }else{
489 ++overlapVertices;
490 }
491 }
492
493 template<class G>
494 template<class V, class R>
495 void ConnectivityConstructor<G,SequentialInformation>::examine(G& graph,
496 V& visitedMap,
497 const SequentialInformation& pinfo,
498 const AggregatesMap<Vertex>& aggregates,
499 R& row)
500 {
502 typedef typename G::VertexIterator VertexIterator;
503
504 VertexIterator vend=graph.end();
505 for(VertexIterator vertex = graph.begin(); vertex != vend; ++vertex) {
506 if(!get(visitedMap, *vertex)) {
507 constructNonOverlapConnectivity(row, graph, visitedMap, aggregates, *vertex);
508 ++row;
509 }
510 }
511
512 }
513
514 template<class M>
516 : row_(matrix.createbegin()),
517 minRowSize_(std::numeric_limits<std::size_t>::max()),
518 maxRowSize_(0), sumRowSize_(0)
519 {
520#ifdef DUNE_ISTL_WITH_CHECKING
521 diagonalInserted = false;
522#endif
523 }
524 template<class M>
526 {
527 return maxRowSize_;
528 }
529 template<class M>
530 std::size_t SparsityBuilder<M>::minRowSize()
531 {
532 return minRowSize_;
533 }
534
535 template<class M>
536 std::size_t SparsityBuilder<M>::sumRowSize()
537 {
538 return sumRowSize_;
539 }
540 template<class M>
541 void SparsityBuilder<M>::operator++()
542 {
543 sumRowSize_ += row_.size();
544 minRowSize_=std::min(minRowSize_, row_.size());
545 maxRowSize_=std::max(maxRowSize_, row_.size());
546 ++row_;
547#ifdef DUNE_ISTL_WITH_CHECKING
548 assert(diagonalInserted);
549 diagonalInserted = false;
550#endif
551 }
552
553 template<class M>
554 void SparsityBuilder<M>::insert(const typename M::size_type& index)
555 {
556 row_.insert(index);
557#ifdef DUNE_ISTL_WITH_CHECKING
558 diagonalInserted = diagonalInserted || row_.index()==index;
559#endif
560 }
561
562 template<class T>
563 template<class G, class V, class Set>
564 typename G::MutableMatrix*
565 GalerkinProduct<T>::build(G& fineGraph, V& visitedMap,
566 const ParallelInformation& pinfo,
568 const typename G::Matrix::size_type& size,
569 const Set& overlap)
570 {
571 typedef OverlapVertex<typename G::VertexDescriptor> OverlapVertex;
572
573 std::size_t count;
574
575 const OverlapVertex* overlapVertices = buildOverlapVertices(fineGraph,
576 pinfo,
577 aggregates,
578 overlap,
579 count);
580 typedef typename G::MutableMatrix M;
581 M* coarseMatrix = new M(size, size, M::row_wise);
582
583 // Reset the visited flags of all vertices.
584 // As the isolated nodes will be skipped we simply mark them as visited
585
586 typedef typename G::VertexIterator Vertex;
587 Vertex vend = fineGraph.end();
588 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
590 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
591 }
592
593 typedef typename G::MutableMatrix M;
594 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
595
596 ConnectivityConstructor<G,T>::examine(fineGraph, visitedMap, pinfo,
597 aggregates, overlap,
598 overlapVertices,
599 overlapVertices+count,
600 sparsityBuilder);
601
602 dinfo<<pinfo.communicator().rank()<<": Matrix ("<<coarseMatrix->N()<<"x"<<coarseMatrix->M()<<" row: min="<<sparsityBuilder.minRowSize()<<" max="
603 <<sparsityBuilder.maxRowSize()<<" avg="
604 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()
605 <<std::endl;
606
607 delete[] overlapVertices;
608
609 return coarseMatrix;
610 }
611
612 template<class G, class V, class Set>
613 typename G::MutableMatrix*
614 GalerkinProduct<SequentialInformation>::build(G& fineGraph, V& visitedMap,
615 const SequentialInformation& pinfo,
617 const typename G::Matrix::size_type& size,
618 const Set& overlap)
619 {
620 DUNE_UNUSED_PARAMETER(overlap);
621 typedef typename G::MutableMatrix M;
622 M* coarseMatrix = new M(size, size, M::row_wise);
623
624 // Reset the visited flags of all vertices.
625 // As the isolated nodes will be skipped we simply mark them as visited
626
627 typedef typename G::VertexIterator Vertex;
628 Vertex vend = fineGraph.end();
629 for(Vertex vertex = fineGraph.begin(); vertex != vend; ++vertex) {
631 put(visitedMap, *vertex, aggregates[*vertex]==AggregatesMap<typename G::VertexDescriptor>::ISOLATED);
632 }
633
634 SparsityBuilder<M> sparsityBuilder(*coarseMatrix);
635
636 ConnectivityConstructor<G,SequentialInformation>::examine(fineGraph, visitedMap, pinfo,
637 aggregates, sparsityBuilder);
638 dinfo<<"Matrix row: min="<<sparsityBuilder.minRowSize()<<" max="
639 <<sparsityBuilder.maxRowSize()<<" average="
640 <<static_cast<double>(sparsityBuilder.sumRowSize())/coarseMatrix->N()<<std::endl;
641 return coarseMatrix;
642 }
643
644 template<class M, class V, class P, class O>
645 void BaseGalerkinProduct::calculate(const M& fine, const AggregatesMap<V>& aggregates, M& coarse,
646 const P& pinfo, const O& copy)
647 {
649 coarse = static_cast<typename M::field_type>(0);
650
651 typedef typename M::ConstIterator RowIterator;
652 RowIterator endRow = fine.end();
653
654 for(RowIterator row = fine.begin(); row != endRow; ++row)
655 if(aggregates[row.index()] != AggregatesMap<V>::ISOLATED) {
656 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
657 typedef typename M::ConstColIterator ColIterator;
658 ColIterator endCol = row->end();
659
660 for(ColIterator col = row->begin(); col != endCol; ++col)
661 if(aggregates[col.index()] != AggregatesMap<V>::ISOLATED) {
662 assert(aggregates[row.index()]!=AggregatesMap<V>::UNAGGREGATED);
663 coarse[aggregates[row.index()]][aggregates[col.index()]]+=*col;
664 }
665 }
666
667 // get the right diagonal matrix values on copy lines from owner processes
668 typedef typename M::block_type BlockType;
669 std::vector<BlockType> rowsize(coarse.N(),BlockType(0));
670 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
671 rowsize[row.index()]=coarse[row.index()][row.index()];
672 pinfo.copyOwnerToAll(rowsize,rowsize);
673 for (RowIterator row = coarse.begin(); row != coarse.end(); ++row)
674 coarse[row.index()][row.index()] = rowsize[row.index()];
675
676 // don't set dirichlet boundaries for copy lines to make novlp case work,
677 // the preconditioner yields slightly different results now.
678
679 // Set the dirichlet border
680 //DirichletBoundarySetter<P>::template set<M>(coarse, pinfo, copy);
681
682 }
683
684 template<class T>
685 template<class M, class O>
686 void DirichletBoundarySetter<T>::set(M& coarse, const T& pinfo, const O& copy)
687 {
688 typedef typename T::ParallelIndexSet::const_iterator ConstIterator;
689 ConstIterator end = pinfo.indexSet().end();
690 typedef typename M::block_type Block;
691 Block identity=Block(0.0);
692 for(typename Block::RowIterator b=identity.begin(); b != identity.end(); ++b)
693 b->operator[](b.index())=1.0;
694
695 for(ConstIterator index = pinfo.indexSet().begin();
696 index != end; ++index) {
697 if(copy.contains(index->local().attribute())) {
698 typedef typename M::ColIterator ColIterator;
699 typedef typename M::row_type Row;
700 Row row = coarse[index->local()];
701 ColIterator cend = row.find(index->local());
702 ColIterator col = row.begin();
703 for(; col != cend; ++col)
704 *col = 0;
705
706 cend = row.end();
707
708 assert(col != cend); // There should be a diagonal entry
709 *col = identity;
710
711 for(++col; col != cend; ++col)
712 *col = 0;
713 }
714 }
715 }
716
717 template<class M, class O>
718 void DirichletBoundarySetter<SequentialInformation>::set(M& coarse,
719 const SequentialInformation& pinfo,
720 const O& overlap)
721 {}
722
723 } // namespace Amg
724} // namespace Dune
725#endif
Provides classes for the Coloring process of AMG.
Class providing information about the mapping of the vertices onto aggregates.
Definition: aggregates.hh:498
Visitor for identifying connected aggregates during a breadthFirstSearch.
Definition: galerkin.hh:206
Functor for building the sparsity pattern of the matrix using examineConnectivity.
Definition: galerkin.hh:63
A pair consisting of a global and local index.
Definition: indexset.hh:85
A single linked list.
Definition: sllist.hh:43
Classes for building sets out of enumeration values.
LocalIndex & local()
Get the local index.
G Graph
The type of the graph.
Definition: galerkin.hh:211
void operator()(const ConstEdgeIterator &edge)
Process an edge pointing to another aggregate.
Definition: galerkin.hh:359
T Aggregate
The aggregate descriptor.
Definition: galerkin.hh:37
SparsityBuilder(M &matrix)
Constructor.
Definition: galerkin.hh:515
ConnectedBuilder(const AggregatesMap< Vertex > &aggregates, Graph &graph, VisitedMap &visitedMap, Set &connected)
Constructor.
Definition: galerkin.hh:352
Graph::ConstEdgeIterator ConstEdgeIterator
The constant edge iterator.
Definition: galerkin.hh:215
T Vertex
The vertex descriptor.
Definition: galerkin.hh:42
V VisitedMap
The type of the map for marking vertices as visited.
Definition: galerkin.hh:225
int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
Visit all neighbour vertices of a vertex in a graph.
static const Vertex ISOLATED
Identifier of isolated vertices.
Definition: aggregates.hh:509
S Set
The type of the connected set.
Definition: galerkin.hh:220
Aggregate * aggregate
The aggregate the vertex belongs to.
Definition: galerkin.hh:47
Vertex vertex
The vertex descriptor.
Definition: galerkin.hh:52
Graph::VertexDescriptor Vertex
The vertex descriptor of the graph.
Definition: galerkin.hh:230
void calculate(const M &fine, const AggregatesMap< V > &aggregates, M &coarse, const I &pinfo, const O &copy)
Calculate the galerkin product.
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:94
DInfoType dinfo(std::cout)
Stream for informative output.
Definition: stdstreams.hh:139
DVerbType dverb(std::cout)
Singleton of verbose debug stream.
Definition: stdstreams.hh:115
Dune namespace.
Definition: alignment.hh:14
STL namespace.
An stl-compliant pool allocator.
@ nonoverlapping
Category for on overlapping solvers.
Definition: solvercategory.hh:24
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)