1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include <dune/istl/matrixmatrix.hh>
6 #include <dune/pdelab.hh>
7
8 /** Parameter class for the stationary convection-diffusion equation of the following form:
9 *
10 * \f{align*}{
11 * \nabla\cdot(-A(x) \nabla u + b(x) u) + c(x)u &=& f \mbox{ in } \Omega, \ \
12 * u &=& g \mbox{ on } \partial\Omega_D (Dirichlet)\ \
13 * (b(x,u) - A(x)\nabla u) \cdot n &=& j \mbox{ on } \partial\Omega_N (Flux)\ \
14 * -(A(x)\nabla u) \cdot n &=& o \mbox{ on } \partial\Omega_O (Outflow)
15 * \f}
16 * Note:
17 * - This formulation is valid for velocity fields which are non-divergence free.
18 * - Outflow boundary conditions should only be set on the outflow boundary
19 *
20 * The template parameters are:
21 * - GV a model of a GridView
22 * - RF numeric type to represent results
23 */
24
25 template<typename GV, typename RF>
26 class GenericEllipticProblem
27 {
28 typedef Dune::PDELab::ConvectionDiffusionBoundaryConditions::Type BCType;
29
30 public:
31 typedef Dune::PDELab::ConvectionDiffusionParameterTraits<GV,RF> Traits;
32
33 //! tensor diffusion constant per cell? return false if you want more than one evaluation of A per cell.
permeabilityIsConstantPerCell()34 static constexpr bool permeabilityIsConstantPerCell()
35 {
36 return true;
37 }
38
39 //! tensor diffusion coefficient
40 typename Traits::PermTensorType
A(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const41 A (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
42 {
43 typename Traits::PermTensorType I;
44 for (std::size_t i=0; i<Traits::dimDomain; i++)
45 for (std::size_t j=0; j<Traits::dimDomain; j++)
46 I[i][j] = (i==j) ? 1 : 0;
47 return I;
48 }
49
50 //! velocity field
51 typename Traits::RangeType
b(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const52 b (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
53 {
54 typename Traits::RangeType v(0.0);
55 return v;
56 }
57
58 //! sink term
59 typename Traits::RangeFieldType
c(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const60 c (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
61 {
62 return 0.0;
63 }
64
65 //! source term
66 typename Traits::RangeFieldType
f(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const67 f (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
68 {
69 return 0.0;
70 }
71
72 //! boundary condition type function
73 /* return Dune::PDELab::ConvectionDiffusionBoundaryConditions::Dirichlet for Dirichlet boundary conditions
74 * return Dune::PDELab::ConvectionDiffusionBoundaryConditions::Neumann for flux boundary conditions
75 * return Dune::PDELab::ConvectionDiffusionBoundaryConditions::Outflow for outflow boundary conditions
76 */
77 BCType
bctype(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const78 bctype (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
79 {
80 return Dune::PDELab::ConvectionDiffusionBoundaryConditions::Dirichlet;
81 }
82
83 //! Dirichlet boundary condition value
84 typename Traits::RangeFieldType
g(const typename Traits::ElementType & e,const typename Traits::DomainType & xlocal) const85 g (const typename Traits::ElementType& e, const typename Traits::DomainType& xlocal) const
86 {
87 typename Traits::DomainType x = e.geometry().global(xlocal);
88 return exp(-(x*x));
89 }
90
91 //! flux boundary condition
92 typename Traits::RangeFieldType
j(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const93 j (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
94 {
95 return 0.0;
96 }
97
98 //! outflow boundary condition
99 typename Traits::RangeFieldType
o(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const100 o (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
101 {
102 return 0.0;
103 }
104 };
105
main(int argc,char ** argv)106 int main(int argc, char **argv)
107 {
108 // initialize MPI, finalize is done automatically on exit
109 Dune::MPIHelper::instance(argc,argv);
110
111 // command line args
112 int cells=16; if (argc>=2) sscanf(argv[1],"%d",&cells);
113 int refinements=0; if (argc>=3) sscanf(argv[2],"%d",&refinements);
114
115 Dune::Timer watch;
116
117 // define parameters
118 const unsigned int dim = 2;
119 const unsigned int degree = 1;
120 const Dune::GeometryType::BasicType elemtype = Dune::GeometryType::cube;
121 const Dune::PDELab::MeshType meshtype = Dune::PDELab::MeshType::conforming;
122 const Dune::SolverCategory::Category solvertype = Dune::SolverCategory::overlapping;
123 typedef double NumberType;
124
125 // make grid
126 typedef Dune::YaspGrid<dim> GM;
127 typedef Dune::PDELab::StructuredGrid<GM> Grid;
128 Grid grid(elemtype,cells,1);
129 grid->loadBalance();
130 grid->refineOptions(false);
131 grid->globalRefine(refinements);
132
133 // make problem parameters
134 typedef GenericEllipticProblem<GM::LeafGridView,NumberType> Problem;
135 Problem problem;
136 // make dummy constraints parameters, DG has no essential boundary conditions
137 typedef Dune::PDELab::DirichletConstraintsParameters BCType;
138 BCType bctype;
139
140 // make DG finite element space
141 typedef Dune::PDELab::DGQkSpace<GM,NumberType,degree,elemtype,solvertype> FS;
142 FS fs(grid->leafGridView());
143 fs.assembleConstraints(bctype);
144 //std::cout << "number of constraints is " << fs.getCC().size() << std::endl;
145
146 // assembler for finite elemenent problem
147 typedef Dune::PDELab::ConvectionDiffusionDG<Problem,typename FS::FEM> LOP;
148 LOP lop(problem,Dune::PDELab::ConvectionDiffusionDGMethod::SIPG,Dune::PDELab::ConvectionDiffusionDGWeights::weightsOn,2.0);
149 typedef Dune::PDELab::GalerkinGlobalAssemblerNewBackend<FS,LOP,solvertype> ASSEMBLER;
150 ASSEMBLER assembler(fs,lop,ASSEMBLER::MBE(5)); // 5 entries per row with cartesian mesh in 2D and blocked DG space
151
152 // allocate solution vector
153 typedef FS::DOF V;
154 V x(fs.getGFS(),0.0);
155 std::cout << "number of elements is " << Dune::PDELab::Backend::native(x).N() << std::endl;
156
157 // use purely Neumann-zero boundary conditions
158 // projected matrix from DG space has no essential boundary conditions
159 typedef Dune::PDELab::NoDirichletConstraintsParameters CGBCType;
160 CGBCType cgbctype;
161 // CG space
162 typedef Dune::PDELab::CGSpace<GM,NumberType,1,CGBCType,elemtype,meshtype,solvertype> CGFS;
163 CGFS cgfs(*grid,cgbctype);
164 cgfs.assembleConstraints(cgbctype);
165
166 // need to set up my own grid operator that does not use P0Constraints
167 typedef typename FS::GFS GFS;
168 typedef typename FS::CC DGCC2;
169 DGCC2 dgcc2; // empty: no constraints!
170 typedef Dune::PDELab::ISTL::BCRSMatrixBackend<> MBE;
171 typedef Dune::PDELab::GridOperator<GFS,GFS,LOP,MBE,NumberType,NumberType,NumberType,DGCC2,DGCC2> DGGO2;
172 DGGO2 dggo2(fs.getGFS(),dgcc2,fs.getGFS(),dgcc2,lop,MBE(5));
173
174 /////////////////// SEQUENTIAL
175 // make linear solver and solve problem
176 {
177 typedef Dune::PDELab::ISTLBackend_SEQ_AMG_4_DG<ASSEMBLER::GO,CGFS::GFS,
178 Dune::PDELab::CG2DGProlongation,Dune::SeqSSOR,Dune::CGSolver> LS;
179 LS ls(assembler.getGO(),cgfs.getGFS(),1000,3);
180 // set parameters for AMG in CG-subspace
181 Dune::Amg::Parameters params = ls.parameters();
182 params.setCoarsenTarget(2000);
183 params.setMaxLevel(20);
184 params.setProlongationDampingFactor(1.8);
185 params.setNoPreSmoothSteps(2);
186 params.setNoPostSmoothSteps(2);
187 params.setGamma(1);
188 params.setAdditive(false);
189 ls.setParameters(params);
190 typedef Dune::PDELab::StationaryLinearProblemSolver<DGGO2,LS,V> SLP;
191 SLP slp(dggo2,ls,x,1e-8);
192 slp.setHangingNodeModifications(false);
193 slp.apply();
194 }
195
196 /////////////////// OVERLAPPING
197 // reset initial iterate
198 x = 0.0;
199 // make linear solver and solve problem
200 #if HAVE_MPI
201 {
202 typedef Dune::PDELab::ISTLBackend_OVLP_AMG_4_DG<ASSEMBLER::GO,FS::CC,CGFS::GFS,CGFS::CC,
203 Dune::PDELab::CG2DGProlongation,Dune::SeqSSOR,Dune::CGSolver> LS;
204 LS ls(assembler.getGO(),fs.getCC(),cgfs.getGFS(),cgfs.getCC(),1000,3);
205 // set parameters for AMG in CG-subspace
206 Dune::Amg::Parameters params = ls.parameters();
207 params.setCoarsenTarget(2000);
208 params.setMaxLevel(20);
209 params.setProlongationDampingFactor(1.8);
210 params.setNoPreSmoothSteps(2);
211 params.setNoPostSmoothSteps(2);
212 params.setGamma(1);
213 params.setAdditive(false);
214 ls.setParameters(params);
215 typedef Dune::PDELab::StationaryLinearProblemSolver<DGGO2,LS,V> SLP;
216 SLP slp(dggo2,ls,x,1e-8);
217 slp.setHangingNodeModifications(false);
218 slp.apply();
219 }
220 #endif // HAVE_MPI
221
222 // done
223 return 0;
224 }
225