Reference documentation for deal.II version 9.0.0
fe_values.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 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 #include <deal.II/base/array_view.h>
17 #include <deal.II/base/memory_consumption.h>
18 #include <deal.II/base/multithread_info.h>
19 #include <deal.II/base/numbers.h>
20 #include <deal.II/base/quadrature.h>
21 #include <deal.II/base/signaling_nan.h>
22 #include <deal.II/base/std_cxx14/memory.h>
23 #include <deal.II/differentiation/ad.h>
24 #include <deal.II/lac/vector.h>
25 #include <deal.II/lac/block_vector.h>
26 #include <deal.II/lac/la_vector.h>
27 #include <deal.II/lac/la_parallel_vector.h>
28 #include <deal.II/lac/la_parallel_block_vector.h>
29 #include <deal.II/lac/vector_element_access.h>
30 #include <deal.II/lac/petsc_parallel_vector.h>
31 #include <deal.II/lac/petsc_parallel_block_vector.h>
32 #include <deal.II/lac/trilinos_vector.h>
33 #include <deal.II/lac/trilinos_parallel_block_vector.h>
34 #include <deal.II/grid/tria_iterator.h>
35 #include <deal.II/grid/tria_accessor.h>
36 #include <deal.II/grid/tria_boundary.h>
37 #include <deal.II/dofs/dof_accessor.h>
38 #include <deal.II/fe/mapping_q1.h>
39 #include <deal.II/fe/fe_values.h>
40 #include <deal.II/fe/fe.h>
41 
42 #include <iomanip>
43 #include <type_traits>
44 
45 
46 #include <boost/container/small_vector.hpp>
47 
48 DEAL_II_NAMESPACE_OPEN
49 
50 
51 namespace internal
52 {
53  template <class VectorType>
54  typename VectorType::value_type
55  inline
56  get_vector_element (const VectorType &vector,
57  const types::global_dof_index cell_number)
58  {
59  return internal::ElementAccess<VectorType>::get(vector,cell_number);
60  }
61 
62 
63 
65  inline
66  get_vector_element (const IndexSet &is,
67  const types::global_dof_index cell_number)
68  {
69  return (is.is_element(cell_number) ? 1 : 0);
70  }
71 
72 
73 
74  template <int dim, int spacedim>
75  inline
76  std::vector<unsigned int>
77  make_shape_function_to_row_table (const FiniteElement<dim,spacedim> &fe)
78  {
79  std::vector<unsigned int> shape_function_to_row_table (fe.dofs_per_cell * fe.n_components(),
81  unsigned int row = 0;
82  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
83  {
84  // loop over all components that are nonzero for this particular
85  // shape function. if a component is zero then we leave the
86  // value in the table unchanged (at the invalid value)
87  // otherwise it is mapped to the next free entry
88  unsigned int nth_nonzero_component = 0;
89  for (unsigned int c=0; c<fe.n_components(); ++c)
90  if (fe.get_nonzero_components(i)[c] == true)
91  {
92  shape_function_to_row_table[i*fe.n_components()+c] = row + nth_nonzero_component;
93  ++nth_nonzero_component;
94  }
95  row += fe.n_nonzero_components (i);
96  }
97 
98  return shape_function_to_row_table;
99  }
100 
101  namespace
102  {
103  // Check to see if a DoF value is zero, implying that subsequent operations
104  // with the value have no effect.
105  template <typename Number, typename T = void>
106  struct CheckForZero
107  {
108  static bool
109  value (const Number &value)
110  {
111  return value == ::internal::NumberType<Number>::value(0.0);
112  }
113  };
114 
115  // For auto-differentiable numbers, the fact that a DoF value is zero
116  // does not imply that its derivatives are zero as well. So we
117  // can't filter by value for these number types.
118  // Note that we also want to avoid actually checking the value itself,
119  // since some AD numbers are not contextually convertible to booleans.
120  template <typename Number>
121  struct CheckForZero<Number, typename std::enable_if<Differentiation::AD::is_ad_number<Number>::value>::type>
122  {
123  static bool
124  value (const Number &/*value*/)
125  {
126  return false;
127  }
128  };
129  }
130 }
131 
132 
133 
134 namespace FEValuesViews
135 {
136  template <int dim, int spacedim>
138  const unsigned int component)
139  :
140  fe_values (&fe_values),
141  component (component),
142  shape_function_data (this->fe_values->fe->dofs_per_cell)
143  {
144  const FiniteElement<dim, spacedim> &fe = *this->fe_values->fe;
145  Assert (component < fe.n_components(),
147 
148 //TODO: we'd like to use the fields with the same name as these
149 // variables from FEValuesBase, but they aren't initialized yet
150 // at the time we get here, so re-create it all
151  const std::vector<unsigned int> shape_function_to_row_table
152  = ::internal::make_shape_function_to_row_table (fe);
153 
154  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
155  {
156  const bool is_primitive = fe.is_primitive() || fe.is_primitive(i);
157 
158  if (is_primitive == true)
159  shape_function_data[i].is_nonzero_shape_function_component
160  = (component ==
161  fe.system_to_component_index(i).first);
162  else
163  shape_function_data[i].is_nonzero_shape_function_component
165  == true);
166 
167  if (shape_function_data[i].is_nonzero_shape_function_component == true)
168  shape_function_data[i].row_index
169  = shape_function_to_row_table[i*fe.n_components()+component];
170  else
172  }
173  }
174 
175 
176 
177  template <int dim, int spacedim>
179  :
180  fe_values (nullptr),
181  component (numbers::invalid_unsigned_int)
182  {}
183 
184 
185 
186  template <int dim, int spacedim>
189  {
190  // we shouldn't be copying these objects
191  Assert (false, ExcInternalError());
192  return *this;
193  }
194 
195 
196 
197  template <int dim, int spacedim>
199  const unsigned int first_vector_component)
200  :
201  fe_values (&fe_values),
202  first_vector_component (first_vector_component),
203  shape_function_data (this->fe_values->fe->dofs_per_cell)
204  {
205  const FiniteElement<dim, spacedim> &fe = *this->fe_values->fe;
206  Assert (first_vector_component+spacedim-1 < fe.n_components(),
208  fe.n_components()));
209 
210 //TODO: we'd like to use the fields with the same name as these
211 // variables from FEValuesBase, but they aren't initialized yet
212 // at the time we get here, so re-create it all
213  const std::vector<unsigned int> shape_function_to_row_table
214  = ::internal::make_shape_function_to_row_table (fe);
215 
216  for (unsigned int d=0; d<spacedim; ++d)
217  {
218  const unsigned int component = first_vector_component + d;
219 
220  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
221  {
222  const bool is_primitive = fe.is_primitive() || fe.is_primitive(i);
223 
224  if (is_primitive == true)
225  shape_function_data[i].is_nonzero_shape_function_component[d]
226  = (component ==
227  fe.system_to_component_index(i).first);
228  else
229  shape_function_data[i].is_nonzero_shape_function_component[d]
230  = (fe.get_nonzero_components(i)[component]
231  == true);
232 
233  if (shape_function_data[i].is_nonzero_shape_function_component[d]
234  == true)
235  shape_function_data[i].row_index[d]
236  = shape_function_to_row_table[i*fe.n_components()+component];
237  else
238  shape_function_data[i].row_index[d]
240  }
241  }
242 
243  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
244  {
245  unsigned int n_nonzero_components = 0;
246  for (unsigned int d=0; d<spacedim; ++d)
247  if (shape_function_data[i].is_nonzero_shape_function_component[d]
248  == true)
249  ++n_nonzero_components;
250 
251  if (n_nonzero_components == 0)
252  shape_function_data[i].single_nonzero_component = -2;
253  else if (n_nonzero_components > 1)
254  shape_function_data[i].single_nonzero_component = -1;
255  else
256  {
257  for (unsigned int d=0; d<spacedim; ++d)
258  if (shape_function_data[i].is_nonzero_shape_function_component[d]
259  == true)
260  {
261  shape_function_data[i].single_nonzero_component
262  = shape_function_data[i].row_index[d];
263  shape_function_data[i].single_nonzero_component_index
264  = d;
265  break;
266  }
267  }
268  }
269  }
270 
271 
272 
273  template <int dim, int spacedim>
275  :
276  fe_values (nullptr),
277  first_vector_component (numbers::invalid_unsigned_int)
278  {}
279 
280 
281 
282  template <int dim, int spacedim>
285  {
286  // we shouldn't be copying these objects
287  Assert (false, ExcInternalError());
288  return *this;
289  }
290 
291 
292 
293  template <int dim, int spacedim>
296  const unsigned int first_tensor_component)
297  :
298  fe_values(&fe_values),
299  first_tensor_component(first_tensor_component),
300  shape_function_data(this->fe_values->fe->dofs_per_cell)
301  {
302  const FiniteElement<dim, spacedim> &fe = *this->fe_values->fe;
303  Assert(first_tensor_component + (dim*dim+dim)/2 - 1
304  <
305  fe.n_components(),
306  ExcIndexRange(first_tensor_component +
308  0,
309  fe.n_components()));
310 //TODO: we'd like to use the fields with the same name as these
311 // variables from FEValuesBase, but they aren't initialized yet
312 // at the time we get here, so re-create it all
313  const std::vector<unsigned int> shape_function_to_row_table
314  = ::internal::make_shape_function_to_row_table (fe);
315 
316  for (unsigned int d = 0; d < ::SymmetricTensor<2,dim>::n_independent_components; ++d)
317  {
318  const unsigned int component = first_tensor_component + d;
319 
320  for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
321  {
322  const bool is_primitive = fe.is_primitive() || fe.is_primitive(i);
323 
324  if (is_primitive == true)
325  shape_function_data[i].is_nonzero_shape_function_component[d]
326  = (component ==
327  fe.system_to_component_index(i).first);
328  else
329  shape_function_data[i].is_nonzero_shape_function_component[d]
330  = (fe.get_nonzero_components(i)[component]
331  == true);
332 
333  if (shape_function_data[i].is_nonzero_shape_function_component[d]
334  == true)
335  shape_function_data[i].row_index[d]
336  = shape_function_to_row_table[i*fe.n_components()+component];
337  else
338  shape_function_data[i].row_index[d]
340  }
341  }
342 
343  for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
344  {
345  unsigned int n_nonzero_components = 0;
346  for (unsigned int d = 0; d < ::SymmetricTensor<2,dim>::n_independent_components; ++d)
347  if (shape_function_data[i].is_nonzero_shape_function_component[d]
348  == true)
349  ++n_nonzero_components;
350 
351  if (n_nonzero_components == 0)
352  shape_function_data[i].single_nonzero_component = -2;
353  else if (n_nonzero_components > 1)
354  shape_function_data[i].single_nonzero_component = -1;
355  else
356  {
357  for (unsigned int d = 0; d < ::SymmetricTensor<2,dim>::n_independent_components; ++d)
358  if (shape_function_data[i].is_nonzero_shape_function_component[d]
359  == true)
360  {
361  shape_function_data[i].single_nonzero_component
362  = shape_function_data[i].row_index[d];
363  shape_function_data[i].single_nonzero_component_index
364  = d;
365  break;
366  }
367  }
368  }
369  }
370 
371 
372 
373  template <int dim, int spacedim>
375  :
376  fe_values(nullptr),
377  first_tensor_component(numbers::invalid_unsigned_int)
378  {}
379 
380 
381 
382  template <int dim, int spacedim>
385  {
386  // we shouldn't be copying these objects
387  Assert(false, ExcInternalError());
388  return *this;
389  }
390 
391 
392 
393  template <int dim, int spacedim>
396  const unsigned int first_tensor_component)
397  :
398  fe_values(&fe_values),
399  first_tensor_component(first_tensor_component),
400  shape_function_data(this->fe_values->fe->dofs_per_cell)
401  {
402  const FiniteElement<dim, spacedim> &fe = *this->fe_values->fe;
403  Assert(first_tensor_component + dim*dim - 1
404  <
405  fe.n_components(),
406  ExcIndexRange(first_tensor_component +
407  dim*dim - 1,
408  0,
409  fe.n_components()));
410 //TODO: we'd like to use the fields with the same name as these
411 // variables from FEValuesBase, but they aren't initialized yet
412 // at the time we get here, so re-create it all
413  const std::vector<unsigned int> shape_function_to_row_table
414  = ::internal::make_shape_function_to_row_table (fe);
415 
416  for (unsigned int d = 0; d < dim*dim; ++d)
417  {
418  const unsigned int component = first_tensor_component + d;
419 
420  for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
421  {
422  const bool is_primitive = fe.is_primitive() || fe.is_primitive(i);
423 
424  if (is_primitive == true)
425  shape_function_data[i].is_nonzero_shape_function_component[d]
426  = (component ==
427  fe.system_to_component_index(i).first);
428  else
429  shape_function_data[i].is_nonzero_shape_function_component[d]
430  = (fe.get_nonzero_components(i)[component]
431  == true);
432 
433  if (shape_function_data[i].is_nonzero_shape_function_component[d]
434  == true)
435  shape_function_data[i].row_index[d]
436  = shape_function_to_row_table[i*fe.n_components()+component];
437  else
438  shape_function_data[i].row_index[d]
440  }
441  }
442 
443  for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
444  {
445  unsigned int n_nonzero_components = 0;
446  for (unsigned int d = 0; d < dim*dim; ++d)
447  if (shape_function_data[i].is_nonzero_shape_function_component[d]
448  == true)
449  ++n_nonzero_components;
450 
451  if (n_nonzero_components == 0)
452  shape_function_data[i].single_nonzero_component = -2;
453  else if (n_nonzero_components > 1)
454  shape_function_data[i].single_nonzero_component = -1;
455  else
456  {
457  for (unsigned int d = 0; d < dim*dim; ++d)
458  if (shape_function_data[i].is_nonzero_shape_function_component[d]
459  == true)
460  {
461  shape_function_data[i].single_nonzero_component
462  = shape_function_data[i].row_index[d];
463  shape_function_data[i].single_nonzero_component_index
464  = d;
465  break;
466  }
467  }
468  }
469  }
470 
471 
472 
473  template <int dim, int spacedim>
475  :
476  fe_values(nullptr),
477  first_tensor_component(numbers::invalid_unsigned_int)
478  {}
479 
480 
481 
482  template <int dim, int spacedim>
485  {
486  // we shouldn't be copying these objects
487  Assert(false, ExcInternalError());
488  return *this;
489  }
490 
491 
492 
493  namespace internal
494  {
495  // Given values of degrees of freedom, evaluate the
496  // values/gradients/... at quadrature points
497 
498  // ------------------------- scalar functions --------------------------
499  template <int dim, int spacedim, typename Number>
500  void
501  do_function_values (const ArrayView<Number> &dof_values,
502  const Table<2,double> &shape_values,
503  const std::vector<typename Scalar<dim,spacedim>::ShapeFunctionData> &shape_function_data,
504  std::vector<typename ProductType<Number,double>::type> &values)
505  {
506  const unsigned int dofs_per_cell = dof_values.size();
507  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
508  shape_values.n_cols() : values.size();
509  AssertDimension (values.size(), n_quadrature_points);
510 
511  std::fill (values.begin(), values.end(),
513 
514  for (unsigned int shape_function=0;
515  shape_function<dofs_per_cell; ++shape_function)
516  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
517  {
518  const Number &value = dof_values[shape_function];
519  // For auto-differentiable numbers, the fact that a DoF value is zero
520  // does not imply that its derivatives are zero as well. So we
521  // can't filter by value for these number types.
522  if (::internal::CheckForZero<Number>::value(value) == true)
523  continue;
524 
525  const double *shape_value_ptr =
526  &shape_values(shape_function_data[shape_function].row_index, 0);
527  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
528  values[q_point] += value * (*shape_value_ptr++);
529  }
530  }
531 
532 
533 
534  // same code for gradient and Hessian, template argument 'order' to give
535  // the order of the derivative (= rank of gradient/Hessian tensor)
536  template <int order, int dim, int spacedim, typename Number>
537  void
538  do_function_derivatives (const ArrayView<Number> &dof_values,
539  const Table<2,::Tensor<order,spacedim> > &shape_derivatives,
540  const std::vector<typename Scalar<dim,spacedim>::ShapeFunctionData> &shape_function_data,
541  std::vector<typename ProductType<Number,::Tensor<order,spacedim> >::type> &derivatives)
542  {
543  const unsigned int dofs_per_cell = dof_values.size();
544  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
545  shape_derivatives[0].size() : derivatives.size();
546  AssertDimension (derivatives.size(), n_quadrature_points);
547 
548  std::fill (derivatives.begin(), derivatives.end(),
550 
551  for (unsigned int shape_function=0;
552  shape_function<dofs_per_cell; ++shape_function)
553  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
554  {
555  const Number &value = dof_values[shape_function];
556  // For auto-differentiable numbers, the fact that a DoF value is zero
557  // does not imply that its derivatives are zero as well. So we
558  // can't filter by value for these number types.
559  if (::internal::CheckForZero<Number>::value(value) == true)
560  continue;
561 
562  const ::Tensor<order,spacedim> *shape_derivative_ptr =
563  &shape_derivatives[shape_function_data[shape_function].row_index][0];
564  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
565  derivatives[q_point] += value * (*shape_derivative_ptr++);
566  }
567  }
568 
569 
570 
571  template <int dim, int spacedim, typename Number>
572  void
573  do_function_laplacians (const ArrayView<Number> &dof_values,
574  const Table<2,::Tensor<2,spacedim> > &shape_hessians,
575  const std::vector<typename Scalar<dim,spacedim>::ShapeFunctionData> &shape_function_data,
576  std::vector<typename Scalar<dim,spacedim>::template OutputType<Number>::laplacian_type> &laplacians)
577  {
578  const unsigned int dofs_per_cell = dof_values.size();
579  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
580  shape_hessians[0].size() : laplacians.size();
581  AssertDimension (laplacians.size(), n_quadrature_points);
582 
583  std::fill (laplacians.begin(), laplacians.end(),
584  typename Scalar<dim,spacedim>::template OutputType<Number>::laplacian_type());
585 
586  for (unsigned int shape_function=0;
587  shape_function<dofs_per_cell; ++shape_function)
588  if (shape_function_data[shape_function].is_nonzero_shape_function_component)
589  {
590  const Number &value = dof_values[shape_function];
591  // For auto-differentiable numbers, the fact that a DoF value is zero
592  // does not imply that its derivatives are zero as well. So we
593  // can't filter by value for these number types.
594  if (::internal::CheckForZero<Number>::value(value) == true)
595  continue;
596 
597  const ::Tensor<2,spacedim> *shape_hessian_ptr =
598  &shape_hessians[shape_function_data[shape_function].row_index][0];
599  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
600  laplacians[q_point] += value * trace(*shape_hessian_ptr++);
601  }
602  }
603 
604 
605 
606  // ----------------------------- vector part ---------------------------
607 
608  template <int dim, int spacedim, typename Number>
609  void do_function_values (const ArrayView<Number> &dof_values,
610  const Table<2,double> &shape_values,
611  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
612  std::vector<typename ProductType<Number,::Tensor<1,spacedim> >::type> &values)
613  {
614  const unsigned int dofs_per_cell = dof_values.size();
615  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
616  shape_values.n_cols() : values.size();
617  AssertDimension (values.size(), n_quadrature_points);
618 
619  std::fill (values.begin(), values.end(),
620  typename ProductType<Number,::Tensor<1,spacedim> >::type());
621 
622  for (unsigned int shape_function=0;
623  shape_function<dofs_per_cell; ++shape_function)
624  {
625  const int snc = shape_function_data[shape_function].single_nonzero_component;
626 
627  if (snc == -2)
628  // shape function is zero for the selected components
629  continue;
630 
631  const Number &value = dof_values[shape_function];
632  // For auto-differentiable numbers, the fact that a DoF value is zero
633  // does not imply that its derivatives are zero as well. So we
634  // can't filter by value for these number types.
635  if (::internal::CheckForZero<Number>::value(value) == true)
636  continue;
637 
638  if (snc != -1)
639  {
640  const unsigned int comp =
641  shape_function_data[shape_function].single_nonzero_component_index;
642  const double *shape_value_ptr = &shape_values(snc,0);
643  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
644  values[q_point][comp] += value * (*shape_value_ptr++);
645  }
646  else
647  for (unsigned int d=0; d<spacedim; ++d)
648  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
649  {
650  const double *shape_value_ptr =
651  &shape_values(shape_function_data[shape_function].row_index[d],0);
652  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
653  values[q_point][d] += value * (*shape_value_ptr++);
654  }
655  }
656  }
657 
658 
659 
660  template <int order, int dim, int spacedim, typename Number>
661  void
662  do_function_derivatives (const ArrayView<Number> &dof_values,
663  const Table<2,::Tensor<order,spacedim> > &shape_derivatives,
664  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
665  std::vector<typename ProductType<Number,::Tensor<order+1,spacedim> >::type> &derivatives)
666  {
667  const unsigned int dofs_per_cell = dof_values.size();
668  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
669  shape_derivatives[0].size() : derivatives.size();
670  AssertDimension (derivatives.size(), n_quadrature_points);
671 
672  std::fill (derivatives.begin(), derivatives.end(),
674 
675  for (unsigned int shape_function=0;
676  shape_function<dofs_per_cell; ++shape_function)
677  {
678  const int snc = shape_function_data[shape_function].single_nonzero_component;
679 
680  if (snc == -2)
681  // shape function is zero for the selected components
682  continue;
683 
684  const Number &value = dof_values[shape_function];
685  // For auto-differentiable numbers, the fact that a DoF value is zero
686  // does not imply that its derivatives are zero as well. So we
687  // can't filter by value for these number types.
688  if (::internal::CheckForZero<Number>::value(value) == true)
689  continue;
690 
691  if (snc != -1)
692  {
693  const unsigned int comp =
694  shape_function_data[shape_function].single_nonzero_component_index;
695  const ::Tensor<order,spacedim> *shape_derivative_ptr =
696  &shape_derivatives[snc][0];
697  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
698  derivatives[q_point][comp] += value * (*shape_derivative_ptr++);
699  }
700  else
701  for (unsigned int d=0; d<spacedim; ++d)
702  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
703  {
704  const ::Tensor<order,spacedim> *shape_derivative_ptr =
705  &shape_derivatives[shape_function_data[shape_function].
706  row_index[d]][0];
707  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
708  derivatives[q_point][d] += value * (*shape_derivative_ptr++);
709  }
710  }
711  }
712 
713 
714 
715  template <int dim, int spacedim, typename Number>
716  void
717  do_function_symmetric_gradients (const ArrayView<Number> &dof_values,
718  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
719  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
720  std::vector<typename ProductType<Number,::SymmetricTensor<2,spacedim> >::type> &symmetric_gradients)
721  {
722  const unsigned int dofs_per_cell = dof_values.size();
723  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
724  shape_gradients[0].size() : symmetric_gradients.size();
725  AssertDimension (symmetric_gradients.size(), n_quadrature_points);
726 
727  std::fill (symmetric_gradients.begin(), symmetric_gradients.end(),
729 
730  for (unsigned int shape_function=0;
731  shape_function<dofs_per_cell; ++shape_function)
732  {
733  const int snc = shape_function_data[shape_function].single_nonzero_component;
734 
735  if (snc == -2)
736  // shape function is zero for the selected components
737  continue;
738 
739  const Number &value = dof_values[shape_function];
740  // For auto-differentiable numbers, the fact that a DoF value is zero
741  // does not imply that its derivatives are zero as well. So we
742  // can't filter by value for these number types.
743  if (::internal::CheckForZero<Number>::value(value) == true)
744  continue;
745 
746  if (snc != -1)
747  {
748  const unsigned int comp =
749  shape_function_data[shape_function].single_nonzero_component_index;
750  const ::Tensor<1,spacedim> *shape_gradient_ptr =
751  &shape_gradients[snc][0];
752  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
753  symmetric_gradients[q_point] += value *
754  ::SymmetricTensor<2,spacedim> (symmetrize_single_row(comp, *shape_gradient_ptr++));
755  }
756  else
757  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
758  {
759  typename ProductType<Number,::Tensor<2,spacedim> >::type grad;
760  for (unsigned int d=0; d<spacedim; ++d)
761  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
762  grad[d] = value *
763  shape_gradients[shape_function_data[shape_function].row_index[d]][q_point];
764  symmetric_gradients[q_point] += symmetrize(grad);
765  }
766  }
767  }
768 
769 
770 
771  template <int dim, int spacedim, typename Number>
772  void
773  do_function_divergences (const ArrayView<Number> &dof_values,
774  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
775  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
776  std::vector<typename Vector<dim,spacedim>::template OutputType<Number>::divergence_type> &divergences)
777  {
778  const unsigned int dofs_per_cell = dof_values.size();
779  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
780  shape_gradients[0].size() : divergences.size();
781  AssertDimension (divergences.size(), n_quadrature_points);
782 
783  std::fill (divergences.begin(), divergences.end(),
784  typename Vector<dim,spacedim>::template OutputType<Number>::divergence_type());
785 
786  for (unsigned int shape_function=0;
787  shape_function<dofs_per_cell; ++shape_function)
788  {
789  const int snc = shape_function_data[shape_function].single_nonzero_component;
790 
791  if (snc == -2)
792  // shape function is zero for the selected components
793  continue;
794 
795  const Number &value = dof_values[shape_function];
796  // For auto-differentiable numbers, the fact that a DoF value is zero
797  // does not imply that its derivatives are zero as well. So we
798  // can't filter by value for these number types.
799  if (::internal::CheckForZero<Number>::value(value) == true)
800  continue;
801 
802  if (snc != -1)
803  {
804  const unsigned int comp =
805  shape_function_data[shape_function].single_nonzero_component_index;
806  const ::Tensor<1,spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
807  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
808  divergences[q_point] += value * (*shape_gradient_ptr++)[comp];
809  }
810  else
811  for (unsigned int d=0; d<spacedim; ++d)
812  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
813  {
814  const ::Tensor<1,spacedim> *shape_gradient_ptr =
815  &shape_gradients[shape_function_data[shape_function].
816  row_index[d]][0];
817  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
818  divergences[q_point] += value * (*shape_gradient_ptr++)[d];
819  }
820  }
821  }
822 
823 
824 
825  template <int dim, int spacedim, typename Number>
826  void
827  do_function_curls (const ArrayView<Number> &dof_values,
828  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
829  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
830  std::vector<typename ProductType<Number,typename ::internal::CurlType<spacedim>::type>::type> &curls)
831  {
832  const unsigned int dofs_per_cell = dof_values.size();
833  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
834  shape_gradients[0].size() : curls.size();
835  AssertDimension (curls.size(), n_quadrature_points);
836 
837  std::fill (curls.begin(), curls.end(),
839 
840  switch (spacedim)
841  {
842  case 1:
843  {
844  Assert (false, ExcMessage("Computing the curl in 1d is not a useful operation"));
845  break;
846  }
847 
848  case 2:
849  {
850  for (unsigned int shape_function = 0;
851  shape_function < dofs_per_cell; ++shape_function)
852  {
853  const int snc = shape_function_data[shape_function].single_nonzero_component;
854 
855  if (snc == -2)
856  // shape function is zero for the selected components
857  continue;
858 
859  const Number &value = dof_values[shape_function];
860  // For auto-differentiable numbers, the fact that a DoF value is zero
861  // does not imply that its derivatives are zero as well. So we
862  // can't filter by value for these number types.
863  if (::internal::CheckForZero<Number>::value(value) == true)
864  continue;
865 
866  if (snc != -1)
867  {
868  const ::Tensor<1, spacedim> *shape_gradient_ptr =
869  &shape_gradients[snc][0];
870 
871  Assert (shape_function_data[shape_function].single_nonzero_component >= 0,
872  ExcInternalError());
873  // we're in 2d, so the formula for the curl is simple:
874  if (shape_function_data[shape_function].single_nonzero_component_index == 0)
875  for (unsigned int q_point = 0;
876  q_point < n_quadrature_points; ++q_point)
877  curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
878  else
879  for (unsigned int q_point = 0;
880  q_point < n_quadrature_points; ++q_point)
881  curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
882  }
883  else
884  // we have multiple non-zero components in the shape functions. not
885  // all of them must necessarily be within the 2-component window
886  // this FEValuesViews::Vector object considers, however.
887  {
888  if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
889  {
890  const ::Tensor<1,spacedim> *shape_gradient_ptr =
891  &shape_gradients[shape_function_data[shape_function].row_index[0]][0];
892 
893  for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
894  curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
895  }
896 
897  if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
898  {
899  const ::Tensor<1,spacedim> *shape_gradient_ptr =
900  &shape_gradients[shape_function_data[shape_function].row_index[1]][0];
901 
902  for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
903  curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
904  }
905  }
906  }
907  break;
908  }
909 
910  case 3:
911  {
912  for (unsigned int shape_function = 0;
913  shape_function < dofs_per_cell; ++shape_function)
914  {
915  const int snc = shape_function_data[shape_function].single_nonzero_component;
916 
917  if (snc == -2)
918  // shape function is zero for the selected components
919  continue;
920 
921  const Number &value = dof_values[shape_function];
922  // For auto-differentiable numbers, the fact that a DoF value is zero
923  // does not imply that its derivatives are zero as well. So we
924  // can't filter by value for these number types.
925  if (::internal::CheckForZero<Number>::value(value) == true)
926  continue;
927 
928  if (snc != -1)
929  {
930  const ::Tensor<1, spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
931 
932  switch (shape_function_data[shape_function].single_nonzero_component_index)
933  {
934  case 0:
935  {
936  for (unsigned int q_point = 0;
937  q_point < n_quadrature_points; ++q_point)
938  {
939  curls[q_point][1] += value * (*shape_gradient_ptr)[2];
940  curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
941  }
942 
943  break;
944  }
945 
946  case 1:
947  {
948  for (unsigned int q_point = 0;
949  q_point < n_quadrature_points; ++q_point)
950  {
951  curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
952  curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
953  }
954 
955  break;
956  }
957 
958  case 2:
959  {
960  for (unsigned int q_point = 0;
961  q_point < n_quadrature_points; ++q_point)
962  {
963  curls[q_point][0] += value * (*shape_gradient_ptr)[1];
964  curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
965  }
966  break;
967  }
968 
969  default:
970  Assert (false, ExcInternalError());
971  }
972  }
973 
974  else
975  // we have multiple non-zero components in the shape functions. not
976  // all of them must necessarily be within the 3-component window
977  // this FEValuesViews::Vector object considers, however.
978  {
979  if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
980  {
981  const ::Tensor<1,spacedim> *shape_gradient_ptr =
982  &shape_gradients[shape_function_data[shape_function].row_index[0]][0];
983 
984  for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
985  {
986  curls[q_point][1] += value * (*shape_gradient_ptr)[2];
987  curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
988  }
989  }
990 
991  if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
992  {
993  const ::Tensor<1,spacedim> *shape_gradient_ptr =
994  &shape_gradients[shape_function_data[shape_function].row_index[1]][0];
995 
996  for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
997  {
998  curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
999  curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
1000  }
1001  }
1002 
1003  if (shape_function_data[shape_function].is_nonzero_shape_function_component[2])
1004  {
1005  const ::Tensor<1,spacedim> *shape_gradient_ptr =
1006  &shape_gradients[shape_function_data[shape_function].row_index[2]][0];
1007 
1008  for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
1009  {
1010  curls[q_point][0] += value * (*shape_gradient_ptr)[1];
1011  curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
1012  }
1013  }
1014  }
1015  }
1016  }
1017  }
1018  }
1019 
1020 
1021 
1022  template <int dim, int spacedim, typename Number>
1023  void
1024  do_function_laplacians (const ArrayView<Number> &dof_values,
1025  const Table<2,::Tensor<2,spacedim> > &shape_hessians,
1026  const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
1027  std::vector<typename Vector<dim,spacedim>::template OutputType<Number>::laplacian_type> &laplacians)
1028  {
1029  const unsigned int dofs_per_cell = dof_values.size();
1030  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1031  shape_hessians[0].size() : laplacians.size();
1032  AssertDimension (laplacians.size(), n_quadrature_points);
1033 
1034  std::fill (laplacians.begin(), laplacians.end(),
1035  typename Vector<dim,spacedim>::template OutputType<Number>::laplacian_type());
1036 
1037  for (unsigned int shape_function=0;
1038  shape_function<dofs_per_cell; ++shape_function)
1039  {
1040  const int snc = shape_function_data[shape_function].single_nonzero_component;
1041 
1042  if (snc == -2)
1043  // shape function is zero for the selected components
1044  continue;
1045 
1046  const Number &value = dof_values[shape_function];
1047  // For auto-differentiable numbers, the fact that a DoF value is zero
1048  // does not imply that its derivatives are zero as well. So we
1049  // can't filter by value for these number types.
1050  if (::internal::CheckForZero<Number>::value(value) == true)
1051  continue;
1052 
1053  if (snc != -1)
1054  {
1055  const unsigned int comp =
1056  shape_function_data[shape_function].single_nonzero_component_index;
1057  const ::Tensor<2,spacedim> *shape_hessian_ptr =
1058  &shape_hessians[snc][0];
1059  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1060  laplacians[q_point][comp] += value * trace(*shape_hessian_ptr++);
1061  }
1062  else
1063  for (unsigned int d=0; d<spacedim; ++d)
1064  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1065  {
1066  const ::Tensor<2,spacedim> *shape_hessian_ptr =
1067  &shape_hessians[shape_function_data[shape_function].
1068  row_index[d]][0];
1069  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1070  laplacians[q_point][d] += value * trace(*shape_hessian_ptr++);
1071  }
1072  }
1073  }
1074 
1075 
1076 
1077  // ---------------------- symmetric tensor part ------------------------
1078 
1079  template <int dim, int spacedim, typename Number>
1080  void
1081  do_function_values (const ArrayView<Number> &dof_values,
1082  const ::Table<2,double> &shape_values,
1083  const std::vector<typename SymmetricTensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
1084  std::vector<typename ProductType<Number,::SymmetricTensor<2,spacedim> >::type> &values)
1085  {
1086  const unsigned int dofs_per_cell = dof_values.size();
1087  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1088  shape_values.n_cols() : values.size();
1089  AssertDimension (values.size(), n_quadrature_points);
1090 
1091  std::fill (values.begin(), values.end(),
1093 
1094  for (unsigned int shape_function=0;
1095  shape_function<dofs_per_cell; ++shape_function)
1096  {
1097  const int snc = shape_function_data[shape_function].single_nonzero_component;
1098 
1099  if (snc == -2)
1100  // shape function is zero for the selected components
1101  continue;
1102 
1103  const Number &value = dof_values[shape_function];
1104  // For auto-differentiable numbers, the fact that a DoF value is zero
1105  // does not imply that its derivatives are zero as well. So we
1106  // can't filter by value for these number types.
1107  if (::internal::CheckForZero<Number>::value(value) == true)
1108  continue;
1109 
1110  if (snc != -1)
1111  {
1112  const TableIndices<2> comp =
1114  (shape_function_data[shape_function].single_nonzero_component_index);
1115  const double *shape_value_ptr = &shape_values(snc,0);
1116  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1117  values[q_point][comp] += value * (*shape_value_ptr++);
1118  }
1119  else
1120  for (unsigned int d=0;
1121  d<::SymmetricTensor<2,spacedim>::n_independent_components; ++d)
1122  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1123  {
1124  const TableIndices<2> comp =
1126  const double *shape_value_ptr =
1127  &shape_values(shape_function_data[shape_function].row_index[d],0);
1128  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1129  values[q_point][comp] += value * (*shape_value_ptr++);
1130  }
1131  }
1132  }
1133 
1134 
1135 
1136  template <int dim, int spacedim, typename Number>
1137  void
1138  do_function_divergences (const ArrayView<Number> &dof_values,
1139  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
1140  const std::vector<typename SymmetricTensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
1141  std::vector<typename SymmetricTensor<2,dim,spacedim>::template OutputType<Number>::divergence_type> &divergences)
1142  {
1143  const unsigned int dofs_per_cell = dof_values.size();
1144  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1145  shape_gradients[0].size() : divergences.size();
1146  AssertDimension (divergences.size(), n_quadrature_points);
1147 
1148  std::fill (divergences.begin(), divergences.end(),
1149  typename SymmetricTensor<2,dim,spacedim>::template OutputType<Number>::divergence_type());
1150 
1151  for (unsigned int shape_function=0;
1152  shape_function<dofs_per_cell; ++shape_function)
1153  {
1154  const int snc = shape_function_data[shape_function].single_nonzero_component;
1155 
1156  if (snc == -2)
1157  // shape function is zero for the selected components
1158  continue;
1159 
1160  const Number &value = dof_values[shape_function];
1161  // For auto-differentiable numbers, the fact that a DoF value is zero
1162  // does not imply that its derivatives are zero as well. So we
1163  // can't filter by value for these number types.
1164  if (::internal::CheckForZero<Number>::value(value) == true)
1165  continue;
1166 
1167  if (snc != -1)
1168  {
1169  const unsigned int comp =
1170  shape_function_data[shape_function].single_nonzero_component_index;
1171 
1172  const ::Tensor < 1, spacedim> *shape_gradient_ptr =
1173  &shape_gradients[snc][0];
1174 
1175  const unsigned int ii = ::SymmetricTensor<2,spacedim>::
1177  const unsigned int jj = ::SymmetricTensor<2,spacedim>::
1179 
1180  for (unsigned int q_point = 0; q_point < n_quadrature_points;
1181  ++q_point, ++shape_gradient_ptr)
1182  {
1183  divergences[q_point][ii] += value * (*shape_gradient_ptr)[jj];
1184 
1185  if (ii != jj)
1186  divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
1187  }
1188  }
1189  else
1190  {
1191  for (unsigned int d = 0;
1192  d < ::SymmetricTensor<2,spacedim>::n_independent_components; ++d)
1193  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1194  {
1195  Assert (false, ExcNotImplemented());
1196 
1197  // the following implementation needs to be looked over -- I
1198  // think it can't be right, because we are in a case where
1199  // there is no single nonzero component
1200  //
1201  // the following is not implemented! we need to consider the
1202  // interplay between multiple non-zero entries in shape
1203  // function and the representation as a symmetric
1204  // second-order tensor
1205  const unsigned int comp =
1206  shape_function_data[shape_function].single_nonzero_component_index;
1207 
1208  const ::Tensor < 1, spacedim> *shape_gradient_ptr =
1209  &shape_gradients[shape_function_data[shape_function].
1210  row_index[d]][0];
1211  for (unsigned int q_point = 0; q_point < n_quadrature_points;
1212  ++q_point, ++shape_gradient_ptr)
1213  {
1214  for (unsigned int j = 0; j < spacedim; ++j)
1215  {
1216  const unsigned int vector_component = ::SymmetricTensor<2,spacedim>::component_to_unrolled_index (TableIndices<2>(comp,j));
1217  divergences[q_point][vector_component] += value * (*shape_gradient_ptr++)[j];
1218  }
1219  }
1220  }
1221  }
1222  }
1223  }
1224 
1225  // ---------------------- non-symmetric tensor part ------------------------
1226 
1227  template <int dim, int spacedim, typename Number>
1228  void
1229  do_function_values (const ArrayView<Number> &dof_values,
1230  const ::Table<2,double> &shape_values,
1231  const std::vector<typename Tensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
1232  std::vector<typename ProductType<Number,::Tensor<2,spacedim> >::type> &values)
1233  {
1234  const unsigned int dofs_per_cell = dof_values.size();
1235  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1236  shape_values.n_cols() : values.size();
1237  AssertDimension (values.size(), n_quadrature_points);
1238 
1239  std::fill (values.begin(), values.end(),
1240  typename ProductType<Number,::Tensor<2,spacedim> >::type());
1241 
1242  for (unsigned int shape_function=0;
1243  shape_function<dofs_per_cell; ++shape_function)
1244  {
1245  const int snc = shape_function_data[shape_function].single_nonzero_component;
1246 
1247  if (snc == -2)
1248  // shape function is zero for the selected components
1249  continue;
1250 
1251  const Number &value = dof_values[shape_function];
1252  // For auto-differentiable numbers, the fact that a DoF value is zero
1253  // does not imply that its derivatives are zero as well. So we
1254  // can't filter by value for these number types.
1255  if (::internal::CheckForZero<Number>::value(value) == true)
1256  continue;
1257 
1258  if (snc != -1)
1259  {
1260  const unsigned int comp =
1261  shape_function_data[shape_function].single_nonzero_component_index;
1262 
1264 
1265  const double *shape_value_ptr = &shape_values(snc,0);
1266  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1267  values[q_point][indices] += value * (*shape_value_ptr++);
1268  }
1269  else
1270  for (unsigned int d=0;
1271  d<dim*dim; ++d)
1272  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1273  {
1275 
1276  const double *shape_value_ptr =
1277  &shape_values(shape_function_data[shape_function].row_index[d],0);
1278  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
1279  values[q_point][indices] += value * (*shape_value_ptr++);
1280  }
1281  }
1282  }
1283 
1284 
1285 
1286  template <int dim, int spacedim, typename Number>
1287  void
1288  do_function_divergences (const ArrayView<Number> &dof_values,
1289  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
1290  const std::vector<typename Tensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
1291  std::vector<typename Tensor<2,dim,spacedim>::template OutputType<Number>::divergence_type> &divergences)
1292  {
1293  const unsigned int dofs_per_cell = dof_values.size();
1294  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1295  shape_gradients[0].size() : divergences.size();
1296  AssertDimension (divergences.size(), n_quadrature_points);
1297 
1298  std::fill (divergences.begin(), divergences.end(),
1299  typename Tensor<2,dim,spacedim>::template OutputType<Number>::divergence_type());
1300 
1301  for (unsigned int shape_function=0;
1302  shape_function<dofs_per_cell; ++shape_function)
1303  {
1304  const int snc = shape_function_data[shape_function].single_nonzero_component;
1305 
1306  if (snc == -2)
1307  // shape function is zero for the selected components
1308  continue;
1309 
1310  const Number &value = dof_values[shape_function];
1311  // For auto-differentiable numbers, the fact that a DoF value is zero
1312  // does not imply that its derivatives are zero as well. So we
1313  // can't filter by value for these number types.
1314  if (::internal::CheckForZero<Number>::value(value) == true)
1315  continue;
1316 
1317  if (snc != -1)
1318  {
1319  const unsigned int comp =
1320  shape_function_data[shape_function].single_nonzero_component_index;
1321 
1322  const ::Tensor < 1, spacedim> *shape_gradient_ptr =
1323  &shape_gradients[snc][0];
1324 
1326  const unsigned int ii = indices[0];
1327  const unsigned int jj = indices[1];
1328 
1329  for (unsigned int q_point = 0; q_point < n_quadrature_points;
1330  ++q_point, ++shape_gradient_ptr)
1331  {
1332  divergences[q_point][ii] += value * (*shape_gradient_ptr)[jj];
1333  }
1334  }
1335  else
1336  {
1337  for (unsigned int d = 0;
1338  d < dim*dim; ++d)
1339  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1340  {
1341  Assert (false, ExcNotImplemented());
1342  }
1343  }
1344  }
1345  }
1346 
1347 
1348 
1349  template <int dim, int spacedim, typename Number>
1350  void
1351  do_function_gradients (const ArrayView<Number> &dof_values,
1352  const Table<2,::Tensor<1,spacedim> > &shape_gradients,
1353  const std::vector<typename Tensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
1354  std::vector<typename Tensor<2,dim,spacedim>::template OutputType<Number>::gradient_type> &gradients)
1355  {
1356  const unsigned int dofs_per_cell = dof_values.size();
1357  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
1358  shape_gradients[0].size() : gradients.size();
1359  AssertDimension (gradients.size(), n_quadrature_points);
1360 
1361  std::fill (gradients.begin(), gradients.end(),
1362  typename Tensor<2,dim,spacedim>::template OutputType<Number>::gradient_type());
1363 
1364  for (unsigned int shape_function=0;
1365  shape_function<dofs_per_cell; ++shape_function)
1366  {
1367  const int snc = shape_function_data[shape_function].single_nonzero_component;
1368 
1369  if (snc == -2)
1370  // shape function is zero for the selected components
1371  continue;
1372 
1373  const Number &value = dof_values[shape_function];
1374  // For auto-differentiable numbers, the fact that a DoF value is zero
1375  // does not imply that its derivatives are zero as well. So we
1376  // can't filter by value for these number types.
1377  if (::internal::CheckForZero<Number>::value(value) == true)
1378  continue;
1379 
1380  if (snc != -1)
1381  {
1382  const unsigned int comp =
1383  shape_function_data[shape_function].single_nonzero_component_index;
1384 
1385  const ::Tensor < 1, spacedim> *shape_gradient_ptr =
1386  &shape_gradients[snc][0];
1387 
1389  const unsigned int ii = indices[0];
1390  const unsigned int jj = indices[1];
1391 
1392  for (unsigned int q_point = 0; q_point < n_quadrature_points;
1393  ++q_point, ++shape_gradient_ptr)
1394  {
1395  gradients[q_point][ii][jj] += value * (*shape_gradient_ptr);
1396  }
1397  }
1398  else
1399  {
1400  for (unsigned int d = 0;
1401  d < dim*dim; ++d)
1402  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
1403  {
1404  Assert (false, ExcNotImplemented());
1405  }
1406  }
1407  }
1408  }
1409 
1410  } // end of namespace internal
1411 
1412 
1413 
1414  template <int dim, int spacedim>
1415  template <class InputVector>
1416  void
1418  get_function_values (const InputVector &fe_function,
1419  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &values) const
1420  {
1421  Assert (fe_values->update_flags & update_values,
1422  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
1423  Assert (fe_values->present_cell.get() != nullptr,
1424  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1425  AssertDimension (fe_function.size(),
1426  fe_values->present_cell->n_dofs_for_dof_handler());
1427 
1428  // get function values of dofs on this cell and call internal worker function
1429  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
1430  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1431  internal::do_function_values<dim,spacedim>
1432  (make_array_view(dof_values.begin(), dof_values.end()),
1433  fe_values->finite_element_output.shape_values, shape_function_data, values);
1434  }
1435 
1436 
1437 
1438  template <int dim, int spacedim>
1439  template <class InputVector>
1440  void
1442  get_function_values_from_local_dof_values (const InputVector &dof_values,
1443  std::vector<typename OutputType<typename InputVector::value_type>::value_type> &values) const
1444  {
1445  Assert (fe_values->update_flags & update_values,
1446  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
1447  Assert (fe_values->present_cell.get() != nullptr,
1448  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1449  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1450 
1451  internal::do_function_values<dim,spacedim>
1452  (make_array_view(dof_values.begin(), dof_values.end()),
1453  fe_values->finite_element_output.shape_values, shape_function_data, values);
1454  }
1455 
1456 
1457 
1458  template <int dim, int spacedim>
1459  template <class InputVector>
1460  void
1462  get_function_gradients (const InputVector &fe_function,
1463  std::vector<typename ProductType<gradient_type,typename InputVector::value_type>::type> &gradients) const
1464  {
1465  Assert (fe_values->update_flags & update_gradients,
1466  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1467  Assert (fe_values->present_cell.get() != nullptr,
1468  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1469  AssertDimension (fe_function.size(),
1470  fe_values->present_cell->n_dofs_for_dof_handler());
1471 
1472  // get function values of dofs on this cell
1473  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1474  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1475  internal::do_function_derivatives<1,dim,spacedim>
1476  (make_array_view(dof_values.begin(), dof_values.end()),
1477  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
1478  }
1479 
1480 
1481 
1482  template <int dim, int spacedim>
1483  template <class InputVector>
1484  void
1487  std::vector<typename OutputType<typename InputVector::value_type>::gradient_type> &gradients) const
1488  {
1489  Assert (fe_values->update_flags & update_gradients,
1490  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1491  Assert (fe_values->present_cell.get() != nullptr,
1492  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1493  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1494 
1495  internal::do_function_derivatives<1,dim,spacedim>
1496  (make_array_view(dof_values.begin(), dof_values.end()),
1497  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
1498  }
1499 
1500 
1501 
1502  template <int dim, int spacedim>
1503  template <class InputVector>
1504  void
1506  get_function_hessians (const InputVector &fe_function,
1507  std::vector<typename ProductType<hessian_type,typename InputVector::value_type>::type> &hessians) const
1508  {
1509  Assert (fe_values->update_flags & update_hessians,
1510  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1511  Assert (fe_values->present_cell.get() != nullptr,
1512  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1513  AssertDimension (fe_function.size(),
1514  fe_values->present_cell->n_dofs_for_dof_handler());
1515 
1516  // get function values of dofs on this cell
1517  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1518  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1519  internal::do_function_derivatives<2,dim,spacedim>
1520  (make_array_view(dof_values.begin(), dof_values.end()),
1521  fe_values->finite_element_output.shape_hessians, shape_function_data, hessians);
1522  }
1523 
1524 
1525 
1526  template <int dim, int spacedim>
1527  template <class InputVector>
1528  void
1530  get_function_hessians_from_local_dof_values(const InputVector &dof_values,
1531  std::vector<typename OutputType<typename InputVector::value_type>::hessian_type> &hessians) const
1532  {
1533  Assert (fe_values->update_flags & update_hessians,
1534  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1535  Assert (fe_values->present_cell.get() != nullptr,
1536  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1537  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1538 
1539  internal::do_function_derivatives<2,dim,spacedim>
1540  (make_array_view(dof_values.begin(), dof_values.end()),
1541  fe_values->finite_element_output.shape_hessians, shape_function_data, hessians);
1542  }
1543 
1544 
1545 
1546  template <int dim, int spacedim>
1547  template <class InputVector>
1548  void
1550  get_function_laplacians (const InputVector &fe_function,
1551  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &laplacians) const
1552  {
1553  Assert (fe_values->update_flags & update_hessians,
1554  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1555  Assert (fe_values->present_cell.get() != nullptr,
1556  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1557  AssertDimension (fe_function.size(),
1558  fe_values->present_cell->n_dofs_for_dof_handler());
1559 
1560  // get function values of dofs on this cell
1561  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1562  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1563  internal::do_function_laplacians<dim,spacedim>
1564  (make_array_view(dof_values.begin(), dof_values.end()),
1565  fe_values->finite_element_output.shape_hessians, shape_function_data, laplacians);
1566  }
1567 
1568 
1569 
1570  template <int dim, int spacedim>
1571  template <class InputVector>
1572  void
1575  std::vector<typename OutputType<typename InputVector::value_type>::laplacian_type> &laplacians) const
1576  {
1577  Assert (fe_values->update_flags & update_hessians,
1578  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1579  Assert (fe_values->present_cell.get() != nullptr,
1580  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1581  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1582 
1583  internal::do_function_laplacians<dim,spacedim>
1584  (make_array_view(dof_values.begin(), dof_values.end()),
1585  fe_values->finite_element_output.shape_hessians, shape_function_data, laplacians);
1586  }
1587 
1588 
1589 
1590  template <int dim, int spacedim>
1591  template <class InputVector>
1592  void
1594  get_function_third_derivatives (const InputVector &fe_function,
1595  std::vector<typename ProductType<third_derivative_type,typename InputVector::value_type>::type> &third_derivatives) const
1596  {
1597  Assert (fe_values->update_flags & update_3rd_derivatives,
1598  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_3rd_derivatives")));
1599  Assert (fe_values->present_cell.get() != nullptr,
1600  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1601  AssertDimension (fe_function.size(),
1602  fe_values->present_cell->n_dofs_for_dof_handler());
1603 
1604  // get function values of dofs on this cell
1605  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1606  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1607  internal::do_function_derivatives<3,dim,spacedim>
1608  (make_array_view(dof_values.begin(), dof_values.end()),
1609  fe_values->finite_element_output.shape_3rd_derivatives, shape_function_data, third_derivatives);
1610  }
1611 
1612 
1613 
1614  template <int dim, int spacedim>
1615  template <class InputVector>
1616  void
1619  std::vector<typename OutputType<typename InputVector::value_type>::third_derivative_type> &third_derivatives) const
1620  {
1621  Assert (fe_values->update_flags & update_3rd_derivatives,
1622  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_3rd_derivatives")));
1623  Assert (fe_values->present_cell.get() != nullptr,
1624  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1625  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1626 
1627  internal::do_function_derivatives<3,dim,spacedim>
1628  (make_array_view(dof_values.begin(), dof_values.end()),
1629  fe_values->finite_element_output.shape_3rd_derivatives, shape_function_data, third_derivatives);
1630  }
1631 
1632 
1633 
1634  template <int dim, int spacedim>
1635  template <class InputVector>
1636  void
1638  get_function_values (const InputVector &fe_function,
1639  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &values) const
1640  {
1641  Assert (fe_values->update_flags & update_values,
1642  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
1643  Assert (fe_values->present_cell.get() != nullptr,
1644  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1645  AssertDimension (fe_function.size(),
1646  fe_values->present_cell->n_dofs_for_dof_handler());
1647 
1648  // get function values of dofs on this cell
1649  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1650  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1651  internal::do_function_values<dim,spacedim>
1652  (make_array_view(dof_values.begin(), dof_values.end()),
1653  fe_values->finite_element_output.shape_values, shape_function_data, values);
1654  }
1655 
1656 
1657 
1658  template <int dim, int spacedim>
1659  template <class InputVector>
1660  void
1662  get_function_values_from_local_dof_values (const InputVector &dof_values,
1663  std::vector<typename OutputType<typename InputVector::value_type>::value_type> &values) const
1664  {
1665  Assert (fe_values->update_flags & update_values,
1666  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
1667  Assert (fe_values->present_cell.get() != nullptr,
1668  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1669  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1670 
1671  internal::do_function_values<dim,spacedim>
1672  (make_array_view(dof_values.begin(), dof_values.end()),
1673  fe_values->finite_element_output.shape_values, shape_function_data, values);
1674  }
1675 
1676 
1677 
1678  template <int dim, int spacedim>
1679  template <class InputVector>
1680  void
1682  get_function_gradients (const InputVector &fe_function,
1683  std::vector<typename ProductType<gradient_type,typename InputVector::value_type>::type> &gradients) const
1684  {
1685  Assert (fe_values->update_flags & update_gradients,
1686  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1687  Assert (fe_values->present_cell.get() != nullptr,
1688  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1689  AssertDimension (fe_function.size(),
1690  fe_values->present_cell->n_dofs_for_dof_handler());
1691 
1692  // get function values of dofs on this cell
1693  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1694  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1695  internal::do_function_derivatives<1,dim,spacedim>
1696  (make_array_view(dof_values.begin(), dof_values.end()),
1697  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
1698  }
1699 
1700 
1701 
1702  template <int dim, int spacedim>
1703  template <class InputVector>
1704  void
1706  get_function_gradients_from_local_dof_values (const InputVector &dof_values,
1707  std::vector<typename OutputType<typename InputVector::value_type>::gradient_type> &gradients) const
1708  {
1709  Assert (fe_values->update_flags & update_gradients,
1710  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1711  Assert (fe_values->present_cell.get() != nullptr,
1712  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1713  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1714 
1715  internal::do_function_derivatives<1,dim,spacedim>
1716  (make_array_view(dof_values.begin(), dof_values.end()),
1717  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
1718  }
1719 
1720 
1721 
1722  template <int dim, int spacedim>
1723  template <class InputVector>
1724  void
1726  get_function_symmetric_gradients (const InputVector &fe_function,
1727  std::vector<typename ProductType<symmetric_gradient_type,typename InputVector::value_type>::type> &symmetric_gradients) const
1728  {
1729  Assert (fe_values->update_flags & update_gradients,
1730  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1731  Assert (fe_values->present_cell.get() != nullptr,
1732  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1733  AssertDimension (fe_function.size(),
1734  fe_values->present_cell->n_dofs_for_dof_handler());
1735 
1736  // get function values of dofs on this cell
1737  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1738  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1739  internal::do_function_symmetric_gradients<dim,spacedim>
1740  (make_array_view(dof_values.begin(), dof_values.end()),
1741  fe_values->finite_element_output.shape_gradients, shape_function_data,
1742  symmetric_gradients);
1743  }
1744 
1745 
1746 
1747  template <int dim, int spacedim>
1748  template <class InputVector>
1749  void
1752  std::vector<typename OutputType<typename InputVector::value_type>::symmetric_gradient_type> &symmetric_gradients) const
1753  {
1754  Assert (fe_values->update_flags & update_gradients,
1755  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1756  Assert (fe_values->present_cell.get() != nullptr,
1757  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1758  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1759 
1760  internal::do_function_symmetric_gradients<dim,spacedim>
1761  (make_array_view(dof_values.begin(), dof_values.end()),
1762  fe_values->finite_element_output.shape_gradients, shape_function_data,
1763  symmetric_gradients);
1764  }
1765 
1766 
1767 
1768  template <int dim, int spacedim>
1769  template <class InputVector>
1770  void
1772  get_function_divergences (const InputVector &fe_function,
1773  std::vector<typename ProductType<divergence_type,typename InputVector::value_type>::type> &divergences) const
1774  {
1775  Assert (fe_values->update_flags & update_gradients,
1776  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1777  Assert (fe_values->present_cell.get() != nullptr,
1778  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1779  AssertDimension (fe_function.size(),
1780  fe_values->present_cell->n_dofs_for_dof_handler());
1781 
1782  // get function values of dofs
1783  // on this cell
1784  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1785  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1786  internal::do_function_divergences<dim,spacedim>
1787  (make_array_view(dof_values.begin(), dof_values.end()),
1788  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
1789  }
1790 
1791 
1792 
1793  template <int dim, int spacedim>
1794  template <class InputVector>
1795  void
1798  std::vector<typename OutputType<typename InputVector::value_type>::divergence_type> &divergences) const
1799  {
1800  Assert (fe_values->update_flags & update_gradients,
1801  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1802  Assert (fe_values->present_cell.get() != nullptr,
1803  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1804  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1805 
1806  internal::do_function_divergences<dim,spacedim>
1807  (make_array_view(dof_values.begin(), dof_values.end()),
1808  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
1809  }
1810 
1811 
1812 
1813  template <int dim, int spacedim>
1814  template <class InputVector>
1815  void
1817  get_function_curls (const InputVector &fe_function,
1818  std::vector<typename ProductType<curl_type,typename InputVector::value_type>::type> &curls) const
1819  {
1820  Assert (fe_values->update_flags & update_gradients,
1821  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1822  Assert (fe_values->present_cell.get () != nullptr,
1823  ExcMessage ("FEValues object is not reinited to any cell"));
1824  AssertDimension (fe_function.size (),
1825  fe_values->present_cell->n_dofs_for_dof_handler ());
1826 
1827  // get function values of dofs on this cell
1828  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1829  fe_values->present_cell->get_interpolated_dof_values (fe_function, dof_values);
1830  internal::do_function_curls<dim,spacedim>
1831  (make_array_view(dof_values.begin(), dof_values.end()),
1832  fe_values->finite_element_output.shape_gradients, shape_function_data, curls);
1833  }
1834 
1835 
1836 
1837  template <int dim, int spacedim>
1838  template <class InputVector>
1839  void
1841  get_function_curls_from_local_dof_values(const InputVector &dof_values,
1842  std::vector<typename OutputType<typename InputVector::value_type>::curl_type> &curls) const
1843  {
1844  Assert (fe_values->update_flags & update_gradients,
1845  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
1846  Assert (fe_values->present_cell.get () != nullptr,
1847  ExcMessage ("FEValues object is not reinited to any cell"));
1848  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1849 
1850  internal::do_function_curls<dim,spacedim>
1851  (make_array_view(dof_values.begin(), dof_values.end()),
1852  fe_values->finite_element_output.shape_gradients, shape_function_data, curls);
1853  }
1854 
1855 
1856 
1857  template <int dim, int spacedim>
1858  template <class InputVector>
1859  void
1861  get_function_hessians (const InputVector &fe_function,
1862  std::vector<typename ProductType<hessian_type,typename InputVector::value_type>::type> &hessians) const
1863  {
1864  Assert (fe_values->update_flags & update_hessians,
1865  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1866  Assert (fe_values->present_cell.get() != nullptr,
1867  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1868  AssertDimension (fe_function.size(),
1869  fe_values->present_cell->n_dofs_for_dof_handler());
1870 
1871  // get function values of dofs on this cell
1872  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1873  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1874  internal::do_function_derivatives<2,dim,spacedim>
1875  (make_array_view(dof_values.begin(), dof_values.end()),
1876  fe_values->finite_element_output.shape_hessians, shape_function_data, hessians);
1877  }
1878 
1879 
1880 
1881  template <int dim, int spacedim>
1882  template <class InputVector>
1883  void
1885  get_function_hessians_from_local_dof_values (const InputVector &dof_values,
1886  std::vector<typename OutputType<typename InputVector::value_type>::hessian_type> &hessians) const
1887  {
1888  Assert (fe_values->update_flags & update_hessians,
1889  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1890  Assert (fe_values->present_cell.get() != nullptr,
1891  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1892  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1893 
1894  internal::do_function_derivatives<2,dim,spacedim>
1895  (make_array_view(dof_values.begin(), dof_values.end()),
1896  fe_values->finite_element_output.shape_hessians, shape_function_data, hessians);
1897  }
1898 
1899 
1900 
1901  template <int dim, int spacedim>
1902  template <class InputVector>
1903  void
1905  get_function_laplacians (const InputVector &fe_function,
1906  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &laplacians) const
1907  {
1908  Assert (fe_values->update_flags & update_hessians,
1909  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1910  Assert (laplacians.size() == fe_values->n_quadrature_points,
1911  ExcDimensionMismatch(laplacians.size(), fe_values->n_quadrature_points));
1912  Assert (fe_values->present_cell.get() != nullptr,
1913  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1914  Assert (fe_function.size() == fe_values->present_cell->n_dofs_for_dof_handler(),
1915  ExcDimensionMismatch(fe_function.size(),
1916  fe_values->present_cell->n_dofs_for_dof_handler()));
1917 
1918  // get function values of dofs on this cell
1919  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1920  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1921  internal::do_function_laplacians<dim,spacedim>
1922  (make_array_view(dof_values.begin(), dof_values.end()),
1923  fe_values->finite_element_output.shape_hessians, shape_function_data, laplacians);
1924  }
1925 
1926 
1927 
1928  template <int dim, int spacedim>
1929  template <class InputVector>
1930  void
1933  std::vector<typename OutputType<typename InputVector::value_type>::laplacian_type> &laplacians) const
1934  {
1935  Assert (fe_values->update_flags & update_hessians,
1936  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_hessians")));
1937  Assert (laplacians.size() == fe_values->n_quadrature_points,
1938  ExcDimensionMismatch(laplacians.size(), fe_values->n_quadrature_points));
1939  Assert (fe_values->present_cell.get() != nullptr,
1940  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1941  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1942 
1943  internal::do_function_laplacians<dim,spacedim>
1944  (make_array_view(dof_values.begin(), dof_values.end()),
1945  fe_values->finite_element_output.shape_hessians, shape_function_data, laplacians);
1946  }
1947 
1948 
1949 
1950  template <int dim, int spacedim>
1951  template <class InputVector>
1952  void
1954  get_function_third_derivatives (const InputVector &fe_function,
1955  std::vector<typename ProductType<third_derivative_type,typename InputVector::value_type>::type> &third_derivatives) const
1956  {
1957  Assert (fe_values->update_flags & update_3rd_derivatives,
1958  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_3rd_derivatives")));
1959  Assert (fe_values->present_cell.get() != nullptr,
1960  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1961  AssertDimension (fe_function.size(),
1962  fe_values->present_cell->n_dofs_for_dof_handler());
1963 
1964  // get function values of dofs on this cell
1965  ::Vector<typename InputVector::value_type> dof_values (fe_values->dofs_per_cell);
1966  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
1967  internal::do_function_derivatives<3,dim,spacedim>
1968  (make_array_view(dof_values.begin(), dof_values.end()),
1969  fe_values->finite_element_output.shape_3rd_derivatives, shape_function_data, third_derivatives);
1970  }
1971 
1972 
1973 
1974  template <int dim, int spacedim>
1975  template <class InputVector>
1976  void
1979  std::vector<typename OutputType<typename InputVector::value_type>::third_derivative_type> &third_derivatives) const
1980  {
1981  Assert (fe_values->update_flags & update_3rd_derivatives,
1982  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_3rd_derivatives")));
1983  Assert (fe_values->present_cell.get() != nullptr,
1984  ExcMessage ("FEValues object is not reinit'ed to any cell"));
1985  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
1986 
1987  internal::do_function_derivatives<3,dim,spacedim>
1988  (make_array_view(dof_values.begin(), dof_values.end()),
1989  fe_values->finite_element_output.shape_3rd_derivatives, shape_function_data, third_derivatives);
1990  }
1991 
1992 
1993 
1994  template <int dim, int spacedim>
1995  template <class InputVector>
1996  void
1997  SymmetricTensor<2, dim, spacedim>::
1998  get_function_values(const InputVector &fe_function,
1999  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &values) const
2000  {
2001  Assert(fe_values->update_flags & update_values,
2002  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
2003  Assert(fe_values->present_cell.get() != nullptr,
2004  ExcMessage("FEValues object is not reinit'ed to any cell"));
2005  AssertDimension(fe_function.size(),
2006  fe_values->present_cell->n_dofs_for_dof_handler());
2007 
2008  // get function values of dofs on this cell
2009  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
2010  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
2011  internal::do_function_values<dim,spacedim>
2012  (make_array_view(dof_values.begin(), dof_values.end()),
2013  fe_values->finite_element_output.shape_values, shape_function_data, values);
2014  }
2015 
2016 
2017 
2018  template <int dim, int spacedim>
2019  template <class InputVector>
2020  void
2021  SymmetricTensor<2, dim, spacedim>::
2022  get_function_values_from_local_dof_values(const InputVector &dof_values,
2023  std::vector<typename OutputType<typename InputVector::value_type>::value_type> &values) const
2024  {
2025  Assert(fe_values->update_flags & update_values,
2026  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
2027  Assert(fe_values->present_cell.get() != nullptr,
2028  ExcMessage("FEValues object is not reinit'ed to any cell"));
2029  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
2030 
2031  internal::do_function_values<dim,spacedim>
2032  (make_array_view(dof_values.begin(), dof_values.end()),
2033  fe_values->finite_element_output.shape_values, shape_function_data, values);
2034  }
2035 
2036 
2037 
2038  template <int dim, int spacedim>
2039  template <class InputVector>
2040  void
2041  SymmetricTensor<2, dim, spacedim>::
2042  get_function_divergences(const InputVector &fe_function,
2043  std::vector<typename ProductType<divergence_type,typename InputVector::value_type>::type> &divergences) const
2044  {
2045  Assert(fe_values->update_flags & update_gradients,
2046  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2047  Assert(fe_values->present_cell.get() != nullptr,
2048  ExcMessage("FEValues object is not reinit'ed to any cell"));
2049  AssertDimension(fe_function.size(),
2050  fe_values->present_cell->n_dofs_for_dof_handler());
2051 
2052  // get function values of dofs
2053  // on this cell
2054  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
2055  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
2056  internal::do_function_divergences<dim,spacedim>
2057  (make_array_view(dof_values.begin(), dof_values.end()),
2058  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
2059  }
2060 
2061 
2062 
2063  template <int dim, int spacedim>
2064  template <class InputVector>
2065  void
2066  SymmetricTensor<2, dim, spacedim>::
2067  get_function_divergences_from_local_dof_values(const InputVector &dof_values,
2068  std::vector<typename OutputType<typename InputVector::value_type>::divergence_type> &divergences) const
2069  {
2070  Assert(fe_values->update_flags & update_gradients,
2071  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2072  Assert(fe_values->present_cell.get() != nullptr,
2073  ExcMessage("FEValues object is not reinit'ed to any cell"));
2074  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
2075 
2076  internal::do_function_divergences<dim,spacedim>
2077  (make_array_view(dof_values.begin(), dof_values.end()),
2078  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
2079  }
2080 
2081 
2082 
2083  template <int dim, int spacedim>
2084  template <class InputVector>
2085  void
2086  Tensor<2, dim, spacedim>::
2087  get_function_values(const InputVector &fe_function,
2088  std::vector<typename ProductType<value_type,typename InputVector::value_type>::type> &values) const
2089  {
2090  Assert(fe_values->update_flags & update_values,
2091  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
2092  Assert(fe_values->present_cell.get() != nullptr,
2093  ExcMessage("FEValues object is not reinit'ed to any cell"));
2094  AssertDimension(fe_function.size(),
2095  fe_values->present_cell->n_dofs_for_dof_handler());
2096 
2097  // get function values of dofs on this cell
2098  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
2099  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
2100  internal::do_function_values<dim,spacedim>
2101  (make_array_view(dof_values.begin(), dof_values.end()),
2102  fe_values->finite_element_output.shape_values, shape_function_data, values);
2103  }
2104 
2105 
2106 
2107  template <int dim, int spacedim>
2108  template <class InputVector>
2109  void
2110  Tensor<2, dim, spacedim>::
2111  get_function_values_from_local_dof_values (const InputVector &dof_values,
2112  std::vector<typename OutputType<typename InputVector::value_type>::value_type> &values) const
2113  {
2114  Assert(fe_values->update_flags & update_values,
2115  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_values")));
2116  Assert(fe_values->present_cell.get() != nullptr,
2117  ExcMessage("FEValues object is not reinit'ed to any cell"));
2118  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
2119 
2120  internal::do_function_values<dim,spacedim>
2121  (make_array_view(dof_values.begin(), dof_values.end()),
2122  fe_values->finite_element_output.shape_values, shape_function_data, values);
2123  }
2124 
2125 
2126 
2127  template <int dim, int spacedim>
2128  template <class InputVector>
2129  void
2130  Tensor<2, dim, spacedim>::
2131  get_function_divergences(const InputVector &fe_function,
2132  std::vector<typename ProductType<divergence_type,typename InputVector::value_type>::type> &divergences) const
2133  {
2134  Assert(fe_values->update_flags & update_gradients,
2135  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2136  Assert(fe_values->present_cell.get() != nullptr,
2137  ExcMessage("FEValues object is not reinit'ed to any cell"));
2138  AssertDimension(fe_function.size(),
2139  fe_values->present_cell->n_dofs_for_dof_handler());
2140 
2141  // get function values of dofs
2142  // on this cell
2143  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
2144  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
2145  internal::do_function_divergences<dim,spacedim>
2146  (make_array_view(dof_values.begin(), dof_values.end()),
2147  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
2148  }
2149 
2150 
2151 
2152  template <int dim, int spacedim>
2153  template <class InputVector>
2154  void
2155  Tensor<2, dim, spacedim>::
2156  get_function_divergences_from_local_dof_values (const InputVector &dof_values,
2157  std::vector<typename OutputType<typename InputVector::value_type>::divergence_type> &divergences) const
2158  {
2159  Assert(fe_values->update_flags & update_gradients,
2160  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2161  Assert(fe_values->present_cell.get() != nullptr,
2162  ExcMessage("FEValues object is not reinit'ed to any cell"));
2163  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
2164 
2165  internal::do_function_divergences<dim,spacedim>
2166  (make_array_view(dof_values.begin(), dof_values.end()),
2167  fe_values->finite_element_output.shape_gradients, shape_function_data, divergences);
2168  }
2169 
2170 
2171 
2172  template <int dim, int spacedim>
2173  template <class InputVector>
2174  void
2175  Tensor<2, dim, spacedim>::
2176  get_function_gradients(const InputVector &fe_function,
2177  std::vector<typename ProductType<gradient_type,typename InputVector::value_type>::type> &gradients) const
2178  {
2179  Assert(fe_values->update_flags & update_gradients,
2180  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2181  Assert(fe_values->present_cell.get() != nullptr,
2182  ExcMessage("FEValues object is not reinit'ed to any cell"));
2183  AssertDimension(fe_function.size(),
2184  fe_values->present_cell->n_dofs_for_dof_handler());
2185 
2186  // get function values of dofs
2187  // on this cell
2188  ::Vector<typename InputVector::value_type> dof_values(fe_values->dofs_per_cell);
2189  fe_values->present_cell->get_interpolated_dof_values(fe_function, dof_values);
2190  internal::do_function_gradients<dim,spacedim>
2191  (make_array_view(dof_values.begin(), dof_values.end()),
2192  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
2193  }
2194 
2195 
2196 
2197  template <int dim, int spacedim>
2198  template <class InputVector>
2199  void
2200  Tensor<2, dim, spacedim>::
2201  get_function_gradients_from_local_dof_values (const InputVector &dof_values,
2202  std::vector<typename OutputType<typename InputVector::value_type>::gradient_type> &gradients) const
2203  {
2204  Assert(fe_values->update_flags & update_gradients,
2205  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_gradients")));
2206  Assert(fe_values->present_cell.get() != nullptr,
2207  ExcMessage("FEValues object is not reinit'ed to any cell"));
2208  AssertDimension (dof_values.size(), fe_values->dofs_per_cell);
2209 
2210  internal::do_function_gradients<dim,spacedim>
2211  (make_array_view(dof_values.begin(), dof_values.end()),
2212  fe_values->finite_element_output.shape_gradients, shape_function_data, gradients);
2213  }
2214 
2215 }
2216 
2217 
2218 namespace internal
2219 {
2220  namespace FEValuesViews
2221  {
2222  template <int dim, int spacedim>
2224  {
2225  const FiniteElement<dim,spacedim> &fe = fe_values.get_fe();
2226 
2227  // create the views objects: Allocate a bunch of default-constructed ones
2228  // then destroy them again and do in-place construction of those we
2229  // actually want to use.
2230  const unsigned int n_scalars = fe.n_components();
2231  scalars.resize (n_scalars);
2232  for (unsigned int component=0; component<n_scalars; ++component)
2233  {
2234  // Use a typedef here to work around an issue with gcc-4.1:
2235  typedef ::FEValuesViews::Scalar<dim,spacedim> ScalarView;
2236  scalars[component].ScalarView::~ScalarView ();
2237 
2238  new (&scalars[component])
2240  component);
2241  }
2242 
2243  // compute number of vectors that we can fit into this finite element. note
2244  // that this is based on the dimensionality 'dim' of the
2245  // manifold, not 'spacedim' of the output vector
2246  const unsigned int n_vectors = (fe.n_components() >= spacedim ?
2247  fe.n_components()-spacedim+1 :
2248  0);
2249  vectors.resize (n_vectors);
2250  for (unsigned int component=0; component<n_vectors; ++component)
2251  {
2252  // Use a typedef here to work around an issue with gcc-4.1:
2253  typedef ::FEValuesViews::Vector<dim,spacedim> VectorView;
2254  vectors[component].VectorView::~VectorView ();
2255 
2256  new (&vectors[component])
2258  component);
2259  }
2260 
2261  // compute number of symmetric tensors in the same way as above
2262  const unsigned int n_symmetric_second_order_tensors
2263  = (fe.n_components() >= (dim*dim + dim)/2 ?
2264  fe.n_components() - (dim*dim + dim)/2 + 1 :
2265  0);
2266  symmetric_second_order_tensors.resize(n_symmetric_second_order_tensors);
2267  for (unsigned int component = 0; component < n_symmetric_second_order_tensors; ++component)
2268  {
2269  // Use a typedef here to work around an issue with gcc-4.1:
2270  typedef ::FEValuesViews::SymmetricTensor<2, dim, spacedim> SymmetricTensorView;
2271  symmetric_second_order_tensors[component].SymmetricTensorView::~SymmetricTensorView();
2272 
2273  new (&symmetric_second_order_tensors[component])
2275  component);
2276  }
2277 
2278 
2279  // compute number of symmetric tensors in the same way as above
2280  const unsigned int n_second_order_tensors
2281  = (fe.n_components() >= dim*dim ?
2282  fe.n_components() - dim*dim + 1 :
2283  0);
2284  second_order_tensors.resize(n_second_order_tensors);
2285  for (unsigned int component = 0; component < n_second_order_tensors; ++component)
2286  {
2287  // Use a typedef here to work around an issue with gcc-4.1:
2288  typedef ::FEValuesViews::Tensor<2, dim, spacedim> TensorView;
2289  second_order_tensors[component].TensorView::~TensorView();
2290 
2291  new (&second_order_tensors[component])
2293  component);
2294  }
2295  }
2296  }
2297 }
2298 
2299 
2300 /* ---------------- FEValuesBase<dim,spacedim>::CellIteratorBase --------- */
2301 
2302 template <int dim, int spacedim>
2303 class FEValuesBase<dim,spacedim>::CellIteratorBase
2304 {
2305 public:
2310  virtual ~CellIteratorBase () = default;
2311 
2318  virtual
2319  operator typename Triangulation<dim,spacedim>::cell_iterator () const = 0;
2320 
2325  virtual
2327  n_dofs_for_dof_handler () const = 0;
2328 
2329 #include "fe_values.decl.1.inst"
2330 
2335  virtual
2336  void
2337  get_interpolated_dof_values (const IndexSet &in,
2338  Vector<IndexSet::value_type> &out) const = 0;
2339 };
2340 
2341 /* ---------------- classes derived from FEValuesBase<dim,spacedim>::CellIteratorBase --------- */
2342 
2343 
2350 template <int dim, int spacedim>
2351 template <typename CI>
2352 class FEValuesBase<dim,spacedim>::CellIterator : public FEValuesBase<dim,spacedim>::CellIteratorBase
2353 {
2354 public:
2358  CellIterator (const CI &cell);
2359 
2366  virtual
2367  operator typename Triangulation<dim,spacedim>::cell_iterator () const;
2368 
2373  virtual
2375  n_dofs_for_dof_handler () const;
2376 
2377 #include "fe_values.decl.2.inst"
2378 
2383  virtual
2384  void
2385  get_interpolated_dof_values (const IndexSet &in,
2386  Vector<IndexSet::value_type> &out) const;
2387 
2388 private:
2392  const CI cell;
2393 };
2394 
2395 
2415 template <int dim, int spacedim>
2416 class FEValuesBase<dim,spacedim>::TriaCellIterator : public FEValuesBase<dim,spacedim>::CellIteratorBase
2417 {
2418 public:
2423 
2431  virtual
2432  operator typename Triangulation<dim,spacedim>::cell_iterator () const;
2433 
2438  virtual
2440  n_dofs_for_dof_handler () const;
2441 
2442 #include "fe_values.decl.2.inst"
2443 
2448  virtual
2449  void
2450  get_interpolated_dof_values (const IndexSet &in,
2451  Vector<IndexSet::value_type> &out) const;
2452 
2453 private:
2458 
2464  static const char *const message_string;
2465 };
2466 
2467 
2468 
2469 
2470 /* ---------------- FEValuesBase<dim,spacedim>::CellIterator<CI> --------- */
2471 
2472 
2473 template <int dim, int spacedim>
2474 template <typename CI>
2476  :
2477  cell(cell)
2478 {}
2479 
2480 
2481 
2482 template <int dim, int spacedim>
2483 template <typename CI>
2486 {
2487  return cell;
2488 }
2489 
2490 
2491 
2492 template <int dim, int spacedim>
2493 template <typename CI>
2496 {
2497  return cell->get_dof_handler().n_dofs();
2498 }
2499 
2500 
2501 
2502 #include "fe_values.impl.1.inst"
2503 
2504 
2505 
2506 template <int dim, int spacedim>
2507 template <typename CI>
2508 void
2511  Vector<IndexSet::value_type> &out) const
2512 {
2513  Assert (cell->has_children() == false, ExcNotImplemented());
2514 
2515  std::vector<types::global_dof_index> dof_indices (cell->get_fe().dofs_per_cell);
2516  cell->get_dof_indices (dof_indices);
2517 
2518  for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
2519  out[i] = (in.is_element (dof_indices[i]) ? 1 : 0);
2520 }
2521 
2522 
2523 /* ---------------- FEValuesBase<dim,spacedim>::TriaCellIterator --------- */
2524 
2525 template <int dim, int spacedim>
2526 const char *const
2528  = ("You have previously called the FEValues::reinit function with a\n"
2529  "cell iterator of type Triangulation<dim,spacedim>::cell_iterator. However,\n"
2530  "when you do this, you cannot call some functions in the FEValues\n"
2531  "class, such as the get_function_values/gradients/hessians/third_derivatives\n"
2532  "functions. If you need these functions, then you need to call\n"
2533  "FEValues::reinit with an iterator type that allows to extract\n"
2534  "degrees of freedom, such as DoFHandler<dim,spacedim>::cell_iterator.");
2535 
2536 
2537 
2538 template <int dim, int spacedim>
2541  :
2542  cell(cell)
2543 {}
2544 
2545 
2546 
2547 template <int dim, int spacedim>
2550 {
2551  return cell;
2552 }
2553 
2554 
2555 
2556 template <int dim, int spacedim>
2559 {
2560  Assert (false, ExcMessage (message_string));
2561  return 0;
2562 }
2563 
2564 
2565 
2566 #include "fe_values.impl.2.inst"
2567 
2568 
2569 
2570 template <int dim, int spacedim>
2571 void
2574  Vector<IndexSet::value_type> &) const
2575 {
2576  Assert (false, ExcMessage (message_string));
2577 }
2578 
2579 
2580 
2581 namespace internal
2582 {
2583  namespace FEValuesImplementation
2584  {
2585  template <int dim, int spacedim>
2586  void
2588  const UpdateFlags flags)
2589  {
2590  if (flags & update_quadrature_points)
2591  this->quadrature_points.resize(n_quadrature_points,
2593 
2594  if (flags & update_JxW_values)
2595  this->JxW_values.resize(n_quadrature_points,
2596  numbers::signaling_nan<double>());
2597 
2598  if (flags & update_jacobians)
2599  this->jacobians.resize(n_quadrature_points,
2601 
2602  if (flags & update_jacobian_grads)
2603  this->jacobian_grads.resize(n_quadrature_points,
2605 
2607  this->jacobian_pushed_forward_grads.resize(n_quadrature_points,
2609 
2610  if (flags & update_jacobian_2nd_derivatives)
2611  this->jacobian_2nd_derivatives.resize(n_quadrature_points,
2613 
2615  this->jacobian_pushed_forward_2nd_derivatives.resize(n_quadrature_points,
2617 
2618  if (flags & update_jacobian_3rd_derivatives)
2619  this->jacobian_3rd_derivatives.resize(n_quadrature_points);
2620 
2622  this->jacobian_pushed_forward_3rd_derivatives.resize(n_quadrature_points,
2624 
2625  if (flags & update_inverse_jacobians)
2626  this->inverse_jacobians.resize(n_quadrature_points,
2628 
2629  if (flags & update_boundary_forms)
2630  this->boundary_forms.resize(n_quadrature_points,
2632 
2633  if (flags & update_normal_vectors)
2634  this->normal_vectors.resize(n_quadrature_points,
2636  }
2637 
2638 
2639 
2640  template <int dim, int spacedim>
2641  std::size_t
2643  {
2644  return (MemoryConsumption::memory_consumption (JxW_values) +
2646  MemoryConsumption::memory_consumption (jacobian_grads) +
2647  MemoryConsumption::memory_consumption (jacobian_pushed_forward_grads) +
2648  MemoryConsumption::memory_consumption (jacobian_2nd_derivatives) +
2649  MemoryConsumption::memory_consumption (jacobian_pushed_forward_2nd_derivatives) +
2650  MemoryConsumption::memory_consumption (jacobian_3rd_derivatives) +
2651  MemoryConsumption::memory_consumption (jacobian_pushed_forward_3rd_derivatives) +
2652  MemoryConsumption::memory_consumption (inverse_jacobians) +
2653  MemoryConsumption::memory_consumption (quadrature_points) +
2654  MemoryConsumption::memory_consumption (normal_vectors) +
2655  MemoryConsumption::memory_consumption (boundary_forms));
2656  }
2657 
2658 
2659 
2660  template <int dim, int spacedim>
2661  void
2664  const UpdateFlags flags)
2665  {
2666  // initialize the table mapping from shape function number to
2667  // the rows in the tables storing the data by shape function and
2668  // nonzero component
2669  this->shape_function_to_row_table
2670  = ::internal::make_shape_function_to_row_table (fe);
2671 
2672  // count the total number of non-zero components accumulated
2673  // over all shape functions
2674  unsigned int n_nonzero_shape_components = 0;
2675  for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2676  n_nonzero_shape_components += fe.n_nonzero_components (i);
2677  Assert (n_nonzero_shape_components >= fe.dofs_per_cell,
2678  ExcInternalError());
2679 
2680  // with the number of rows now known, initialize those fields
2681  // that we will need to their correct size
2682  if (flags & update_values)
2683  {
2684  this->shape_values.reinit(n_nonzero_shape_components,
2686  this->shape_values.fill(numbers::signaling_nan<double>());
2687  }
2688 
2689  if (flags & update_gradients)
2690  {
2691  this->shape_gradients.reinit(n_nonzero_shape_components,
2693  this->shape_gradients.fill (numbers::signaling_nan<Tensor<1,spacedim> >());
2694  }
2695 
2696  if (flags & update_hessians)
2697  {
2698  this->shape_hessians.reinit(n_nonzero_shape_components,
2700  this->shape_hessians.fill (numbers::signaling_nan<Tensor<2,spacedim> >());
2701  }
2702 
2703  if (flags & update_3rd_derivatives)
2704  {
2705  this->shape_3rd_derivatives.reinit(n_nonzero_shape_components,
2707  this->shape_3rd_derivatives.fill (numbers::signaling_nan<Tensor<3,spacedim> >());
2708  }
2709  }
2710 
2711 
2712 
2713 
2714  template <int dim, int spacedim>
2715  std::size_t
2717  {
2718  return (MemoryConsumption::memory_consumption (shape_values) +
2719  MemoryConsumption::memory_consumption (shape_gradients) +
2720  MemoryConsumption::memory_consumption (shape_hessians) +
2721  MemoryConsumption::memory_consumption (shape_3rd_derivatives) +
2722  MemoryConsumption::memory_consumption (shape_function_to_row_table));
2723  }
2724  }
2725 }
2726 
2727 
2728 
2729 /*------------------------------- FEValuesBase ---------------------------*/
2730 
2731 
2732 template <int dim, int spacedim>
2733 FEValuesBase<dim,spacedim>::FEValuesBase (const unsigned int n_q_points,
2734  const unsigned int dofs_per_cell,
2735  const UpdateFlags flags,
2738  :
2739  n_quadrature_points (n_q_points),
2741  mapping(&mapping, typeid(*this).name()),
2742  fe(&fe, typeid(*this).name()),
2743  cell_similarity(CellSimilarity::Similarity::none),
2744  fe_values_views_cache (*this)
2745 {
2746  Assert (n_q_points > 0,
2747  ExcMessage ("There is nothing useful you can do with an FEValues "
2748  "object when using a quadrature formula with zero "
2749  "quadrature points!"));
2750  this->update_flags = flags;
2751 }
2752 
2753 
2754 
2755 template <int dim, int spacedim>
2757 {
2758  tria_listener_refinement.disconnect ();
2759  tria_listener_mesh_transform.disconnect ();
2760 }
2761 
2762 
2763 
2764 namespace internal
2765 {
2766  // put shape function part of get_function_xxx methods into separate
2767  // internal functions. this allows us to reuse the same code for several
2768  // functions (e.g. both the versions with and without indices) as well as
2769  // the same code for gradients and Hessians. Moreover, this speeds up
2770  // compilation and reduces the size of the final file since all the
2771  // different global vectors get channeled through the same code.
2772 
2773  template <typename Number, typename Number2>
2774  void
2775  do_function_values (const Number2 *dof_values_ptr,
2776  const ::Table<2,double> &shape_values,
2777  std::vector<Number> &values)
2778  {
2779  // scalar finite elements, so shape_values.size() == dofs_per_cell
2780  const unsigned int dofs_per_cell = shape_values.n_rows();
2781  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
2782  shape_values.n_cols() : values.size();
2783  AssertDimension(values.size(), n_quadrature_points);
2784 
2785  // initialize with zero
2786  std::fill_n (values.begin(), n_quadrature_points,
2788 
2789  // add up contributions of trial functions. note that here we deal with
2790  // scalar finite elements, so no need to check for non-primitivity of
2791  // shape functions. in order to increase the speed of this function, we
2792  // directly access the data in the shape_values array, and increment
2793  // pointers for accessing the data. this saves some lookup time and
2794  // indexing. moreover, the order of the loops is such that we can access
2795  // the shape_values data stored contiguously
2796  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
2797  {
2798  const Number2 value = dof_values_ptr[shape_func];
2799  // For auto-differentiable numbers, the fact that a DoF value is zero
2800  // does not imply that its derivatives are zero as well. So we
2801  // can't filter by value for these number types.
2803  if (value == ::internal::NumberType<Number2>::value(0.0))
2804  continue;
2805 
2806  const double *shape_value_ptr = &shape_values(shape_func, 0);
2807  for (unsigned int point=0; point<n_quadrature_points; ++point)
2808  values[point] += value * (*shape_value_ptr++);
2809  }
2810  }
2811 
2812 
2813 
2814  template <int dim, int spacedim, typename VectorType>
2815  void
2816  do_function_values (const typename VectorType::value_type *dof_values_ptr,
2817  const ::Table<2,double> &shape_values,
2818  const FiniteElement<dim,spacedim> &fe,
2819  const std::vector<unsigned int> &shape_function_to_row_table,
2820  ArrayView<VectorType> values,
2821  const bool quadrature_points_fastest = false,
2822  const unsigned int component_multiple = 1)
2823  {
2824  typedef typename VectorType::value_type Number;
2825  // initialize with zero
2826  for (unsigned int i=0; i<values.size(); ++i)
2827  std::fill_n (values[i].begin(), values[i].size(),
2828  typename VectorType::value_type());
2829 
2830  // see if there the current cell has DoFs at all, and if not
2831  // then there is nothing else to do.
2832  const unsigned int dofs_per_cell = fe.dofs_per_cell;
2833  if (dofs_per_cell == 0)
2834  return;
2835 
2836  const unsigned int n_quadrature_points = shape_values.n_cols();
2837  const unsigned int n_components = fe.n_components();
2838 
2839  // Assert that we can write all components into the result vectors
2840  const unsigned result_components = n_components * component_multiple;
2841  (void)result_components;
2842  if (quadrature_points_fastest)
2843  {
2844  AssertDimension(values.size(), result_components);
2845  for (unsigned int i=0; i<values.size(); ++i)
2846  AssertDimension (values[i].size(), n_quadrature_points);
2847  }
2848  else
2849  {
2850  AssertDimension(values.size(), n_quadrature_points);
2851  for (unsigned int i=0; i<values.size(); ++i)
2852  AssertDimension (values[i].size(), result_components);
2853  }
2854 
2855  // add up contributions of trial functions. now check whether the shape
2856  // function is primitive or not. if it is, then set its only non-zero
2857  // component, otherwise loop over components
2858  for (unsigned int mc = 0; mc < component_multiple; ++mc)
2859  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
2860  {
2861  const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
2862  // For auto-differentiable numbers, the fact that a DoF value is zero
2863  // does not imply that its derivatives are zero as well. So we
2864  // can't filter by value for these number types.
2865  if (::internal::CheckForZero<Number>::value(value) == true)
2866  continue;
2867 
2868  if (fe.is_primitive(shape_func))
2869  {
2870  const unsigned int comp =
2871  fe.system_to_component_index(shape_func).first
2872  + mc * n_components;
2873  const unsigned int
2874  row = shape_function_to_row_table[shape_func*n_components+comp];
2875 
2876  const double *shape_value_ptr = &shape_values(row, 0);
2877 
2878  if (quadrature_points_fastest)
2879  {
2880  VectorType &values_comp = values[comp];
2881  for (unsigned int point=0; point<n_quadrature_points; ++point)
2882  values_comp[point] += value * (*shape_value_ptr++);
2883  }
2884  else
2885  for (unsigned int point=0; point<n_quadrature_points; ++point)
2886  values[point][comp] += value * (*shape_value_ptr++);
2887  }
2888  else
2889  for (unsigned int c=0; c<n_components; ++c)
2890  {
2891  if (fe.get_nonzero_components(shape_func)[c] == false)
2892  continue;
2893 
2894  const unsigned int
2895  row = shape_function_to_row_table[shape_func*n_components+c];
2896 
2897  const double *shape_value_ptr = &shape_values(row, 0);
2898  const unsigned int comp = c + mc * n_components;
2899 
2900  if (quadrature_points_fastest)
2901  {
2902  VectorType &values_comp = values[comp];
2903  for (unsigned int point=0; point<n_quadrature_points;
2904  ++point)
2905  values_comp[point] += value * (*shape_value_ptr++);
2906  }
2907  else
2908  for (unsigned int point=0; point<n_quadrature_points; ++point)
2909  values[point][comp] += value * (*shape_value_ptr++);
2910  }
2911  }
2912  }
2913 
2914 
2915 
2916  // use the same implementation for gradients and Hessians, distinguish them
2917  // by the rank of the tensors
2918  template <int order, int spacedim, typename Number>
2919  void
2920  do_function_derivatives (const Number *dof_values_ptr,
2921  const ::Table<2,Tensor<order,spacedim> > &shape_derivatives,
2922  std::vector<Tensor<order,spacedim,Number> > &derivatives)
2923  {
2924  const unsigned int dofs_per_cell = shape_derivatives.size()[0];
2925  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
2926  shape_derivatives[0].size() : derivatives.size();
2927  AssertDimension(derivatives.size(), n_quadrature_points);
2928 
2929  // initialize with zero
2930  std::fill_n (derivatives.begin(), n_quadrature_points, Tensor<order,spacedim,Number>());
2931 
2932  // add up contributions of trial functions. note that here we deal with
2933  // scalar finite elements, so no need to check for non-primitivity of
2934  // shape functions. in order to increase the speed of this function, we
2935  // directly access the data in the shape_gradients/hessians array, and
2936  // increment pointers for accessing the data. this saves some lookup time
2937  // and indexing. moreover, the order of the loops is such that we can
2938  // access the shape_gradients/hessians data stored contiguously
2939  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
2940  {
2941  const Number &value = dof_values_ptr[shape_func];
2942  // For auto-differentiable numbers, the fact that a DoF value is zero
2943  // does not imply that its derivatives are zero as well. So we
2944  // can't filter by value for these number types.
2945  if (::internal::CheckForZero<Number>::value(value) == true)
2946  continue;
2947 
2948  const Tensor<order,spacedim> *shape_derivative_ptr
2949  = &shape_derivatives[shape_func][0];
2950  for (unsigned int point=0; point<n_quadrature_points; ++point)
2951  derivatives[point] += value * (*shape_derivative_ptr++);
2952  }
2953  }
2954 
2955 
2956 
2957  template <int order, int dim, int spacedim, typename Number>
2958  void
2959  do_function_derivatives (const Number *dof_values_ptr,
2960  const ::Table<2,Tensor<order,spacedim> > &shape_derivatives,
2961  const FiniteElement<dim,spacedim> &fe,
2962  const std::vector<unsigned int> &shape_function_to_row_table,
2963  ArrayView<std::vector<Tensor<order,spacedim,Number> > > derivatives,
2964  const bool quadrature_points_fastest = false,
2965  const unsigned int component_multiple = 1)
2966  {
2967  // initialize with zero
2968  for (unsigned int i=0; i<derivatives.size(); ++i)
2969  std::fill_n (derivatives[i].begin(), derivatives[i].size(),
2971 
2972  // see if there the current cell has DoFs at all, and if not
2973  // then there is nothing else to do.
2974  const unsigned int dofs_per_cell = fe.dofs_per_cell;
2975  if (dofs_per_cell == 0)
2976  return;
2977 
2978 
2979  const unsigned int n_quadrature_points = shape_derivatives[0].size();
2980  const unsigned int n_components = fe.n_components();
2981 
2982  // Assert that we can write all components into the result vectors
2983  const unsigned result_components = n_components * component_multiple;
2984  (void)result_components;
2985  if (quadrature_points_fastest)
2986  {
2987  AssertDimension(derivatives.size(), result_components);
2988  for (unsigned int i=0; i<derivatives.size(); ++i)
2989  AssertDimension (derivatives[i].size(), n_quadrature_points);
2990  }
2991  else
2992  {
2993  AssertDimension(derivatives.size(), n_quadrature_points);
2994  for (unsigned int i=0; i<derivatives.size(); ++i)
2995  AssertDimension (derivatives[i].size(), result_components);
2996  }
2997 
2998  // add up contributions of trial functions. now check whether the shape
2999  // function is primitive or not. if it is, then set its only non-zero
3000  // component, otherwise loop over components
3001  for (unsigned int mc = 0; mc < component_multiple; ++mc)
3002  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
3003  {
3004  const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
3005  // For auto-differentiable numbers, the fact that a DoF value is zero
3006  // does not imply that its derivatives are zero as well. So we
3007  // can't filter by value for these number types.
3008  if (::internal::CheckForZero<Number>::value(value) == true)
3009  continue;
3010 
3011  if (fe.is_primitive(shape_func))
3012  {
3013  const unsigned int comp =
3014  fe.system_to_component_index(shape_func).first
3015  + mc * n_components;
3016  const unsigned int
3017  row = shape_function_to_row_table[shape_func*n_components+comp];
3018 
3019  const Tensor<order,spacedim> *shape_derivative_ptr =
3020  &shape_derivatives[row][0];
3021 
3022  if (quadrature_points_fastest)
3023  for (unsigned int point=0; point<n_quadrature_points; ++point)
3024  derivatives[comp][point] += value * (*shape_derivative_ptr++);
3025  else
3026  for (unsigned int point=0; point<n_quadrature_points; ++point)
3027  derivatives[point][comp] += value * (*shape_derivative_ptr++);
3028  }
3029  else
3030  for (unsigned int c=0; c<n_components; ++c)
3031  {
3032  if (fe.get_nonzero_components(shape_func)[c] == false)
3033  continue;
3034 
3035  const unsigned int
3036  row = shape_function_to_row_table[shape_func*n_components+c];
3037 
3038  const Tensor<order,spacedim> *shape_derivative_ptr =
3039  &shape_derivatives[row][0];
3040  const unsigned int comp = c + mc * n_components;
3041 
3042  if (quadrature_points_fastest)
3043  for (unsigned int point=0; point<n_quadrature_points; ++point)
3044  derivatives[comp][point] += value * (*shape_derivative_ptr++);
3045  else
3046  for (unsigned int point=0; point<n_quadrature_points; ++point)
3047  derivatives[point][comp] += value * (*shape_derivative_ptr++);
3048  }
3049  }
3050  }
3051 
3052 
3053 
3054  template <int spacedim, typename Number, typename Number2>
3055  void
3056  do_function_laplacians (const Number2 *dof_values_ptr,
3057  const ::Table<2,Tensor<2,spacedim> > &shape_hessians,
3058  std::vector<Number> &laplacians)
3059  {
3060  const unsigned int dofs_per_cell = shape_hessians.size()[0];
3061  const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
3062  shape_hessians[0].size() : laplacians.size();
3063  AssertDimension(laplacians.size(), n_quadrature_points);
3064 
3065  // initialize with zero
3066  std::fill_n (laplacians.begin(), n_quadrature_points,
3068 
3069  // add up contributions of trial functions. note that here we deal with
3070  // scalar finite elements and also note that the Laplacian is
3071  // the trace of the Hessian.
3072  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
3073  {
3074  const Number2 value = dof_values_ptr[shape_func];
3075  // For auto-differentiable numbers, the fact that a DoF value is zero
3076  // does not imply that its derivatives are zero as well. So we
3077  // can't filter by value for these number types.
3079  if (value == ::internal::NumberType<Number2>::value(0.0))
3080  continue;
3081 
3082  const Tensor<2,spacedim> *shape_hessian_ptr
3083  = &shape_hessians[shape_func][0];
3084  for (unsigned int point=0; point<n_quadrature_points; ++point)
3085  laplacians[point] += value * trace(*shape_hessian_ptr++);
3086  }
3087  }
3088 
3089 
3090 
3091  template <int dim, int spacedim, typename VectorType, typename Number>
3092  void
3093  do_function_laplacians (const Number *dof_values_ptr,
3094  const ::Table<2,Tensor<2,spacedim> > &shape_hessians,
3095  const FiniteElement<dim,spacedim> &fe,
3096  const std::vector<unsigned int> &shape_function_to_row_table,
3097  std::vector<VectorType> &laplacians,
3098  const bool quadrature_points_fastest = false,
3099  const unsigned int component_multiple = 1)
3100  {
3101  // initialize with zero
3102  for (unsigned int i=0; i<laplacians.size(); ++i)
3103  std::fill_n (laplacians[i].begin(), laplacians[i].size(),
3104  typename VectorType::value_type());
3105 
3106  // see if there the current cell has DoFs at all, and if not
3107  // then there is nothing else to do.
3108  const unsigned int dofs_per_cell = fe.dofs_per_cell;
3109  if (dofs_per_cell == 0)
3110  return;
3111 
3112 
3113  const unsigned int n_quadrature_points = shape_hessians[0].size();
3114  const unsigned int n_components = fe.n_components();
3115 
3116  // Assert that we can write all components into the result vectors
3117  const unsigned result_components = n_components * component_multiple;
3118  (void)result_components;
3119  if (quadrature_points_fastest)
3120  {
3121  AssertDimension(laplacians.size(), result_components);
3122  for (unsigned int i=0; i<laplacians.size(); ++i)
3123  AssertDimension (laplacians[i].size(), n_quadrature_points);
3124  }
3125  else
3126  {
3127  AssertDimension(laplacians.size(), n_quadrature_points);
3128  for (unsigned int i=0; i<laplacians.size(); ++i)
3129  AssertDimension (laplacians[i].size(), result_components);
3130  }
3131 
3132  // add up contributions of trial functions. now check whether the shape
3133  // function is primitive or not. if it is, then set its only non-zero
3134  // component, otherwise loop over components
3135  for (unsigned int mc = 0; mc < component_multiple; ++mc)
3136  for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
3137  {
3138  const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
3139  // For auto-differentiable numbers, the fact that a DoF value is zero
3140  // does not imply that its derivatives are zero as well. So we
3141  // can't filter by value for these number types.
3142  if (::internal::CheckForZero<Number>::value(value) == true)
3143  continue;
3144 
3145  if (fe.is_primitive(shape_func))
3146  {
3147  const unsigned int comp =
3148  fe.system_to_component_index(shape_func).first
3149  + mc * n_components;
3150  const unsigned int
3151  row = shape_function_to_row_table[shape_func*n_components+comp];
3152 
3153  const Tensor<2,spacedim> *shape_hessian_ptr =
3154  &shape_hessians[row][0];
3155  if (quadrature_points_fastest)
3156  {
3157  VectorType &laplacians_comp = laplacians[comp];
3158  for (unsigned int point=0; point<n_quadrature_points; ++point)
3159  laplacians_comp[point] += value * trace(*shape_hessian_ptr++);
3160  }
3161  else
3162  for (unsigned int point=0; point<n_quadrature_points; ++point)
3163  laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
3164  }
3165  else
3166  for (unsigned int c=0; c<n_components; ++c)
3167  {
3168  if (fe.get_nonzero_components(shape_func)[c] == false)
3169  continue;
3170 
3171  const unsigned int
3172  row = shape_function_to_row_table[shape_func*n_components+c];
3173 
3174  const Tensor<2,spacedim> *shape_hessian_ptr =
3175  &shape_hessians[row][0];
3176  const unsigned int comp = c + mc * n_components;
3177 
3178  if (quadrature_points_fastest)
3179  {
3180  VectorType &laplacians_comp = laplacians[comp];
3181  for (unsigned int point=0; point<n_quadrature_points;
3182  ++point)
3183  laplacians_comp[point] += value * trace(*shape_hessian_ptr++);
3184  }
3185  else
3186  for (unsigned int point=0; point<n_quadrature_points; ++point)
3187  laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
3188  }
3189  }
3190  }
3191 }
3192 
3193 
3194 
3195 template <int dim, int spacedim>
3196 template <class InputVector>
3198  const InputVector &fe_function,
3199  std::vector<typename InputVector::value_type> &values) const
3200 {
3201  typedef typename InputVector::value_type Number;
3202  Assert (this->update_flags & update_values,
3203  ExcAccessToUninitializedField("update_values"));
3204  AssertDimension (fe->n_components(), 1);
3205  Assert (present_cell.get() != nullptr,
3206  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3207  AssertDimension (fe_function.size(),
3208  present_cell->n_dofs_for_dof_handler());
3209 
3210  // get function values of dofs on this cell
3211  Vector<Number> dof_values (dofs_per_cell);
3212  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3213  internal::do_function_values (dof_values.begin(), this->finite_element_output.shape_values,
3214  values);
3215 }
3216 
3217 
3218 
3219 template <int dim, int spacedim>
3220 template <class InputVector>
3222  const InputVector &fe_function,
3223  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3224  std::vector<typename InputVector::value_type> &values) const
3225 {
3226  typedef typename InputVector::value_type Number;
3227  Assert (this->update_flags & update_values,
3228  ExcAccessToUninitializedField("update_values"));
3229  AssertDimension (fe->n_components(), 1);
3230  AssertDimension (indices.size(), dofs_per_cell);
3231 
3232  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3233  for (unsigned int i=0; i<dofs_per_cell; ++i)
3234  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3235  internal::do_function_values(dof_values.data(), this->finite_element_output.shape_values, values);
3236 }
3237 
3238 
3239 
3240 template <int dim, int spacedim>
3241 template <class InputVector>
3243  const InputVector &fe_function,
3244  std::vector<Vector<typename InputVector::value_type> > &values) const
3245 {
3246  typedef typename InputVector::value_type Number;
3247  Assert (present_cell.get() != nullptr,
3248  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3249 
3250  Assert (this->update_flags & update_values,
3251  ExcAccessToUninitializedField("update_values"));
3252  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3253 
3254  // get function values of dofs on this cell
3255  Vector<Number> dof_values (dofs_per_cell);
3256  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3257  internal::do_function_values(dof_values.begin(),
3258  this->finite_element_output.shape_values,
3259  *fe,
3260  this->finite_element_output.shape_function_to_row_table,
3261  make_array_view(values.begin(), values.end()));
3262 }
3263 
3264 
3265 
3266 template <int dim, int spacedim>
3267 template <class InputVector>
3269  const InputVector &fe_function,
3270  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3271  std::vector<Vector<typename InputVector::value_type> > &values) const
3272 {
3273  typedef typename InputVector::value_type Number;
3274  // Size of indices must be a multiple of dofs_per_cell such that an integer
3275  // number of function values is generated in each point.
3276  Assert (indices.size() % dofs_per_cell == 0,
3277  ExcNotMultiple(indices.size(), dofs_per_cell));
3278  Assert (this->update_flags & update_values,
3279  ExcAccessToUninitializedField("update_values"));
3280 
3281  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3282  for (unsigned int i=0; i<dofs_per_cell; ++i)
3283  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3284  internal::do_function_values(dof_values.data(),
3285  this->finite_element_output.shape_values,
3286  *fe,
3287  this->finite_element_output.shape_function_to_row_table,
3288  make_array_view(values.begin(), values.end()),
3289  false,
3290  indices.size()/dofs_per_cell);
3291 }
3292 
3293 
3294 
3295 template <int dim, int spacedim>
3296 template <class InputVector>
3298  const InputVector &fe_function,
3299  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3300  VectorSlice<std::vector<std::vector<typename InputVector::value_type> > > values,
3301  bool quadrature_points_fastest) const
3302 {
3303  typedef typename InputVector::value_type Number;
3304  Assert (this->update_flags & update_values,
3305  ExcAccessToUninitializedField("update_values"));
3306 
3307  // Size of indices must be a multiple of dofs_per_cell such that an integer
3308  // number of function values is generated in each point.
3309  Assert (indices.size() % dofs_per_cell == 0,
3310  ExcNotMultiple(indices.size(), dofs_per_cell));
3311 
3312  boost::container::small_vector<Number, 200> dof_values(indices.size());
3313  for (unsigned int i=0; i<indices.size(); ++i)
3314  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3315  internal::do_function_values(dof_values.data(),
3316  this->finite_element_output.shape_values,
3317  *fe,
3318  this->finite_element_output.shape_function_to_row_table,
3319  make_array_view(values.begin(), values.end()),
3320  quadrature_points_fastest,
3321  indices.size()/dofs_per_cell);
3322 }
3323 
3324 
3325 
3326 template <int dim, int spacedim>
3327 template <class InputVector>
3328 void
3330  const InputVector &fe_function,
3331  std::vector<Tensor<1,spacedim,typename InputVector::value_type> > &gradients) const
3332 {
3333  typedef typename InputVector::value_type Number;
3334  Assert (this->update_flags & update_gradients,
3335  ExcAccessToUninitializedField("update_gradients"));
3336  AssertDimension (fe->n_components(), 1);
3337  Assert (present_cell.get() != nullptr,
3338  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3339  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3340 
3341  // get function values of dofs on this cell
3342  Vector<Number> dof_values (dofs_per_cell);
3343  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3344  internal::do_function_derivatives(dof_values.begin(), this->finite_element_output.shape_gradients,
3345  gradients);
3346 }
3347 
3348 
3349 
3350 template <int dim, int spacedim>
3351 template <class InputVector>
3353  const InputVector &fe_function,
3354  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3355  std::vector<Tensor<1,spacedim,typename InputVector::value_type> > &gradients) const
3356 {
3357  typedef typename InputVector::value_type Number;
3358  Assert (this->update_flags & update_gradients,
3359  ExcAccessToUninitializedField("update_gradients"));
3360  AssertDimension (fe->n_components(), 1);
3361  AssertDimension (indices.size(), dofs_per_cell);
3362 
3363  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3364  for (unsigned int i=0; i<dofs_per_cell; ++i)
3365  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3366  internal::do_function_derivatives(dof_values.data(), this->finite_element_output.shape_gradients,
3367  gradients);
3368 }
3369 
3370 
3371 
3372 template <int dim, int spacedim>
3373 template <class InputVector>
3374 void
3376  const InputVector &fe_function,
3377  std::vector<std::vector<Tensor<1,spacedim,typename InputVector::value_type> > > &gradients) const
3378 {
3379  typedef typename InputVector::value_type Number;
3380  Assert (this->update_flags & update_gradients,
3381  ExcAccessToUninitializedField("update_gradients"));
3382  Assert (present_cell.get() != nullptr,
3383  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3384  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3385 
3386  // get function values of dofs on this cell
3387  Vector<Number> dof_values (dofs_per_cell);
3388  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3389  internal::do_function_derivatives(dof_values.begin(),
3390  this->finite_element_output.shape_gradients,
3391  *fe,
3392  this->finite_element_output.shape_function_to_row_table,
3393  make_array_view(gradients.begin(), gradients.end()));
3394 }
3395 
3396 
3397 
3398 template <int dim, int spacedim>
3399 template <class InputVector>
3401  const InputVector &fe_function,
3402  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3403  VectorSlice<std::vector<std::vector<Tensor<1,spacedim,typename InputVector::value_type> > > > gradients,
3404  bool quadrature_points_fastest) const
3405 {
3406  typedef typename InputVector::value_type Number;
3407  // Size of indices must be a multiple of dofs_per_cell such that an integer
3408  // number of function values is generated in each point.
3409  Assert (indices.size() % dofs_per_cell == 0,
3410  ExcNotMultiple(indices.size(), dofs_per_cell));
3411  Assert (this->update_flags & update_gradients,
3412  ExcAccessToUninitializedField("update_gradients"));
3413 
3414  boost::container::small_vector<Number, 200> dof_values(indices.size());
3415  for (unsigned int i=0; i<indices.size(); ++i)
3416  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3417  internal::do_function_derivatives(dof_values.data(),
3418  this->finite_element_output.shape_gradients,
3419  *fe,
3420  this->finite_element_output.shape_function_to_row_table,
3421  make_array_view(gradients.begin(), gradients.end()),
3422  quadrature_points_fastest,
3423  indices.size()/dofs_per_cell);
3424 }
3425 
3426 
3427 
3428 template <int dim, int spacedim>
3429 template <class InputVector>
3430 void
3432 get_function_hessians (const InputVector &fe_function,
3433  std::vector<Tensor<2,spacedim,typename InputVector::value_type> > &hessians) const
3434 {
3435  typedef typename InputVector::value_type Number;
3436  AssertDimension (fe->n_components(), 1);
3437  Assert (this->update_flags & update_hessians,
3438  ExcAccessToUninitializedField("update_hessians"));
3439  Assert (present_cell.get() != nullptr,
3440  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3441  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3442 
3443  // get function values of dofs on this cell
3444  Vector<Number> dof_values (dofs_per_cell);
3445  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3446  internal::do_function_derivatives(dof_values.begin(), this->finite_element_output.shape_hessians,
3447  hessians);
3448 }
3449 
3450 
3451 
3452 template <int dim, int spacedim>
3453 template <class InputVector>
3455  const InputVector &fe_function,
3456  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3457  std::vector<Tensor<2,spacedim,typename InputVector::value_type> > &hessians) const
3458 {
3459  typedef typename InputVector::value_type Number;
3460  Assert (this->update_flags & update_hessians,
3461  ExcAccessToUninitializedField("update_hessians"));
3462  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3463  AssertDimension (indices.size(), dofs_per_cell);
3464 
3465  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3466  for (unsigned int i=0; i<dofs_per_cell; ++i)
3467  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3468  internal::do_function_derivatives(dof_values.data(), this->finite_element_output.shape_hessians,
3469  hessians);
3470 }
3471 
3472 
3473 
3474 template <int dim, int spacedim>
3475 template <class InputVector>
3476 void
3478 get_function_hessians (const InputVector &fe_function,
3479  std::vector<std::vector<Tensor<2,spacedim,typename InputVector::value_type> > > &hessians,
3480  bool quadrature_points_fastest) const
3481 {
3482  typedef typename InputVector::value_type Number;
3483  Assert (this->update_flags & update_hessians,
3484  ExcAccessToUninitializedField("update_hessians"));
3485  Assert (present_cell.get() != nullptr,
3486  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3487  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3488 
3489  // get function values of dofs on this cell
3490  Vector<Number> dof_values (dofs_per_cell);
3491  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3492  internal::do_function_derivatives(dof_values.begin(),
3493  this->finite_element_output.shape_hessians,
3494  *fe,
3495  this->finite_element_output.shape_function_to_row_table,
3496  make_array_view(hessians.begin(), hessians.end()),
3497  quadrature_points_fastest);
3498 }
3499 
3500 
3501 
3502 template <int dim, int spacedim>
3503 template <class InputVector>
3505  const InputVector &fe_function,
3506  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3507  VectorSlice<std::vector<std::vector<Tensor<2,spacedim,typename InputVector::value_type> > > > hessians,
3508  bool quadrature_points_fastest) const
3509 {
3510  typedef typename InputVector::value_type Number;
3511  Assert (this->update_flags & update_hessians,
3512  ExcAccessToUninitializedField("update_hessians"));
3513  Assert (indices.size() % dofs_per_cell == 0,
3514  ExcNotMultiple(indices.size(), dofs_per_cell));
3515 
3516  boost::container::small_vector<Number, 200> dof_values(indices.size());
3517  for (unsigned int i=0; i<indices.size(); ++i)
3518  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3519  internal::do_function_derivatives(dof_values.data(),
3520  this->finite_element_output.shape_hessians,
3521  *fe,
3522  this->finite_element_output.shape_function_to_row_table,
3523  make_array_view(hessians.begin(), hessians.end()),
3524  quadrature_points_fastest,
3525  indices.size()/dofs_per_cell);
3526 }
3527 
3528 
3529 
3530 template <int dim, int spacedim>
3531 template <class InputVector>
3533  const InputVector &fe_function,
3534  std::vector<typename InputVector::value_type> &laplacians) const
3535 {
3536  typedef typename InputVector::value_type Number;
3537  Assert (this->update_flags & update_hessians,
3538  ExcAccessToUninitializedField("update_hessians"));
3539  AssertDimension (fe->n_components(), 1);
3540  Assert (present_cell.get() != nullptr,
3541  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3542  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3543 
3544  // get function values of dofs on this cell
3545  Vector<Number> dof_values (dofs_per_cell);
3546  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3547  internal::do_function_laplacians(dof_values.begin(), this->finite_element_output.shape_hessians,
3548  laplacians);
3549 }
3550 
3551 
3552 
3553 template <int dim, int spacedim>
3554 template <class InputVector>
3556  const InputVector &fe_function,
3557  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3558  std::vector<typename InputVector::value_type> &laplacians) const
3559 {
3560  typedef typename InputVector::value_type Number;
3561  Assert (this->update_flags & update_hessians,
3562  ExcAccessToUninitializedField("update_hessians"));
3563  AssertDimension (fe->n_components(), 1);
3564  AssertDimension (indices.size(), dofs_per_cell);
3565 
3566  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3567  for (unsigned int i=0; i<dofs_per_cell; ++i)
3568  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3569  internal::do_function_laplacians(dof_values.data(), this->finite_element_output.shape_hessians,
3570  laplacians);
3571 }
3572 
3573 
3574 
3575 template <int dim, int spacedim>
3576 template <class InputVector>
3578  const InputVector &fe_function,
3579  std::vector<Vector<typename InputVector::value_type> > &laplacians) const
3580 {
3581  typedef typename InputVector::value_type Number;
3582  Assert (present_cell.get() != nullptr,
3583  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3584  Assert (this->update_flags & update_hessians,
3585  ExcAccessToUninitializedField("update_hessians"));
3586  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3587 
3588  // get function values of dofs on this cell
3589  Vector<Number> dof_values (dofs_per_cell);
3590  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3591  internal::do_function_laplacians(dof_values.begin(), this->finite_element_output.shape_hessians,
3592  *fe, this->finite_element_output.shape_function_to_row_table,
3593  laplacians);
3594 }
3595 
3596 
3597 
3598 template <int dim, int spacedim>
3599 template <class InputVector>
3601  const InputVector &fe_function,
3602  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3603  std::vector<Vector<typename InputVector::value_type> > &laplacians) const
3604 {
3605  typedef typename InputVector::value_type Number;
3606  // Size of indices must be a multiple of dofs_per_cell such that an integer
3607  // number of function values is generated in each point.
3608  Assert (indices.size() % dofs_per_cell == 0,
3609  ExcNotMultiple(indices.size(), dofs_per_cell));
3610  Assert (this->update_flags & update_hessians,
3611  ExcAccessToUninitializedField("update_hessians"));
3612 
3613  boost::container::small_vector<Number, 200> dof_values(indices.size());
3614  for (unsigned int i=0; i<indices.size(); ++i)
3615  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3616  internal::do_function_laplacians(dof_values.data(), this->finite_element_output.shape_hessians,
3617  *fe, this->finite_element_output.shape_function_to_row_table,
3618  laplacians, false,
3619  indices.size()/dofs_per_cell);
3620 }
3621 
3622 
3623 
3624 template <int dim, int spacedim>
3625 template <class InputVector>
3627  const InputVector &fe_function,
3628  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3629  std::vector<std::vector<typename InputVector::value_type> > &laplacians,
3630  bool quadrature_points_fastest) const
3631 {
3632  typedef typename InputVector::value_type Number;
3633  Assert (indices.size() % dofs_per_cell == 0,
3634  ExcNotMultiple(indices.size(), dofs_per_cell));
3635  Assert (this->update_flags & update_hessians,
3636  ExcAccessToUninitializedField("update_hessians"));
3637 
3638  boost::container::small_vector<Number, 200> dof_values(indices.size());
3639  for (unsigned int i=0; i<indices.size(); ++i)
3640  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3641  internal::do_function_laplacians(dof_values.data(), this->finite_element_output.shape_hessians,
3642  *fe, this->finite_element_output.shape_function_to_row_table,
3643  laplacians, quadrature_points_fastest,
3644  indices.size()/dofs_per_cell);
3645 }
3646 
3647 
3648 
3649 template <int dim, int spacedim>
3650 template <class InputVector>
3651 void
3653 get_function_third_derivatives (const InputVector &fe_function,
3654  std::vector<Tensor<3,spacedim,typename InputVector::value_type> > &third_derivatives) const
3655 {
3656  typedef typename InputVector::value_type Number;
3657  AssertDimension (fe->n_components(), 1);
3658  Assert (this->update_flags & update_3rd_derivatives,
3659  ExcAccessToUninitializedField("update_3rd_derivatives"));
3660  Assert (present_cell.get() != nullptr,
3661  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3662  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3663 
3664  // get function values of dofs on this cell
3665  Vector<Number> dof_values (dofs_per_cell);
3666  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3667  internal::do_function_derivatives(dof_values.begin(), this->finite_element_output.shape_3rd_derivatives,
3668  third_derivatives);
3669 }
3670 
3671 
3672 
3673 template <int dim, int spacedim>
3674 template <class InputVector>
3676  const InputVector &fe_function,
3677  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3678  std::vector<Tensor<3,spacedim,typename InputVector::value_type> > &third_derivatives) const
3679 {
3680  typedef typename InputVector::value_type Number;
3681  Assert (this->update_flags & update_3rd_derivatives,
3682  ExcAccessToUninitializedField("update_3rd_derivatives"));
3683  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3684  AssertDimension (indices.size(), dofs_per_cell);
3685 
3686  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
3687  for (unsigned int i=0; i<dofs_per_cell; ++i)
3688  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3689  internal::do_function_derivatives(dof_values.data(), this->finite_element_output.shape_3rd_derivatives,
3690  third_derivatives);
3691 }
3692 
3693 
3694 
3695 template <int dim, int spacedim>
3696 template <class InputVector>
3697 void
3699 get_function_third_derivatives (const InputVector &fe_function,
3700  std::vector<std::vector<Tensor<3,spacedim,typename InputVector::value_type> > > &third_derivatives,
3701  bool quadrature_points_fastest) const
3702 {
3703  typedef typename InputVector::value_type Number;
3704  Assert (this->update_flags & update_3rd_derivatives,
3705  ExcAccessToUninitializedField("update_3rd_derivatives"));
3706  Assert (present_cell.get() != nullptr,
3707  ExcMessage ("FEValues object is not reinit'ed to any cell"));
3708  AssertDimension (fe_function.size(), present_cell->n_dofs_for_dof_handler());
3709 
3710  // get function values of dofs on this cell
3711  Vector<Number> dof_values (dofs_per_cell);
3712  present_cell->get_interpolated_dof_values(fe_function, dof_values);
3713  internal::do_function_derivatives(dof_values.begin(),
3714  this->finite_element_output.shape_3rd_derivatives,
3715  *fe,
3716  this->finite_element_output.shape_function_to_row_table,
3717  make_array_view(third_derivatives.begin(), third_derivatives.end()),
3718  quadrature_points_fastest);
3719 }
3720 
3721 
3722 
3723 template <int dim, int spacedim>
3724 template <class InputVector>
3726  const InputVector &fe_function,
3727  const VectorSlice<const std::vector<types::global_dof_index> > &indices,
3728  VectorSlice<std::vector<std::vector<Tensor<3,spacedim,typename InputVector::value_type> > > > third_derivatives,
3729  bool quadrature_points_fastest) const
3730 {
3731  typedef typename InputVector::value_type Number;
3732  Assert (this->update_flags & update_3rd_derivatives,
3733  ExcAccessToUninitializedField("update_3rd_derivatives"));
3734  Assert (indices.size() % dofs_per_cell == 0,
3735  ExcNotMultiple(indices.size(), dofs_per_cell));
3736 
3737  boost::container::small_vector<Number, 200> dof_values(indices.size());
3738  for (unsigned int i=0; i<indices.size(); ++i)
3739  dof_values[i] = internal::get_vector_element (fe_function, indices[i]);
3740  internal::do_function_derivatives(dof_values.data(),
3741  this->finite_element_output.shape_3rd_derivatives,
3742  *fe,
3743  this->finite_element_output.shape_function_to_row_table,
3744  make_array_view(third_derivatives.begin(), third_derivatives.end()),
3745  quadrature_points_fastest,
3746  indices.size()/dofs_per_cell);
3747 }
3748 
3749 
3750 
3751 template <int dim, int spacedim>
3754 {
3755  return *present_cell;
3756 }
3757 
3758 
3759 
3760 template <int dim, int spacedim>
3761 const std::vector<Tensor<1,spacedim> > &
3763 {
3764  Assert (this->update_flags & update_normal_vectors,
3765  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_normal_vectors")));
3766  return get_normal_vectors();
3767 }
3768 
3769 
3770 
3771 template <int dim, int spacedim>
3772 const std::vector<Tensor<1,spacedim> > &
3774 {
3775  Assert (this->update_flags & update_normal_vectors,
3776  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_normal_vectors")));
3777 
3778  return this->mapping_output.normal_vectors;
3779 }
3780 
3781 
3782 
3783 template <int dim, int spacedim>
3784 std::size_t
3786 {
3787  return (sizeof(this->update_flags) +
3788  MemoryConsumption::memory_consumption (n_quadrature_points) +
3789  sizeof (cell_similarity) +
3790  MemoryConsumption::memory_consumption (dofs_per_cell) +
3792  MemoryConsumption::memory_consumption (mapping_data) +
3793  MemoryConsumption::memory_consumption (*mapping_data) +
3794  MemoryConsumption::memory_consumption (mapping_output) +
3798  MemoryConsumption::memory_consumption (finite_element_output));
3799 }
3800 
3801 
3802 
3803 template <int dim, int spacedim>
3806 {
3807  // first find out which objects need to be recomputed on each
3808  // cell we visit. this we have to ask the finite element and mapping.
3809  // elements are first since they might require update in mapping
3810  //
3811  // there is no need to iterate since mappings will never require
3812  // the finite element to compute something for them
3813  UpdateFlags flags = update_flags
3814  | fe->requires_update_flags (update_flags);
3815  flags |= mapping->requires_update_flags (flags);
3816 
3817  return flags;
3818 }
3819 
3820 
3821 
3822 template <int dim, int spacedim>
3823 void
3825 {
3826  // if there is no present cell, then we shouldn't be
3827  // connected via a signal to a triangulation
3828  Assert (present_cell.get() != nullptr, ExcInternalError());
3829 
3830  // so delete the present cell and
3831  // disconnect from the signal we have with
3832  // it
3833  tria_listener_refinement.disconnect ();
3834  tria_listener_mesh_transform.disconnect ();
3835  present_cell.reset ();
3836 }
3837 
3838 
3839 
3840 template <int dim, int spacedim>
3841 void
3844 {
3845  if (present_cell.get() != nullptr)
3846  {
3847  if (&cell->get_triangulation() !=
3848  &present_cell->operator typename Triangulation<dim,spacedim>::cell_iterator()
3849  ->get_triangulation())
3850  {
3851  // the triangulations for the previous cell and the current cell
3852  // do not match. disconnect from the previous triangulation and
3853  // connect to the current one; also invalidate the previous
3854  // cell because we shouldn't be comparing cells from different
3855  // triangulations
3856  invalidate_present_cell();
3857  tria_listener_refinement =
3858  cell->get_triangulation().signals.any_change.connect
3860  std::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
3861  tria_listener_mesh_transform =
3862  cell->get_triangulation().signals.mesh_movement.connect
3864  std::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
3865  }
3866  }
3867  else
3868  {
3869  // if this FEValues has never been set to any cell at all, then
3870  // at least subscribe to the triangulation to get notified of
3871  // changes
3872  tria_listener_refinement =
3873  cell->get_triangulation().signals.post_refinement.connect
3875  std::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
3876  tria_listener_mesh_transform =
3877  cell->get_triangulation().signals.mesh_movement.connect
3879  std::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
3880  }
3881 }
3882 
3883 
3884 
3885 template <int dim, int spacedim>
3886 inline
3887 void
3890 {
3891  // Unfortunately, the detection of simple geometries with CellSimilarity is
3892  // sensitive to the first cell detected. When doing this with multiple
3893  // threads, each thread will get its own scratch data object with an
3894  // FEValues object in the implementation framework from late 2013, which is
3895  // initialized to the first cell the thread sees. As this number might
3896  // different between different runs (after all, the tasks are scheduled
3897  // dynamically onto threads), this slight deviation leads to difference in
3898  // roundoff errors that propagate through the program. Therefore, we need to
3899  // disable CellSimilarity in case there is more than one thread in the
3900  // problem. This will likely not affect many MPI test cases as there
3901  // multithreading is disabled on default, but in many other situations
3902  // because we rarely explicitly set the number of threads.
3903  //
3904  // TODO: Is it reasonable to introduce a flag "unsafe" in the constructor of
3905  // FEValues to re-enable this feature?
3906  if (MultithreadInfo::n_threads() > 1)
3907  {
3908  cell_similarity = CellSimilarity::none;
3909  return;
3910  }
3911 
3912  // case that there has not been any cell before
3913  if (this->present_cell.get() == nullptr)
3914  cell_similarity = CellSimilarity::none;
3915  else
3916  // in MappingQ, data can have been modified during the last call. Then, we
3917  // can't use that data on the new cell.
3918  if (cell_similarity == CellSimilarity::invalid_next_cell)
3919  cell_similarity = CellSimilarity::none;
3920  else
3921  cell_similarity = (cell->is_translation_of
3922  (static_cast<const typename Triangulation<dim,spacedim>::cell_iterator &>(*this->present_cell))
3923  ?
3925  :
3927 
3928  if ( (dim<spacedim) && (cell_similarity == CellSimilarity::translation) )
3929  {
3930  if (static_cast<const typename Triangulation<dim,spacedim>::cell_iterator &>
3931  (*this->present_cell)->direction_flag()
3932  != cell->direction_flag() )
3933  cell_similarity = CellSimilarity::inverted_translation;
3934  }
3935  // TODO: here, one could implement other checks for similarity, e.g. for
3936  // children of a parallelogram.
3937 }
3938 
3939 
3940 
3941 template <int dim, int spacedim>
3944 {
3945  return cell_similarity;
3946 }
3947 
3948 
3949 
3950 template <int dim, int spacedim>
3951 const unsigned int FEValuesBase<dim,spacedim>::dimension;
3952 
3953 
3954 
3955 template <int dim, int spacedim>
3957 
3958 /*------------------------------- FEValues -------------------------------*/
3959 
3960 template <int dim, int spacedim>
3962 
3963 
3964 
3965 template <int dim, int spacedim>
3967  const FiniteElement<dim,spacedim> &fe,
3968  const Quadrature<dim> &q,
3969  const UpdateFlags update_flags)
3970  :
3971  FEValuesBase<dim,spacedim> (q.size(),
3972  fe.dofs_per_cell,
3974  mapping,
3975  fe),
3976  quadrature (q)
3977 {
3979 }
3980 
3981 
3982 
3983 template <int dim, int spacedim>
3985  const Quadrature<dim> &q,
3986  const UpdateFlags update_flags)
3987  :
3988  FEValuesBase<dim,spacedim> (q.size(),
3989  fe.dofs_per_cell,
3991  StaticMappingQ1<dim,spacedim>::mapping,
3992  fe),
3993  quadrature (q)
3994 {
3996 }
3997 
3998 
3999 
4000 template <int dim, int spacedim>
4001 void
4003 {
4004  // You can compute normal vectors to the cells only in the
4005  // codimension one case.
4006  if (dim != spacedim-1)
4007  Assert ((update_flags & update_normal_vectors) == false,
4008  ExcMessage ("You can only pass the 'update_normal_vectors' "
4009  "flag to FEFaceValues or FESubfaceValues objects, "
4010  "but not to an FEValues object unless the "
4011  "triangulation it refers to is embedded in a higher "
4012  "dimensional space."));
4013 
4014  const UpdateFlags flags = this->compute_update_flags (update_flags);
4015 
4016  // initialize the base classes
4017  if (flags & update_mapping)
4018  this->mapping_output.initialize(this->n_quadrature_points, flags);
4019  this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags);
4020 
4021  // then get objects into which the FE and the Mapping can store
4022  // intermediate data used across calls to reinit. we can do this in parallel
4025  *this->fe,
4026  flags,
4027  *this->mapping,
4028  quadrature,
4029  this->finite_element_output);
4031  mapping_get_data;
4032  if (flags & update_mapping)
4034  *this->mapping,
4035  flags,
4036  quadrature);
4037 
4038  this->update_flags = flags;
4039 
4040  // then collect answers from the two task above
4041  this->fe_data = std::move(fe_get_data.return_value());
4042  if (flags & update_mapping)
4043  this->mapping_data = std::move(mapping_get_data.return_value());
4044  else
4045  this->mapping_data = std_cxx14::make_unique<typename Mapping<dim,spacedim>::InternalDataBase> ();
4046 }
4047 
4048 
4049 
4050 namespace
4051 {
4052  // Reset a unique_ptr. If we can, do not de-allocate the previously
4053  // held memory but re-use it for the next item to avoid the repeated
4054  // memory allocation. We do this because FEValues objects are heavily
4055  // used in multithreaded contexts where memory allocations are evil.
4056  template <typename Type, typename Pointer, typename Iterator>
4057  void
4058  reset_pointer_in_place_if_possible
4059  (std::unique_ptr<Pointer> &present_cell,
4060  const Iterator &new_cell)
4061  {
4062  // see if the existing pointer is non-null and if the type of
4063  // the old object pointed to matches that of the one we'd
4064  // like to create
4065  if (present_cell.get()
4066  &&
4067  (typeid(*present_cell.get()) == typeid(Type)))
4068  {
4069  // call destructor of the old object
4070  static_cast<const Type *>(present_cell.get())->~Type();
4071 
4072  // then construct a new object in-place
4073  new (const_cast<void *>(static_cast<const void *>(present_cell.get()))) Type(new_cell);
4074  }
4075  else
4076  // if the types don't match, there is nothing we can do here
4077  present_cell = std_cxx14::make_unique<Type> (new_cell);
4078  }
4079 }
4080 
4081 
4082 
4083 template <int dim, int spacedim>
4085 {
4086  // no FE in this cell, so no assertion
4087  // necessary here
4088  this->maybe_invalidate_previous_present_cell (cell);
4089  this->check_cell_similarity(cell);
4090 
4091  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
4092  (this->present_cell, cell);
4093 
4094  // this was the part of the work that is dependent on the actual
4095  // data type of the iterator. now pass on to the function doing
4096  // the real work.
4097  do_reinit ();
4098 }
4099 
4100 
4101 
4102 template <int dim, int spacedim>
4103 template <template <int, int> class DoFHandlerType, bool lda>
4104 void
4106 (const TriaIterator<DoFCellAccessor<DoFHandlerType<dim,spacedim>, lda> > &cell)
4107 {
4108  // assert that the finite elements passed to the constructor and
4109  // used by the DoFHandler used by this cell, are the same
4110  Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
4111  static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
4113 
4114  this->maybe_invalidate_previous_present_cell (cell);
4115  this->check_cell_similarity(cell);
4116 
4117  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template
4119  lda> > > >
4120  (this->present_cell, cell);
4121 
4122  // this was the part of the work that is dependent on the actual
4123  // data type of the iterator. now pass on to the function doing
4124  // the real work.
4125  do_reinit ();
4126 }
4127 
4128 
4129 
4130 template <int dim, int spacedim>
4132 {
4133  // first call the mapping and let it generate the data
4134  // specific to the mapping. also let it inspect the
4135  // cell similarity flag and, if necessary, update
4136  // it
4137  if (this->update_flags & update_mapping)
4138  {
4139  this->cell_similarity
4140  = this->get_mapping().fill_fe_values(*this->present_cell,
4141  this->cell_similarity,
4142  quadrature,
4143  *this->mapping_data,
4144  this->mapping_output);
4145  }
4146 
4147  // then call the finite element and, with the data
4148  // already filled by the mapping, let it compute the
4149  // data for the mapped shape function values, gradients,
4150  // etc.
4151  this->get_fe().fill_fe_values(*this->present_cell,
4152  this->cell_similarity,
4153  this->quadrature,
4154  this->get_mapping(),
4155  *this->mapping_data,
4156  this->mapping_output,
4157  *this->fe_data,
4158  this->finite_element_output);
4159 }
4160 
4161 
4162 
4163 template <int dim, int spacedim>
4164 std::size_t
4166 {
4169 }
4170 
4171 
4172 /*------------------------------- FEFaceValuesBase --------------------------*/
4173 
4174 
4175 template <int dim, int spacedim>
4177  const unsigned int dofs_per_cell,
4178  const UpdateFlags,
4179  const Mapping<dim,spacedim> &mapping,
4180  const FiniteElement<dim,spacedim> &fe,
4181  const Quadrature<dim-1>& quadrature)
4182  :
4183  FEValuesBase<dim,spacedim> (n_q_points,
4184  dofs_per_cell,
4186  mapping,
4187  fe),
4188  present_face_index (numbers::invalid_unsigned_int),
4189  quadrature(quadrature)
4190 {}
4191 
4192 
4193 
4194 template <int dim, int spacedim>
4195 const std::vector<Tensor<1,spacedim> > &
4197 {
4198  Assert (this->update_flags & update_boundary_forms,
4199  (typename FEValuesBase<dim,spacedim>::ExcAccessToUninitializedField("update_boundary_forms")));
4200  return this->mapping_output.boundary_forms;
4201 }
4202 
4203 
4204 
4205 template <int dim, int spacedim>
4206 std::size_t
4208 {
4211 }
4212 
4213 
4214 /*------------------------------- FEFaceValues -------------------------------*/
4215 
4216 template <int dim, int spacedim>
4217 const unsigned int FEFaceValues<dim,spacedim>::dimension;
4218 
4219 
4220 
4221 template <int dim, int spacedim>
4223 
4224 
4225 
4226 template <int dim, int spacedim>
4228  const FiniteElement<dim,spacedim> &fe,
4229  const Quadrature<dim-1> &quadrature,
4230  const UpdateFlags update_flags)
4231  :
4232  FEFaceValuesBase<dim,spacedim> (quadrature.size(),
4233  fe.dofs_per_cell,
4234  update_flags,
4235  mapping,
4236  fe, quadrature)
4237 {
4239 }
4240 
4241 
4242 
4243 template <int dim, int spacedim>
4245  const Quadrature<dim-1> &quadrature,
4246  const UpdateFlags update_flags)
4247  :
4248  FEFaceValuesBase<dim,spacedim> (quadrature.size(),
4249  fe.dofs_per_cell,
4250  update_flags,
4251  StaticMappingQ1<dim,spacedim>::mapping,
4252  fe, quadrature)
4253 {
4255 }
4256 
4257 
4258 
4259 template <int dim, int spacedim>
4260 void
4262 {
4263  const UpdateFlags flags = this->compute_update_flags (update_flags);
4264 
4265  // initialize the base classes
4266  if (flags & update_mapping)
4267  this->mapping_output.initialize(this->n_quadrature_points, flags);
4268  this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags);
4269 
4270  // then get objects into which the FE and the Mapping can store
4271  // intermediate data used across calls to reinit. this can be done in parallel
4274  *this->fe,
4275  flags,
4276  *this->mapping,
4277  this->quadrature,
4278  this->finite_element_output);
4280  mapping_get_data;
4281  if (flags & update_mapping)
4283  *this->mapping,
4284  flags,
4285  this->quadrature);
4286 
4287  this->update_flags = flags;
4288 
4289  // then collect answers from the two task above
4290  this->fe_data = std::move(fe_get_data.return_value());
4291  if (flags & update_mapping)
4292  this->mapping_data = std::move(mapping_get_data.return_value());
4293  else
4294  this->mapping_data = std_cxx14::make_unique<typename Mapping<dim,spacedim>::InternalDataBase> ();
4295 }
4296 
4297 
4298 
4299 template <int dim, int spacedim>
4300 template <template <int, int> class DoFHandlerType, bool lda>
4301 void
4303 (const TriaIterator<DoFCellAccessor<DoFHandlerType<dim,spacedim>, lda> > &cell,
4304  const unsigned int face_no)
4305 {
4306  // assert that the finite elements passed to the constructor and
4307  // used by the DoFHandler used by this cell, are the same
4308  Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
4309  static_cast<const FiniteElementData<dim>&>(
4310  cell->get_dof_handler().get_fe(cell->active_fe_index ())),
4312 
4315 
4316  this->maybe_invalidate_previous_present_cell (cell);
4317  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template
4319  lda> > > >
4320  (this->present_cell, cell);
4321 
4322  // this was the part of the work that is dependent on the actual
4323  // data type of the iterator. now pass on to the function doing
4324  // the real work.
4325  do_reinit (face_no);
4326 }
4327 
4328 
4329 
4330 template <int dim, int spacedim>
4332  const unsigned int face_no)
4333 {
4336 
4337  this->maybe_invalidate_previous_present_cell (cell);
4338  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
4339  (this->present_cell, cell);
4340 
4341  // this was the part of the work that is dependent on the actual
4342  // data type of the iterator. now pass on to the function doing
4343  // the real work.
4344  do_reinit (face_no);
4345 }
4346 
4347 
4348 
4349 template <int dim, int spacedim>
4350 void FEFaceValues<dim,spacedim>::do_reinit (const unsigned int face_no)
4351 {
4352  // first of all, set the present_face_index (if available)
4353  const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
4354  this->present_face_index=cell->face_index(face_no);
4355 
4356  if (this->update_flags & update_mapping)
4357  {
4358  this->get_mapping().fill_fe_face_values(*this->present_cell,
4359  face_no,
4360  this->quadrature,
4361  *this->mapping_data,
4362  this->mapping_output);
4363  }
4364 
4365  this->get_fe().fill_fe_face_values(*this->present_cell,
4366  face_no,
4367  this->quadrature,
4368  this->get_mapping(),
4369  *this->mapping_data,
4370  this->mapping_output,
4371  *this->fe_data,
4372  this->finite_element_output);
4373 }
4374 
4375 
4376 /*------------------------------- FESubFaceValues -------------------------------*/
4377 
4378 
4379 template <int dim, int spacedim>
4380 const unsigned int FESubfaceValues<dim,spacedim>::dimension;
4381 
4382 
4383 
4384 template <int dim, int spacedim>
4386 
4387 
4388 
4389 template <int dim, int spacedim>
4391  const FiniteElement<dim,spacedim> &fe,
4392  const Quadrature<dim-1> &quadrature,
4393  const UpdateFlags update_flags)
4394  :
4395  FEFaceValuesBase<dim,spacedim> (quadrature.size(),
4396  fe.dofs_per_cell,
4397  update_flags,
4398  mapping,
4399  fe, quadrature)
4400 {
4402 }
4403 
4404 
4405 
4406 template <int dim, int spacedim>
4408  const Quadrature<dim-1> &quadrature,
4409  const UpdateFlags update_flags)
4410  :
4411  FEFaceValuesBase<dim,spacedim> (quadrature.size(),
4412  fe.dofs_per_cell,
4413  update_flags,
4414  StaticMappingQ1<dim,spacedim>::mapping,
4415  fe, quadrature)
4416 {
4418 }
4419 
4420 
4421 
4422 template <int dim, int spacedim>
4423 void
4425 {
4426  const UpdateFlags flags = this->compute_update_flags (update_flags);
4427 
4428  // initialize the base classes
4429  if (flags & update_mapping)
4430  this->mapping_output.initialize(this->n_quadrature_points, flags);
4431  this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags);
4432 
4433  // then get objects into which the FE and the Mapping can store
4434  // intermediate data used across calls to reinit. this can be done
4435  // in parallel
4438  *this->fe,
4439  flags,
4440  *this->mapping,
4441  this->quadrature,
4442  this->finite_element_output);
4444  mapping_get_data;
4445  if (flags & update_mapping)
4447  *this->mapping,
4448  flags,
4449  this->quadrature);
4450 
4451  this->update_flags = flags;
4452 
4453  // then collect answers from the two task above
4454  this->fe_data = std::move(fe_get_data.return_value());
4455  if (flags & update_mapping)
4456  this->mapping_data = std::move(mapping_get_data.return_value());
4457  else
4458  this->mapping_data = std_cxx14::make_unique<typename Mapping<dim,spacedim>::InternalDataBase> ();
4459 }
4460 
4461 
4462 
4463 template <int dim, int spacedim>
4464 template <template <int, int> class DoFHandlerType, bool lda>
4466 (const TriaIterator<DoFCellAccessor<DoFHandlerType<dim,spacedim>, lda> > &cell,
4467  const unsigned int face_no,
4468  const unsigned int subface_no)
4469 {
4470  // assert that the finite elements passed to the constructor and
4471  // used by the hp::DoFHandler used by this cell, are the same
4472  Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
4473  static_cast<const FiniteElementData<dim>&>(
4474  cell->get_dof_handler().get_fe(cell->active_fe_index ())),
4478  // We would like to check for subface_no < cell->face(face_no)->n_children(),
4479  // but unfortunately the current function is also called for
4480  // faces without children (see tests/fe/mapping.cc). Therefore,
4481  // we must use following workaround of two separate assertions
4482  Assert (cell->face(face_no)->has_children() ||
4483  subface_no < GeometryInfo<dim>::max_children_per_face,
4485  Assert (!cell->face(face_no)->has_children() ||
4486  subface_no < cell->face(face_no)->number_of_children(),
4487  ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
4488  Assert (cell->has_children() == false,
4489  ExcMessage ("You can't use subface data for cells that are "
4490  "already refined. Iterate over their children "
4491  "instead in these cases."));
4492 
4493  this->maybe_invalidate_previous_present_cell (cell);
4494  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::template
4496  lda> > > >
4497  (this->present_cell, cell);
4498 
4499  // this was the part of the work that is dependent on the actual
4500  // data type of the iterator. now pass on to the function doing
4501  // the real work.
4502  do_reinit (face_no, subface_no);
4503 }
4504 
4505 
4506 
4507 template <int dim, int spacedim>
4509  const unsigned int face_no,
4510  const unsigned int subface_no)
4511 {
4514  Assert (subface_no < cell->face(face_no)->n_children(),
4515  ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
4516 
4517  this->maybe_invalidate_previous_present_cell (cell);
4518  reset_pointer_in_place_if_possible<typename FEValuesBase<dim,spacedim>::TriaCellIterator>
4519  (this->present_cell, cell);
4520 
4521  // this was the part of the work that is dependent on the actual
4522  // data type of the iterator. now pass on to the function doing
4523  // the real work.
4524  do_reinit (face_no, subface_no);
4525 }
4526 
4527 
4528 
4529 template <int dim, int spacedim>
4530 void FESubfaceValues<dim,spacedim>::do_reinit (const unsigned int face_no,
4531  const unsigned int subface_no)
4532 {
4533  // first of all, set the present_face_index (if available)
4534  const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
4535 
4536  if (!cell->face(face_no)->has_children())
4537  // no subfaces at all, so set present_face_index to this face rather
4538  // than any subface
4539  this->present_face_index=cell->face_index(face_no);
4540  else if (dim!=3)
4541  this->present_face_index=cell->face(face_no)->child_index(subface_no);
4542  else
4543  {
4544  // this is the same logic we use in cell->neighbor_child_on_subface(). See
4545  // there for an explanation of the different cases
4546  unsigned int subface_index=numbers::invalid_unsigned_int;
4547  switch (cell->subface_case(face_no))
4548  {
4552  subface_index=cell->face(face_no)->child_index(subface_no);
4553  break;
4556  subface_index=cell->face(face_no)->child(subface_no/2)->child_index(subface_no%2);
4557  break;
4560  switch (subface_no)
4561  {
4562  case 0:
4563  case 1:
4564  subface_index=cell->face(face_no)->child(0)->child_index(subface_no);
4565  break;
4566  case 2:
4567  subface_index=cell->face(face_no)->child_index(1);
4568  break;
4569  default:
4570  Assert(false, ExcInternalError());
4571  }
4572  break;
4575  switch (subface_no)
4576  {
4577  case 0:
4578  subface_index=cell->face(face_no)->child_index(0);
4579  break;
4580  case 1:
4581  case 2:
4582  subface_index=cell->face(face_no)->child(1)->child_index(subface_no-1);
4583  break;
4584  default:
4585  Assert(false, ExcInternalError());
4586  }
4587  break;
4588  default:
4589  Assert(false, ExcInternalError());
4590  break;
4591  }
4592  Assert(subface_index!=numbers::invalid_unsigned_int,
4593  ExcInternalError());
4594  this->present_face_index=subface_index;
4595  }
4596 
4597  // now ask the mapping and the finite element to do the actual work
4598  if (this->update_flags & update_mapping)
4599  {
4600  this->get_mapping().fill_fe_subface_values(*this->present_cell,
4601  face_no,
4602  subface_no,
4603  this->quadrature,
4604  *this->mapping_data,
4605  this->mapping_output);
4606  }
4607 
4608  this->get_fe().fill_fe_subface_values(*this->present_cell,
4609  face_no,
4610  subface_no,
4611  this->quadrature,
4612  this->get_mapping(),
4613  *this->mapping_data,
4614  this->mapping_output,
4615  *this->fe_data,
4616  this->finite_element_output);
4617 }
4618 
4619 
4620 /*------------------------------- Explicit Instantiations -------------*/
4621 #define SPLIT_INSTANTIATIONS_COUNT 6
4622 #ifndef SPLIT_INSTANTIATIONS_INDEX
4623 #define SPLIT_INSTANTIATIONS_INDEX 0
4624 #endif
4625 #include "fe_values.inst"
4626 
4627 DEAL_II_NAMESPACE_CLOSE
void get_function_third_derivatives(const InputVector &fe_function, std::vector< typename ProductType< third_derivative_type, typename InputVector::value_type >::type > &third_derivatives) const
Definition: fe_values.cc:1594
Transformed quadrature weights.
void get_function_gradients(const InputVector &fe_function, std::vector< Tensor< 1, spacedim, typename InputVector::value_type > > &gradients) const
Definition: fe_values.cc:3329
Shape function values.
ProductType< Number, typename Scalar< dim, spacedim >::third_derivative_type >::type third_derivative_type
Definition: fe_values.h:205
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const =0
static const unsigned int invalid_unsigned_int
Definition: types.h:173
ProductType< Number, typename Vector< dim, spacedim >::third_derivative_type >::type third_derivative_type
Definition: fe_values.h:640
CellSimilarity::Similarity cell_similarity
Definition: fe_values.h:3090
Cache(const FEValuesBase< dim, spacedim > &fe_values)
Definition: fe_values.cc:2223
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
static unsigned int component_to_unrolled_index(const TableIndices< rank_ > &indices)
iterator begin() const
Definition: array_view.h:378
unsigned int n_nonzero_components(const unsigned int i) const
Definition: fe.h:3217
static ::ExceptionBase & ExcAccessToUninitializedField()
ProductType< Number, typename Tensor< 2, dim, spacedim >::gradient_type >::type gradient_type
Definition: fe_values.h:1436
Task< RT > new_task(const std::function< RT()> &function)
Point< spacedim > point(const gp_Pnt &p, const double &tolerance=1e-10)
Definition: utilities.cc:183
static const unsigned int n_independent_components
const unsigned int dofs_per_cell
Definition: fe_values.h:1847
const unsigned int component
Definition: fe_values.h:486
void get_function_symmetric_gradients_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::symmetric_gradient_type > &symmetric_gradients) const
Definition: fe_values.cc:1751
void get_function_values(const InputVector &fe_function, std::vector< typename ProductType< value_type, typename InputVector::value_type >::type > &values) const
Definition: fe_values.cc:1418
Number trace(const SymmetricTensor< 2, dim, Number > &d)
FEValuesBase(const unsigned int n_q_points, const unsigned int dofs_per_cell, const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe)
Definition: fe_values.cc:2733
signed int value_type
Definition: index_set.h:98
Volume element.
void get_function_third_derivatives(const InputVector &fe_function, std::vector< typename ProductType< third_derivative_type, typename InputVector::value_type >::type > &third_derivatives) const
Definition: fe_values.cc:1954
void get_function_values(const InputVector &fe_function, std::vector< typename InputVector::value_type > &values) const
Definition: fe_values.cc:3197
Outer normal vector, not normalized.
const FiniteElement< dim, spacedim > & get_fe() const
static ::ExceptionBase & ExcFEDontMatch()
Scalar & operator=(const Scalar< dim, spacedim > &)
Definition: fe_values.cc:188
void get_function_divergences(const InputVector &fe_function, std::vector< typename ProductType< divergence_type, typename InputVector::value_type >::type > &divergences) const
Definition: fe_values.cc:1772
void get_function_laplacians(const InputVector &fe_function, std::vector< typename ProductType< value_type, typename InputVector::value_type >::type > &laplacians) const
Definition: fe_values.cc:1905
TriaCellIterator(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: fe_values.cc:2540
STL namespace.
Transformed quadrature points.
SymmetricTensor & operator=(const SymmetricTensor< rank_, dim, OtherNumber > &rhs)
void do_reinit(const unsigned int face_no)
Definition: fe_values.cc:4350
virtual void get_interpolated_dof_values(const IndexSet &in, Vector< IndexSet::value_type > &out) const
Definition: fe_values.cc:2573
ProductType< Number, typename SymmetricTensor< 2, dim, spacedim >::divergence_type >::type divergence_type
Definition: fe_values.h:1166
std::size_t memory_consumption() const
Definition: fe_values.cc:4207
bool is_primitive() const
Definition: fe.h:3228
void check_cell_similarity(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: fe_values.cc:3889
::internal::FEValuesViews::Cache< dim, spacedim > fe_values_views_cache
Definition: fe_values.h:3116
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
Tensor & operator=(const Tensor< rank_, dim, OtherNumber > &rhs)
ProductType< Number, typename Vector< dim, spacedim >::hessian_type >::type hessian_type
Definition: fe_values.h:634
void get_function_hessians(const InputVector &fe_function, std::vector< Tensor< 2, spacedim, typename InputVector::value_type > > &hessians) const
Definition: fe_values.cc:3432
void do_reinit(const unsigned int face_no, const unsigned int subface_no)
Definition: fe_values.cc:4530
static TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell, const unsigned int face_no, const unsigned int subface_no)
Definition: fe_values.cc:4466
ProductType< Number, typename Vector< dim, spacedim >::gradient_type >::type gradient_type
Definition: fe_values.h:604
void get_function_divergences_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::divergence_type > &divergences) const
Definition: fe_values.cc:1797
void get_function_curls_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::curl_type > &curls) const
Definition: fe_values.cc:1841
void get_function_laplacians(const InputVector &fe_function, std::vector< typename ProductType< value_type, typename InputVector::value_type >::type > &laplacians) const
Definition: fe_values.cc:1550
void get_function_hessians_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::hessian_type > &hessians) const
Definition: fe_values.cc:1885
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type > make_array_view(const Iterator begin, const Iterator end)
Definition: array_view.h:490
ProductType< Number, typename Vector< dim, spacedim >::value_type >::type value_type
Definition: fe_values.h:598
ProductType< Number, typename Scalar< dim, spacedim >::gradient_type >::type gradient_type
Definition: fe_values.h:187
void get_function_gradients(const InputVector &fe_function, std::vector< typename ProductType< gradient_type, typename InputVector::value_type >::type > &gradients) const
Definition: fe_values.cc:1462
void get_function_hessians(const InputVector &fe_function, std::vector< typename ProductType< hessian_type, typename InputVector::value_type >::type > &hessians) const
Definition: fe_values.cc:1861
void get_function_laplacians(const InputVector &fe_function, std::vector< typename InputVector::value_type > &laplacians) const
Definition: fe_values.cc:3532
const SmartPointer< const FiniteElement< dim, spacedim >, FEValuesBase< dim, spacedim > > fe
Definition: fe_values.h:3054
static ::ExceptionBase & ExcMessage(std::string arg1)
void get_function_gradients_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::gradient_type > &gradients) const
Definition: fe_values.cc:1706
ProductType< Number, typename Scalar< dim, spacedim >::hessian_type >::type hessian_type
Definition: fe_values.h:199
No update.
CellSimilarity::Similarity get_cell_similarity() const
Definition: fe_values.cc:3943
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1509
unsigned int global_dof_index
Definition: types.h:88
Third derivatives of shape functions.
void get_function_third_derivatives(const InputVector &fe_function, std::vector< Tensor< 3, spacedim, typename InputVector::value_type > > &third_derivatives) const
Definition: fe_values.cc:3653
UpdateFlags compute_update_flags(const UpdateFlags update_flags) const
Definition: fe_values.cc:3805
void get_function_laplacians_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::laplacian_type > &laplacians) const
Definition: fe_values.cc:1574
#define Assert(cond, exc)
Definition: exceptions.h:1142
UpdateFlags
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell, const unsigned int face_no)
Definition: fe_values.cc:4303
iterator end() const
Definition: array_view.h:388
Abstract base class for mapping classes.
Definition: dof_tools.h:46
const ComponentMask & get_nonzero_components(const unsigned int i) const
Definition: fe.h:3206
std::vector< ShapeFunctionData > shape_function_data
Definition: fe_values.h:1095
const unsigned int first_vector_component
Definition: fe_values.h:1090
const Triangulation< dim, spacedim >::cell_iterator cell
Definition: fe_values.cc:2457
void invalidate_present_cell()
Definition: fe_values.cc:3824
ProductType< Number, typename Scalar< dim, spacedim >::value_type >::type value_type
Definition: fe_values.h:181
const SmartPointer< const Mapping< dim, spacedim >, FEValuesBase< dim, spacedim > > mapping
Definition: fe_values.h:3034
Vector & operator=(const Vector< dim, spacedim > &)
Definition: fe_values.cc:284
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
Tensor()
Definition: tensor.h:974
static const char *const message_string
Definition: fe_values.cc:2464
void get_function_hessians_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::hessian_type > &hessians) const
Definition: fe_values.cc:1530
std::size_t size() const
Definition: array_view.h:370
void get_function_symmetric_gradients(const InputVector &fe_function, std::vector< typename ProductType< symmetric_gradient_type, typename InputVector::value_type >::type > &symmetric_gradients) const
Definition: fe_values.cc:1726
ProductType< Number, typename Vector< dim, spacedim >::divergence_type >::type divergence_type
Definition: fe_values.h:616
Second derivatives of shape functions.
Gradient of volume element.
const std::vector< Tensor< 1, spacedim > > & get_all_normal_vectors() const
Definition: fe_values.cc:3762
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static TableIndices< rank_ > unrolled_to_component_indices(const unsigned int i)
Definition: tensor.h:1335
std::size_t memory_consumption() const
Definition: fe_values.cc:4165
ProductType< Number, typename Vector< dim, spacedim >::symmetric_gradient_type >::type symmetric_gradient_type
Definition: fe_values.h:610
const unsigned int dofs_per_cell
Definition: fe_base.h:295
void get_function_hessians(const InputVector &fe_function, std::vector< typename ProductType< hessian_type, typename InputVector::value_type >::type > &hessians) const
Definition: fe_values.cc:1506
const unsigned int n_quadrature_points
Definition: fe_values.h:1840
ProductType< Number, typename Vector< dim, spacedim >::value_type >::type laplacian_type
Definition: fe_values.h:622
void get_function_curls(const InputVector &fe_function, std::vector< typename ProductType< curl_type, typename InputVector::value_type >::type > &curls) const
Definition: fe_values.cc:1817
internal::return_value< RT >::reference_type return_value()
size_type size(const unsigned int i) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
Definition: fe.h:3032
void get_function_laplacians_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::laplacian_type > &laplacians) const
Definition: fe_values.cc:1932
unsigned int n_components() const
Definition: mpi.h:53
FEFaceValuesBase(const unsigned int n_q_points, const unsigned int dofs_per_cell, const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim-1 > &quadrature)
Definition: fe_values.cc:4176
ProductType< Number, typename SymmetricTensor< 2, dim, spacedim >::value_type >::type value_type
Definition: fe_values.h:1160
void initialize(const UpdateFlags update_flags)
Definition: fe_values.cc:4002
Shape function gradients.
void get_function_third_derivatives_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::third_derivative_type > &third_derivatives) const
Definition: fe_values.cc:1978
Normal vectors.
void maybe_invalidate_previous_present_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
Definition: fe_values.cc:3843
T signaling_nan()
value_type * data() const noexcept
Definition: array_view.h:346
Definition: fe.h:33
void initialize(const UpdateFlags update_flags)
Definition: fe_values.cc:4424
void get_function_gradients_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::gradient_type > &gradients) const
Definition: fe_values.cc:1486
static ::ExceptionBase & ExcNotMultiple(int arg1, int arg2)
static ::ExceptionBase & ExcNotImplemented()
ProductType< Number, typename Vector< dim, spacedim >::curl_type >::type curl_type
Definition: fe_values.h:628
static unsigned int n_threads()
const Triangulation< dim, spacedim >::cell_iterator get_cell() const
Definition: fe_values.cc:3753
bool is_element(const size_type index) const
Definition: index_set.h:1645
void get_function_values(const InputVector &fe_function, std::vector< typename ProductType< value_type, typename InputVector::value_type >::type > &values) const
Definition: fe_values.cc:1638
const std::vector< Tensor< 1, spacedim > > & get_boundary_forms() const
Definition: fe_values.cc:4196
void initialize(const UpdateFlags update_flags)
Definition: fe_values.cc:4261
FEValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &quadrature, const UpdateFlags update_flags)
Definition: fe_values.cc:3966
void get_function_gradients(const InputVector &fe_function, std::vector< typename ProductType< gradient_type, typename InputVector::value_type >::type > &gradients) const
Definition: fe_values.cc:1682
void get_function_third_derivatives_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::third_derivative_type > &third_derivatives) const
Definition: fe_values.cc:1618
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
const std::vector< Tensor< 1, spacedim > > & get_normal_vectors() const
Definition: fe_values.cc:3773
void do_reinit()
Definition: fe_values.cc:4131
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
Definition: fe_values.cc:4106
ProductType< Number, typename Tensor< 2, dim, spacedim >::divergence_type >::type divergence_type
Definition: fe_values.h:1430
void get_function_values_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::value_type > &values) const
Definition: fe_values.cc:1442
FESubfaceValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim-1 > &face_quadrature, const UpdateFlags update_flags)
Definition: fe_values.cc:4390
ProductType< Number, typename Scalar< dim, spacedim >::value_type >::type laplacian_type
Definition: fe_values.h:193
FEFaceValues(const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const Quadrature< dim-1 > &quadrature, const UpdateFlags update_flags)
Definition: fe_values.cc:4227
std::size_t memory_consumption() const
Definition: fe_values.cc:3785
void get_function_values_from_local_dof_values(const InputVector &dof_values, std::vector< typename OutputType< typename InputVector::value_type >::value_type > &values) const
Definition: fe_values.cc:1662
virtual types::global_dof_index n_dofs_for_dof_handler() const
Definition: fe_values.cc:2558
std::vector< ShapeFunctionData > shape_function_data
Definition: fe_values.h:491
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
UpdateFlags update_flags
Definition: fe_values.h:3073
static ::ExceptionBase & ExcInternalError()
ProductType< Number, typename Tensor< 2, dim, spacedim >::value_type >::type value_type
Definition: fe_values.h:1424