Reference documentation for deal.II version 8.4.2
maxwell.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2010 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__integrators_maxwell_h
17 #define dealii__integrators_maxwell_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/quadrature.h>
23 #include <deal.II/lac/full_matrix.h>
24 #include <deal.II/fe/mapping.h>
25 #include <deal.II/fe/fe_values.h>
26 #include <deal.II/meshworker/dof_info.h>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 namespace LocalIntegrators
31 {
63  namespace Maxwell
64  {
91  template <int dim>
94  const Tensor<2,dim> &h0,
95  const Tensor<2,dim> &h1,
96  const Tensor<2,dim> &h2)
97  {
98  Tensor<1,dim> result;
99  switch (dim)
100  {
101  case 2:
102  result[0] = h1[0][1]-h0[1][1];
103  result[1] = h0[0][1]-h1[0][0];
104  break;
105  case 3:
106  result[0] = h1[0][1]+h2[0][2]-h0[1][1]-h0[2][2];
107  result[1] = h2[1][2]+h0[1][0]-h1[2][2]-h1[0][0];
108  result[2] = h0[2][0]+h1[2][1]-h2[0][0]-h2[1][1];
109  break;
110  default:
111  Assert(false, ExcNotImplemented());
112  }
113  return result;
114  }
115 
129  template <int dim>
132  const Tensor<1,dim> &g0,
133  const Tensor<1,dim> &g1,
134  const Tensor<1,dim> &g2,
135  const Tensor<1,dim> &normal)
136  {
137  Tensor<1,dim> result;
138 
139  switch (dim)
140  {
141  case 2:
142  result[0] = normal[1] * (g1[0]-g0[1]);
143  result[1] =-normal[0] * (g1[0]-g0[1]);
144  break;
145  case 3:
146  result[0] = normal[2]*(g2[1]-g0[2])+normal[1]*(g1[0]-g0[1]);
147  result[1] = normal[0]*(g0[2]-g1[0])+normal[2]*(g2[1]-g1[2]);
148  result[2] = normal[1]*(g1[0]-g2[1])+normal[0]*(g0[2]-g2[0]);
149  break;
150  default:
151  Assert(false, ExcNotImplemented());
152  }
153  return result;
154  }
155 
167  template <int dim>
170  const FEValuesBase<dim> &fe,
171  const double factor = 1.)
172  {
173  const unsigned int n_dofs = fe.dofs_per_cell;
174 
175  AssertDimension(fe.get_fe().n_components(), dim);
176  AssertDimension(M.m(), n_dofs);
177  AssertDimension(M.n(), n_dofs);
178 
179  // Depending on the dimension,
180  // the cross product is either
181  // a scalar (2d) or a vector
182  // (3d). Accordingly, in the
183  // latter case we have to sum
184  // up three bilinear forms, but
185  // in 2d, we don't. Thus, we
186  // need to adapt the loop over
187  // all dimensions
188  const unsigned int d_max = (dim==2) ? 1 : dim;
189 
190  for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
191  {
192  const double dx = factor * fe.JxW(k);
193  for (unsigned int i=0; i<n_dofs; ++i)
194  for (unsigned int j=0; j<n_dofs; ++j)
195  for (unsigned int d=0; d<d_max; ++d)
196  {
197  const unsigned int d1 = (d+1)%dim;
198  const unsigned int d2 = (d+2)%dim;
199 
200  const double cv = fe.shape_grad_component(i,k,d1)[d2] - fe.shape_grad_component(i,k,d2)[d1];
201  const double cu = fe.shape_grad_component(j,k,d1)[d2] - fe.shape_grad_component(j,k,d2)[d1];
202 
203  M(i,j) += dx * cu * cv;
204  }
205  }
206  }
207 
221  template <int dim>
222  void curl_matrix (
224  const FEValuesBase<dim> &fe,
225  const FEValuesBase<dim> &fetest,
226  double factor = 1.)
227  {
228  unsigned int t_comp = (dim==3) ? dim : 1;
229  const unsigned int n_dofs = fe.dofs_per_cell;
230  const unsigned int t_dofs = fetest.dofs_per_cell;
231  AssertDimension(fe.get_fe().n_components(), dim);
232  AssertDimension(fetest.get_fe().n_components(), t_comp);
233  AssertDimension(M.m(), t_dofs);
234  AssertDimension(M.n(), n_dofs);
235 
236  const unsigned int d_max = (dim==2) ? 1 : dim;
237 
238  for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
239  {
240  const double dx = fe.JxW(k) * factor;
241  for (unsigned int i=0; i<t_dofs; ++i)
242  for (unsigned int j=0; j<n_dofs; ++j)
243  for (unsigned int d=0; d<d_max; ++d)
244  {
245  const unsigned int d1 = (d+1)%dim;
246  const unsigned int d2 = (d+2)%dim;
247 
248  const double vv = fetest.shape_value_component(i,k,d);
249  const double cu = fe.shape_grad_component(j,k,d1)[d2] - fe.shape_grad_component(j,k,d2)[d1];
250  M(i,j) += dx * cu * vv;
251  }
252  }
253  }
254 
271  template <int dim>
274  const FEValuesBase<dim> &fe,
275  double penalty,
276  double factor = 1.)
277  {
278  const unsigned int n_dofs = fe.dofs_per_cell;
279 
280  AssertDimension(fe.get_fe().n_components(), dim);
281  AssertDimension(M.m(), n_dofs);
282  AssertDimension(M.n(), n_dofs);
283 
284  // Depending on the
285  // dimension, the cross
286  // product is either a scalar
287  // (2d) or a vector
288  // (3d). Accordingly, in the
289  // latter case we have to sum
290  // up three bilinear forms,
291  // but in 2d, we don't. Thus,
292  // we need to adapt the loop
293  // over all dimensions
294  const unsigned int d_max = (dim==2) ? 1 : dim;
295 
296  for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
297  {
298  const double dx = factor * fe.JxW(k);
299  const Tensor<1,dim> n = fe.normal_vector(k);
300  for (unsigned int i=0; i<n_dofs; ++i)
301  for (unsigned int j=0; j<n_dofs; ++j)
302  for (unsigned int d=0; d<d_max; ++d)
303  {
304  const unsigned int d1 = (d+1)%dim;
305  const unsigned int d2 = (d+2)%dim;
306 
307  const double cv = fe.shape_grad_component(i,k,d1)[d2] - fe.shape_grad_component(i,k,d2)[d1];
308  const double cu = fe.shape_grad_component(j,k,d1)[d2] - fe.shape_grad_component(j,k,d2)[d1];
309  const double v= fe.shape_value_component(i,k,d1)*n(d2) - fe.shape_value_component(i,k,d2)*n(d1);
310  const double u= fe.shape_value_component(j,k,d1)*n(d2) - fe.shape_value_component(j,k,d2)*n(d1);
311 
312  M(i,j) += dx*(2.*penalty*u*v - cv*u - cu*v);
313  }
314  }
315  }
326  template <int dim>
329  const FEValuesBase<dim> &fe,
330  double factor = 1.)
331  {
332  const unsigned int n_dofs = fe.dofs_per_cell;
333 
334  AssertDimension(fe.get_fe().n_components(), dim);
335  AssertDimension(M.m(), n_dofs);
336  AssertDimension(M.n(), n_dofs);
337 
338  // Depending on the
339  // dimension, the cross
340  // product is either a scalar
341  // (2d) or a vector
342  // (3d). Accordingly, in the
343  // latter case we have to sum
344  // up three bilinear forms,
345  // but in 2d, we don't. Thus,
346  // we need to adapt the loop
347  // over all dimensions
348  const unsigned int d_max = (dim==2) ? 1 : dim;
349 
350  for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
351  {
352  const double dx = factor * fe.JxW(k);
353  const Tensor<1,dim> n = fe.normal_vector(k);
354  for (unsigned int i=0; i<n_dofs; ++i)
355  for (unsigned int j=0; j<n_dofs; ++j)
356  for (unsigned int d=0; d<d_max; ++d)
357  {
358  const unsigned int d1 = (d+1)%dim;
359  const unsigned int d2 = (d+2)%dim;
360 
361  const double v= fe.shape_value_component(i,k,d1)*n(d2) - fe.shape_value_component(i,k,d2)*n(d1);
362  const double u= fe.shape_value_component(j,k,d1)*n(d2) - fe.shape_value_component(j,k,d2)*n(d1);
363 
364  M(i,j) += dx*u*v;
365  }
366  }
367  }
368 
384  template <int dim>
385  inline void ip_curl_matrix (
386  FullMatrix<double> &M11,
387  FullMatrix<double> &M12,
388  FullMatrix<double> &M21,
389  FullMatrix<double> &M22,
390  const FEValuesBase<dim> &fe1,
391  const FEValuesBase<dim> &fe2,
392  const double pen,
393  const double factor1 = 1.,
394  const double factor2 = -1.)
395  {
396  const unsigned int n_dofs = fe1.dofs_per_cell;
397 
398  AssertDimension(fe1.get_fe().n_components(), dim);
399  AssertDimension(fe2.get_fe().n_components(), dim);
400  AssertDimension(M11.m(), n_dofs);
401  AssertDimension(M11.n(), n_dofs);
402  AssertDimension(M12.m(), n_dofs);
403  AssertDimension(M12.n(), n_dofs);
404  AssertDimension(M21.m(), n_dofs);
405  AssertDimension(M21.n(), n_dofs);
406  AssertDimension(M22.m(), n_dofs);
407  AssertDimension(M22.n(), n_dofs);
408 
409  const double nu1 = factor1;
410  const double nu2 = (factor2 < 0) ? factor1 : factor2;
411  const double penalty = .5 * pen * (nu1 + nu2);
412 
413  // Depending on the
414  // dimension, the cross
415  // product is either a scalar
416  // (2d) or a vector
417  // (3d). Accordingly, in the
418  // latter case we have to sum
419  // up three bilinear forms,
420  // but in 2d, we don't. Thus,
421  // we need to adapt the loop
422  // over all dimensions
423  const unsigned int d_max = (dim==2) ? 1 : dim;
424 
425  for (unsigned int k=0; k<fe1.n_quadrature_points; ++k)
426  {
427  const double dx = fe1.JxW(k);
428  const Tensor<1,dim> n = fe1.normal_vector(k);
429  for (unsigned int i=0; i<n_dofs; ++i)
430  for (unsigned int j=0; j<n_dofs; ++j)
431  for (unsigned int d=0; d<d_max; ++d)
432  {
433  const unsigned int d1 = (d+1)%dim;
434  const unsigned int d2 = (d+2)%dim;
435  // curl u, curl v
436  const double cv1 = nu1*fe1.shape_grad_component(i,k,d1)[d2] - fe1.shape_grad_component(i,k,d2)[d1];
437  const double cv2 = nu2*fe2.shape_grad_component(i,k,d1)[d2] - fe2.shape_grad_component(i,k,d2)[d1];
438  const double cu1 = nu1*fe1.shape_grad_component(j,k,d1)[d2] - fe1.shape_grad_component(j,k,d2)[d1];
439  const double cu2 = nu2*fe2.shape_grad_component(j,k,d1)[d2] - fe2.shape_grad_component(j,k,d2)[d1];
440 
441  // u x n, v x n
442  const double u1= fe1.shape_value_component(j,k,d1)*n(d2) - fe1.shape_value_component(j,k,d2)*n(d1);
443  const double u2=-fe2.shape_value_component(j,k,d1)*n(d2) + fe2.shape_value_component(j,k,d2)*n(d1);
444  const double v1= fe1.shape_value_component(i,k,d1)*n(d2) - fe1.shape_value_component(i,k,d2)*n(d1);
445  const double v2=-fe2.shape_value_component(i,k,d1)*n(d2) + fe2.shape_value_component(i,k,d2)*n(d1);
446 
447  M11(i,j) += .5*dx*(2.*penalty*u1*v1 - cv1*u1 - cu1*v1);
448  M12(i,j) += .5*dx*(2.*penalty*v1*u2 - cv1*u2 - cu2*v1);
449  M21(i,j) += .5*dx*(2.*penalty*u1*v2 - cv2*u1 - cu1*v2);
450  M22(i,j) += .5*dx*(2.*penalty*u2*v2 - cv2*u2 - cu2*v2);
451  }
452  }
453  }
454 
455 
456  }
457 }
458 
459 
460 DEAL_II_NAMESPACE_CLOSE
461 
462 #endif
size_type m() const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
const unsigned int dofs_per_cell
Definition: fe_values.h:1464
const FiniteElement< dim, spacedim > & get_fe() const
Tensor< 1, dim > curl_curl(const Tensor< 2, dim > &h0, const Tensor< 2, dim > &h1, const Tensor< 2, dim > &h2)
Definition: maxwell.h:93
Tensor< 1, dim > tangential_curl(const Tensor< 1, dim > &g0, const Tensor< 1, dim > &g1, const Tensor< 1, dim > &g2, const Tensor< 1, dim > &normal)
Definition: maxwell.h:131
void tangential_trace_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, double factor=1.)
Definition: maxwell.h:327
double shape_value_component(const unsigned int function_no, const unsigned int point_no, const unsigned int component) const
Library of integrals over cells and faces.
Definition: advection.h:30
void curl_curl_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const double factor=1.)
Definition: maxwell.h:168
size_type n() const
#define Assert(cond, exc)
Definition: exceptions.h:294
void curl_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, double factor=1.)
Definition: maxwell.h:222
const unsigned int n_quadrature_points
Definition: fe_values.h:1457
void ip_curl_matrix(FullMatrix< double > &M11, FullMatrix< double > &M12, FullMatrix< double > &M21, FullMatrix< double > &M22, const FEValuesBase< dim > &fe1, const FEValuesBase< dim > &fe2, const double pen, const double factor1=1., const double factor2=-1.)
Definition: maxwell.h:385
double JxW(const unsigned int quadrature_point) const
void nitsche_curl_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, double penalty, double factor=1.)
Definition: maxwell.h:272
const Tensor< 1, spacedim > & normal_vector(const unsigned int i) const
Tensor< 1, spacedim > shape_grad_component(const unsigned int function_no, const unsigned int point_no, const unsigned int component) const