Dune Core Modules (2.5.1)

novlpschwarz.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ISTL_NOVLPSCHWARZ_HH
4 #define DUNE_ISTL_NOVLPSCHWARZ_HH
5 
6 #include <iostream> // for input/output to shell
7 #include <fstream> // for input/output to files
8 #include <vector> // STL vector class
9 #include <sstream>
10 
11 #include <cmath> // Yes, we do some math here
12 
13 #include <dune/common/timer.hh>
14 
15 #include "io.hh"
16 #include "bvector.hh"
17 #include "vbvector.hh"
18 #include "bcrsmatrix.hh"
19 #include "io.hh"
20 #include "gsetc.hh"
21 #include "ilu.hh"
22 #include "operators.hh"
23 #include "solvers.hh"
24 #include "preconditioners.hh"
25 #include "scalarproducts.hh"
26 #include "owneroverlapcopy.hh"
27 
28 namespace Dune {
29 
58  template<class M, class X, class Y, class C>
60  {
61  public:
63  typedef M matrix_type;
65  typedef X domain_type;
67  typedef Y range_type;
69  typedef typename X::field_type field_type;
71  typedef C communication_type;
72 
73  typedef typename C::PIS PIS;
74  typedef typename C::RI RI;
75  typedef typename RI::RemoteIndexList RIL;
76  typedef typename RI::const_iterator RIIterator;
77  typedef typename RIL::const_iterator RILIterator;
78  typedef typename M::ConstColIterator ColIterator;
79  typedef typename M::ConstRowIterator RowIterator;
80  typedef std::multimap<int,int> MM;
81  typedef std::multimap<int,std::pair<int,RILIterator> > RIMap;
82  typedef typename RIMap::iterator RIMapit;
83 
84  enum {
87  };
88 
97  : _A_(A), communication(com), buildcomm(true)
98  {}
99 
101  virtual void apply (const X& x, Y& y) const
102  {
103  y = 0;
104  novlp_op_apply(x,y,1);
105  communication.addOwnerCopyToOwnerCopy(y,y);
106  }
107 
109  virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
110  {
111  // only apply communication to alpha*A*x to make it consistent,
112  // y already has to be consistent.
113  Y y1(y);
114  y = 0;
115  novlp_op_apply(x,y,alpha);
116  communication.addOwnerCopyToOwnerCopy(y,y);
117  y += y1;
118  }
119 
121  virtual const matrix_type& getmat () const
122  {
123  return _A_;
124  }
125 
126  void novlp_op_apply (const X& x, Y& y, field_type alpha) const
127  {
128  //get index sets
129  const PIS& pis=communication.indexSet();
130  const RI& ri = communication.remoteIndices();
131 
132  // at the beginning make a multimap "bordercontribution".
133  // process has i and j as border dofs but is not the owner
134  // => only contribute to Ax if i,j is in bordercontribution
135  if (buildcomm == true) {
136 
137  // set up mask vector
138  if (mask.size()!=static_cast<typename std::vector<double>::size_type>(x.size())) {
139  mask.resize(x.size());
140  for (typename std::vector<double>::size_type i=0; i<mask.size(); i++)
141  mask[i] = 1;
142  for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
143  if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
144  mask[i->local().local()] = 0;
145  else if (i->local().attribute()==OwnerOverlapCopyAttributeSet::overlap)
146  mask[i->local().local()] = 2;
147  }
148 
149  for (MM::iterator iter = bordercontribution.begin();
150  iter != bordercontribution.end(); ++iter)
151  bordercontribution.erase(iter);
152  std::map<int,int> owner; //key: local index i, value: process, that owns i
153  RIMap rimap;
154 
155  // for each local index make multimap rimap:
156  // key: local index i, data: pair of process that knows i and pointer to RI entry
157  for (RowIterator i = _A_.begin(); i != _A_.end(); ++i)
158  if (mask[i.index()] == 0)
159  for (RIIterator remote = ri.begin(); remote != ri.end(); ++remote) {
160  RIL& ril = *(remote->second.first);
161  for (RILIterator rindex = ril.begin(); rindex != ril.end(); ++rindex)
162  if (rindex->attribute() != OwnerOverlapCopyAttributeSet::overlap)
163  if (rindex->localIndexPair().local().local() == i.index()) {
164  rimap.insert
165  (std::make_pair(i.index(),
166  std::pair<int,RILIterator>(remote->first, rindex)));
167  if(rindex->attribute()==OwnerOverlapCopyAttributeSet::owner)
168  owner.insert(std::make_pair(i.index(),remote->first));
169  }
170  }
171 
172  int iowner = 0;
173  for (RowIterator i = _A_.begin(); i != _A_.end(); ++i) {
174  if (mask[i.index()] == 0) {
175  std::map<int,int>::iterator it = owner.find(i.index());
176  iowner = it->second;
177  std::pair<RIMapit, RIMapit> foundiit = rimap.equal_range(i.index());
178  for (ColIterator j = _A_[i.index()].begin(); j != _A_[i.index()].end(); ++j) {
179  if (mask[j.index()] == 0) {
180  bool flag = true;
181  for (RIMapit foundi = foundiit.first; foundi != foundiit.second; ++foundi) {
182  std::pair<RIMapit, RIMapit> foundjit = rimap.equal_range(j.index());
183  for (RIMapit foundj = foundjit.first; foundj != foundjit.second; ++foundj)
184  if (foundj->second.first == foundi->second.first)
185  if (foundj->second.second->attribute() == OwnerOverlapCopyAttributeSet::owner
186  || foundj->second.first == iowner
187  || foundj->second.first < communication.communicator().rank()) {
188  flag = false;
189  continue;
190  }
191  if (flag == false)
192  continue;
193  }
194  // donĀ“t contribute to Ax if
195  // 1. the owner of j has i as interior/border dof
196  // 2. iowner has j as interior/border dof
197  // 3. there is another process with smaller rank that has i and j
198  // as interor/border dofs
199  // if the owner of j does not have i as interior/border dof,
200  // it will not be taken into account
201  if (flag==true)
202  bordercontribution.insert(std::pair<int,int>(i.index(),j.index()));
203  }
204  }
205  }
206  }
207  buildcomm = false;
208  }
209 
210  //compute alpha*A*x nonoverlapping case
211  for (RowIterator i = _A_.begin(); i != _A_.end(); ++i) {
212  if (mask[i.index()] == 0) {
213  //dof doesn't belong to process but is border (not ghost)
214  for (ColIterator j = _A_[i.index()].begin(); j != _A_[i.index()].end(); ++j) {
215  if (mask[j.index()] == 1) //j is owner => then sum entries
216  (*j).usmv(alpha,x[j.index()],y[i.index()]);
217  else if (mask[j.index()] == 0) {
218  std::pair<MM::iterator, MM::iterator> itp =
219  bordercontribution.equal_range(i.index());
220  for (MM::iterator it = itp.first; it != itp.second; ++it)
221  if ((*it).second == (int)j.index())
222  (*j).usmv(alpha,x[j.index()],y[i.index()]);
223  }
224  }
225  }
226  else if (mask[i.index()] == 1) {
227  for (ColIterator j = _A_[i.index()].begin(); j != _A_[i.index()].end(); ++j)
228  if (mask[j.index()] != 2)
229  (*j).usmv(alpha,x[j.index()],y[i.index()]);
230  }
231  }
232  }
233 
234  private:
235  const matrix_type& _A_;
236  const communication_type& communication;
237  mutable bool buildcomm;
238  mutable std::vector<double> mask;
239  mutable std::multimap<int,int> bordercontribution;
240  };
241 
253  template<class X, class C>
255  {
256  public:
258  typedef X domain_type;
260  typedef typename X::field_type field_type;
262  typedef typename FieldTraits<field_type>::real_type real_type;
265 
267  enum {category=SolverCategory::nonoverlapping};
268 
274  : communication(com)
275  {}
276 
281  virtual field_type dot (const X& x, const X& y)
282  {
283  field_type result;
284  communication.dot(x,y,result);
285  return result;
286  }
287 
291  virtual real_type norm (const X& x)
292  {
293  return communication.norm(x);
294  }
295 
298  void make_consistent (X& x) const
299  {
300  communication.copyOwnerToAll(x,x);
301  }
302 
303  private:
304  const communication_type& communication;
305  };
306 
307  template<class X, class C>
308  struct ScalarProductChooser<X,C,SolverCategory::nonoverlapping>
309  {
311  typedef NonoverlappingSchwarzScalarProduct<X,C> ScalarProduct;
313  typedef C communication_type;
314 
315  enum {
318  };
319 
320  static ScalarProduct* construct(const communication_type& comm)
321  {
322  return new ScalarProduct(comm);
323  }
324  };
325 
326  namespace Amg
327  {
328  template<class T> class ConstructionTraits;
329  }
330 
340  template<class C, class P>
342  : public Dune::Preconditioner<typename P::domain_type,typename P::range_type> {
344  public:
346  typedef typename P::domain_type domain_type;
348  typedef typename P::range_type range_type;
351 
352  // define the category
353  enum {
356  };
357 
366  : preconditioner(prec), communication(c)
367  {}
368 
374  virtual void pre (domain_type& x, range_type& b)
375  {
376  preconditioner.pre(x,b);
377  }
378 
384  virtual void apply (domain_type& v, const range_type& d)
385  {
386  // block preconditioner equivalent to WrappedPreconditioner from
387  // pdelab/backend/ovlpistsolverbackend.hh,
388  // but not to BlockPreconditioner from schwarz.hh
389  preconditioner.apply(v,d);
390  communication.addOwnerCopyToOwnerCopy(v,v);
391  }
392 
398  virtual void post (domain_type& x)
399  {
400  preconditioner.post(x);
401  }
402 
403  private:
405  P& preconditioner;
406 
408  const communication_type& communication;
409  };
410 
413 } // end namespace
414 
415 #endif
Implementation of the BCRSMatrix class.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Traits class for generically constructing non default constructable types.
Definition: construction.hh:38
A linear operator exporting itself in matrix form.
Definition: operators.hh:94
Nonoverlapping parallel preconditioner.
Definition: novlpschwarz.hh:342
virtual void apply(domain_type &v, const range_type &d)
Apply the preconditioner.
Definition: novlpschwarz.hh:384
@ category
The category the preconditioner is part of.
Definition: novlpschwarz.hh:355
P::range_type range_type
The range type of the preconditioner.
Definition: novlpschwarz.hh:348
virtual void post(domain_type &x)
Clean up.
Definition: novlpschwarz.hh:398
C communication_type
The type of the communication object.
Definition: novlpschwarz.hh:350
NonoverlappingBlockPreconditioner(P &prec, const communication_type &c)
Constructor.
Definition: novlpschwarz.hh:365
virtual void pre(domain_type &x, range_type &b)
Prepare the preconditioner.
Definition: novlpschwarz.hh:374
P::domain_type domain_type
The domain type of the preconditioner.
Definition: novlpschwarz.hh:346
A nonoverlapping operator with communication object.
Definition: novlpschwarz.hh:60
C communication_type
The type of the communication object.
Definition: novlpschwarz.hh:71
virtual void apply(const X &x, Y &y) const
apply operator to x:
Definition: novlpschwarz.hh:101
X domain_type
The type of the domain.
Definition: novlpschwarz.hh:65
Y range_type
The type of the range.
Definition: novlpschwarz.hh:67
M matrix_type
The type of the matrix we operate on.
Definition: novlpschwarz.hh:63
virtual const matrix_type & getmat() const
get matrix via *
Definition: novlpschwarz.hh:121
virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const
apply operator to x, scale and add:
Definition: novlpschwarz.hh:109
X::field_type field_type
The field type of the range.
Definition: novlpschwarz.hh:69
@ category
The solver category.
Definition: novlpschwarz.hh:86
NonoverlappingSchwarzOperator(const matrix_type &A, const communication_type &com)
constructor: just store a reference to a matrix.
Definition: novlpschwarz.hh:96
Nonoverlapping Scalar Product with communication object.
Definition: novlpschwarz.hh:255
FieldTraits< field_type >::real_type real_type
The real-type of the range.
Definition: novlpschwarz.hh:262
X domain_type
The type of the domain.
Definition: novlpschwarz.hh:258
X::field_type field_type
The type of the range.
Definition: novlpschwarz.hh:260
C communication_type
The type of the communication object.
Definition: novlpschwarz.hh:264
virtual real_type norm(const X &x)
Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
Definition: novlpschwarz.hh:291
void make_consistent(X &x) const
make additive vector consistent
Definition: novlpschwarz.hh:298
virtual field_type dot(const X &x, const X &y)
Dot product of two vectors. It is assumed that the vectors are consistent on the interior+border part...
Definition: novlpschwarz.hh:281
NonoverlappingSchwarzScalarProduct(const communication_type &com)
Constructor.
Definition: novlpschwarz.hh:273
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:26
Base class for scalar product and norm computation.
Definition: scalarproducts.hh:44
Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
Some generic functions for pretty printing vectors and matrices.
Dune namespace.
Definition: alignment.hh:11
Define general, extensible interface for operators. The available implementation wraps a matrix.
Classes providing communication interfaces for overlapping Schwarz methods.
Define general preconditioner interface.
Define base class for scalar product and norm.
Implementations of the inverse operator interface.
C communication_type
The type of the communication object.
Definition: scalarproducts.hh:79
@ solverCategory
The solver category.
Definition: scalarproducts.hh:83
@ nonoverlapping
Category for non-overlapping solvers.
Definition: solvercategory.hh:23
A simple timing class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 9, 22:29, 2024)