Reference documentation for deal.II version 8.4.2
operators.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 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 
17 #ifndef dealii__matrix_free_operators_h
18 #define dealii__matrix_free_operators_h
19 
20 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/vectorization.h>
23 
24 #include <deal.II/matrix_free/fe_evaluation.h>
25 
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 
30 namespace MatrixFreeOperators
31 {
51  template <int dim, int fe_degree, int n_components = 1, typename Number = double>
53  {
54  public:
60 
69  void apply(const AlignedVector<VectorizedArray<Number> > &inverse_coefficient,
70  const unsigned int n_actual_components,
71  const VectorizedArray<Number> *in_array,
72  VectorizedArray<Number> *out_array) const;
73 
80 
81  private:
86 
91  };
92 
93 
94 
95  // ------------------------------------ inline functions ---------------------
96 
97  template <int dim, int fe_degree, int n_components, typename Number>
98  inline
101  :
102  fe_eval (fe_eval)
103  {
104  FullMatrix<double> shapes_1d(fe_degree+1, fe_degree+1);
105  for (unsigned int i=0, c=0; i<shapes_1d.m(); ++i)
106  for (unsigned int j=0; j<shapes_1d.n(); ++j, ++c)
107  shapes_1d(i,j) = fe_eval.get_shape_info().shape_values_number[c];
108  shapes_1d.gauss_jordan();
109  const unsigned int stride = (fe_degree+2)/2;
110  inverse_shape.resize(stride*(fe_degree+1));
111  for (unsigned int i=0; i<stride; ++i)
112  for (unsigned int q=0; q<(fe_degree+2)/2; ++q)
113  {
114  inverse_shape[i*stride+q] =
115  0.5 * (shapes_1d(i,q) + shapes_1d(i,fe_degree-q));
116  inverse_shape[(fe_degree-i)*stride+q] =
117  0.5 * (shapes_1d(i,q) - shapes_1d(i,fe_degree-q));
118  }
119  if (fe_degree % 2 == 0)
120  for (unsigned int q=0; q<(fe_degree+2)/2; ++q)
121  inverse_shape[fe_degree/2*stride+q] = shapes_1d(fe_degree/2,q);
122  }
123 
124 
125 
126  template <int dim, int fe_degree, int n_components, typename Number>
127  inline
128  void
131  {
132  const unsigned int dofs_per_cell = Utilities::fixed_int_power<fe_degree+1,dim>::value;
133  Assert(inverse_jxw.size() > 0 &&
134  inverse_jxw.size() % dofs_per_cell == 0,
135  ExcMessage("Expected diagonal to be a multiple of scalar dof per cells"));
136 
137  // temporarily reduce size of inverse_jxw to dofs_per_cell to get JxW values
138  // from fe_eval (will not reallocate any memory)
139  const unsigned int previous_size = inverse_jxw.size();
140  inverse_jxw.resize(dofs_per_cell);
141  fe_eval.fill_JxW_values(inverse_jxw);
142 
143  // invert
144  inverse_jxw.resize_fast(previous_size);
145  for (unsigned int q=0; q<dofs_per_cell; ++q)
146  inverse_jxw[q] = 1./inverse_jxw[q];
147  // copy values to rest of vector
148  for (unsigned int q=dofs_per_cell; q<previous_size; )
149  for (unsigned int i=0; i<dofs_per_cell; ++i, ++q)
150  inverse_jxw[q] = inverse_jxw[i];
151  }
152 
153 
154 
155  template <int dim, int fe_degree, int n_components, typename Number>
156  inline
157  void
159  ::apply(const AlignedVector<VectorizedArray<Number> > &inverse_coefficients,
160  const unsigned int n_actual_components,
161  const VectorizedArray<Number> *in_array,
162  VectorizedArray<Number> *out_array) const
163  {
164  const unsigned int dofs_per_cell = Utilities::fixed_int_power<fe_degree+1,dim>::value;
165  Assert(inverse_coefficients.size() > 0 &&
166  inverse_coefficients.size() % dofs_per_cell == 0,
167  ExcMessage("Expected diagonal to be a multiple of scalar dof per cells"));
168  if (inverse_coefficients.size() != dofs_per_cell)
169  AssertDimension(n_actual_components * dofs_per_cell, inverse_coefficients.size());
170 
171  Assert(dim == 2 || dim == 3, ExcNotImplemented());
172 
173  internal::EvaluatorTensorProduct<internal::evaluate_evenodd,dim,fe_degree,
174  fe_degree+1, VectorizedArray<Number> >
176 
177  const unsigned int shift_coefficient =
178  inverse_coefficients.size() > dofs_per_cell ? dofs_per_cell : 0;
179  const VectorizedArray<Number> *inv_coefficient = &inverse_coefficients[0];
180  VectorizedArray<Number> temp_data_field[dofs_per_cell];
181  for (unsigned int d=0; d<n_actual_components; ++d)
182  {
183  const VectorizedArray<Number> *in = in_array+d*dofs_per_cell;
184  VectorizedArray<Number> *out = out_array+d*dofs_per_cell;
185  // Need to select 'apply' method with hessian slot because values
186  // assume symmetries that do not exist in the inverse shapes
187  evaluator.template hessians<0,false,false> (in, temp_data_field);
188  evaluator.template hessians<1,false,false> (temp_data_field, out);
189 
190  if (dim == 3)
191  {
192  evaluator.template hessians<2,false,false> (out, temp_data_field);
193  for (unsigned int q=0; q<dofs_per_cell; ++q)
194  temp_data_field[q] *= inv_coefficient[q];
195  evaluator.template hessians<2,true,false> (temp_data_field, out);
196  }
197  else if (dim == 2)
198  for (unsigned int q=0; q<dofs_per_cell; ++q)
199  out[q] *= inv_coefficient[q];
200 
201  evaluator.template hessians<1,true,false>(out, temp_data_field);
202  evaluator.template hessians<0,true,false>(temp_data_field, out);
203 
204  inv_coefficient += shift_coefficient;
205  }
206  }
207 
208 } // end of namespace MatrixFreeOperators
209 
210 
211 DEAL_II_NAMESPACE_CLOSE
212 
213 #endif
size_type m() const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
void apply(const AlignedVector< VectorizedArray< Number > > &inverse_coefficient, const unsigned int n_actual_components, const VectorizedArray< Number > *in_array, VectorizedArray< Number > *out_array) const
Definition: operators.h:159
void gauss_jordan()
::ExceptionBase & ExcMessage(std::string arg1)
const FEEvaluationBase< dim, n_components, Number > & fe_eval
Definition: operators.h:85
void fill_JxW_values(AlignedVector< VectorizedArray< Number > > &JxW_values) const
size_type n() const
#define Assert(cond, exc)
Definition: exceptions.h:294
void resize(const size_type size_in, const T &init=T())
AlignedVector< VectorizedArray< Number > > inverse_shape
Definition: operators.h:90
CellwiseInverseMassMatrix(const FEEvaluationBase< dim, n_components, Number > &fe_eval)
Definition: operators.h:100
void fill_inverse_JxW_values(AlignedVector< VectorizedArray< Number > > &inverse_jxw) const
Definition: operators.h:130
const internal::MatrixFreeFunctions::ShapeInfo< Number > & get_shape_info() const