DUNE PDELab (git)

ovlp_amg_dg_backend.hh
1 #ifndef DUNE_PDELAB_BACKEND_ISTL_OVLP_AMG_DG_BACKEND_HH
2 #define DUNE_PDELAB_BACKEND_ISTL_OVLP_AMG_DG_BACKEND_HH
3 
5 #include <dune/common/math.hh>
6 
8 
10 #include <dune/pdelab/backend/istl/vector.hh>
11 #include <dune/pdelab/backend/istl/bcrsmatrix.hh>
12 #include <dune/pdelab/backend/istl/bcrsmatrixbackend.hh>
13 #include <dune/pdelab/backend/istl/ovlpistlsolverbackend.hh>
14 #include <dune/pdelab/gridoperator/gridoperator.hh>
15 #include <dune/pdelab/localoperator/flags.hh>
16 #include <dune/pdelab/localoperator/idefault.hh>
17 #include <dune/pdelab/localoperator/pattern.hh>
18 #include <dune/pdelab/localoperator/defaultimp.hh>
19 
20 namespace Dune {
21  namespace PDELab {
22  //***********************************************************
23  // A data handle / function to communicate matrix entries
24  // in the overlap. It turned out that it is actually not
25  // required to do that, but anyway it is there now.
26  //***********************************************************
27 
30  template<class GFS>
32  : public Dune::CommDataHandleIF<LocalGlobalMapDataHandle<GFS>,int>
33  {
34  public:
35  // some types from the grid view
36  typedef typename GFS::Traits::GridView GV;
37  typedef typename GV::IndexSet IndexSet;
38  typedef typename IndexSet::IndexType IndexType;
39  typedef typename GV::Grid Grid;
40  typedef typename Grid::Traits::GlobalIdSet GlobalIdSet;
41  typedef typename GlobalIdSet::IdType IdType;
42 
44  typedef int DataType;
45 
46  // map types
47  typedef std::map<IndexType,IdType> LocalToGlobalMap;
48  typedef std::map<IdType,IndexType> GlobalToLocalMap;
49 
51  bool contains (int dim, int codim) const
52  {
53  return (codim==0);
54  }
55 
57  bool fixedSize (int dim, int codim) const
58  {
59  return true;
60  }
61 
66  template<class EntityType>
67  size_t size (EntityType& e) const
68  {
69  return 1;
70  }
71 
73  template<class MessageBuffer, class EntityType>
74  void gather (MessageBuffer& buff, const EntityType& e) const
75  {
76  // fill map
77  IndexType myindex = indexSet.index(e);
78  IdType myid = globalIdSet.id(e);
79  l2g[myindex] = myid;
80  g2l[myid] = myindex;
81  //std::cout << gv.comm().rank() << ": gather local=" << myindex << " global=" << myid << std::endl;
82 
83  buff.write(0); // this is a dummy, we are not interested in the data
84  }
85 
90  template<class MessageBuffer, class EntityType>
91  void scatter (MessageBuffer& buff, const EntityType& e, size_t n)
92  {
93  DataType x;
94  buff.read(x); // this is a dummy, we are not interested in the data
95 
96  IndexType myindex = indexSet.index(e);
97  IdType myid = globalIdSet.id(e);
98  l2g[myindex] = myid;
99  g2l[myid] = myindex;
100  //std::cout << gv.comm().rank() << ": scatter local=" << myindex << " global=" << myid << std::endl;
101  }
102 
104  LocalGlobalMapDataHandle (const GFS& gfs_, LocalToGlobalMap& l2g_, GlobalToLocalMap& g2l_)
105  : gfs(gfs_), gv(gfs.gridView()), indexSet(gv.indexSet()),
106  grid(gv.grid()), globalIdSet(grid.globalIdSet()),
107  l2g(l2g_), g2l(g2l_)
108  {
109  }
110 
111  private:
112  const GFS& gfs;
113  GV gv;
114  const IndexSet& indexSet;
115  const Grid& grid;
116  const GlobalIdSet& globalIdSet;
117  LocalToGlobalMap& l2g;
118  GlobalToLocalMap& g2l;
119  };
120 
121 
122  // A DataHandle class to exchange rows of a sparse matrix
123  template<class GFS, class M> // mapper type and vector type
124  class MatrixExchangeDataHandle
125  : public Dune::CommDataHandleIF<MatrixExchangeDataHandle<GFS,M>,
126  std::pair<typename GFS::Traits::GridView::Grid::Traits::GlobalIdSet::IdType,
127  typename M::block_type> >
128  {
129  public:
130  // some types from the grid view
131  typedef typename GFS::Traits::GridView GV;
132  typedef typename GV::IndexSet IndexSet;
133  typedef typename IndexSet::IndexType IndexType;
134  typedef typename GV::Grid Grid;
135  typedef typename Grid::Traits::GlobalIdSet GlobalIdSet;
136  typedef typename GlobalIdSet::IdType IdType;
137 
138  // some types from the matrix
139  typedef typename M::block_type B;
140 
142  typedef std::pair<IdType,B> DataType;
143 
144  // map types
145  typedef std::map<IndexType,IdType> LocalToGlobalMap;
146  typedef std::map<IdType,IndexType> GlobalToLocalMap;
147 
149  bool contains (int dim, int codim) const
150  {
151  return (codim==0);
152  }
153 
155  bool fixedSize (int dim, int codim) const
156  {
157  return false;
158  }
159 
164  template<class EntityType>
165  size_t size (EntityType& e) const
166  {
167  IndexType myindex = indexSet.index(e);
168  typename M::row_type myrow = m[myindex];
169  typename M::row_type::iterator endit=myrow.end();
170  size_t count=0;
171  for (typename M::row_type::iterator it=myrow.begin(); it!=endit; ++it)
172  {
173  typename LocalToGlobalMap::const_iterator find=l2g.find(it.index());
174  if (find!=l2g.end())
175  {
176  count++;
177  }
178  }
179  //std::cout << gv.comm().rank() << ": row=" << myindex << " size=" << count << std::endl;
180  return count;
181  }
182 
184  template<class MessageBuffer, class EntityType>
185  void gather (MessageBuffer& buff, const EntityType& e) const
186  {
187  IndexType myindex = indexSet.index(e);
188  typename M::row_type myrow = m[myindex];
189  typename M::row_type::iterator endit=myrow.end();
190  for (typename M::row_type::iterator it=myrow.begin(); it!=endit; ++it)
191  {
192  typename LocalToGlobalMap::const_iterator find=l2g.find(it.index());
193  if (find!=l2g.end())
194  {
195  buff.write(std::make_pair(find->second,*it));
196  }
197  }
198  }
199 
204  template<class MessageBuffer, class EntityType>
205  void scatter (MessageBuffer& buff, const EntityType& e, size_t n)
206  {
207  IndexType myindex = indexSet.index(e);
208  std::cout << gv.comm().rank() << ": begin scatter local=" << myindex << " size=" << n << std::endl;
209  DataType x;
210  for (size_t i=0; i<n; ++i)
211  {
212  buff.read(x);
213  std::cout << gv.comm().rank() << ": --> received global=" << x.first << std::endl;
214  typename GlobalToLocalMap::const_iterator find=g2l.find(x.first);
215  if (find!=g2l.end())
216  {
217  IndexType nbindex=find->second;
218  if (m.exists(myindex,nbindex))
219  {
220  m[myindex][nbindex] = x.second;
221  B block(x.second);
222  block -= m2[myindex][nbindex];
223  std::cout << gv.comm().rank() << ": compare i=" << myindex << " j=" << nbindex
224  << " norm=" << block.infinity_norm() << std::endl;
225 
226  }
227  }
228  }
229  }
230 
232  MatrixExchangeDataHandle (const GFS& gfs_, M& m_, const LocalToGlobalMap& l2g_, const GlobalToLocalMap& g2l_,M& m2_)
233  : gfs(gfs_), m(m_), gv(gfs.gridView()), indexSet(gv.indexSet()),
234  grid(gv.grid()), globalIdSet(grid.globalIdSet()),
235  l2g(l2g_), g2l(g2l_), m2(m2_)
236  {
237  }
238 
239  private:
240  const GFS& gfs;
241  M& m;
242  GV gv;
243  const IndexSet& indexSet;
244  const Grid& grid;
245  const GlobalIdSet& globalIdSet;
246  const LocalToGlobalMap& l2g;
247  const GlobalToLocalMap& g2l;
248  M& m2;
249  };
250 
251 
254  template<class GFS, class T, class A, int n, int m>
255  void restore_overlap_entries (const GFS& gfs, Dune::BCRSMatrix<Dune::FieldMatrix<T,n,m>,A>& matrix,
257  {
258  typedef Dune::FieldMatrix<T,n,m> B;
259  typedef Dune::BCRSMatrix<B,A> M; // m is of type M
260  typedef typename LocalGlobalMapDataHandle<GFS>::LocalToGlobalMap LocalToGlobalMap;
261  typedef typename LocalGlobalMapDataHandle<GFS>::GlobalToLocalMap GlobalToLocalMap;
262 
263  // build up two maps to associate local indices and global ids
264  LocalToGlobalMap l2g;
265  GlobalToLocalMap g2l;
266  LocalGlobalMapDataHandle<GFS> lgdh(gfs,l2g,g2l);
267  if (gfs.gridView().comm().size()>1)
268  gfs.gridView().communicate(lgdh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
269 
270  // exchange matrix entries
271  MatrixExchangeDataHandle<GFS,M> mexdh(gfs,matrix,l2g,g2l,matrix2);
272  if (gfs.gridView().comm().size()>1)
273  gfs.gridView().communicate(mexdh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
274  }
275 
276  //***********************************************************
277  // The DG/AMG preconditioner in the overlapping case
278  //***********************************************************
279 
289  template<class DGGFS, class DGMatrix, class DGPrec, class DGCC,
290  class CGGFS, class CGPrec, class CGCC,
291  class P, class DGHelper, class Comm>
293  : public Dune::Preconditioner<Dune::PDELab::Backend::Vector<DGGFS,typename DGPrec::domain_type::field_type>,
294  Dune::PDELab::Backend::Vector<DGGFS,typename DGPrec::range_type::field_type>>
295  {
296  const DGGFS& dggfs;
297  DGMatrix& dgmatrix;
298  DGPrec& dgprec;
299  const DGCC& dgcc;
300  const CGGFS& cggfs;
301  CGPrec& cgprec;
302  const CGCC& cgcc;
303  P& p;
304  const DGHelper& dghelper;
305  const Comm& comm;
306  int n1,n2;
307 
308  public:
309  using V = Dune::PDELab::Backend::Vector<DGGFS,typename DGPrec::domain_type::field_type>;
310  using W = Dune::PDELab::Backend::Vector<DGGFS,typename DGPrec::range_type::field_type>;
311  using X = Backend::Native<V>;
312  using Y = Backend::Native<W>;
313  using CGV = Dune::PDELab::Backend::Vector<CGGFS,typename CGPrec::domain_type::field_type>;
314  using CGW = Dune::PDELab::Backend::Vector<CGGFS,typename CGPrec::range_type::field_type>;
315 
316  // define the category
318  {
320  }
321 
329  OvlpDGAMGPrec (const DGGFS& dggfs_, DGMatrix& dgmatrix_, DGPrec& dgprec_, const DGCC& dgcc_,
330  const CGGFS& cggfs_, CGPrec& cgprec_, const CGCC& cgcc_, P& p_,
331  const DGHelper& dghelper_, const Comm& comm_, int n1_, int n2_)
332  : dggfs(dggfs_), dgmatrix(dgmatrix_), dgprec(dgprec_), dgcc(dgcc_),
333  cggfs(cggfs_), cgprec(cgprec_), cgcc(cgcc_), p(p_), dghelper(dghelper_),
334  comm(comm_), n1(n1_), n2(n2_)
335  {
336  }
337 
343  virtual void pre (V& x, W& b) override
344  {
345  using Backend::native;
346  dgprec.pre(native(x),native(b));
347  CGW cgd(cggfs,0.0);
348  CGV cgv(cggfs,0.0);
349  cgprec.pre(native(cgv),native(cgd));
350  }
351 
357  virtual void apply (V& x, const W& b) override
358  {
359  using Backend::native;
360  // need local copies to store defect and solution
361  W d(b);
363  V v(x); // only to get correct size
364 
365  // pre-smoothing on DG matrix
366  for (int i=0; i<n1; i++)
367  {
368  using Backend::native;
369  v = 0.0;
370  dgprec.apply(native(v),native(d));
371  Dune::PDELab::AddDataHandle<DGGFS,V> adddh(dggfs,v);
372  if (dggfs.gridView().comm().size()>1)
373  dggfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication);
374  dgmatrix.mmv(native(v),native(d));
376  x += v;
377  }
378 
379  // restrict defect to CG subspace
380  dghelper.maskForeignDOFs(d); // DG defect is additive for overlap 1, but in case we use more
381  CGW cgd(cggfs,0.0);
382  p.mtv(native(d),native(cgd));
383  Dune::PDELab::AddDataHandle<CGGFS,CGW> adddh(cggfs,cgd);
384  if (cggfs.gridView().comm().size()>1)
385  cggfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication); // now we have consistent defect on coarse grid
387  comm.project(native(cgd));
388  CGV cgv(cggfs,0.0);
389 
390 
391  // call preconditioner
392  cgprec.apply(native(cgv),native(cgd));
393 
394  // prolongate correction
395  p.mv(native(cgv),native(v));
396  dgmatrix.mmv(native(v),native(d));
398  x += v;
399 
400  // post-smoothing on DG matrix
401  for (int i=0; i<n2; i++)
402  {
403  v = 0.0;
404  dgprec.apply(native(v),native(d));
405  Dune::PDELab::AddDataHandle<DGGFS,V> adddh(dggfs,v);
406  if (dggfs.gridView().comm().size()>1)
407  dggfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication);
408  dgmatrix.mmv(native(v),native(d));
410  x += v;
411  }
412  }
413 
419  virtual void post (V& x) override
420  {
421  dgprec.post(Backend::native(x));
422  CGV cgv(cggfs,0.0);
423  cgprec.post(Backend::native(cgv));
424  }
425  };
426 
427 //***********************************************************
428 // The DG/AMG linear solver backend in the overlapping case
429 //***********************************************************
430 
454 template<class DGGO, class DGCC, class CGGFS, class CGCC, class TransferLOP,
455  template<class,class,class,int> class DGPrec, template<class> class Solver, int s=96>
457  public Dune::PDELab::OVLPScalarProductImplementation<typename DGGO::Traits::TrialGridFunctionSpace>,
458  public Dune::PDELab::LinearResultStorage
459 {
460 public:
461  // DG grid function space
462  typedef typename DGGO::Traits::TrialGridFunctionSpace GFS;
463 
464  // vectors and matrices on DG level
465  typedef typename DGGO::Traits::Jacobian M; // wrapped istl DG matrix
466  typedef typename DGGO::Traits::Domain V; // wrapped istl DG vector
467  typedef Backend::Native<M> Matrix; // istl DG matrix
468  typedef Backend::Native<V> Vector; // istl DG vector
469  typedef typename Vector::field_type field_type;
470 
471  // vectors and matrices on CG level
472  using CGV = Dune::PDELab::Backend::Vector<CGGFS,field_type>; // wrapped istl CG vector
473  typedef Backend::Native<CGV> CGVector; // istl CG vector
474 
475  // prolongation matrix
477  typedef Dune::PDELab::EmptyTransformation CC;
478  typedef TransferLOP CGTODGLOP; // local operator
480  typedef typename PGO::Jacobian PMatrix; // wrapped ISTL prolongation matrix
481  typedef Backend::Native<PMatrix> P; // ISTL prolongation matrix
482 
483  // CG subspace matrix
485  typedef typename Dune::MatMultMatResult<PTADG,P>::type CGMatrix; // istl coarse space matrix
486 
487  // AMG in CG-subspace
488  typedef typename Dune::PDELab::ISTL::CommSelector<s,Dune::MPIHelper::isFake>::type Comm;
494 
495 private:
496 
497  const GFS& gfs;
498  DGGO& dggo;
499  const DGCC& dgcc;
500  CGGFS& cggfs;
501  const CGCC& cgcc;
502  std::shared_ptr<AMG> amg;
503  Parameters amg_parameters;
504  unsigned maxiter;
505  int verbose;
506  bool reuse;
507  bool firstapply;
508  bool usesuperlu;
509  std::size_t low_order_space_entries_per_row;
510 
511  // Parameters for DG smoother
512  double smoother_relaxation = 0.92; // Relaxation parameter of DG smoother
513  int n1=3; // Number of DG pre-smoothing steps
514  int n2=3; // Number of DG post-smoothing steps
515 
516  CGTODGLOP cgtodglop; // local operator to assemble prolongation matrix
517  PGO pgo; // grid operator to assemble prolongation matrix
518  PMatrix pmatrix; // wrapped prolongation matrix
519 
522  class EmptyLop : public Dune::PDELab::NumericalJacobianApplyVolume<EmptyLop>,
526  {
527  };
528 
529  // grid operator with empty local operator for constraints assembly in parallel
531  // CG-subspace matrix
532  typedef typename CGGO::Jacobian CGM;
533  CGM acg;
534 
535 public:
536 
537  // access to prolongation matrix
538  PMatrix& prolongation_matrix ()
539  {
540  return pmatrix;
541  }
542 
547  void setParameters(const Parameters& amg_parameters_)
548  {
549  amg_parameters = amg_parameters_;
550  }
551 
559  const Parameters& parameters() const
560  {
561  return amg_parameters;
562  }
563 
565  void setReuse(bool reuse_)
566  {
567  reuse = reuse_;
568  }
569 
571  bool getReuse() const
572  {
573  return reuse;
574  }
575 
578  ISTLBackend_OVLP_AMG_4_DG(DGGO& dggo_, const DGCC& dgcc_, CGGFS& cggfs_, const CGCC& cgcc_,
579  unsigned maxiter_=5000, int verbose_=1, bool reuse_=false,
580  bool usesuperlu_=true)
581  : Dune::PDELab::OVLPScalarProductImplementation<typename DGGO::Traits::TrialGridFunctionSpace>(dggo_.trialGridFunctionSpace())
582  , gfs(dggo_.trialGridFunctionSpace())
583  , dggo(dggo_)
584  , dgcc(dgcc_)
585  , cggfs(cggfs_)
586  , cgcc(cgcc_)
587  , amg_parameters(15,2000)
588  , maxiter(maxiter_)
589  , verbose(verbose_)
590  , reuse(reuse_)
591  , firstapply(true)
592  , usesuperlu(usesuperlu_)
593  , low_order_space_entries_per_row(Dune::power(3,GFS::Traits::GridView::dimension))
594  , cgtodglop()
595  , pgo(cggfs,dggo.trialGridFunctionSpace(),cgtodglop,MBE(low_order_space_entries_per_row))
596  , pmatrix(pgo)
597  , acg(Backend::attached_container())
598  {
599  amg_parameters.setDefaultValuesIsotropic(GFS::Traits::GridViewType::Traits::Grid::dimension);
600  amg_parameters.setDebugLevel(verbose_);
601 #if !HAVE_SUPERLU
602  if (usesuperlu == true)
603  {
604  if (gfs.gridView().comm().rank()==0)
605  std::cout << "WARNING: You are using AMG without SuperLU!"
606  << " Please consider installing SuperLU,"
607  << " or set the usesuperlu flag to false"
608  << " to suppress this warning." << std::endl;
609  }
610 #endif
611 
612  // assemble prolongation matrix; this will not change from one apply to the next
613  pmatrix = 0.0;
614  if (verbose>0 && gfs.gridView().comm().rank()==0) std::cout << "allocated prolongation matrix of size " << pmatrix.N() << " x " << pmatrix.M() << std::endl;
615  CGV cgx(cggfs,0.0); // need vector to call jacobian
616  pgo.jacobian(cgx,pmatrix);
617  }
618 
619 
622  ISTLBackend_OVLP_AMG_4_DG(DGGO& dggo_, const DGCC& dgcc_, CGGFS& cggfs_, const CGCC& cgcc_,
623  const ParameterTree& params)
624  : Dune::PDELab::OVLPScalarProductImplementation<typename DGGO::Traits::TrialGridFunctionSpace>(dggo_.trialGridFunctionSpace())
625  , gfs(dggo_.trialGridFunctionSpace())
626  , dggo(dggo_)
627  , dgcc(dgcc_)
628  , cggfs(cggfs_)
629  , cgcc(cgcc_)
630  , maxiter(params.get<int>("max_iterations",5000))
631  , amg_parameters(15,2000)
632  , verbose(params.get<int>("verbose",1))
633  , reuse(params.get<bool>("reuse",false))
634  , firstapply(true)
635  , usesuperlu(params.get<bool>("use_superlu",true))
636  , low_order_space_entries_per_row(params.get<std::size_t>("low_order_space.entries_per_row",Dune::power(3,GFS::Traits::GridView::dimension)))
637  , cgtodglop()
638  , pgo(cggfs,dggo.trialGridFunctionSpace(),cgtodglop,MBE(low_order_space_entries_per_row))
639  , pmatrix(pgo)
640  , acg(Backend::attached_container())
641  {
642  amg_parameters.setDefaultValuesIsotropic(GFS::Traits::GridViewType::Traits::Grid::dimension);
643  amg_parameters.setDebugLevel(params.get<int>("verbose",1));
644 #if !HAVE_SUPERLU
645  if (usesuperlu == true)
646  {
647  if (gfs.gridView().comm().rank()==0)
648  std::cout << "WARNING: You are using AMG without SuperLU!"
649  << " Please consider installing SuperLU,"
650  << " or set the usesuperlu flag to false"
651  << " to suppress this warning." << std::endl;
652  }
653 #endif
654 
655  // assemble prolongation matrix; this will not change from one apply to the next
656  pmatrix = 0.0;
657  if (verbose>0 && gfs.gridView().comm().rank()==0) std::cout << "allocated prolongation matrix of size " << pmatrix.N() << " x " << pmatrix.M() << std::endl;
658  CGV cgx(cggfs,0.0); // need vector to call jacobian
659  pgo.jacobian(cgx,pmatrix);
660  }
661 
662 
664  void setDGSmootherRelaxation(double relaxation_)
665  {
666  smoother_relaxation = relaxation_;
667  }
668 
670  void setNoDGPreSmoothSteps(int n1_)
671  {
672  n1 = n1_;
673  }
674 
677  {
678  n2 = n2_;
679  }
680 
681 
689  void apply (M& A, V& z, V& r, typename Dune::template FieldTraits<typename V::ElementType >::real_type reduction)
690  {
691  using Backend::native;
692  // make operator and scalar product for overlapping solver
693  typedef Dune::PDELab::OverlappingOperator<DGCC,M,V,V> POP;
694  POP pop(dgcc,A);
695  typedef Dune::PDELab::OVLPScalarProduct<GFS,V> PSP;
696  PSP psp(*this);
697 
698  // compute CG matrix
699  // make grid operator with empty local operator => matrix data type and constraints assembly
700  EmptyLop emptylop;
701  CGGO cggo(cggfs,cgcc,cggfs,cgcc,emptylop,MBE(low_order_space_entries_per_row));
702 
703  // do triple matrix product ACG = P^T ADG P; this is purely local
704  Dune::Timer watch;
705  watch.reset();
706  // only do triple matrix product if the matrix changes
707  double triple_product_time = 0.0;
708  // no need to set acg here back to zero, this is done in matMultmat
709  if(reuse == false || firstapply == true) {
710  PTADG ptadg;
711  Dune::transposeMatMultMat(ptadg,native(pmatrix),native(A)); // 1a
712  //Dune::transposeMatMultMat(ptadg,native(pmatrix),native(A2)); // 1b
713  Dune::matMultMat(native(acg),ptadg,native(pmatrix));
714  triple_product_time = watch.elapsed();
715  if (verbose>0 && gfs.gridView().comm().rank()==0)
716  std::cout << "=== triple matrix product " << triple_product_time << " s" << std::endl;
717  //Dune::printmatrix(std::cout,native(acg),"triple product matrix","row",10,2);
718  CGV cgx(cggfs,0.0); // need vector to call jacobian
719  cggo.jacobian(cgx,acg); // insert trivial rows at processor boundaries
720  //std::cout << "CG constraints: " << cgcc.size() << " out of " << cggfs.globalSize() << std::endl;
721  }
722  else if(verbose>0 && gfs.gridView().comm().rank()==0)
723  std::cout << "=== reuse CG matrix, SKIPPING triple matrix product " << std::endl;
724 
725  // NOW we need to insert the processor boundary conditions in DG matrix
727  DGGOEmpty dggoempty(gfs,dgcc,gfs,dgcc,emptylop,MBE(1 << GFS::Traits::GridView::dimension));
728  dggoempty.jacobian(z,A);
729 
730  // and in the residual
732 
733  // now set up parallel AMG solver for the CG subspace
734  Comm oocc(gfs.gridView().comm());
735  typedef Dune::PDELab::ISTL::ParallelHelper<CGGFS> CGHELPER;
736  CGHELPER cghelper(cggfs,2);
737  cghelper.createIndexSetAndProjectForAMG(acg,oocc);
738  ParCGOperator paroop(native(acg),oocc);
740 
741  typedef typename Dune::Amg::SmootherTraits<ParSmoother>::Arguments SmootherArgs;
742  SmootherArgs smootherArgs;
743  smootherArgs.iterations = 1;
744  smootherArgs.relaxationFactor = 1.0;
746  Criterion criterion(amg_parameters);
747  watch.reset();
748 
749  // only construct a new AMG for the CG-subspace if the matrix changes
750  double amg_setup_time = 0.0;
751  if(reuse == false || firstapply == true) {
752  amg.reset(new AMG(paroop,criterion,smootherArgs,oocc));
753  firstapply = false;
754  amg_setup_time = watch.elapsed();
755  if (verbose>0 && gfs.gridView().comm().rank()==0)
756  std::cout << "=== AMG setup " <<amg_setup_time << " s" << std::endl;
757  }
758  else if (verbose>0 && gfs.gridView().comm().rank()==0)
759  std::cout << "=== reuse CG matrix, SKIPPING AMG setup " << std::endl;
760 
761  // set up hybrid DG/CG preconditioner
762  typedef DGPrec<Matrix,Vector,Vector,1> DGPrecType;
763  DGPrecType dgprec(native(A),1,smoother_relaxation);
764  typedef Dune::PDELab::ISTL::ParallelHelper<GFS> DGHELPER;
766  HybridPrec hybridprec(gfs,native(A),dgprec,dgcc,cggfs,*amg,cgcc,native(pmatrix),
767  this->parallelHelper(),oocc,n1,n2);
768 
769  // /********/
770  // /* Test */
771  // /********/
772  // Solver<CGVector> testsolver(paroop,sp,amg,1e-8,100,2);
773  // CGV cgxx(cggfs,0.0);
774  // CGV cgdd(cggfs,1.0);
775  // Dune::InverseOperatorResult statstat;
776  // testsolver.apply(native(cgxx),native(cgdd),statstat);
777  // /********/
778 
779  // set up solver
780  int verb=verbose;
781  if (gfs.gridView().comm().rank()>0) verb=0;
782  Solver<V> solver(pop,psp,hybridprec,reduction,maxiter,verb);
783 
784  // solve
786  watch.reset();
787  solver.apply(z,r,stat);
788  double amg_solve_time = watch.elapsed();
789  if (verbose>0 && gfs.gridView().comm().rank()==0) std::cout << "=== Hybrid total solve time " << amg_solve_time+amg_setup_time+triple_product_time << " s" << std::endl;
790  res.converged = stat.converged;
791  res.iterations = stat.iterations;
792  res.elapsed = amg_solve_time+amg_setup_time+triple_product_time;
793  res.reduction = stat.reduction;
794  res.conv_rate = stat.conv_rate;
795  }
796 
797 };
798 }
799 }
800 #endif // DUNE_PDELAB_BACKEND_ISTL_OVLP_AMG_DG_BACKEND_HH
Parallel algebraic multigrid based on agglomeration.
Definition: amg.hh:65
The criterion describing the stop criteria for the coarsening process.
Definition: matrixhierarchy.hh:283
All parameters for AMG.
Definition: parameters.hh:416
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:466
Block parallel preconditioner.
Definition: schwarz.hh:278
CommDataHandleIF describes the features of a data handle for communication in parallel runs using the...
Definition: datahandleif.hh:78
void scatter(MessageBufferImp &buff, const EntityType &e, size_t n)
unpack data from message buffer to user.
Definition: datahandleif.hh:143
void gather(MessageBufferImp &buff, const EntityType &e) const
pack data from user to message buffer
Definition: datahandleif.hh:129
A dense n x m matrix.
Definition: fmatrix.hh:117
Grid view abstract base class.
Definition: gridview.hh:66
Grid abstract base class.
Definition: grid.hh:375
Index Set Interface base class.
Definition: indexidset.hh:78
IndexTypeImp IndexType
The type used for the indices.
Definition: indexidset.hh:92
An overlapping Schwarz operator.
Definition: schwarz.hh:75
Scalar product for overlapping Schwarz methods.
Definition: scalarproducts.hh:201
sparsity pattern generator
Definition: pattern.hh:14
void jacobian(const Domain &x, Jacobian &a) const
Assembler jacobian.
Definition: gridoperator.hh:184
Dune::PDELab::Backend::Matrix< MBE, Domain, Range, field_type > Jacobian
The type of the jacobian.
Definition: gridoperator.hh:47
Definition: ovlp_amg_dg_backend.hh:459
void setDGSmootherRelaxation(double relaxation_)
set number of presmoothing steps on the DG level
Definition: ovlp_amg_dg_backend.hh:664
void setNoDGPostSmoothSteps(int n2_)
set number of postsmoothing steps on the DG level
Definition: ovlp_amg_dg_backend.hh:676
bool getReuse() const
Return whether the AMG is reused during call to apply()
Definition: ovlp_amg_dg_backend.hh:571
ISTLBackend_OVLP_AMG_4_DG(DGGO &dggo_, const DGCC &dgcc_, CGGFS &cggfs_, const CGCC &cgcc_, unsigned maxiter_=5000, int verbose_=1, bool reuse_=false, bool usesuperlu_=true)
Definition: ovlp_amg_dg_backend.hh:578
void setNoDGPreSmoothSteps(int n1_)
set number of presmoothing steps on the DG level
Definition: ovlp_amg_dg_backend.hh:670
void apply(M &A, V &z, V &r, typename Dune::template FieldTraits< typename V::ElementType >::real_type reduction)
solve the given linear system
Definition: ovlp_amg_dg_backend.hh:689
void setReuse(bool reuse_)
Set whether the AMG should be reused again during call to apply().
Definition: ovlp_amg_dg_backend.hh:565
const Parameters & parameters() const
Get the parameters describing the behaviuour of AMG.
Definition: ovlp_amg_dg_backend.hh:559
void setParameters(const Parameters &amg_parameters_)
set AMG parameters
Definition: ovlp_amg_dg_backend.hh:547
ISTLBackend_OVLP_AMG_4_DG(DGGO &dggo_, const DGCC &dgcc_, CGGFS &cggfs_, const CGCC &cgcc_, const ParameterTree &params)
Definition: ovlp_amg_dg_backend.hh:622
Default class for additional methods in instationary local operators.
Definition: idefault.hh:90
Definition: ovlp_amg_dg_backend.hh:33
LocalGlobalMapDataHandle(const GFS &gfs_, LocalToGlobalMap &l2g_, GlobalToLocalMap &g2l_)
constructor
Definition: ovlp_amg_dg_backend.hh:104
bool fixedSize(int dim, int codim) const
returns true if size per entity of given dim and codim is a constant
Definition: ovlp_amg_dg_backend.hh:57
int DataType
export type of data for message buffer
Definition: ovlp_amg_dg_backend.hh:44
void gather(MessageBuffer &buff, const EntityType &e) const
pack data from user to message buffer
Definition: ovlp_amg_dg_backend.hh:74
size_t size(EntityType &e) const
Definition: ovlp_amg_dg_backend.hh:67
bool contains(int dim, int codim) const
returns true if data for this codim should be communicated
Definition: ovlp_amg_dg_backend.hh:51
void scatter(MessageBuffer &buff, const EntityType &e, size_t n)
Definition: ovlp_amg_dg_backend.hh:91
Default flags for all local operators.
Definition: flags.hh:19
Implements linear and nonlinear versions of jacobian_apply_volume() based on alpha_volume()
Definition: numericaljacobianapply.hh:34
Definition: ovlp_amg_dg_backend.hh:295
virtual void pre(V &x, W &b) override
Prepare the preconditioner.
Definition: ovlp_amg_dg_backend.hh:343
virtual void apply(V &x, const W &b) override
Apply the precondioner.
Definition: ovlp_amg_dg_backend.hh:357
SolverCategory::Category category() const override
Category of the preconditioner (see SolverCategory::Category)
Definition: ovlp_amg_dg_backend.hh:317
virtual void post(V &x) override
Clean up.
Definition: ovlp_amg_dg_backend.hh:419
OvlpDGAMGPrec(const DGGFS &dggfs_, DGMatrix &dgmatrix_, DGPrec &dgprec_, const DGCC &dgcc_, const CGGFS &cggfs_, CGPrec &cgprec_, const CGCC &cgcc_, P &p_, const DGHelper &dghelper_, const Comm &comm_, int n1_, int n2_)
Constructor.
Definition: ovlp_amg_dg_backend.hh:329
Hierarchical structure of string parameters.
Definition: parametertree.hh:37
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:185
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:32
Sequential SSOR preconditioner.
Definition: preconditioners.hh:142
A simple stop watch.
Definition: timer.hh:43
void reset() noexcept
Reset timer while keeping the running/stopped state.
Definition: timer.hh:57
double elapsed() const noexcept
Get elapsed user-time from last reset until now/last stop in seconds.
Definition: timer.hh:77
Describes the parallel communication interface class for MessageBuffers and DataHandles.
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
@ InteriorBorder_All_Interface
send interior and border, receive all entities
Definition: gridenums.hh:88
@ All_All_Interface
send all and receive all entities
Definition: gridenums.hh:91
concept GridView
Model of a grid view.
Definition: gridview.hh:81
concept Grid
Requirements for implementations of the Dune::Grid interface.
Definition: grid.hh:98
concept IndexSet
Model of an index set.
Definition: indexidset.hh:44
concept MessageBuffer
Model of a message buffer.
Definition: messagebuffer.hh:17
void set_constrained_dofs(const CG &cg, typename XG::ElementType x, XG &xg)
construct constraints from given boundary condition function
Definition: constraints.hh:796
void setDebugLevel(int level)
Set the debugging level.
Definition: parameters.hh:424
void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
Sets reasonable default values for an isotropic problem.
Definition: parameters.hh:109
int iterations
The number of iterations to perform.
Definition: smoother.hh:47
void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
Calculate product of two sparse matrices ( ).
Definition: matrixmatrix.hh:575
void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, [[maybe_unused]] bool tryHard=false)
Calculate product of a transposed sparse matrix with another sparse matrices ( ).
Definition: matrixmatrix.hh:590
Some useful basic math stuff.
provides functions for sparse matrix matrix multiplication.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr Base power(Base m, Exponent p)
Power method for integer exponents.
Definition: math.hh:75
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
A hierarchical structure of string parameters.
The default class for the smoother arguments.
Definition: smoother.hh:38
Statistics about the application of an inverse operator.
Definition: solver.hh:48
int iterations
Number of iterations.
Definition: solver.hh:67
double reduction
Reduction achieved: .
Definition: solver.hh:70
double conv_rate
Convergence rate (average reduction per step)
Definition: solver.hh:76
bool converged
True if convergence criterion has been met.
Definition: solver.hh:73
Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
Definition: matrixmatrix.hh:510
Backend using (possibly nested) ISTL BCRSMatrices.
Definition: bcrsmatrixbackend.hh:188
Category
Definition: solvercategory.hh:23
@ overlapping
Category for overlapping solvers.
Definition: solvercategory.hh:29
Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
Definition: matrixmatrix.hh:535
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 24, 22:30, 2024)