Amandus: Simulations based on multilevel Schwarz methods
laplace/solution.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_solution_h
10 #define __laplace_solution_h
11 
12 #include <amandus/integrator.h>
13 #include <deal.II/base/smartpointer.h>
14 #include <deal.II/base/tensor.h>
15 #include <deal.II/integrators/l2.h>
16 #include <deal.II/integrators/laplace.h>
17 
18 using namespace dealii;
19 using namespace LocalIntegrators;
20 using namespace MeshWorker;
21 
22 namespace LaplaceIntegrators
23 {
30 template <int dim>
31 class SolutionRHS : public AmandusIntegrator<dim>
32 {
33 public:
34  SolutionRHS(Function<dim>& solution);
35 
36  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
37  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
38  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
39  IntegrationInfo<dim>& info2) const;
40 
41 private:
42  SmartPointer<Function<dim>, SolutionRHS<dim>> solution;
43 };
44 
51 template <int dim>
53 {
54 public:
55  SolutionResidual(Function<dim>& solution);
56 
57  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
58  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
59  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
60  IntegrationInfo<dim>& info2) const;
61 
62 private:
63  SmartPointer<Function<dim>, SolutionResidual<dim>> solution;
64 };
65 
66 template <int dim>
67 class SolutionError : public AmandusIntegrator<dim>
68 {
69 public:
70  SolutionError(Function<dim>& solution);
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  SmartPointer<Function<dim>, SolutionError<dim>> solution;
79 };
80 
81 template <int dim>
83 {
84 public:
85  SolutionEstimate(Function<dim>& solution);
86 
87  virtual void cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
88  virtual void boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const;
89  virtual void face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
90  IntegrationInfo<dim>& info2) const;
91 
92 private:
93  SmartPointer<Function<dim>, SolutionEstimate<dim>> solution;
94 };
95 
96 //----------------------------------------------------------------------//
97 
98 template <int dim>
99 SolutionRHS<dim>::SolutionRHS(Function<dim>& solution)
100  : solution(&solution)
101 {
102  this->use_boundary = true;
103  this->use_face = false;
104 }
105 
106 template <int dim>
107 void
108 SolutionRHS<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
109 {
110  std::vector<double> rhs(info.fe_values(0).n_quadrature_points, 0.);
111 
112  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
113  rhs[k] = -solution->laplacian(info.fe_values(0).quadrature_point(k));
114 
115  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs);
116 }
117 
118 template <int dim>
119 void
120 SolutionRHS<dim>::boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
121 {
122  if (info.fe_values(0).get_fe().conforms(FiniteElementData<dim>::H1))
123  return;
124 
125  const FEValuesBase<dim>& fe = info.fe_values();
126  Vector<double>& local_vector = dinfo.vector(0).block(0);
127 
128  std::vector<double> boundary_values(fe.n_quadrature_points);
129  solution->value_list(fe.get_quadrature_points(), boundary_values);
130 
131  const unsigned int deg = fe.get_fe().tensor_degree();
132  const double penalty = 2. * Laplace::compute_penalty(dinfo, dinfo, deg, deg);
133 
134  for (unsigned k = 0; k < fe.n_quadrature_points; ++k)
135  for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
136  local_vector(i) += (penalty * fe.shape_value(i, k) * boundary_values[k] -
137  (fe.normal_vector(k) * fe.shape_grad(i, k)) * boundary_values[k]) *
138  fe.JxW(k);
139 }
140 
141 template <int dim>
142 void
143 SolutionRHS<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&,
144  IntegrationInfo<dim>&) const
145 {
146 }
147 
148 //----------------------------------------------------------------------//
149 
150 template <int dim>
152  : solution(&solution)
153 {
154  this->use_boundary = true;
155  this->use_face = true;
156 }
157 
158 template <int dim>
159 void
160 SolutionResidual<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
161 {
162  Assert(info.values.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
163  Assert(info.gradients.size() >= 1, ExcDimensionMismatch(info.values.size(), 1));
164 
165  std::vector<double> rhs(info.fe_values(0).n_quadrature_points, 0.);
166 
167  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
168  rhs[k] = -solution->laplacian(info.fe_values(0).quadrature_point(k));
169 
170  double factor = 1.;
171  if (this->timestep != 0)
172  {
173  factor = -this->timestep;
174  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), info.values[0][0]);
175  }
176  L2::L2(dinfo.vector(0).block(0), info.fe_values(0), rhs, -factor);
177  Laplace::cell_residual(dinfo.vector(0).block(0), info.fe_values(0), info.gradients[0][0], factor);
178 }
179 
180 template <int dim>
181 void
182 SolutionResidual<dim>::boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
183 {
184  if (info.fe_values(0).get_fe().conforms(FiniteElementData<dim>::H1))
185  return;
186 
187  std::vector<double> boundary_values(info.fe_values(0).n_quadrature_points, 0.);
188  solution->value_list(info.fe_values(0).get_quadrature_points(), boundary_values);
189 
190  const double factor = (this->timestep == 0.) ? 1. : this->timestep;
191  const unsigned int deg = info.fe_values(0).get_fe().tensor_degree();
192  Laplace::nitsche_residual(dinfo.vector(0).block(0),
193  info.fe_values(0),
194  info.values[0][0],
195  info.gradients[0][0],
196  boundary_values,
197  Laplace::compute_penalty(dinfo, dinfo, deg, deg),
198  factor);
199 }
200 
201 template <int dim>
202 void
203 SolutionResidual<dim>::face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
204  IntegrationInfo<dim>& info2) const
205 {
206  if (info1.fe_values(0).get_fe().conforms(FiniteElementData<dim>::H1))
207  return;
208 
209  const unsigned int deg = info1.fe_values(0).get_fe().tensor_degree();
210  const double factor = (this->timestep == 0.) ? 1. : this->timestep;
211  Laplace::ip_residual(dinfo1.vector(0).block(0),
212  dinfo2.vector(0).block(0),
213  info1.fe_values(0),
214  info2.fe_values(0),
215  info1.values[0][0],
216  info1.gradients[0][0],
217  info2.values[0][0],
218  info2.gradients[0][0],
219  Laplace::compute_penalty(dinfo1, dinfo2, deg, deg),
220  factor);
221 }
222 
223 //----------------------------------------------------------------------//
224 
225 template <int dim>
227  : solution(&solution)
228 {
229  this->use_boundary = false;
230  this->use_face = false;
231  this->error_types.push_back(2);
232  this->error_types.push_back(2);
233 }
234 
235 template <int dim>
236 void
237 SolutionError<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
238 {
239  Assert(dinfo.n_values() >= 2, ExcDimensionMismatch(dinfo.n_values(), 4));
240 
241  for (unsigned int k = 0; k < info.fe_values(0).n_quadrature_points; ++k)
242  {
243  const double dx = info.fe_values(0).JxW(k);
244 
245  Tensor<1, dim> Du_h = info.gradients[0][0][k];
246  Tensor<1, dim> Du = solution->gradient(info.fe_values(0).quadrature_point(k));
247  Tensor<1, dim> ddiff = Du - Du_h;
248  double u_h = info.values[0][0][k];
249  double u = solution->value(info.fe_values(0).quadrature_point(k));
250  double diff = u - u_h;
251 
252  // 0. L^2(u)
253  dinfo.value(0) += (diff * diff) * dx;
254  // 1. H^1(u)
255  dinfo.value(1) += (ddiff * ddiff) * dx;
256  }
257  dinfo.value(0) = std::sqrt(dinfo.value(0));
258  dinfo.value(1) = std::sqrt(dinfo.value(1));
259 }
260 
261 template <int dim>
262 void
263 SolutionError<dim>::boundary(DoFInfo<dim>&, IntegrationInfo<dim>&) const
264 {
265 }
266 
267 template <int dim>
268 void
269 SolutionError<dim>::face(DoFInfo<dim>&, DoFInfo<dim>&, IntegrationInfo<dim>&,
270  IntegrationInfo<dim>&) const
271 {
272 }
273 
274 //----------------------------------------------------------------------//
275 
276 template <int dim>
278  : solution(&solution)
279 {
280  this->use_boundary = true;
281  this->use_face = true;
282  this->add_flags(update_hessians);
283 }
284 
285 template <int dim>
286 void
287 SolutionEstimate<dim>::cell(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
288 {
289  const FEValuesBase<dim>& fe = info.fe_values();
290 
291  const std::vector<Tensor<2, dim>>& DDuh = info.hessians[0][0];
292  for (unsigned k = 0; k < fe.n_quadrature_points; ++k)
293  {
294  const double t = dinfo.cell->diameter() *
295  (trace(DDuh[k]) - solution->laplacian(info.fe_values(0).quadrature_point(k)));
296  dinfo.value(0) += t * t * fe.JxW(k);
297  }
298  dinfo.value(0) = std::sqrt(dinfo.value(0));
299 }
300 
301 template <int dim>
302 void
303 SolutionEstimate<dim>::boundary(DoFInfo<dim>& dinfo, IntegrationInfo<dim>& info) const
304 {
305  const FEValuesBase<dim>& fe = info.fe_values();
306 
307  std::vector<double> boundary_values(fe.n_quadrature_points, 0.);
308  solution->value_list(fe.get_quadrature_points(), boundary_values);
309 
310  const std::vector<double>& uh = info.values[0][0];
311 
312  const unsigned int deg = fe.get_fe().tensor_degree();
313  const double penalty = Laplace::compute_penalty(dinfo, dinfo, deg, deg);
314 
315  for (unsigned k = 0; k < fe.n_quadrature_points; ++k)
316  dinfo.value(0) +=
317  penalty * (boundary_values[k] - uh[k]) * (boundary_values[k] - uh[k]) * fe.JxW(k);
318  dinfo.value(0) = std::sqrt(dinfo.value(0));
319 }
320 
321 template <int dim>
322 void
323 SolutionEstimate<dim>::face(DoFInfo<dim>& dinfo1, DoFInfo<dim>& dinfo2, IntegrationInfo<dim>& info1,
324  IntegrationInfo<dim>& info2) const
325 {
326  const FEValuesBase<dim>& fe = info1.fe_values();
327  const std::vector<double>& uh1 = info1.values[0][0];
328  const std::vector<double>& uh2 = info2.values[0][0];
329  const std::vector<Tensor<1, dim>>& Duh1 = info1.gradients[0][0];
330  const std::vector<Tensor<1, dim>>& Duh2 = info2.gradients[0][0];
331 
332  const unsigned int deg1 = info1.fe_values().get_fe().tensor_degree();
333  const unsigned int deg2 = info2.fe_values().get_fe().tensor_degree();
334  const double penalty = 2. * Laplace::compute_penalty(dinfo1, dinfo2, deg1, deg2);
335 
336  double h;
337  if (dim == 3)
338  h = std::sqrt(dinfo1.face->measure());
339  else
340  h = dinfo1.face->measure();
341 
342  for (unsigned k = 0; k < fe.n_quadrature_points; ++k)
343  {
344  double diff1 = uh1[k] - uh2[k];
345  double diff2 = fe.normal_vector(k) * Duh1[k] - fe.normal_vector(k) * Duh2[k];
346  dinfo1.value(0) += (penalty * diff1 * diff1 + h * diff2 * diff2) * fe.JxW(k);
347  }
348  dinfo1.value(0) = std::sqrt(dinfo1.value(0));
349  dinfo2.value(0) = dinfo1.value(0);
350 }
351 }
352 
353 #endif
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/solution.h:143
Definition: laplace/solution.h:31
SolutionResidual(Function< dim > &solution)
Definition: laplace/solution.h:151
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/solution.h:269
SmartPointer< Function< dim >, SolutionError< dim > > solution
Definition: laplace/solution.h:78
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:237
double timestep
Current timestep if applicable.
Definition: integrator.h:48
Definition: laplace/eigen.h:19
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/solution.h:203
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:303
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:287
Definition: laplace/solution.h:67
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:160
virtual void face(DoFInfo< dim > &dinfo1, DoFInfo< dim > &dinfo2, IntegrationInfo< dim > &info1, IntegrationInfo< dim > &info2) const
Definition: laplace/solution.h:323
SmartPointer< Function< dim >, SolutionRHS< dim > > solution
Definition: laplace/solution.h:42
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:120
std::vector< unsigned int > error_types
Definition: integrator.h:113
SolutionEstimate(Function< dim > &solution)
Definition: laplace/solution.h:277
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
SmartPointer< Function< dim >, SolutionEstimate< dim > > solution
Definition: laplace/solution.h:93
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:182
Definition: laplace/solution.h:52
virtual void cell(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:108
virtual void boundary(DoFInfo< dim > &dinfo, IntegrationInfo< dim > &info) const
Definition: laplace/solution.h:263
void add_flags(const dealii::UpdateFlags flags)
Add update flags on all objects.
Definition: integrator.h:454
SolutionError(Function< dim > &solution)
Definition: laplace/solution.h:226
Definition: integrator.h:29
SmartPointer< Function< dim >, SolutionResidual< dim > > solution
Definition: laplace/solution.h:63
Definition: laplace/solution.h:82