dune-composites (2.5.1)

geneo.hh
1#ifndef GENEO_SOLVER_HH
2#define GENEO_SOLVER_HH
3
4#include "conbase_fork.hh"
5#include "cg_fork.hh"
6#include "neumann_boundary_condition.hh"
7
8#include "two_level_schwarz.hh"
9
10#include "subdomainprojectedcoarsespace.hh"
11
12#include "partitionofunity.hh"
13#include "localoperator_ovlp_region.hh"
14
15#include "geneobasis.hh"
16#include "liptonbabuskabasis.hh"
17#include "partitionofunitybasis.hh"
18#include "zembasis.hh"
19
20namespace Dune{
21 namespace Geneo{
22
23 template<class V, class GFS, class GO, class LOP, class CON, class MBE>
24 class CG_GenEO :
25 public PDELab::OVLPScalarProductImplementation<GFS>,
26 public PDELab::LinearResultStorage
27 {
28
29 public:
30
31 typedef double RF;
32
33 CG_GenEO(V& x0_, const GFS& gfs_, LOP& lop_, CON& constraints_, MBE& mbe_, Composites::SolverInfo & si_, Dune::MPIHelper& helper_, int cells_) :
34 PDELab::OVLPScalarProductImplementation<GFS>(gfs_),
35 x0(x0_),
36 gfs(gfs_),
37 lop(lop_),
38 constraints(constraints_),
39 mbe(mbe_),
40 solver_info(si_),
41 helper(helper_),
42 cells(cells_) { }
43
44 void inline apply(){
45
46 typedef typename GFS::template ConstraintsContainer<double>::Type C;
47 C cg; cg.clear();
48 C cg_ext; cg_ext.clear();
49
50 Dune::PDELab::constraints(constraints,gfs,cg);
51
52 std::vector<double> times;
53 Dune::Timer watch;
54 watch.reset();
55
56#if HAVE_SUITESPARSE
57 //Neumann boudary conditions between processors
58 Dune::PDELab::constraints_exterior(constraints,gfs,cg_ext);
59 auto cc_bnd_neu_int_dir = C();
61 cc_bnd_neu_int_dir.clear();
62 Dune::PDELab::constraints(pnbc,gfs,cc_bnd_neu_int_dir);
63
64 //Set up Grid operator
65 typedef typename GO::Jacobian J;
66
67 //Matrix with "correct" boundary conditions
68 GO go(gfs,cg,gfs,cg,lop,mbe);
69 J AF(go);
70 AF = 0.0;
71 go.jacobian(x0,AF);
72
73 //Matrix with pure neumann boundary conditions
74 GO go_neu(gfs,cg_ext,gfs,cg_ext,lop,mbe);
75 J AF_neu(go_neu);
76 AF_neu = 0.0;
77 go_neu.jacobian(x0,AF_neu);
78
79 //Create local operator on overlap
80 typedef Dune::PDELab::LocalOperatorOvlpRegion<LOP, GFS> LOP_ovlp;
81 LOP_ovlp lop_ovlp(lop,gfs);
82 typedef Dune::PDELab::GridOperator<GFS,GFS,LOP_ovlp,MBE,RF,RF,RF,C,C> GO_ovlp;
83 GO_ovlp go_ovlp(gfs,cg_ext,gfs,cg_ext,lop_ovlp,mbe);
84 typedef typename GO_ovlp::Jacobian J2;
85 J2 AF_ovlp(go_ovlp);
86 AF_ovlp = 0.0;
87 go_ovlp.jacobian(x0,AF_ovlp);
88
89 //Set up solution vector and some necessary operators
90 typedef Dune::PDELab::OverlappingOperator<C,J,V,V> POP;
91 POP popf(cg,AF);
92 typedef Dune::PDELab::istl::ParallelHelper<GFS> PIH;
93 PIH pihf(gfs);
94 typedef Dune::PDELab::OverlappingScalarProduct<GFS,V> OSP;
95 OSP ospf(gfs,pihf);
96
97 //Preconditioner
98
99 auto gv = gfs.gridView();
100
101 double eigenvalue_threshold = solver_info.eigenvalue_threshold*(double)solver_info.overlap/(cells+solver_info.overlap); //eigenvalue threshhold
102 if(helper.rank() == 0) std::cout << "Eigenvalue threshhold: " << eigenvalue_threshold << std::endl;
103 int verb = 10;
104 //if (gfs.gridView().comm().rank()==0) verb=solver_info.verb;
105 typedef Dune::PDELab::LocalFunctionSpace<GFS, Dune::PDELab::AnySpaceTag> LFSU;
106 typedef typename LFSU::template Child<0>::Type LFS;
107 LFSU lfsu(gfs);
108 LFS lfs = lfsu.template child<0>();
109
110 //file << "Time for geneo setup:" << timer.elapsed() << "\n";
111 //times.push_back(watch.elapsed());
112 //watch.reset();
113
114 std::shared_ptr<V> part_unity;
115 if (solver_info.widlund_part_unity == false)
116 part_unity = sarkisPartitionOfUnity<3,V>(gfs, lfs, cc_bnd_neu_int_dir);
117 else
118 part_unity = standardPartitionOfUnity<3,V>(gfs, lfs, cc_bnd_neu_int_dir);
119
120 //times.push_back(watch.elapsed());
121 //watch.reset();
122
123 V dummy(gfs, 1);
124 Dune::PDELab::set_constrained_dofs(cg_ext,0.0,dummy); // Zero on subdomain boundary
125
126 int nev = solver_info.nev;
127
128 std::shared_ptr<SubdomainBasis<V> > subdomain_basis;
129 //SubdomainBasis<V> subdomain_basis2;
130 if (nev > 0)
131 subdomain_basis = std::make_shared<GenEOBasis<GFS,J,V,V,Composites::SolverInfo,3> >(gfs, AF_neu, AF_ovlp, eigenvalue_threshold, *part_unity, solver_info);//,subdomain_basis2);
132 else if (nev == 0){
133 subdomain_basis = std::make_shared<ZEMBasis<GFS,LFS,V,3,3> >(gfs, lfs, *part_unity);
134 //subdomain_basis2 = *subdomain_basis;
135 }
136 else{
137 subdomain_basis = std::make_shared<PartitionOfUnityBasis<V> >(*part_unity);
138 //subdomain_basis2 = *subdomain_basis;
139 }
140
141 auto partunityspace = std::make_shared<SubdomainProjectedCoarseSpace<GFS,J,V,V,3> >(gfs, AF_neu, subdomain_basis, verb);
142
143 //typedef TwoLevelOverlappingAdditiveSchwarz<GFS,J,V,V> PREC_PCG;
144 typedef TwoLevelOverlappingAdditiveSchwarzDC<GFS,J,V,V> PREC_DC;
145 //std::shared_ptr<PREC_PCG> prec;
146 std::shared_ptr<PREC_DC> prec;
147
148 // std::shared_ptr<SubdomainProjectedCoarseSpace<GFS,J,V,V,3>> partunityspace2;
149 //partunityspace2 = std::make_shared<SubdomainProjectedCoarseSpace<GFS,J,V,V,3> >(gfs, AF_neu, std::make_shared<SubdomainBasis<V>>(subdomain_basis2), verb);
150 prec = std::make_shared<PREC_DC>(gfs, AF, partunityspace,solver_info.coarseSpaceActive);
151
152 MPI_Barrier(gfs.gridView().comm());
153 if(helper.rank()==0) std::cout << "Geneo setup time " << watch.elapsed() << std::endl;
154 times.push_back(watch.elapsed());
155 watch.reset();
156
157 // set up and assemble right hand side w.r.t. l(v)-a(u_g,v)
158 V d(gfs,0.0);
159 go.residual(x0,d);
160
161 // now solve defect equation A*v = d
162 V v(gfs,0.0);
163 //Solve using CG
164
165 std::shared_ptr<CGSolverFork<V>> solver;
166 solver = std::make_shared<CGSolverFork<V> >(popf,ospf,*prec,solver_info.KrylovTol,solver_info.MaxIt,solver_info.verb,true);
167 Dune::InverseOperatorResult result;
168 solver->apply(v,d,result);
169
170 times.push_back(watch.elapsed());
171 watch.reset();
172 x0 -= v;
173
174 solver_info.setTimes(times);
175 solver_info.recordResult(result);
176
177#else
178 std::cout << "Solver not available . . . Please install UMFPACK as part of SuiteSparse" << std::endl;
179 return;
180#endif
181 }
182
183 //Templated apply for Newton solver
184 template<class M, class V2, class W>
185 void apply(M& A, V2& z, W& r, typename Dune::template FieldTraits<typename V2::ElementType >::real_type reduction)
186 {
187 this->apply(z,r,reduction);
188 }
189
190 private:
191 V & x0;
192 const GFS& gfs;
193 LOP& lop;
194 const CON& constraints;
195 const MBE& mbe;
196 Composites::SolverInfo& solver_info;
197 Dune::MPIHelper& helper;
198 int cells;
199 };
200 }
201}
202
203#endif
204
205
Definition: neumann_boundary_condition.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 5, 22:35, 2025)