Amandus: Simulations based on multilevel Schwarz methods
brinkman/matrix.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 __brinkman_matrix_h
10 #define __brinkman_matrix_h
11 
12 #include <deal.II/integrators/divergence.h>
13 #include <deal.II/integrators/elasticity.h>
14 #include <deal.II/integrators/elasticity.h>
15 #include <deal.II/integrators/l2.h>
16 #include <deal.II/integrators/laplace.h>
17 
18 #include <amandus/brinkman/parameters.h>
19 #include <amandus/integrator.h>
20 
21 using namespace dealii;
22 using namespace dealii::LocalIntegrators;
23 
24 namespace Brinkman
25 {
33 template <int dim>
34 void
35 tangential_friction(FullMatrix<double>& M, const FEValuesBase<dim>& int_fe,
36  double friction_coefficient)
37 {
38  const unsigned int n_dofs = int_fe.dofs_per_cell;
39  const unsigned int n_comp = int_fe.get_fe().n_components();
40 
41  AssertDimension(M.m(), n_dofs);
42  AssertDimension(M.n(), n_dofs);
43  AssertDimension(n_comp, dim);
44 
45  Tensor<1, dim> aux1;
46  Tensor<1, dim> aux2;
47 
48  const double factor = friction_coefficient;
49 
50  for (unsigned k = 0; k < int_fe.n_quadrature_points; ++k)
51  {
52  const double dx = int_fe.JxW(k) * factor;
53  const Tensor<1, dim> n = int_fe.normal_vector(k);
54  if (dim == 2)
55  aux1 = cross_product_2d(n);
56 
57  for (unsigned i = 0; i < n_dofs; ++i)
58  {
59  for (unsigned j = 0; j < n_dofs; ++j)
60  {
61  if (dim == 2)
62  for (unsigned int d = 0; d < n_comp; ++d)
63  M(i, j) += dx * aux1[d] * int_fe.shape_value_component(i, k, d) * aux1[d] *
64  int_fe.shape_value_component(j, k, d);
65  else if (dim == 3)
66  {
67  Tensor<1, dim> u;
68  for (unsigned int d = 0; d < dim; ++d)
69  u[d] = int_fe.shape_value_component(i, k, d);
70  aux1 = cross_product_3d(u, n);
71  for (unsigned int d = 0; d < dim; ++d)
72  u[d] = int_fe.shape_value_component(j, k, d);
73  aux2 = cross_product_3d(u, n);
74  M(i, j) += dx * (aux1 * aux2);
75  }
76  else
77  {
78  Assert(false, ExcNotImplemented());
79  }
80  }
81  }
82  }
83 }
84 
90 template <int dim>
91 class Matrix : public AmandusIntegrator<dim>
92 {
93 public:
99  Matrix(const Parameters& par);
100 
101  void cell(MeshWorker::DoFInfo<dim>& dinfo, typename MeshWorker::IntegrationInfo<dim>& info) const;
102  void boundary(MeshWorker::DoFInfo<dim>& dinfo,
103  typename MeshWorker::IntegrationInfo<dim>& info) const;
104  void face(MeshWorker::DoFInfo<dim>& dinfo1, MeshWorker::DoFInfo<dim>& dinfo2,
105  typename MeshWorker::IntegrationInfo<dim>& info1,
106  typename MeshWorker::IntegrationInfo<dim>& info2) const;
107 
108  void cell_error(MeshWorker::DoFInfo<dim>& dinfo, typename MeshWorker::IntegrationInfo<dim>& info);
109 
110 private:
111  dealii::SmartPointer<const Parameters, Matrix<dim>> parameters;
112 };
113 
114 template <int dim>
116  : parameters(&par)
117 {
118 }
119 
120 template <int dim>
121 void
122 Matrix<dim>::cell(MeshWorker::DoFInfo<dim>& dinfo,
123  typename MeshWorker::IntegrationInfo<dim>& info) const
124 {
125  AssertDimension(dinfo.n_matrices(), 4);
126  const unsigned int id = dinfo.cell->material_id();
127  // deallog << id;
128 
129  // a(u,v)
131  dinfo.matrix(0, false).matrix, info.fe_values(0), parameters->viscosity[id]);
132  L2::mass_matrix(dinfo.matrix(0, false).matrix, info.fe_values(0), parameters->resistance[id]);
133  Divergence::grad_div_matrix(
134  dinfo.matrix(0, false).matrix, info.fe_values(0), parameters->graddiv_stabilization[id]);
135  // b(u,q)
136  Divergence::cell_matrix(dinfo.matrix(2, false).matrix, info.fe_values(0), info.fe_values(1));
137  dinfo.matrix(1, false).matrix.copy_transposed(dinfo.matrix(2, false).matrix);
138 }
139 
140 template <int dim>
141 void
142 Matrix<dim>::boundary(MeshWorker::DoFInfo<dim>& dinfo,
143  typename MeshWorker::IntegrationInfo<dim>& info) const
144 {
145  const unsigned int id = dinfo.cell->material_id();
146  const unsigned int deg = info.fe_values(0).get_fe().tensor_degree();
147  // Elasticity::nitsche_matrix(dinfo.matrix(0,false).matrix, info.fe_values(0),
148  // Laplace::compute_penalty(dinfo, dinfo, deg, deg),
149  // parameters->viscosity[id]);
150 }
151 
152 template <int dim>
153 void
154 Matrix<dim>::face(MeshWorker::DoFInfo<dim>& dinfo1, MeshWorker::DoFInfo<dim>& dinfo2,
155  typename MeshWorker::IntegrationInfo<dim>& info1,
156  typename MeshWorker::IntegrationInfo<dim>& info2) const
157 {
158  const unsigned int id1 = dinfo1.cell->material_id();
159  const unsigned int id2 = dinfo2.cell->material_id();
160  // Here we need to implement
161  // different forms depending on
162  // whether we are in the Stokes
163  // region (interior penalty), Darcy
164  // region (zero) or at the
165  // interface (Beavers-Joseph-Saffman)
166  const unsigned int deg = info1.fe_values(0).get_fe().tensor_degree();
167 
168  if (parameters->viscosity[id1] != 0. && parameters->viscosity[id2] != 0.)
169  Elasticity::ip_matrix(dinfo1.matrix(0, false).matrix,
170  dinfo1.matrix(0, true).matrix,
171  dinfo2.matrix(0, true).matrix,
172  dinfo2.matrix(0, false).matrix,
173  info1.fe_values(0),
174  info2.fe_values(0),
175  Laplace::compute_penalty(dinfo1, dinfo2, deg, deg),
176  parameters->viscosity[id1],
177  parameters->viscosity[id2]);
178 
179  if (parameters->viscosity[id1] != 0. && parameters->viscosity[id2] == 0.)
180  tangential_friction(dinfo1.matrix(0, false).matrix,
181  info1.fe_values(0),
182  parameters->saffman * std::sqrt(parameters->resistance[id2]));
183 
184  if (parameters->viscosity[id1] == 0. && parameters->viscosity[id2] != 0.)
185  tangential_friction(dinfo2.matrix(0, false).matrix,
186  info2.fe_values(0),
187  parameters->saffman * std::sqrt(parameters->resistance[id1]));
188 }
189 }
190 
191 #endif
void tangential_friction(FullMatrix< double > &M, const FEValuesBase< dim > &int_fe, double friction_coefficient)
Definition: brinkman/matrix.h:35
void cell_matrix(dealii::FullMatrix< double > &M, 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: matrix_integrators.h:23
dealii::SmartPointer< const Parameters, Matrix< dim > > parameters
Definition: brinkman/matrix.h:111
Definition: brinkman/parameters.h:51
void boundary(MeshWorker::DoFInfo< dim > &dinfo, typename MeshWorker::IntegrationInfo< dim > &info) const
Definition: brinkman/matrix.h:142
Definition: brinkman/matrix.h:91
void face(MeshWorker::DoFInfo< dim > &dinfo1, MeshWorker::DoFInfo< dim > &dinfo2, typename MeshWorker::IntegrationInfo< dim > &info1, typename MeshWorker::IntegrationInfo< dim > &info2) const
Definition: brinkman/matrix.h:154
Definition: brinkman/matrix.h:24
void cell(MeshWorker::DoFInfo< dim > &dinfo, typename MeshWorker::IntegrationInfo< dim > &info) const
Definition: brinkman/matrix.h:122
Definition: integrator.h:29