Amandus: Simulations based on multilevel Schwarz methods
darcy/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 __darcy_polynomial_h
10 #define __darcy_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 
59 namespace DarcyIntegrators
60 {
61 namespace Polynomial
62 {
63 
64 template <int dim>
65 class RHS : public AmandusIntegrator<dim>
66 {
67 public:
68  RHS(const Polynomials::Polynomial<double> curl_potential_1d,
69  const Polynomials::Polynomial<double> grad_potential_1d,
70  const Polynomials::Polynomial<double> pressure_1d);
71 
72  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
73  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
74  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
75  IntegrationInfo<dim>& info2) const;
76 
77 private:
78  Polynomials::Polynomial<double> curl_potential_1d;
79  Polynomials::Polynomial<double> grad_potential_1d;
80  Polynomials::Polynomial<double> pressure_1d;
81 };
82 
90 template <int dim>
91 class Residual : public AmandusIntegrator<dim>
92 {
93 public:
94  Residual(const Polynomials::Polynomial<double> curl_potential_1d,
95  const Polynomials::Polynomial<double> grad_potential_1d,
96  const Polynomials::Polynomial<double> pressure_1d);
97 
98  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
99  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
100  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
101  IntegrationInfo<dim>& info2) const;
102 
103 private:
104  Polynomials::Polynomial<double> curl_potential_1d;
105  Polynomials::Polynomial<double> grad_potential_1d;
106  Polynomials::Polynomial<double> pressure_1d;
107 };
108 
114 template <int dim>
115 class Error : public AmandusIntegrator<dim>
116 {
117 public:
118  Error(const Polynomials::Polynomial<double> curl_potential_1d,
119  const Polynomials::Polynomial<double> grad_potential_1d,
120  const Polynomials::Polynomial<double> pressure_1d);
121 
122  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
123  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
124  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
125  IntegrationInfo<dim>& info2) const;
126 
127 private:
128  Polynomials::Polynomial<double> curl_potential_1d;
129  Polynomials::Polynomial<double> grad_potential_1d;
130  Polynomials::Polynomial<double> pressure_1d;
131 };
132 
133 //----------------------------------------------------------------------//
134 
135 template <int dim>
136 RHS<dim>::RHS(const Polynomials::Polynomial<double> curl_potential_1d,
137  const Polynomials::Polynomial<double> grad_potential_1d,
138  const Polynomials::Polynomial<double> pressure_1d)
139  : curl_potential_1d(curl_potential_1d)
140  , grad_potential_1d(grad_potential_1d)
141  , pressure_1d(pressure_1d)
142 {
143  this->use_boundary = false;
144  this->use_face = false;
145 }
146 
147 template <int dim>
148 void
149 RHS<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
150 {
151  std::vector<std::vector<double>> rhs_u(
152  dim, std::vector<double>(info.fe_values(0).n_quadrature_points));
153  std::vector<double> rhs_p(info.fe_values(0).n_quadrature_points);
154 
155  std::vector<double> px(2);
156  std::vector<double> py(2);
157  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
158  {
159  const double x = info.fe_values(0).quadrature_point(k)(0);
160  const double y = info.fe_values(0).quadrature_point(k)(1);
161  curl_potential_1d.value(x, px);
162  curl_potential_1d.value(y, py);
163 
164  // Right hand side f corresponding to the vector potential of the velocity
165  rhs_u[0][k] = px[0] * py[1];
166  rhs_u[1][k] = -px[1] * py[0];
167 
168  // Add a gradient part to the right hand side f to test for
169  // pressure
170  pressure_1d.value(x, px);
171  pressure_1d.value(y, py);
172  rhs_u[0][k] += px[1] * py[0];
173  rhs_u[1][k] += px[0] * py[1];
174 
175  // Right hand side g corresponding to the scalar potential of the
176  // velocity, entering as inhomogeneity for the divergence.
177 
178  px.resize(3);
179  py.resize(3);
180  grad_potential_1d.value(x, px);
181  grad_potential_1d.value(y, py);
182  rhs_p[k] += px[2] * py[0] + px[0] * py[2];
183  }
184 
185  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs_u);
186  L2::L2(dinfo.vector(0).block(1), info.fe_values(1), rhs_p);
187 }
188 
189 template <int dim>
190 void
191 RHS<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
192 {
193 }
194 
195 template <int dim>
196 void
197 RHS<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&, IntegrationInfo<dim>&) const
198 {
199 }
200 
201 //----------------------------------------------------------------------//
202 
203 template <int dim>
204 Residual<dim>::Residual(const Polynomials::Polynomial<double> curl_potential_1d,
205  const Polynomials::Polynomial<double> grad_potential_1d,
206  const Polynomials::Polynomial<double> pressure_1d)
207  : curl_potential_1d(curl_potential_1d)
208  , grad_potential_1d(grad_potential_1d)
209  , pressure_1d(pressure_1d)
210 {
211  this->use_boundary = false;
212  this->use_face = false;
213  // this->input_vector_names.push_back("Newton iterate");
214 }
215 
216 template <int dim>
217 void
218 Residual<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
219 {
220  Assert(info.values.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
221  Assert(info.gradients.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
222 
223  std::vector<std::vector<double>> rhs_u(
224  dim, std::vector<double>(info.fe_values(0).n_quadrature_points));
225  std::vector<double> rhs_p(info.fe_values(0).n_quadrature_points);
226 
227  std::vector<double> px(2);
228  std::vector<double> py(2);
229  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
230  {
231  const double x = info.fe_values(0).quadrature_point(k)(0);
232  const double y = info.fe_values(0).quadrature_point(k)(1);
233  curl_potential_1d.value(x, px);
234  curl_potential_1d.value(y, py);
235 
236  // Right hand side corresponding to the vector potential of the velocity
237  rhs_u[0][k] = px[0] * py[1];
238  rhs_u[1][k] = -px[1] * py[0];
239 
240  // Add a gradient part to the right hand side to test for
241  // pressure
242  pressure_1d.value(x, px);
243  pressure_1d.value(y, py);
244  rhs_u[0][k] += px[1] * py[0];
245  rhs_u[1][k] += px[0] * py[1];
246 
247  // Right hand side corresponding to the scalar potential of the
248  // velocity, entering as inhomogeneity for the divergence.
249 
250  px.resize(3);
251  py.resize(3);
252  grad_potential_1d.value(x, px);
253  grad_potential_1d.value(y, py);
254  rhs_p[k] -= px[2] * py[0] + px[0] * py[2];
255  }
256 
257  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs_u, -1.);
258  L2::L2(dinfo.vector(0).block(1), info.fe_values(1), rhs_p, -1.);
259 
260  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), make_slice(info.values[0], 0, dim));
261  Divergence::gradient_residual(
262  dinfo.vector(0).block(0), info.fe_values(0), info.values[0][dim], -1.);
264  dinfo.vector(0).block(1), info.fe_values(1), make_slice(info.gradients[0], 0, dim), 1.);
265 }
266 
267 template <int dim>
268 void
269 Residual<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
270 {
271 }
272 
273 template <int dim>
274 void
275 Residual<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&,
276  IntegrationInfo<dim>&) const
277 {
278 }
279 
280 //----------------------------------------------------------------------//
281 
282 template <int dim>
283 Error<dim>::Error(const Polynomials::Polynomial<double> curl_potential_1d,
284  const Polynomials::Polynomial<double> grad_potential_1d,
285  const Polynomials::Polynomial<double> pressure_1d)
286  : curl_potential_1d(curl_potential_1d)
287  , grad_potential_1d(grad_potential_1d)
288  , pressure_1d(pressure_1d)
289 {
290  this->error_types.push_back(2);
291  this->error_names.push_back("L2u");
292  this->error_types.push_back(2);
293  this->error_names.push_back("H1u");
294  this->error_types.push_back(2);
295  this->error_names.push_back("L2divu");
296  this->error_types.push_back(2);
297  this->error_names.push_back("L2p");
298  this->error_types.push_back(2);
299  this->error_names.push_back("H1p");
300  this->error_types.push_back(1);
301  this->error_names.push_back("meanp");
302  this->use_boundary = false;
303  this->use_face = false;
304 }
305 
306 template <int dim>
307 void
308 Error<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
309 {
310  std::vector<double> px(3);
311  std::vector<double> py(3);
312  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
313  {
314  const double x = info.fe_values(0).quadrature_point(k)(0);
315  const double y = info.fe_values(0).quadrature_point(k)(1);
316  curl_potential_1d.value(x, px);
317  curl_potential_1d.value(y, py);
318  const double dx = info.fe_values(0).JxW(k);
319 
320  Tensor<1, dim> Du0 = info.gradients[0][0][k];
321  Du0[0] -= px[1] * py[1];
322  Du0[1] -= px[0] * py[2];
323  Tensor<1, dim> Du1 = info.gradients[0][1][k];
324  Du1[0] += px[2] * py[0];
325  Du1[1] += px[1] * py[1];
326  double u0 = info.values[0][0][k];
327  u0 -= px[0] * py[1];
328  double u1 = info.values[0][1][k];
329  u1 += px[1] * py[0];
330 
331  pressure_1d.value(x, px);
332  pressure_1d.value(y, py);
333  double p = info.values[0][dim][k];
334  p += px[0] * py[0];
335  Tensor<1, dim> Dp = info.gradients[0][dim][k];
336  Dp[0] += px[1] * py[0];
337  Dp[1] += px[0] * py[1];
338 
339  grad_potential_1d.value(x, px);
340  grad_potential_1d.value(y, py);
341  u0 -= px[1] * py[0];
342  u1 -= px[0] * py[1];
343  Du0[0] -= px[2] * py[0];
344  Du0[1] -= px[1] * py[1];
345  Du1[0] -= px[1] * py[1];
346  Du1[1] -= px[0] * py[2];
347  double dive = Du0[0] + Du1[1];
348 
349  p -= px[0] * py[0];
350  Dp[0] -= px[1] * py[0];
351  Dp[1] -= px[0] * py[1];
352 
353  // 0. L^2(u)
354  dinfo.value(0) += (u0 * u0 + u1 * u1) * dx;
355  // 1. H^1(u)
356  dinfo.value(1) += ((Du0 * Du0) + (Du1 * Du1)) * dx;
357  // 2. div u
358  dinfo.value(2) += dive * dive * dx;
359  // 3. L^2(p) up to mean value
360  dinfo.value(3) += p * p * dx;
361  // 4. H^1(p)
362  dinfo.value(4) += Dp * Dp * dx;
363  // 5. Mean value of p
364  dinfo.value(5) += p * dx;
365  }
366 
367  for (unsigned int i = 0; i <= 4; ++i)
368  {
369  if (this->error_type(i) == 2)
370  dinfo.value(i) = std::sqrt(dinfo.value(i));
371  }
372 }
373 
374 template <int dim>
375 void
376 Error<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
377 {
378 }
379 
380 template <int dim>
381 void
382 Error<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&, IntegrationInfo<dim>&) const
383 {
384 }
385 }
386 }
387 
388 #endif
Residual(const Polynomials::Polynomial< double > curl_potential_1d, const Polynomials::Polynomial< double > grad_potential_1d, const Polynomials::Polynomial< double > pressure_1d)
Definition: darcy/polynomial.h:204
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:269
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:308
Polynomials::Polynomial< double > pressure_1d
Definition: darcy/polynomial.h:130
std::vector< std::string > error_names
Definition: integrator.h:120
Polynomials::Polynomial< double > curl_potential_1d
Definition: darcy/polynomial.h:128
Polynomials::Polynomial< double > curl_potential_1d
Definition: darcy/polynomial.h:78
Polynomials::Polynomial< double > grad_potential_1d
Definition: darcy/polynomial.h:129
Polynomials::Polynomial< double > pressure_1d
Definition: darcy/polynomial.h:106
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:149
Polynomials::Polynomial< double > curl_potential_1d
Definition: darcy/polynomial.h:104
Polynomials::Polynomial< double > grad_potential_1d
Definition: darcy/polynomial.h:105
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:191
Definition: estimator.h:33
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:376
std::vector< unsigned int > error_types
Definition: integrator.h:113
Polynomials::Polynomial< double > pressure_1d
Definition: darcy/polynomial.h:80
Error(const Polynomials::Polynomial< double > curl_potential_1d, const Polynomials::Polynomial< double > grad_potential_1d, const Polynomials::Polynomial< double > pressure_1d)
Definition: darcy/polynomial.h:283
Definition: darcy/polynomial.h:115
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: darcy/polynomial.h:275
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
Definition: darcy/polynomial.h:65
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: darcy/polynomial.h:382
Definition: darcy/polynomial.h:91
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: darcy/polynomial.h:197
unsigned int error_type(unsigned int i) const
Definition: integrator.h:437
Definition: integrator.h:29
Polynomials::Polynomial< double > grad_potential_1d
Definition: darcy/polynomial.h:79
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: darcy/polynomial.h:218