Amandus: Simulations based on multilevel Schwarz methods
laplace/polynomial.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (C) 2011 - 2014 by the authors
3  * Distributed under the MIT License
4  *
5  * See the files AUTHORS and LICENSE in the project root directory
6  *
7  **********************************************************************/
8 
9 #ifndef __laplace_polynomial_h
10 #define __laplace_polynomial_h
11 
12 #include <amandus/integrator.h>
13 #include <deal.II/base/polynomial.h>
14 #include <deal.II/base/tensor.h>
15 #include <deal.II/integrators/divergence.h>
16 #include <deal.II/integrators/l2.h>
17 #include <deal.II/integrators/laplace.h>
18 
19 using namespace dealii;
20 using namespace LocalIntegrators;
21 using namespace MeshWorker;
22 
23 namespace LaplaceIntegrators
24 {
32 template <int dim>
33 class PolynomialRHS : public AmandusIntegrator<dim>
34 {
35 public:
36  PolynomialRHS(const Polynomials::Polynomial<double> solution_1d);
37 
38  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
39  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
40  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
41  IntegrationInfo<dim>& info2) const;
42 
43 private:
44  Polynomials::Polynomial<double> solution_1d;
45 };
46 
54 template <int dim>
56 {
57 public:
58  PolynomialResidual(const Polynomials::Polynomial<double> solution_1d);
59 
60  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
61  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
62  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
63  IntegrationInfo<dim>& info2) const;
64 
65 private:
66  Polynomials::Polynomial<double> solution_1d;
67 };
68 
69 template <int dim>
70 class PolynomialBoundary : public Function<dim>
71 {
72 public:
73  PolynomialBoundary(const Polynomials::Polynomial<double> solution_1d)
74  : Function<dim>()
75  , solution_1d(solution_1d)
76  {
77  }
78 
79  virtual double value(const Point<dim>& p, const unsigned int component = 0) const;
80 
81 private:
82  Polynomials::Polynomial<double> solution_1d;
83 };
84 
85 template <int dim>
87 {
88 public:
89  PolynomialError(const Polynomials::Polynomial<double> solution_1d);
90 
91  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
92  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
93  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
94  IntegrationInfo<dim>& info2) const;
95 
96 private:
97  Polynomials::Polynomial<double> solution_1d;
98 };
99 
100 //----------------------------------------------------------------------//
101 
102 template <int dim>
103 PolynomialRHS<dim>::PolynomialRHS(const Polynomials::Polynomial<double> solution_1d)
104  : solution_1d(solution_1d)
105 {
106  this->use_boundary = false;
107  this->use_face = false;
108 }
109 
110 template <int dim>
111 void
112 PolynomialRHS<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
113 {
114  std::vector<double> rhs(info.fe_values(0).n_quadrature_points, 0.);
115 
116  std::vector<double> px(3);
117  std::vector<double> py(3);
118  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
119  {
120  const double x = info.fe_values(0).quadrature_point(k)(0);
121  const double y = info.fe_values(0).quadrature_point(k)(1);
122  solution_1d.value(x, px);
123  solution_1d.value(y, py);
124 
125  rhs[k] = -px[2] * py[0] - px[0] * py[2];
126  }
127 
128  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs);
129 }
130 
131 template <int dim>
132 void
133 PolynomialRHS<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
134 {
135 }
136 
137 template <int dim>
138 void
139 PolynomialRHS<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&,
140  IntegrationInfo<dim>&) const
141 {
142 }
143 
144 //----------------------------------------------------------------------//
145 
146 template <int dim>
147 PolynomialResidual<dim>::PolynomialResidual(const Polynomials::Polynomial<double> solution_1d)
148  : solution_1d(solution_1d)
149 {
150  this->use_boundary = true;
151  this->use_face = true;
152 }
153 
154 template <int dim>
155 void
156 PolynomialResidual<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
157 {
158  Assert(info.values.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
159  Assert(info.gradients.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
160 
161  std::vector<double> rhs(info.fe_values(0).n_quadrature_points, 0.);
162 
163  std::vector<double> px(3);
164  std::vector<double> py(3);
165  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
166  {
167  const double x = info.fe_values(0).quadrature_point(k)(0);
168  const double y = info.fe_values(0).quadrature_point(k)(1);
169  solution_1d.value(x, px);
170  solution_1d.value(y, py);
171 
172  rhs[k] = -px[2] * py[0] - px[0] * py[2];
173  }
174 
175  double factor = 1.;
176  if (this->timestep != 0)
177  {
178  factor = -this->timestep;
179  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), info.values[0][0]);
180  }
181  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs, -factor);
182  Laplace::cell_residual(dinfo.vector(0).block(0), info.fe_values(0), info.gradients[0][0], factor);
183 }
184 
185 template <int dim>
186 void
187 PolynomialResidual<dim>::boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
188 {
189  std::vector<double> boundary_values(info.fe_values(0).n_quadrature_points, 0.);
190  std::vector<double> px(1);
191  std::vector<double> py(1);
192  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
193  {
194  const double x = info.fe_values(0).quadrature_point(k)(0);
195  const double y = info.fe_values(0).quadrature_point(k)(1);
196  solution_1d.value(x, px);
197  solution_1d.value(y, py);
198  boundary_values[k] = px[0] * py[0];
199  }
200 
201  const double factor = (this->timestep == 0.) ? 1. : this->timestep;
202  const unsigned int deg = info.fe_values(0).get_fe().tensor_degree();
203  Laplace::nitsche_residual(dinfo.vector(0).block(0),
204  info.fe_values(0),
205  info.values[0][0],
206  info.gradients[0][0],
207  boundary_values,
208  Laplace::compute_penalty(dinfo, dinfo, deg, deg),
209  factor);
210 }
211 
212 template <int dim>
213 void
214 PolynomialResidual<dim>::face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2,
215  IntegrationInfo<dim>& info1, IntegrationInfo<dim>& info2) const
216 {
217  const unsigned int deg = info1.fe_values(0).get_fe().tensor_degree();
218  const double factor = (this->timestep == 0.) ? 1. : this->timestep;
219  Laplace::ip_residual(dinfo1.vector(0).block(0),
220  dinfo2.vector(0).block(0),
221  info1.fe_values(0),
222  info2.fe_values(0),
223  info1.values[0][0],
224  info1.gradients[0][0],
225  info2.values[0][0],
226  info2.gradients[0][0],
227  Laplace::compute_penalty(dinfo1, dinfo2, deg, deg),
228  factor);
229 }
230 
231 //----------------------------------------------------------------------//
232 
233 template <int dim>
234 double
235 PolynomialBoundary<dim>::value(const Point<dim>& p, const unsigned int component) const
236 {
237  Assert(component == 0, ExcNotImplemented());
238 
239  std::vector<double> px(1);
240  std::vector<double> py(1);
241  solution_1d.value(p[0], px);
242  solution_1d.value(p[1], py);
243 
244  return px[0] * py[0];
245 }
246 
247 //----------------------------------------------------------------------//
248 
249 template <int dim>
250 PolynomialError<dim>::PolynomialError(const Polynomials::Polynomial<double> solution_1d)
251  : solution_1d(solution_1d)
252 {
253  this->use_boundary = false;
254  this->use_face = false;
255  this->error_types.push_back(2);
256  this->error_types.push_back(2);
257  this->error_types.push_back(0);
258 }
259 
260 template <int dim>
261 void
262 PolynomialError<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
263 {
264  Assert(dinfo.n_values() >= 2, ExcDimensionMismatch(dinfo.n_values(), 4));
265  dinfo.value(2) = 0.;
266 
267  std::vector<double> px(3);
268  std::vector<double> py(3);
269  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
270  {
271  const double x = info.fe_values(0).quadrature_point(k)(0);
272  const double y = info.fe_values(0).quadrature_point(k)(1);
273  solution_1d.value(x, px);
274  solution_1d.value(y, py);
275  const double dx = info.fe_values(0).JxW(k);
276 
277  Tensor<1, dim> Du = info.gradients[0][0][k];
278  Du[0] -= px[1] * py[0];
279  Du[1] -= px[0] * py[1];
280  double u = info.values[0][0][k];
281  u -= px[0] * py[0];
282 
283  // 0. L^2(u)
284  dinfo.value(0) += (u * u) * dx;
285  // 1. H^1(u)
286  dinfo.value(1) += (Du * Du) * dx;
287  // 2. Linfty(u)
288  if (dinfo.value(2) < u * u)
289  dinfo.value(2) = u * u;
290  }
291 
292  dinfo.value(0) = std::sqrt(dinfo.value(0));
293  dinfo.value(1) = std::sqrt(dinfo.value(1));
294  dinfo.value(2) = std::sqrt(dinfo.value(2));
295 }
296 
297 template <int dim>
298 void
299 PolynomialError<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
300 {
301 }
302 
303 template <int dim>
304 void
305 PolynomialError<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&,
306  IntegrationInfo<dim>&) const
307 {
308 }
309 }
310 
311 #endif
PolynomialBoundary(const Polynomials::Polynomial< double > solution_1d)
Definition: laplace/polynomial.h:73
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/polynomial.h:139
PolynomialError(const Polynomials::Polynomial< double > solution_1d)
Definition: laplace/polynomial.h:250
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:299
double timestep
Current timestep if applicable.
Definition: integrator.h:48
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:156
Polynomials::Polynomial< double > solution_1d
Definition: laplace/polynomial.h:66
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:262
Definition: laplace/eigen.h:19
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:187
Polynomials::Polynomial< double > solution_1d
Definition: laplace/polynomial.h:44
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/polynomial.h:214
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:133
Definition: laplace/polynomial.h:33
Polynomials::Polynomial< double > solution_1d
Definition: laplace/polynomial.h:97
virtual double value(const Point< dim > &p, const unsigned int component=0) const
Definition: laplace/polynomial.h:235
PolynomialResidual(const Polynomials::Polynomial< double > solution_1d)
Definition: laplace/polynomial.h:147
std::vector< unsigned int > error_types
Definition: integrator.h:113
void cell_residual(dealii::Vector< number > &result, const dealii::FEValuesBase< dim > &fe, const dealii::VectorSlice< const std::vector< std::vector< dealii::Tensor< 1, dim >>>> &input, double lambda=0., double mu=1.)
Definition: elasticity/integrators.h:23
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/polynomial.h:112
Definition: laplace/polynomial.h:55
Polynomials::Polynomial< double > solution_1d
Definition: laplace/polynomial.h:82
Definition: laplace/polynomial.h:86
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/polynomial.h:305
Definition: laplace/polynomial.h:70
Definition: integrator.h:29