Reference documentation for deal.II version GIT 9042b9283b 2023-12-02 14:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
fe_values_base.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2023 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
19 #include <deal.II/base/numbers.h>
23 
25 
27 
28 #include <deal.II/fe/fe.h>
29 #include <deal.II/fe/fe_values.h>
30 #include <deal.II/fe/mapping.h>
31 
34 
35 #include <deal.II/lac/vector.h>
36 
37 #include <boost/container/small_vector.hpp>
38 
39 #include <iomanip>
40 #include <memory>
41 #include <type_traits>
42 
44 
45 
46 namespace internal
47 {
48  template <int dim, int spacedim>
49  inline std::vector<unsigned int>
51  {
52  std::vector<unsigned int> shape_function_to_row_table(
54  unsigned int row = 0;
55  for (unsigned int i = 0; i < fe.n_dofs_per_cell(); ++i)
56  {
57  // loop over all components that are nonzero for this particular
58  // shape function. if a component is zero then we leave the
59  // value in the table unchanged (at the invalid value)
60  // otherwise it is mapped to the next free entry
61  unsigned int nth_nonzero_component = 0;
62  for (unsigned int c = 0; c < fe.n_components(); ++c)
63  if (fe.get_nonzero_components(i)[c] == true)
64  {
65  shape_function_to_row_table[i * fe.n_components() + c] =
66  row + nth_nonzero_component;
67  ++nth_nonzero_component;
68  }
69  row += fe.n_nonzero_components(i);
70  }
71 
72  return shape_function_to_row_table;
73  }
74 
75  namespace
76  {
77  // Check to see if a DoF value is zero, implying that subsequent operations
78  // with the value have no effect.
79  template <typename Number, typename T = void>
80  struct CheckForZero
81  {
82  static bool
83  value(const Number &value)
84  {
86  }
87  };
88 
89  // For auto-differentiable numbers, the fact that a DoF value is zero
90  // does not imply that its derivatives are zero as well. So we
91  // can't filter by value for these number types.
92  // Note that we also want to avoid actually checking the value itself,
93  // since some AD numbers are not contextually convertible to booleans.
94  template <typename Number>
95  struct CheckForZero<
96  Number,
97  std::enable_if_t<Differentiation::AD::is_ad_number<Number>::value>>
98  {
99  static bool
100  value(const Number & /*value*/)
101  {
102  return false;
103  }
104  };
105  } // namespace
106 } // namespace internal
107 
108 /* ------------ FEValuesBase<dim,spacedim>::CellIteratorContainer ----------- */
109 
110 template <int dim, int spacedim>
112  : initialized(false)
113  , cell(typename Triangulation<dim, spacedim>::cell_iterator(nullptr, -1, -1))
114  , dof_handler(nullptr)
115  , level_dof_access(false)
116 {}
117 
118 
119 
120 template <int dim, int spacedim>
122  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
123  : initialized(true)
124  , cell(cell)
125  , dof_handler(nullptr)
126  , level_dof_access(false)
127 {}
128 
129 
130 
131 template <int dim, int spacedim>
132 bool
134 {
135  return initialized;
136 }
137 
138 
139 
140 template <int dim, int spacedim>
142 operator typename Triangulation<dim, spacedim>::cell_iterator() const
143 {
144  Assert(is_initialized(), ExcNotReinited());
145 
146  return cell;
147 }
148 
149 
150 
151 template <int dim, int spacedim>
154  const
155 {
156  Assert(is_initialized(), ExcNotReinited());
157  Assert(dof_handler != nullptr, ExcNeedsDoFHandler());
158 
159  return dof_handler->n_dofs();
160 }
161 
162 
163 
164 template <int dim, int spacedim>
165 template <typename Number>
166 void
168  const ReadVector<Number> &in,
169  Vector<Number> &out) const
170 {
171  Assert(is_initialized(), ExcNotReinited());
172  Assert(dof_handler != nullptr, ExcNeedsDoFHandler());
173 
174  if (level_dof_access)
175  DoFCellAccessor<dim, spacedim, true>(&cell->get_triangulation(),
176  cell->level(),
177  cell->index(),
178  dof_handler)
179  .get_interpolated_dof_values(in, out);
180  else
181  DoFCellAccessor<dim, spacedim, false>(&cell->get_triangulation(),
182  cell->level(),
183  cell->index(),
184  dof_handler)
185  .get_interpolated_dof_values(in, out);
186 }
187 
188 
189 
190 template <int dim, int spacedim>
191 void
193  const IndexSet &in,
194  Vector<IndexSet::value_type> &out) const
195 {
196  Assert(is_initialized(), ExcNotReinited());
197  Assert(dof_handler != nullptr, ExcNeedsDoFHandler());
198  Assert(level_dof_access == false, ExcNotImplemented());
199 
201  &cell->get_triangulation(), cell->level(), cell->index(), dof_handler);
202 
203  std::vector<types::global_dof_index> dof_indices(
204  cell_dofs.get_fe().n_dofs_per_cell());
205  cell_dofs.get_dof_indices(dof_indices);
206 
207  for (unsigned int i = 0; i < cell_dofs.get_fe().n_dofs_per_cell(); ++i)
208  out[i] = (in.is_element(dof_indices[i]) ? 1 : 0);
209 }
210 
211 
212 
213 /*------------------------------- FEValuesBase ---------------------------*/
214 
215 
216 template <int dim, int spacedim>
218  const unsigned int n_q_points,
219  const unsigned int dofs_per_cell,
220  const UpdateFlags flags,
223  : n_quadrature_points(n_q_points)
224  , max_n_quadrature_points(n_q_points)
226  , mapping(&mapping, typeid(*this).name())
227  , fe(&fe, typeid(*this).name())
229  , fe_values_views_cache(*this)
231 {
232  Assert(n_q_points > 0,
233  ExcMessage("There is nothing useful you can do with an FEValues "
234  "object when using a quadrature formula with zero "
235  "quadrature points!"));
236  this->update_flags = flags;
237 }
238 
239 
240 
241 template <int dim, int spacedim>
243 {
244  tria_listener_refinement.disconnect();
245  tria_listener_mesh_transform.disconnect();
246 }
247 
248 
249 
250 template <int dim, int spacedim>
251 void
253  const bool allow)
254 {
256 }
257 
258 
259 
260 namespace internal
261 {
262  // put shape function part of get_function_xxx methods into separate
263  // internal functions. this allows us to reuse the same code for several
264  // functions (e.g. both the versions with and without indices) as well as
265  // the same code for gradients and Hessians. Moreover, this speeds up
266  // compilation and reduces the size of the final file since all the
267  // different global vectors get channeled through the same code.
268 
269  template <typename Number, typename Number2>
270  void
272  const ::Table<2, double> &shape_values,
273  std::vector<Number> &values)
274  {
275  // scalar finite elements, so shape_values.size() == dofs_per_cell
276  const unsigned int dofs_per_cell = shape_values.n_rows();
277  const unsigned int n_quadrature_points = values.size();
278 
279  // initialize with zero
280  std::fill_n(values.begin(),
283 
284  // add up contributions of trial functions. note that here we deal with
285  // scalar finite elements, so no need to check for non-primitivity of
286  // shape functions. in order to increase the speed of this function, we
287  // directly access the data in the shape_values array, and increment
288  // pointers for accessing the data. this saves some lookup time and
289  // indexing. moreover, the order of the loops is such that we can access
290  // the shape_values data stored contiguously
291  for (unsigned int shape_func = 0; shape_func < dofs_per_cell; ++shape_func)
292  {
293  const Number2 value = dof_values[shape_func];
294  // For auto-differentiable numbers, the fact that a DoF value is zero
295  // does not imply that its derivatives are zero as well. So we
296  // can't filter by value for these number types.
299  continue;
300 
301  const double *shape_value_ptr = &shape_values(shape_func, 0);
302  for (unsigned int point = 0; point < n_quadrature_points; ++point)
303  values[point] += value * (*shape_value_ptr++);
304  }
305  }
306 
307 
308 
309  template <int dim, int spacedim, typename VectorType>
310  void
313  const ::Table<2, double> &shape_values,
315  const std::vector<unsigned int> &shape_function_to_row_table,
317  const bool quadrature_points_fastest = false,
318  const unsigned int component_multiple = 1)
319  {
320  using Number = typename VectorType::value_type;
321  // initialize with zero
322  for (unsigned int i = 0; i < values.size(); ++i)
323  std::fill_n(values[i].begin(),
324  values[i].size(),
325  typename VectorType::value_type());
326 
327  // see if there the current cell has DoFs at all, and if not
328  // then there is nothing else to do.
329  const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
330  if (dofs_per_cell == 0)
331  return;
332 
333  const unsigned int n_quadrature_points =
334  quadrature_points_fastest ? values[0].size() : values.size();
335  const unsigned int n_components = fe.n_components();
336 
337  // Assert that we can write all components into the result vectors
338  const unsigned result_components = n_components * component_multiple;
339  (void)result_components;
340  if (quadrature_points_fastest)
341  {
342  AssertDimension(values.size(), result_components);
343  for (unsigned int i = 0; i < values.size(); ++i)
345  }
346  else
347  {
349  for (unsigned int i = 0; i < values.size(); ++i)
350  AssertDimension(values[i].size(), result_components);
351  }
352 
353  // add up contributions of trial functions. now check whether the shape
354  // function is primitive or not. if it is, then set its only non-zero
355  // component, otherwise loop over components
356  for (unsigned int mc = 0; mc < component_multiple; ++mc)
357  for (unsigned int shape_func = 0; shape_func < dofs_per_cell;
358  ++shape_func)
359  {
360  const Number &value = dof_values[shape_func + mc * dofs_per_cell];
361  // For auto-differentiable numbers, the fact that a DoF value is zero
362  // does not imply that its derivatives are zero as well. So we
363  // can't filter by value for these number types.
364  if (::internal::CheckForZero<Number>::value(value) == true)
365  continue;
366 
367  if (fe.is_primitive(shape_func))
368  {
369  const unsigned int comp =
370  fe.system_to_component_index(shape_func).first +
371  mc * n_components;
372  const unsigned int row =
373  shape_function_to_row_table[shape_func * n_components + comp];
374 
375  const double *shape_value_ptr = &shape_values(row, 0);
376 
377  if (quadrature_points_fastest)
378  {
379  VectorType &values_comp = values[comp];
380  for (unsigned int point = 0; point < n_quadrature_points;
381  ++point)
382  values_comp[point] += value * (*shape_value_ptr++);
383  }
384  else
385  for (unsigned int point = 0; point < n_quadrature_points;
386  ++point)
387  values[point][comp] += value * (*shape_value_ptr++);
388  }
389  else
390  for (unsigned int c = 0; c < n_components; ++c)
391  {
392  if (fe.get_nonzero_components(shape_func)[c] == false)
393  continue;
394 
395  const unsigned int row =
396  shape_function_to_row_table[shape_func * n_components + c];
397 
398  const double *shape_value_ptr = &shape_values(row, 0);
399  const unsigned int comp = c + mc * n_components;
400 
401  if (quadrature_points_fastest)
402  {
403  VectorType &values_comp = values[comp];
404  for (unsigned int point = 0; point < n_quadrature_points;
405  ++point)
406  values_comp[point] += value * (*shape_value_ptr++);
407  }
408  else
409  for (unsigned int point = 0; point < n_quadrature_points;
410  ++point)
411  values[point][comp] += value * (*shape_value_ptr++);
412  }
413  }
414  }
415 
416 
417 
418  // use the same implementation for gradients and Hessians, distinguish them
419  // by the rank of the tensors
420  template <int order, int spacedim, typename Number>
421  void
423  const ArrayView<Number> &dof_values,
424  const ::Table<2, Tensor<order, spacedim>> &shape_derivatives,
425  std::vector<Tensor<order, spacedim, Number>> &derivatives)
426  {
427  const unsigned int dofs_per_cell = shape_derivatives.size()[0];
428  const unsigned int n_quadrature_points = derivatives.size();
429 
430  // initialize with zero
431  std::fill_n(derivatives.begin(),
434 
435  // add up contributions of trial functions. note that here we deal with
436  // scalar finite elements, so no need to check for non-primitivity of
437  // shape functions. in order to increase the speed of this function, we
438  // directly access the data in the shape_gradients/hessians array, and
439  // increment pointers for accessing the data. this saves some lookup time
440  // and indexing. moreover, the order of the loops is such that we can
441  // access the shape_gradients/hessians data stored contiguously
442  for (unsigned int shape_func = 0; shape_func < dofs_per_cell; ++shape_func)
443  {
444  const Number &value = dof_values[shape_func];
445  // For auto-differentiable numbers, the fact that a DoF value is zero
446  // does not imply that its derivatives are zero as well. So we
447  // can't filter by value for these number types.
448  if (::internal::CheckForZero<Number>::value(value) == true)
449  continue;
450 
451  const Tensor<order, spacedim> *shape_derivative_ptr =
452  &shape_derivatives[shape_func][0];
453  for (unsigned int point = 0; point < n_quadrature_points; ++point)
454  derivatives[point] += value * (*shape_derivative_ptr++);
455  }
456  }
457 
458 
459 
460  template <int order, int dim, int spacedim, typename Number>
461  void
463  const ArrayView<Number> &dof_values,
464  const ::Table<2, Tensor<order, spacedim>> &shape_derivatives,
466  const std::vector<unsigned int> &shape_function_to_row_table,
467  ArrayView<std::vector<Tensor<order, spacedim, Number>>> derivatives,
468  const bool quadrature_points_fastest = false,
469  const unsigned int component_multiple = 1)
470  {
471  // initialize with zero
472  for (unsigned int i = 0; i < derivatives.size(); ++i)
473  std::fill_n(derivatives[i].begin(),
474  derivatives[i].size(),
476 
477  // see if there the current cell has DoFs at all, and if not
478  // then there is nothing else to do.
479  const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
480  if (dofs_per_cell == 0)
481  return;
482 
483 
484  const unsigned int n_quadrature_points =
485  quadrature_points_fastest ? derivatives[0].size() : derivatives.size();
486  const unsigned int n_components = fe.n_components();
487 
488  // Assert that we can write all components into the result vectors
489  const unsigned result_components = n_components * component_multiple;
490  (void)result_components;
491  if (quadrature_points_fastest)
492  {
493  AssertDimension(derivatives.size(), result_components);
494  for (unsigned int i = 0; i < derivatives.size(); ++i)
495  AssertDimension(derivatives[i].size(), n_quadrature_points);
496  }
497  else
498  {
499  AssertDimension(derivatives.size(), n_quadrature_points);
500  for (unsigned int i = 0; i < derivatives.size(); ++i)
501  AssertDimension(derivatives[i].size(), result_components);
502  }
503 
504  // add up contributions of trial functions. now check whether the shape
505  // function is primitive or not. if it is, then set its only non-zero
506  // component, otherwise loop over components
507  for (unsigned int mc = 0; mc < component_multiple; ++mc)
508  for (unsigned int shape_func = 0; shape_func < dofs_per_cell;
509  ++shape_func)
510  {
511  const Number &value = dof_values[shape_func + mc * dofs_per_cell];
512  // For auto-differentiable numbers, the fact that a DoF value is zero
513  // does not imply that its derivatives are zero as well. So we
514  // can't filter by value for these number types.
515  if (::internal::CheckForZero<Number>::value(value) == true)
516  continue;
517 
518  if (fe.is_primitive(shape_func))
519  {
520  const unsigned int comp =
521  fe.system_to_component_index(shape_func).first +
522  mc * n_components;
523  const unsigned int row =
524  shape_function_to_row_table[shape_func * n_components + comp];
525 
526  const Tensor<order, spacedim> *shape_derivative_ptr =
527  &shape_derivatives[row][0];
528 
529  if (quadrature_points_fastest)
530  for (unsigned int point = 0; point < n_quadrature_points;
531  ++point)
532  derivatives[comp][point] += value * (*shape_derivative_ptr++);
533  else
534  for (unsigned int point = 0; point < n_quadrature_points;
535  ++point)
536  derivatives[point][comp] += value * (*shape_derivative_ptr++);
537  }
538  else
539  for (unsigned int c = 0; c < n_components; ++c)
540  {
541  if (fe.get_nonzero_components(shape_func)[c] == false)
542  continue;
543 
544  const unsigned int row =
545  shape_function_to_row_table[shape_func * n_components + c];
546 
547  const Tensor<order, spacedim> *shape_derivative_ptr =
548  &shape_derivatives[row][0];
549  const unsigned int comp = c + mc * n_components;
550 
551  if (quadrature_points_fastest)
552  for (unsigned int point = 0; point < n_quadrature_points;
553  ++point)
554  derivatives[comp][point] +=
555  value * (*shape_derivative_ptr++);
556  else
557  for (unsigned int point = 0; point < n_quadrature_points;
558  ++point)
559  derivatives[point][comp] +=
560  value * (*shape_derivative_ptr++);
561  }
562  }
563  }
564 
565 
566 
567  template <int spacedim, typename Number, typename Number2>
568  void
570  const ArrayView<Number2> &dof_values,
571  const ::Table<2, Tensor<2, spacedim>> &shape_hessians,
572  std::vector<Number> &laplacians)
573  {
574  const unsigned int dofs_per_cell = shape_hessians.size()[0];
575  const unsigned int n_quadrature_points = laplacians.size();
576 
577  // initialize with zero
578  std::fill_n(laplacians.begin(),
581 
582  // add up contributions of trial functions. note that here we deal with
583  // scalar finite elements and also note that the Laplacian is
584  // the trace of the Hessian.
585  for (unsigned int shape_func = 0; shape_func < dofs_per_cell; ++shape_func)
586  {
587  const Number2 value = dof_values[shape_func];
588  // For auto-differentiable numbers, the fact that a DoF value is zero
589  // does not imply that its derivatives are zero as well. So we
590  // can't filter by value for these number types.
592  if (value == ::internal::NumberType<Number2>::value(0.0))
593  continue;
594 
595  const Tensor<2, spacedim> *shape_hessian_ptr =
596  &shape_hessians[shape_func][0];
597  for (unsigned int point = 0; point < n_quadrature_points; ++point)
598  laplacians[point] += value * trace(*shape_hessian_ptr++);
599  }
600  }
601 
602 
603 
604  template <int dim, int spacedim, typename VectorType, typename Number>
605  void
607  const ArrayView<Number> &dof_values,
608  const ::Table<2, Tensor<2, spacedim>> &shape_hessians,
610  const std::vector<unsigned int> &shape_function_to_row_table,
611  std::vector<VectorType> &laplacians,
612  const bool quadrature_points_fastest = false,
613  const unsigned int component_multiple = 1)
614  {
615  // initialize with zero
616  for (unsigned int i = 0; i < laplacians.size(); ++i)
617  std::fill_n(laplacians[i].begin(),
618  laplacians[i].size(),
619  typename VectorType::value_type());
620 
621  // see if there the current cell has DoFs at all, and if not
622  // then there is nothing else to do.
623  const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
624  if (dofs_per_cell == 0)
625  return;
626 
627 
628  const unsigned int n_quadrature_points = laplacians.size();
629  const unsigned int n_components = fe.n_components();
630 
631  // Assert that we can write all components into the result vectors
632  const unsigned result_components = n_components * component_multiple;
633  (void)result_components;
634  if (quadrature_points_fastest)
635  {
636  AssertDimension(laplacians.size(), result_components);
637  for (unsigned int i = 0; i < laplacians.size(); ++i)
638  AssertDimension(laplacians[i].size(), n_quadrature_points);
639  }
640  else
641  {
642  AssertDimension(laplacians.size(), n_quadrature_points);
643  for (unsigned int i = 0; i < laplacians.size(); ++i)
644  AssertDimension(laplacians[i].size(), result_components);
645  }
646 
647  // add up contributions of trial functions. now check whether the shape
648  // function is primitive or not. if it is, then set its only non-zero
649  // component, otherwise loop over components
650  for (unsigned int mc = 0; mc < component_multiple; ++mc)
651  for (unsigned int shape_func = 0; shape_func < dofs_per_cell;
652  ++shape_func)
653  {
654  const Number &value = dof_values[shape_func + mc * dofs_per_cell];
655  // For auto-differentiable numbers, the fact that a DoF value is zero
656  // does not imply that its derivatives are zero as well. So we
657  // can't filter by value for these number types.
658  if (::internal::CheckForZero<Number>::value(value) == true)
659  continue;
660 
661  if (fe.is_primitive(shape_func))
662  {
663  const unsigned int comp =
664  fe.system_to_component_index(shape_func).first +
665  mc * n_components;
666  const unsigned int row =
667  shape_function_to_row_table[shape_func * n_components + comp];
668 
669  const Tensor<2, spacedim> *shape_hessian_ptr =
670  &shape_hessians[row][0];
671  if (quadrature_points_fastest)
672  {
673  VectorType &laplacians_comp = laplacians[comp];
674  for (unsigned int point = 0; point < n_quadrature_points;
675  ++point)
676  laplacians_comp[point] +=
677  value * trace(*shape_hessian_ptr++);
678  }
679  else
680  for (unsigned int point = 0; point < n_quadrature_points;
681  ++point)
682  laplacians[point][comp] +=
683  value * trace(*shape_hessian_ptr++);
684  }
685  else
686  for (unsigned int c = 0; c < n_components; ++c)
687  {
688  if (fe.get_nonzero_components(shape_func)[c] == false)
689  continue;
690 
691  const unsigned int row =
692  shape_function_to_row_table[shape_func * n_components + c];
693 
694  const Tensor<2, spacedim> *shape_hessian_ptr =
695  &shape_hessians[row][0];
696  const unsigned int comp = c + mc * n_components;
697 
698  if (quadrature_points_fastest)
699  {
700  VectorType &laplacians_comp = laplacians[comp];
701  for (unsigned int point = 0; point < n_quadrature_points;
702  ++point)
703  laplacians_comp[point] +=
704  value * trace(*shape_hessian_ptr++);
705  }
706  else
707  for (unsigned int point = 0; point < n_quadrature_points;
708  ++point)
709  laplacians[point][comp] +=
710  value * trace(*shape_hessian_ptr++);
711  }
712  }
713  }
714 } // namespace internal
715 
716 
717 
718 template <int dim, int spacedim>
719 template <typename Number>
720 void
722  const ReadVector<Number> &fe_function,
723  std::vector<Number> &values) const
724 {
726  ExcAccessToUninitializedField("update_values"));
727  AssertDimension(fe->n_components(), 1);
730 
731  // get function values of dofs on this cell
732  Vector<Number> dof_values(dofs_per_cell);
733  present_cell.get_interpolated_dof_values(fe_function, dof_values);
735  dof_values.end()),
736  this->finite_element_output.shape_values,
737  values);
738 }
739 
740 
741 
742 template <int dim, int spacedim>
743 template <typename Number>
744 void
746  const ReadVector<Number> &fe_function,
748  std::vector<Number> &values) const
749 {
751  ExcAccessToUninitializedField("update_values"));
752  AssertDimension(fe->n_components(), 1);
753  AssertDimension(indices.size(), dofs_per_cell);
754 
755  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
756  auto view = make_array_view(dof_values.begin(), dof_values.end());
757  fe_function.extract_subvector_to(indices, view);
760  values);
761 }
762 
763 
764 
765 template <int dim, int spacedim>
766 template <typename Number>
767 void
769  const ReadVector<Number> &fe_function,
770  std::vector<Vector<Number>> &values) const
771 {
773 
775  ExcAccessToUninitializedField("update_values"));
777 
778  // get function values of dofs on this cell
779  Vector<Number> dof_values(dofs_per_cell);
780  present_cell.get_interpolated_dof_values(fe_function, dof_values);
782  make_array_view(dof_values.begin(), dof_values.end()),
783  this->finite_element_output.shape_values,
784  *fe,
785  this->finite_element_output.shape_function_to_row_table,
786  make_array_view(values.begin(), values.end()));
787 }
788 
789 
790 
791 template <int dim, int spacedim>
792 template <typename Number>
793 void
795  const ReadVector<Number> &fe_function,
797  std::vector<Vector<Number>> &values) const
798 {
799  // Size of indices must be a multiple of dofs_per_cell such that an integer
800  // number of function values is generated in each point.
801  Assert(indices.size() % dofs_per_cell == 0,
802  ExcNotMultiple(indices.size(), dofs_per_cell));
804  ExcAccessToUninitializedField("update_values"));
805 
806  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
807  auto view = make_array_view(dof_values.begin(), dof_values.end());
808  fe_function.extract_subvector_to(indices, view);
810  view,
812  *fe,
813  this->finite_element_output.shape_function_to_row_table,
814  make_array_view(values.begin(), values.end()),
815  false,
816  indices.size() / dofs_per_cell);
817 }
818 
819 
820 
821 template <int dim, int spacedim>
822 template <typename Number>
823 void
825  const ReadVector<Number> &fe_function,
827  ArrayView<std::vector<Number>> values,
828  const bool quadrature_points_fastest) const
829 {
830  Assert(this->update_flags & update_values,
831  ExcAccessToUninitializedField("update_values"));
832 
833  // Size of indices must be a multiple of dofs_per_cell such that an integer
834  // number of function values is generated in each point.
835  Assert(indices.size() % dofs_per_cell == 0,
836  ExcNotMultiple(indices.size(), dofs_per_cell));
837 
838  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
839  auto view = make_array_view(dof_values.begin(), dof_values.end());
840  fe_function.extract_subvector_to(indices, view);
842  view,
844  *fe,
845  this->finite_element_output.shape_function_to_row_table,
846  make_array_view(values.begin(), values.end()),
847  quadrature_points_fastest,
848  indices.size() / dofs_per_cell);
849 }
850 
851 
852 
853 template <int dim, int spacedim>
854 template <typename Number>
855 void
857  const ReadVector<Number> &fe_function,
858  std::vector<Tensor<1, spacedim, Number>> &gradients) const
859 {
861  ExcAccessToUninitializedField("update_gradients"));
862  AssertDimension(fe->n_components(), 1);
865 
866  // get function values of dofs on this cell
867  Vector<Number> dof_values(dofs_per_cell);
868  present_cell.get_interpolated_dof_values(fe_function, dof_values);
870  dof_values.end()),
871  this->finite_element_output.shape_gradients,
872  gradients);
873 }
874 
875 
876 
877 template <int dim, int spacedim>
878 template <typename Number>
879 void
881  const ReadVector<Number> &fe_function,
883  std::vector<Tensor<1, spacedim, Number>> &gradients) const
884 {
885  Assert(this->update_flags & update_gradients,
886  ExcAccessToUninitializedField("update_gradients"));
888  AssertDimension(indices.size(), dofs_per_cell);
889 
890  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
891  auto view = make_array_view(dof_values.begin(), dof_values.end());
892  fe_function.extract_subvector_to(indices, view);
895  gradients);
896 }
897 
898 
899 
900 template <int dim, int spacedim>
901 template <typename Number>
902 void
904  const ReadVector<Number> &fe_function,
905  std::vector<std::vector<Tensor<1, spacedim, Number>>> &gradients) const
906 {
907  Assert(this->update_flags & update_gradients,
908  ExcAccessToUninitializedField("update_gradients"));
911 
912  // get function values of dofs on this cell
913  Vector<Number> dof_values(dofs_per_cell);
914  present_cell.get_interpolated_dof_values(fe_function, dof_values);
916  make_array_view(dof_values.begin(), dof_values.end()),
917  this->finite_element_output.shape_gradients,
918  *fe,
919  this->finite_element_output.shape_function_to_row_table,
920  make_array_view(gradients.begin(), gradients.end()));
921 }
922 
923 
924 
925 template <int dim, int spacedim>
926 template <typename Number>
927 void
929  const ReadVector<Number> &fe_function,
932  const bool quadrature_points_fastest) const
933 {
934  // Size of indices must be a multiple of dofs_per_cell such that an integer
935  // number of function values is generated in each point.
936  Assert(indices.size() % dofs_per_cell == 0,
937  ExcNotMultiple(indices.size(), dofs_per_cell));
938  Assert(this->update_flags & update_gradients,
939  ExcAccessToUninitializedField("update_gradients"));
940 
941  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
942  auto view = make_array_view(dof_values.begin(), dof_values.end());
943  fe_function.extract_subvector_to(indices, view);
945  view,
947  *fe,
948  this->finite_element_output.shape_function_to_row_table,
949  make_array_view(gradients.begin(), gradients.end()),
950  quadrature_points_fastest,
951  indices.size() / dofs_per_cell);
952 }
953 
954 
955 
956 template <int dim, int spacedim>
957 template <typename Number>
958 void
960  const ReadVector<Number> &fe_function,
961  std::vector<Tensor<2, spacedim, Number>> &hessians) const
962 {
965  ExcAccessToUninitializedField("update_hessians"));
968 
969  // get function values of dofs on this cell
970  Vector<Number> dof_values(dofs_per_cell);
971  present_cell.get_interpolated_dof_values(fe_function, dof_values);
973  dof_values.end()),
974  this->finite_element_output.shape_hessians,
975  hessians);
976 }
977 
978 
979 
980 template <int dim, int spacedim>
981 template <typename Number>
982 void
984  const ReadVector<Number> &fe_function,
986  std::vector<Tensor<2, spacedim, Number>> &hessians) const
987 {
989  ExcAccessToUninitializedField("update_hessians"));
991  AssertDimension(indices.size(), dofs_per_cell);
992 
993  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
994  auto view = make_array_view(dof_values.begin(), dof_values.end());
995  fe_function.extract_subvector_to(indices, view);
998  hessians);
999 }
1000 
1001 
1002 
1003 template <int dim, int spacedim>
1004 template <typename Number>
1005 void
1007  const ReadVector<Number> &fe_function,
1008  std::vector<std::vector<Tensor<2, spacedim, Number>>> &hessians,
1009  const bool quadrature_points_fastest) const
1010 {
1012  ExcAccessToUninitializedField("update_hessians"));
1015 
1016  // get function values of dofs on this cell
1017  Vector<Number> dof_values(dofs_per_cell);
1018  present_cell.get_interpolated_dof_values(fe_function, dof_values);
1020  make_array_view(dof_values.begin(), dof_values.end()),
1021  this->finite_element_output.shape_hessians,
1022  *fe,
1023  this->finite_element_output.shape_function_to_row_table,
1024  make_array_view(hessians.begin(), hessians.end()),
1025  quadrature_points_fastest);
1026 }
1027 
1028 
1029 
1030 template <int dim, int spacedim>
1031 template <typename Number>
1032 void
1034  const ReadVector<Number> &fe_function,
1037  const bool quadrature_points_fastest) const
1038 {
1039  Assert(this->update_flags & update_hessians,
1040  ExcAccessToUninitializedField("update_hessians"));
1041  Assert(indices.size() % dofs_per_cell == 0,
1042  ExcNotMultiple(indices.size(), dofs_per_cell));
1043 
1044  boost::container::small_vector<Number, 200> dof_values(indices.size());
1045  auto view = make_array_view(dof_values.begin(), dof_values.end());
1046  fe_function.extract_subvector_to(indices, view);
1048  view,
1050  *fe,
1051  this->finite_element_output.shape_function_to_row_table,
1052  make_array_view(hessians.begin(), hessians.end()),
1053  quadrature_points_fastest,
1054  indices.size() / dofs_per_cell);
1055 }
1056 
1057 
1058 
1059 template <int dim, int spacedim>
1060 template <typename Number>
1061 void
1063  const ReadVector<Number> &fe_function,
1064  std::vector<Number> &laplacians) const
1065 {
1066  Assert(this->update_flags & update_hessians,
1067  ExcAccessToUninitializedField("update_hessians"));
1071 
1072  // get function values of dofs on this cell
1073  Vector<Number> dof_values(dofs_per_cell);
1074  present_cell.get_interpolated_dof_values(fe_function, dof_values);
1076  dof_values.end()),
1077  this->finite_element_output.shape_hessians,
1078  laplacians);
1079 }
1080 
1081 
1082 
1083 template <int dim, int spacedim>
1084 template <typename Number>
1085 void
1087  const ReadVector<Number> &fe_function,
1089  std::vector<Number> &laplacians) const
1090 {
1091  Assert(this->update_flags & update_hessians,
1092  ExcAccessToUninitializedField("update_hessians"));
1094  AssertDimension(indices.size(), dofs_per_cell);
1095 
1096  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
1097  auto view = make_array_view(dof_values.begin(), dof_values.end());
1098  fe_function.extract_subvector_to(indices, view);
1101  laplacians);
1102 }
1103 
1104 
1105 
1106 template <int dim, int spacedim>
1107 template <typename Number>
1108 void
1110  const ReadVector<Number> &fe_function,
1111  std::vector<Vector<Number>> &laplacians) const
1112 {
1114  Assert(this->update_flags & update_hessians,
1115  ExcAccessToUninitializedField("update_hessians"));
1117 
1118  // get function values of dofs on this cell
1119  Vector<Number> dof_values(dofs_per_cell);
1120  present_cell.get_interpolated_dof_values(fe_function, dof_values);
1122  make_array_view(dof_values.begin(), dof_values.end()),
1123  this->finite_element_output.shape_hessians,
1124  *fe,
1125  this->finite_element_output.shape_function_to_row_table,
1126  laplacians);
1127 }
1128 
1129 
1130 
1131 template <int dim, int spacedim>
1132 template <typename Number>
1133 void
1135  const ReadVector<Number> &fe_function,
1137  std::vector<Vector<Number>> &laplacians) const
1138 {
1139  // Size of indices must be a multiple of dofs_per_cell such that an integer
1140  // number of function values is generated in each point.
1141  Assert(indices.size() % dofs_per_cell == 0,
1142  ExcNotMultiple(indices.size(), dofs_per_cell));
1143  Assert(this->update_flags & update_hessians,
1144  ExcAccessToUninitializedField("update_hessians"));
1145 
1146  boost::container::small_vector<Number, 200> dof_values(indices.size());
1147  auto view = make_array_view(dof_values.begin(), dof_values.end());
1148  fe_function.extract_subvector_to(indices, view);
1150  view,
1152  *fe,
1153  this->finite_element_output.shape_function_to_row_table,
1154  laplacians,
1155  false,
1156  indices.size() / dofs_per_cell);
1157 }
1158 
1159 
1160 
1161 template <int dim, int spacedim>
1162 template <typename Number>
1163 void
1165  const ReadVector<Number> &fe_function,
1167  std::vector<std::vector<Number>> &laplacians,
1168  const bool quadrature_points_fastest) const
1169 {
1170  Assert(indices.size() % dofs_per_cell == 0,
1171  ExcNotMultiple(indices.size(), dofs_per_cell));
1172  Assert(this->update_flags & update_hessians,
1173  ExcAccessToUninitializedField("update_hessians"));
1174 
1175  boost::container::small_vector<Number, 200> dof_values(indices.size());
1176  auto view = make_array_view(dof_values.begin(), dof_values.end());
1177  fe_function.extract_subvector_to(indices, view);
1179  view,
1181  *fe,
1182  this->finite_element_output.shape_function_to_row_table,
1183  laplacians,
1184  quadrature_points_fastest,
1185  indices.size() / dofs_per_cell);
1186 }
1187 
1188 
1189 
1190 template <int dim, int spacedim>
1191 template <typename Number>
1192 void
1194  const ReadVector<Number> &fe_function,
1195  std::vector<Tensor<3, spacedim, Number>> &third_derivatives) const
1196 {
1199  ExcAccessToUninitializedField("update_3rd_derivatives"));
1202 
1203  // get function values of dofs on this cell
1204  Vector<Number> dof_values(dofs_per_cell);
1205  present_cell.get_interpolated_dof_values(fe_function, dof_values);
1207  make_array_view(dof_values.begin(), dof_values.end()),
1208  this->finite_element_output.shape_3rd_derivatives,
1209  third_derivatives);
1210 }
1211 
1212 
1213 
1214 template <int dim, int spacedim>
1215 template <typename Number>
1216 void
1218  const ReadVector<Number> &fe_function,
1220  std::vector<Tensor<3, spacedim, Number>> &third_derivatives) const
1221 {
1223  ExcAccessToUninitializedField("update_3rd_derivatives"));
1225  AssertDimension(indices.size(), dofs_per_cell);
1226 
1227  boost::container::small_vector<Number, 200> dof_values(dofs_per_cell);
1228  auto view = make_array_view(dof_values.begin(), dof_values.end());
1229  fe_function.extract_subvector_to(indices, view);
1231  view, this->finite_element_output.shape_3rd_derivatives, third_derivatives);
1232 }
1233 
1234 
1235 
1236 template <int dim, int spacedim>
1237 template <typename Number>
1238 void
1240  const ReadVector<Number> &fe_function,
1241  std::vector<std::vector<Tensor<3, spacedim, Number>>> &third_derivatives,
1242  const bool quadrature_points_fastest) const
1243 {
1245  ExcAccessToUninitializedField("update_3rd_derivatives"));
1248 
1249  // get function values of dofs on this cell
1250  Vector<Number> dof_values(dofs_per_cell);
1251  present_cell.get_interpolated_dof_values(fe_function, dof_values);
1253  make_array_view(dof_values.begin(), dof_values.end()),
1254  this->finite_element_output.shape_3rd_derivatives,
1255  *fe,
1256  this->finite_element_output.shape_function_to_row_table,
1257  make_array_view(third_derivatives.begin(), third_derivatives.end()),
1258  quadrature_points_fastest);
1259 }
1260 
1261 
1262 
1263 template <int dim, int spacedim>
1264 template <typename Number>
1265 void
1267  const ReadVector<Number> &fe_function,
1269  ArrayView<std::vector<Tensor<3, spacedim, Number>>> third_derivatives,
1270  const bool quadrature_points_fastest) const
1271 {
1273  ExcAccessToUninitializedField("update_3rd_derivatives"));
1274  Assert(indices.size() % dofs_per_cell == 0,
1275  ExcNotMultiple(indices.size(), dofs_per_cell));
1276 
1277  boost::container::small_vector<Number, 200> dof_values(indices.size());
1278  auto view = make_array_view(dof_values.begin(), dof_values.end());
1279  fe_function.extract_subvector_to(indices, view);
1281  view,
1283  *fe,
1284  this->finite_element_output.shape_function_to_row_table,
1285  make_array_view(third_derivatives.begin(), third_derivatives.end()),
1286  quadrature_points_fastest,
1287  indices.size() / dofs_per_cell);
1288 }
1289 
1290 
1291 
1292 template <int dim, int spacedim>
1295 {
1296  return present_cell;
1297 }
1298 
1299 
1300 
1301 template <int dim, int spacedim>
1302 const std::vector<Tensor<1, spacedim>> &
1304 {
1307  "update_normal_vectors")));
1308 
1309  return this->mapping_output.normal_vectors;
1310 }
1311 
1312 
1313 
1314 template <int dim, int spacedim>
1315 std::size_t
1317 {
1318  return (sizeof(this->update_flags) +
1319  MemoryConsumption::memory_consumption(n_quadrature_points) +
1321  sizeof(cell_similarity) +
1331 }
1332 
1333 
1334 
1335 template <int dim, int spacedim>
1338  const UpdateFlags update_flags) const
1339 {
1340  // first find out which objects need to be recomputed on each
1341  // cell we visit. this we have to ask the finite element and mapping.
1342  // elements are first since they might require update in mapping
1343  //
1344  // there is no need to iterate since mappings will never require
1345  // the finite element to compute something for them
1347  flags |= mapping->requires_update_flags(flags);
1348 
1349  return flags;
1350 }
1351 
1352 
1353 
1354 template <int dim, int spacedim>
1355 void
1357 {
1358  // if there is no present cell, then we shouldn't be
1359  // connected via a signal to a triangulation
1361 
1362  // so delete the present cell and
1363  // disconnect from the signal we have with
1364  // it
1365  tria_listener_refinement.disconnect();
1366  tria_listener_mesh_transform.disconnect();
1367  present_cell = {};
1368 }
1369 
1370 
1371 
1372 template <int dim, int spacedim>
1373 void
1375  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
1376 {
1378  {
1379  if (&cell->get_triangulation() !=
1380  &present_cell
1381  .
1383  ->get_triangulation())
1384  {
1385  // the triangulations for the previous cell and the current cell
1386  // do not match. disconnect from the previous triangulation and
1387  // connect to the current one; also invalidate the previous
1388  // cell because we shouldn't be comparing cells from different
1389  // triangulations
1392  cell->get_triangulation().signals.any_change.connect(
1393  [this]() { this->invalidate_present_cell(); });
1395  cell->get_triangulation().signals.mesh_movement.connect(
1396  [this]() { this->invalidate_present_cell(); });
1397  }
1398  }
1399  else
1400  {
1401  // if this FEValues has never been set to any cell at all, then
1402  // at least subscribe to the triangulation to get notified of
1403  // changes
1405  cell->get_triangulation().signals.post_refinement.connect(
1406  [this]() { this->invalidate_present_cell(); });
1408  cell->get_triangulation().signals.mesh_movement.connect(
1409  [this]() { this->invalidate_present_cell(); });
1410  }
1411 }
1412 
1413 
1414 
1415 template <int dim, int spacedim>
1416 inline void
1418  const typename Triangulation<dim, spacedim>::cell_iterator &cell)
1419 {
1420  if (check_for_cell_similarity_allowed == false)
1421  {
1423  return;
1424  }
1425 
1426  // case that there has not been any cell before
1427  if (this->present_cell.is_initialized() == false)
1429  else
1430  // in MappingQ, data can have been modified during the last call. Then, we
1431  // can't use that data on the new cell.
1434  else
1435  cell_similarity =
1436  (cell->is_translation_of(
1437  static_cast<
1439  this->present_cell)) ?
1442 
1443  if ((dim < spacedim) && (cell_similarity == CellSimilarity::translation))
1444  {
1445  if (static_cast<const typename Triangulation<dim, spacedim>::cell_iterator
1446  &>(this->present_cell)
1447  ->direction_flag() != cell->direction_flag())
1449  }
1450  // TODO: here, one could implement other checks for similarity, e.g. for
1451  // children of a parallelogram.
1452 }
1453 
1454 
1455 
1456 template <int dim, int spacedim>
1459 {
1460  return cell_similarity;
1461 }
1462 
1463 
1464 
1465 template <int dim, int spacedim>
1466 const unsigned int FEValuesBase<dim, spacedim>::dimension;
1467 
1468 
1469 
1470 template <int dim, int spacedim>
1472 
1473 /*-------------------------- Explicit Instantiations -------------------------*/
1475 
1476 #include "fe_values_base.inst"
1477 
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
Definition: array_view.h:950
iterator begin() const
Definition: array_view.h:703
iterator end() const
Definition: array_view.h:712
std::size_t size() const
Definition: array_view.h:685
void get_interpolated_dof_values(const ReadVector< Number > &values, Vector< Number > &interpolated_values, const types::fe_index fe_index=numbers::invalid_fe_index) const
types::global_dof_index n_dofs_for_dof_handler() const
void get_interpolated_dof_values(const ReadVector< Number > &in, Vector< Number > &out) const
CellSimilarity::Similarity cell_similarity
void get_function_hessians(const ReadVector< Number > &fe_function, std::vector< Tensor< 2, spacedim, Number >> &hessians) const
CellIteratorContainer present_cell
::internal::FEValuesViews::Cache< dim, spacedim > fe_values_views_cache
Triangulation< dim, spacedim >::cell_iterator get_cell() const
boost::signals2::connection tria_listener_mesh_transform
void get_function_values(const ReadVector< Number > &fe_function, std::vector< Number > &values) const
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)
internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > mapping_output
void get_function_third_derivatives(const ReadVector< Number > &fe_function, std::vector< Tensor< 3, spacedim, Number >> &third_derivatives) const
virtual ~FEValuesBase() override
const SmartPointer< const Mapping< dim, spacedim >, FEValuesBase< dim, spacedim > > mapping
const unsigned int dofs_per_cell
void check_cell_similarity(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
UpdateFlags update_flags
const SmartPointer< const FiniteElement< dim, spacedim >, FEValuesBase< dim, spacedim > > fe
void always_allow_check_for_cell_similarity(const bool allow)
void get_function_laplacians(const ReadVector< Number > &fe_function, std::vector< Number > &laplacians) const
const unsigned int n_quadrature_points
CellSimilarity::Similarity get_cell_similarity() const
const std::vector< Tensor< 1, spacedim > > & get_normal_vectors() const
std::size_t memory_consumption() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
UpdateFlags compute_update_flags(const UpdateFlags update_flags) const
std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > mapping_data
void get_function_gradients(const ReadVector< Number > &fe_function, std::vector< Tensor< 1, spacedim, Number >> &gradients) const
boost::signals2::connection tria_listener_refinement
void invalidate_present_cell()
bool check_for_cell_similarity_allowed
::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > finite_element_output
std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > fe_data
void maybe_invalidate_previous_present_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell)
const unsigned int max_n_quadrature_points
unsigned int n_dofs_per_cell() const
unsigned int n_components() const
const ComponentMask & get_nonzero_components(const unsigned int i) const
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const =0
unsigned int n_nonzero_components(const unsigned int i) const
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const =0
virtual size_type size() const =0
virtual void extract_subvector_to(const ArrayView< const types::global_dof_index > &indices, ArrayView< Number > &elements) const =0
Definition: tensor.h:516
Triangulation< dim, spacedim > & get_triangulation()
Signals signals
Definition: tria.h:2519
Definition: vector.h:110
iterator end()
iterator begin()
std::vector< Tensor< 1, spacedim > > normal_vectors
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotReinited()
#define Assert(cond, exc)
Definition: exceptions.h:1631
static ::ExceptionBase & ExcNotImplemented()
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1820
static ::ExceptionBase & ExcAccessToUninitializedField(std::string arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcNotMultiple(int arg1, int arg2)
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1571
UpdateFlags
@ update_hessians
Second derivatives of shape functions.
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_3rd_derivatives
Third derivatives of shape functions.
@ update_gradients
Shape function gradients.
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition: utilities.cc:192
VectorType::value_type * begin(VectorType &V)
void do_function_derivatives(const ArrayView< Number > &dof_values, const ::Table< 2, Tensor< order, spacedim >> &shape_derivatives, std::vector< Tensor< order, spacedim, Number >> &derivatives)
void do_function_laplacians(const ArrayView< Number > &dof_values, const ::Table< 2, Tensor< 2, spacedim >> &shape_hessians, const FiniteElement< dim, spacedim > &fe, const std::vector< unsigned int > &shape_function_to_row_table, std::vector< VectorType > &laplacians, const bool quadrature_points_fastest=false, const unsigned int component_multiple=1)
void do_function_values(const ArrayView< typename VectorType::value_type > &dof_values, const ::Table< 2, double > &shape_values, const FiniteElement< dim, spacedim > &fe, const std::vector< unsigned int > &shape_function_to_row_table, ArrayView< VectorType > values, const bool quadrature_points_fastest=false, const unsigned int component_multiple=1)
void do_function_derivatives(const ArrayView< Number > &dof_values, const ::Table< 2, Tensor< order, spacedim >> &shape_derivatives, const FiniteElement< dim, spacedim > &fe, const std::vector< unsigned int > &shape_function_to_row_table, ArrayView< std::vector< Tensor< order, spacedim, Number >>> derivatives, const bool quadrature_points_fastest=false, const unsigned int component_multiple=1)
void do_function_laplacians(const ArrayView< Number2 > &dof_values, const ::Table< 2, Tensor< 2, spacedim >> &shape_hessians, std::vector< Number > &laplacians)
std::vector< unsigned int > make_shape_function_to_row_table(const FiniteElement< dim, spacedim > &fe)
Definition: fe_values.cc:50
void do_function_values(const ArrayView< Number2 > &dof_values, const ::Table< 2, double > &shape_values, std::vector< Number > &values)
static const unsigned int invalid_unsigned_int
Definition: types.h:221
unsigned int global_dof_index
Definition: types.h:82
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
Definition: numbers.h:703
constexpr DEAL_II_HOST Number trace(const SymmetricTensor< 2, dim2, Number > &)