6#include <dune/pdelab/boilerplate/pdelab.hh>
8#include <dune/common/timer.hh>
10#include "coarsespace.hh"
11#include "subdomainprojectedcoarsespace.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/solver.hh>
22#include <dune/istl/solvertype.hh>
23#include <dune/istl/preconditioners.hh>
24#include <dune/istl/preconditioner.hh>
25#include <dune/istl/scalarproducts.hh>
26#include <dune/istl/paamg/amg.hh>
27#include <dune/istl/paamg/pinfo.hh>
28#include <dune/istl/io.hh>
29#include <dune/istl/superlu.hh>
30#include <dune/istl/umfpack.hh>
32#include <dune/istl/istlexception.hh>
33#include <dune/istl/matrixutils.hh>
34#include <dune/istl/gsetc.hh>
35#include <dune/istl/ilu.hh>
37#include <dune/pdelab/constraints/common/constraints.hh>
38#include <dune/pdelab/gridfunctionspace/genericdatahandle.hh>
39#include <dune/pdelab/backend/solver.hh>
40#include <dune/pdelab/backend/istl/vector.hh>
41#include <dune/pdelab/backend/istl/bcrsmatrix.hh>
47 template<
class Coarse,
class COARSE_V,
class COARSE_W>
50 CoarseTransfer(std::shared_ptr<Coarse>& coarse, std::shared_ptr<Coarse>& coarse_small,
int ranks)
52 coarse_small_(coarse_small),
63 COARSE_V restrict(
const COARSE_V& v){
65 int cnt_small=0, cnt=0;
66 COARSE_V v0(coarse_small_->basis_size(),coarse_small_->basis_size());
67 for (
int rank = 0; rank < ranks_; rank++){
68 for (
int i = 0; i< coarse_->get_local_basis_sizes(rank); i++){
69 if(i < coarse_small_->get_local_basis_sizes(rank)){
70 v0[cnt_small] = v[cnt];
82 COARSE_W prolongate(COARSE_W& w,
const COARSE_W& v){
84 COARSE_W w0(coarse_->basis_size(),coarse_->basis_size());
85 int cnt_small = 0, cnt = 0;
86 for (
int rank = 0; rank < ranks_; rank++){
87 for (
int i = 0; i< coarse_->get_local_basis_sizes(rank); i++){
89 if(i < coarse_small_->get_local_basis_sizes(rank)){
90 w0[cnt] = w[cnt_small];
104 COARSE_V restrict_local(
const COARSE_V& v,
int offset,
int size){
106 COARSE_V v0(size,size);
107 for (
int i = 0; i< size; i++){
116 COARSE_W prolongate_local(COARSE_W& w,
int offset,
int size){
118 COARSE_W w0(coarse_->basis_size(),coarse_->basis_size());
119 int cnt_small = 0, cnt = 0;
120 for (
int i = 0; i< coarse_->basis_size(); i++){
122 if(i >= offset && i < offset + size)
130 std::shared_ptr<Coarse> coarse_;
131 std::shared_ptr<Coarse> coarse_small_;
136 template<
class GFS,
class COARSE_M,
class COARSE_V,
class COARSE_W,
class M,
class X,
class Y>
137 class CoarsePrec :
public Preconditioner<COARSE_V,COARSE_W> {
140 typedef Dune::PDELab::Backend::Native<COARSE_M> matrix_type;
145 category=SolverCategory::sequential
154 CoarsePrec (
const GFS& gfs,
const COARSE_M& A, std::shared_ptr<CoarseSpace<M,X> > coarse_space, std::shared_ptr<CoarseSpace<M,X>> coarse_space_small)
155 : my_rank_(gfs.gridView().comm().rank()),
156 ranks_(gfs.gridView().comm().size()),
158 coarse_transfer(coarse_space_,coarse_space_small_,ranks_),
159 CA(Dune::PDELab::Backend::native(A)),
160 coarse_space_(coarse_space),
161 coarse_space_small_(coarse_space_small),
163 local_matrix(ranks_), solver_r(ranks_)
165 for (
int rank = 0; rank < ranks_; rank++){
167 int local_size = coarse_space_->get_local_basis_sizes(rank);
168 auto offset = coarse_space_->basis_array_offset(rank);
171 local_matrix[rank] = std::make_shared<COARSE_M>(setupLocalMatrix(offset, local_size));
173 solver_r[rank] = std::make_shared<Dune::UMFPack<COARSE_M>>(*local_matrix[rank]);
182 virtual void pre (COARSE_V& x, COARSE_W& b)
184 DUNE_UNUSED_PARAMETER(x);
185 DUNE_UNUSED_PARAMETER(b);
193 virtual void apply (COARSE_V& v,
const COARSE_W& d)
195 Dune::InverseOperatorResult result;
197 if(configuration.get<
bool>(
"prec_subdomain",
true)!=
true){
198 for (
int rank = 0; rank < ranks_; rank++){
200 int local_size = coarse_space_->get_local_basis_sizes(rank);
201 auto offset = coarse_space_->basis_array_offset(rank);
204 auto btilde = coarse_transfer.restrict_local(d,offset,local_size);
207 COARSE_V vl(local_size,local_size);
208 solver_r[rank]->apply(vl,btilde,result);
211 auto local_correction = coarse_transfer.prolongate_local(vl,offset,local_size);
212 v += local_correction;
216 auto btilde = coarse_transfer.restrict(d);
217 COARSE_V v0(coarse_space_small_->basis_size(),coarse_space_small_->basis_size());
218 solverc.apply(v0,btilde,result);
219 auto coarse_correction = coarse_transfer.prolongate(v0,d);
220 v = coarse_correction;
224 COARSE_M setupLocalMatrix(
int offset,
int local_size){
226 COARSE_M local_matrix(local_size,local_size,COARSE_M::row_wise );
227 auto A = *coarse_space_->get_coarse_system();
228 auto setup_row = local_matrix.createbegin();
229 for (
int idx = 0; idx < local_size; idx++){
230 for (
int j = 0; j < local_size; j++)
233 for (
int j = 0; j < local_size; j++){
234 if(A.exists(offset+idx,offset+j))
235 local_matrix[idx][j] = A[offset+idx][offset+j];
237 local_matrix[idx][j] = 0;
248 virtual void post (COARSE_V& x)
250 DUNE_UNUSED_PARAMETER(x);
259 std::shared_ptr<CoarseSpace<M,X> > coarse_space_;
260 std::shared_ptr<CoarseSpace<M,X>> coarse_space_small_;
261 Dune::UMFPack<matrix_type> solverc;
262 CoarseTransfer< CoarseSpace<M,X>,COARSE_V,COARSE_W > coarse_transfer;
263 std::vector<std::shared_ptr<COARSE_M> > local_matrix;
264 std::vector<std::shared_ptr<Dune::UMFPack<COARSE_M>> > solver_r;