1 // -*- tab-width: 4; indent-tabs-mode: nil -*-
2 #ifndef DUNE_PDELAB_TEST_TESTPOISSON_PERIODIC_HH
3 #define DUNE_PDELAB_TEST_TESTPOISSON_PERIODIC_HH
4
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include <dune/pdelab/boilerplate/pdelab.hh>
11 #include <dune/pdelab/localoperator/convectiondiffusionfem.hh>
12 #include <dune/pdelab/localoperator/convectiondiffusiondg.hh>
13
14 // Poisson problem definition
15 template<typename GV, typename RF>
16 class GenericEllipticProblem
17 {
18 typedef Dune::PDELab::ConvectionDiffusionBoundaryConditions::Type BCType;
19
20 public:
21 typedef Dune::PDELab::ConvectionDiffusionParameterTraits<GV,RF> Traits;
22
23 //! tensor diffusion constant per cell? return false if you want more than one evaluation of A per cell.
permeabilityIsConstantPerCell()24 static constexpr bool permeabilityIsConstantPerCell()
25 {
26 return true;
27 }
28
29 //! tensor diffusion coefficient
30 typename Traits::PermTensorType
A(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const31 A (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
32 {
33 typename Traits::PermTensorType I;
34 for (std::size_t i=0; i<Traits::dimDomain; i++)
35 for (std::size_t j=0; j<Traits::dimDomain; j++)
36 I[i][j] = (i==j) ? 1 : 0;
37 return I;
38 }
39
40 //! velocity field
41 typename Traits::RangeType
b(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const42 b (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
43 {
44 typename Traits::RangeType v(0.0);
45 return v;
46 }
47
48 //! sink term
49 typename Traits::RangeFieldType
c(const typename Traits::ElementType & e,const typename Traits::DomainType & x) const50 c (const typename Traits::ElementType& e, const typename Traits::DomainType& x) const
51 {
52 return 0.0;
53 }
54
55 //! source term
56 typename Traits::RangeFieldType
f(const typename Traits::ElementType & e,const typename Traits::DomainType & xlocal) const57 f (const typename Traits::ElementType& e, const typename Traits::DomainType& xlocal) const
58 {
59 auto x = e.geometry().global(xlocal);
60 return x[0] * std::sin(5.0*M_PI*x[1]) + std::exp(-((x[0]-0.5)*(x[0]-0.5) + (x[1]-0.5)*(x[1]-0.5)) / 0.02);
61 }
62
63 //! Boundary condition type function. Will not be evaluated on periodic boundary, so we simply set Dirichlet.
64 BCType
bctype(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const65 bctype (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
66 {
67 return Dune::PDELab::ConvectionDiffusionBoundaryConditions::Dirichlet;
68 }
69
70 //! Dirichlet boundary condition value
71 typename Traits::RangeFieldType
g(const typename Traits::ElementType & e,const typename Traits::DomainType & xlocal) const72 g (const typename Traits::ElementType& e, const typename Traits::DomainType& xlocal) const
73 {
74 return 0.0;
75 }
76
77 //! flux boundary condition
78 typename Traits::RangeFieldType
j(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const79 j (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
80 {
81 return 0.0;
82 }
83
84 //! outflow boundary condition
85 typename Traits::RangeFieldType
o(const typename Traits::IntersectionType & is,const typename Traits::IntersectionDomainType & x) const86 o (const typename Traits::IntersectionType& is, const typename Traits::IntersectionDomainType& x) const
87 {
88 return 0.0;
89 }
90 };
91
92 // Problem solver
93 template<typename GridType, typename NumberType, int dim>
poisson(GridType & grid)94 void poisson (GridType& grid)
95 {
96 #if DG == 0
97 const Dune::PDELab::MeshType meshtype = Dune::PDELab::MeshType::conforming;
98 #endif
99 const Dune::SolverCategory::Category solvertype = Dune::SolverCategory::overlapping;
100 const Dune::GeometryType::BasicType elemtype = Dune::GeometryType::cube;
101
102 // make problem parameters
103 typedef GenericEllipticProblem<typename GridType::LeafGridView,NumberType> Problem;
104 Problem problem;
105 typedef Dune::PDELab::ConvectionDiffusionBoundaryConditionAdapter<Problem> BCType;
106 BCType bctype(grid.leafGridView(),problem);
107
108 // make a finite element space
109 #if DG == 0
110 typedef Dune::PDELab::CGSpace<GridType,NumberType,DEGREE,BCType,elemtype,meshtype,solvertype> FS;
111 FS fs(grid,bctype);
112 #else
113 typedef Dune::PDELab::DGQkSpace<GridType,NumberType,DEGREE,elemtype,solvertype> FS;
114 FS fs(grid.leafGridView());
115 #endif
116
117 // make a degree of freedom vector and initialize it with a function
118 typedef typename FS::DOF V;
119 V x(fs.getGFS(),0.0);
120
121 #if DG == 0
122 typedef Dune::PDELab::ConvectionDiffusionDirichletExtensionAdapter<Problem> G;
123 G g(grid.leafGridView(),problem);
124 Dune::PDELab::interpolate(g,fs.getGFS(),x);
125 #endif
126
127 // assemble constraints
128 fs.assembleConstraints(bctype);
129 fs.setNonConstrainedDOFS(x,0.0);
130
131 // assembler for finite elemenent problem
132 #if DG == 0
133 typedef Dune::PDELab::ConvectionDiffusionFEM<Problem,typename FS::FEM> LOP;
134 LOP lop(problem);
135 typedef Dune::PDELab::GalerkinGlobalAssembler<FS,LOP,solvertype> ASSEMBLER;
136 ASSEMBLER assembler(fs,lop,27);
137 #else
138 typedef Dune::PDELab::ConvectionDiffusionDG<Problem,typename FS::FEM> LOP;
139 LOP lop(problem,Dune::PDELab::ConvectionDiffusionDGMethod::SIPG,Dune::PDELab::ConvectionDiffusionDGWeights::weightsOn,2.0);
140 typedef Dune::PDELab::GalerkinGlobalAssembler<FS,LOP,solvertype> ASSEMBLER;
141 ASSEMBLER assembler(fs,lop,27);
142 #endif
143
144 // make linear solver and solve problem
145 typedef Dune::PDELab::ISTLSolverBackend_IterativeDefault<FS,ASSEMBLER,solvertype> SBE;
146 SBE sbe(fs,assembler,5000,1);
147
148 typedef Dune::PDELab::StationaryLinearProblemSolver<typename ASSEMBLER::GO,typename SBE::LS,V> SLP;
149 SLP slp(*assembler,*sbe,x,1e-6);
150 slp.apply();
151
152 // // print statistics about nonzero values per row
153 // typename ASSEMBLER::MAT m(assembler.getGO());
154 // std::cout << m.patternStatistics() << std::endl;
155
156 // output grid to VTK file
157 Dune::SubsamplingVTKWriter<typename GridType::LeafGridView> vtkwriter(grid.leafGridView(),Dune::refinementIntervals(DEGREE));
158 typename FS::DGF xdgf(fs.getGFS(),x);
159 vtkwriter.addVertexData(std::make_shared<typename FS::VTKF>(xdgf,"x_h"));
160 auto out_name = "poisson_periodic_" + std::to_string(dim) + "d_q" + std::to_string(DEGREE) + "_dg" + std::to_string(DG);
161 vtkwriter.write(out_name, Dune::VTK::appendedraw);
162 }
163
164 #endif // DUNE_PDELAB_TEST_TESTPOISSON_PERIODIC_HH
165