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"
10 #include <dune/common/enumset.hh>
11 #include <dune/common/unused.hh>
12 #include <set>
13 #include <limits>
14 #include <algorithm>
15 
16 namespace 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()];
363  assert(vertex!= AggregatesMap<Vertex>::UNAGGREGATED);
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  {
501  DUNE_UNUSED_PARAMETER(pinfo);
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>
525  std::size_t SparsityBuilder<M>::maxRowSize()
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) {
589  assert(aggregates[*vertex] != AggregatesMap<typename G::VertexDescriptor>::UNAGGREGATED);
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) {
630  assert(aggregates[*vertex] != AggregatesMap<typename G::VertexDescriptor>::UNAGGREGATED);
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  {
648  DUNE_UNUSED_PARAMETER(copy);
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
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.80.0 (May 16, 22:29, 2024)