1#ifndef TWO_LEVEL_SCHWARZ_HH
2#define TWO_LEVEL_SCHWARZ_HH
6#include <dune/pdelab/boilerplate/pdelab.hh>
8#include <dune/common/timer.hh>
10#include "coarsespace.hh"
11#include "coarse_prec.hh"
12#include "../hypre/hypreinterface_sequential.hh"
14#include <dune/common/deprecated.hh>
15#include <dune/common/parallel/mpihelper.hh>
17#include <dune/istl/owneroverlapcopy.hh>
18#include <dune/istl/solvercategory.hh>
19#include <dune/istl/operators.hh>
20#include <dune/istl/solvers.hh>
21#include <dune/istl/preconditioners.hh>
22#include <dune/istl/scalarproducts.hh>
23#include <dune/istl/paamg/amg.hh>
24#include <dune/istl/paamg/pinfo.hh>
25#include <dune/istl/io.hh>
26#include <dune/istl/superlu.hh>
27#include <dune/istl/umfpack.hh>
29#include <dune/pdelab/constraints/common/constraints.hh>
30#include <dune/pdelab/gridfunctionspace/genericdatahandle.hh>
31#include <dune/pdelab/backend/solver.hh>
32#include <dune/pdelab/backend/istl/vector.hh>
33#include <dune/pdelab/backend/istl/bcrsmatrix.hh>
42 template<
class GFS,
class M,
class X,
class Y>
43 class TwoLevelOverlappingAdditiveSchwarzDC
44 :
public Dune::Preconditioner<X,Y>
47 typedef Dune::PDELab::Backend::Native<M> ISTLM;
49 typedef Dune::BlockVector<Dune::FieldVector<double,1> > COARSE_V;
50 typedef Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1> > COARSE_M;
53 virtual Dune::SolverCategory::Category category()
const
55 return Dune::SolverCategory::overlapping;
65 TwoLevelOverlappingAdditiveSchwarzDC (
const GFS& gfs_,
const M& AF, std::shared_ptr<CoarseSpace<M,X> > coarse_space,
bool coarseSpaceActive_ =
true)
67 solverf(Dune::PDELab::Backend::native(AF),false),
68 my_rank(gfs.gridView().comm().rank()),
69 coarse_space_(coarse_space) ,
70 coarse_solver_(*coarse_space_->get_coarse_system()),
71 coarseSpaceActive(coarseSpaceActive_)
79 virtual void pre (X& x, Y& b)
87 double coarse_time = 0.0;
90 virtual void apply (X& v,
const Y& d)
94 Dune::InverseOperatorResult result;
95 solverf.apply(v,b,result);
96 if (!coarseSpaceActive) {
98 Dune::PDELab::AddDataHandle<GFS,X> adddh(gfs,v);
100 gfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication);
104 MPI_Barrier(gfs.gridView().comm());
105 Dune::Timer timer_setup;
107 Dune::InverseOperatorResult result;
109 auto coarse_defect = coarse_space_->restrict_defect (d);
112 COARSE_V v0(coarse_space_->basis_size(),coarse_space_->basis_size());
115 coarse_solver_.apply(v0,*coarse_defect,result);
118 auto coarse_correction = coarse_space_->prolongate_defect (v0);
119 v += *coarse_correction;
121 coarse_time += timer_setup.elapsed();
124 Dune::PDELab::AddDataHandle<GFS,X> result_addh(gfs,v);
125 gfs.gridView().communicate(result_addh,Dune::All_All_Interface,Dune::ForwardCommunication);
134 virtual void post (X& x) {
135 if (my_rank == 0) std::cout <<
"Coarse time CT=" << coarse_time << std::endl;
136 if (my_rank == 0) std::cout <<
"Coarse time per apply CTA=" << coarse_time / (double)apply_calls << std::endl;
142 Dune::UMFPack<ISTLM> solverf;
144 std::shared_ptr<CoarseSpace<M,X> > coarse_space_;
145 Dune::UMFPack<COARSE_M> coarse_solver_;
146 bool coarseSpaceActive;
152 template<
class GFS,
class M,
class X,
class Y>
153 class TwoLevelOverlappingAdditiveSchwarzAMG
154 :
public Dune::Preconditioner<X,Y>
157 typedef Dune::PDELab::Backend::Native<M> ISTLM;
159 typedef Dune::BlockVector<Dune::FieldVector<double,1> > COARSE_V;
160 typedef Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1> > COARSE_M;
163 virtual Dune::SolverCategory::Category category()
const
165 return Dune::SolverCategory::overlapping;
175 TwoLevelOverlappingAdditiveSchwarzAMG (
const GFS& gfs_,
const M& AF, std::shared_ptr<CoarseSpace<M,X> > coarse_space,
bool coarseSpaceActive_ =
true)
177 solverf(Dune::PDELab::Backend::native(AF),false),
178 my_rank(gfs.gridView().comm().rank()),
179 coarse_space_(coarse_space) ,
180 coarseSpaceActive(coarseSpaceActive_)
188 virtual void pre (X& x, Y& b)
196 double coarse_time = 0.0;
199 virtual void apply (X& v,
const Y& d)
203 Dune::InverseOperatorResult result;
204 solverf.apply(v,b,result);
205 if (!coarseSpaceActive) {
207 Dune::PDELab::AddDataHandle<GFS,X> adddh(gfs,v);
209 gfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication);
213 MPI_Barrier(gfs.gridView().comm());
214 Dune::Timer timer_setup;
216 Dune::InverseOperatorResult result;
218 auto coarse_defect = coarse_space_->restrict_defect (d);
221 COARSE_V v0(coarse_space_->basis_size(),coarse_space_->basis_size());
223 COARSE_M a = *coarse_space_->get_coarse_system();
224 typedef typename GFS::Traits::GridView GV;
225 GV gv = gfs.gridView();
227 SequentialHypreSolver<GV,COARSE_M, COARSE_V> solver(gv, v0,a,*coarse_defect, 1e-3);
231 auto coarse_correction = coarse_space_->prolongate_defect (v0);
232 v += *coarse_correction;
234 coarse_time += timer_setup.elapsed();
237 Dune::PDELab::AddDataHandle<GFS,X> result_addh(gfs,v);
238 gfs.gridView().communicate(result_addh,Dune::All_All_Interface,Dune::ForwardCommunication);
247 virtual void post (X& x) {
248 if (my_rank == 0) std::cout <<
"Coarse time CT=" << coarse_time << std::endl;
249 if (my_rank == 0) std::cout <<
"Coarse time per apply CTA=" << coarse_time / (double)apply_calls << std::endl;
255 Dune::UMFPack<ISTLM> solverf;
257 std::shared_ptr<CoarseSpace<M,X> > coarse_space_;
258 bool coarseSpaceActive;
264 template<
class GFS,
class M,
class X,
class Y>
265 class TwoLevelOverlappingAdditiveSchwarzPCGC
266 :
public Dune::Preconditioner<X,Y>
269 typedef Dune::PDELab::Backend::Native<M> ISTLM;
271 typedef Dune::BlockVector<Dune::FieldVector<double,1> > COARSE_V;
272 typedef Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1> > COARSE_M;
276 typedef typename Dune::CGSolver<COARSE_V> CSOLVER;
277 typedef CoarsePrec<GFS,COARSE_M,COARSE_V, COARSE_V,M,X,Y> PREC;
280 virtual Dune::SolverCategory::Category category()
const
282 return Dune::SolverCategory::overlapping;
292 TwoLevelOverlappingAdditiveSchwarzPCGC (
const GFS& gfs_,
const M& AF, std::shared_ptr<CoarseSpace<M,X> > coarse_space, std::shared_ptr<CoarseSpace<M,X>> coarse_space_small,
bool coarseSpaceActive_ =
true)
294 solverf(Dune::PDELab::Backend::native(AF),false),
295 my_rank(gfs.gridView().comm().rank()),
296 coarse_space_(coarse_space),
297 coarse_space_small_(coarse_space_small),
298 prec(gfs,*coarse_space_small_->get_coarse_system(), coarse_space_,coarse_space_small_),
299 opa(*coarse_space_->get_coarse_system()),
300 coarseSpaceActive(coarseSpaceActive_)
302 using Dune::PDELab::Backend::native;
304 if(my_rank == 0) verb = 1;
305 coarse_solver_2 = std::make_shared<CSOLVER>(opa,prec,1e-3,5000,verb);
313 virtual void pre (X& x, Y& b)
321 double coarse_time = 0.0;
324 virtual void apply (X& v,
const Y& d)
328 Dune::InverseOperatorResult result;
329 solverf.apply(v,b,result);
331 if (!coarseSpaceActive) {
333 Dune::PDELab::AddDataHandle<GFS,X> adddh(gfs,v);
335 gfs.gridView().communicate(adddh,Dune::All_All_Interface,Dune::ForwardCommunication);
339 MPI_Barrier(gfs.gridView().comm());
340 Dune::Timer timer_setup;
342 Dune::InverseOperatorResult result;
344 auto coarse_defect = coarse_space_->restrict_defect (d);
347 COARSE_V v0(coarse_space_->basis_size(),coarse_space_->basis_size());
349 coarse_solver_2->apply(v0, *coarse_defect, result);
352 auto coarse_correction = coarse_space_->prolongate_defect (v0);
353 v += *coarse_correction;
355 coarse_time += timer_setup.elapsed();
358 Dune::PDELab::AddDataHandle<GFS,X> result_addh(gfs,v);
359 gfs.gridView().communicate(result_addh,Dune::All_All_Interface,Dune::ForwardCommunication);
368 virtual void post (X& x) {
369 if (my_rank == 0) std::cout <<
"Coarse time CT=" << coarse_time << std::endl;
370 if (my_rank == 0) std::cout <<
"Coarse time per apply CTA=" << coarse_time / (double)apply_calls << std::endl;
376 Dune::UMFPack<ISTLM> solverf;
378 std::shared_ptr<CoarseSpace<M,X> > coarse_space_;
379 std::shared_ptr<CoarseSpace<M,X> > coarse_space_small_;
380 Dune::MatrixAdapter<COARSE_M,COARSE_V,COARSE_V> opa;
382 std::shared_ptr<CSOLVER> coarse_solver_2;
383 bool coarseSpaceActive;