Reference documentation for deal.II version 9.0.0
evaluation_selector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 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 
17 #ifndef dealii_matrix_free_evaluation_selector_h
18 #define dealii_matrix_free_evaluation_selector_h
19 
20 #include <deal.II/matrix_free/evaluation_kernels.h>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 #ifndef DOXYGEN
25 namespace
26 {
27 // The following classes serve the purpose of choosing the correct template
28 // specialization of the FEEvaluationImpl* classes in case fe_degree
29 // and n_q_points_1d are only given as runtime parameters.
30 // The logic is the following:
31 // 1. Start with fe_degree=0, n_q_points_1d=0 and DEPTH=0.
32 // 2. If the current assumption on fe_degree doesn't match the runtime
33 // parameter, increase fe_degree by one and try again.
34 // If fe_degree==10 use the class Default which serves as a fallback.
35 // 3. After fixing the fe_degree, DEPTH is increased (DEPTH=1) and we start with
36 // n_q_points=fe_degree+1.
37 // 4. If the current assumption on n_q_points_1d doesn't match the runtime
38 // parameter, increase n_q_points_1d by one and try again.
39 // If n_q_points_1d==degree+3 use the class Default which serves as a fallback.
40 
45  template <int dim, int n_components, typename Number>
46  struct Default
47  {
48  static inline void evaluate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
49  Number *values_dofs_actual,
50  Number *values_quad,
51  Number *gradients_quad,
52  Number *hessians_quad,
53  Number *scratch_data,
54  const bool evaluate_values,
55  const bool evaluate_gradients,
56  const bool evaluate_hessians)
57  {
58  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
59  dim, -1, 0, n_components, Number>
60  ::evaluate(shape_info, values_dofs_actual, values_quad,
61  gradients_quad, hessians_quad, scratch_data,
62  evaluate_values, evaluate_gradients, evaluate_hessians);
63  }
64 
65  static inline void integrate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
66  Number *values_dofs_actual,
67  Number *values_quad,
68  Number *gradients_quad,
69  Number *scratch_data,
70  const bool integrate_values,
71  const bool integrate_gradients)
72  {
73  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
74  dim, -1, 0, n_components, Number>
75  ::integrate(shape_info, values_dofs_actual, values_quad,
76  gradients_quad, scratch_data,
77  integrate_values, integrate_gradients, false);
78  }
79  };
80 
81 
85  template<int dim, int n_components, typename Number,
86  int DEPTH=0, int degree=0, int n_q_points_1d=0, class Enable = void>
87  struct Factory : Default<dim, n_components, Number> {};
88 
93  template<int n_q_points_1d, int dim, int n_components, typename Number>
94  struct Factory<dim, n_components, Number, 0, 10, n_q_points_1d> : Default<dim, n_components, Number> {};
95 
100  template<int degree, int n_q_points_1d, int dim, int n_components, typename Number>
101  struct Factory<dim, n_components, Number, 1, degree, n_q_points_1d,
102  typename std::enable_if<n_q_points_1d==degree+3>::type> : Default<dim, n_components, Number> {};
103 
107  template<int degree, int n_q_points_1d, int dim, int n_components, typename Number>
108  struct Factory<dim, n_components, Number, 0, degree, n_q_points_1d>
109  {
110  static inline void evaluate (
112  Number *values_dofs_actual,
113  Number *values_quad,
114  Number *gradients_quad,
115  Number *hessians_quad,
116  Number *scratch_data,
117  const bool evaluate_values,
118  const bool evaluate_gradients,
119  const bool evaluate_hessians)
120  {
121  const unsigned int runtime_degree = shape_info.fe_degree;
122  constexpr unsigned int start_n_q_points = degree+1;
123  if (runtime_degree == degree)
124  Factory<dim, n_components, Number, 1, degree, start_n_q_points>::evaluate
125  (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad,
126  scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians);
127  else
128  Factory<dim, n_components, Number, 0, degree+1, n_q_points_1d>::evaluate
129  (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad,
130  scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians);
131  }
132 
133  static inline void integrate (
135  Number *values_dofs_actual,
136  Number *values_quad,
137  Number *gradients_quad,
138  Number *scratch_data,
139  const bool integrate_values,
140  const bool integrate_gradients)
141  {
142  const int runtime_degree = shape_info.fe_degree;
143  constexpr unsigned int start_n_q_points = degree+1;
144  if (runtime_degree == degree)
145  Factory<dim, n_components, Number, 1, degree, start_n_q_points>::integrate
146  (shape_info, values_dofs_actual, values_quad, gradients_quad,
147  scratch_data, integrate_values, integrate_gradients);
148  else
149  Factory<dim, n_components, Number, 0, degree+1, n_q_points_1d>::integrate
150  (shape_info, values_dofs_actual, values_quad, gradients_quad,
151  scratch_data, integrate_values, integrate_gradients);
152  }
153  };
154 
158  template<int degree, int n_q_points_1d, int dim, int n_components, typename Number>
159  struct Factory<dim, n_components, Number, 1, degree, n_q_points_1d, typename std::enable_if<(n_q_points_1d<degree+3)>::type>
160  {
161  static inline void evaluate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
162  Number *values_dofs_actual,
163  Number *values_quad,
164  Number *gradients_quad,
165  Number *hessians_quad,
166  Number *scratch_data,
167  const bool evaluate_values,
168  const bool evaluate_gradients,
169  const bool evaluate_hessians)
170  {
171  const int runtime_n_q_points_1d = shape_info.n_q_points_1d;
172  if (runtime_n_q_points_1d == n_q_points_1d)
173  {
174  if (n_q_points_1d == degree+1 &&
175  shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation)
177  ::evaluate(shape_info, values_dofs_actual, values_quad,
178  gradients_quad, hessians_quad, scratch_data,
179  evaluate_values, evaluate_gradients, evaluate_hessians);
180  else if (degree < n_q_points_1d)
182  ::evaluate(shape_info, values_dofs_actual, values_quad,
183  gradients_quad, hessians_quad, scratch_data,
184  evaluate_values, evaluate_gradients, evaluate_hessians);
185  else
187  ::evaluate(shape_info, values_dofs_actual, values_quad,
188  gradients_quad, hessians_quad, scratch_data,
189  evaluate_values, evaluate_gradients, evaluate_hessians);
190  }
191  else
192  Factory<dim, n_components, Number, 1, degree, n_q_points_1d+1>::evaluate (shape_info, values_dofs_actual, values_quad,
193  gradients_quad, hessians_quad, scratch_data,
194  evaluate_values, evaluate_gradients, evaluate_hessians);
195  }
196 
197  static inline void integrate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
198  Number *values_dofs_actual,
199  Number *values_quad,
200  Number *gradients_quad,
201  Number *scratch_data,
202  const bool integrate_values,
203  const bool integrate_gradients)
204  {
205  const int runtime_n_q_points_1d = shape_info.n_q_points_1d;
206  if (runtime_n_q_points_1d == n_q_points_1d)
207  {
208  if (n_q_points_1d == degree+1 &&
209  shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation)
211  ::integrate(shape_info, values_dofs_actual, values_quad,
212  gradients_quad, scratch_data,
213  integrate_values, integrate_gradients, false);
214  else if (degree < n_q_points_1d)
216  ::integrate(shape_info, values_dofs_actual, values_quad,
217  gradients_quad, scratch_data,
218  integrate_values, integrate_gradients, false);
219  else
221  ::integrate(shape_info, values_dofs_actual, values_quad, gradients_quad,
222  scratch_data, integrate_values, integrate_gradients, false);
223  }
224  else
225  Factory<dim, n_components, Number, 1, degree, n_q_points_1d+1>
226  ::integrate (shape_info, values_dofs_actual, values_quad, gradients_quad,
227  scratch_data, integrate_values, integrate_gradients);
228  }
229  };
230 
231 
232 
237  template<int dim, int n_components, typename Number>
238  void symmetric_selector_evaluate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
239  Number *values_dofs_actual,
240  Number *values_quad,
241  Number *gradients_quad,
242  Number *hessians_quad,
243  Number *scratch_data,
244  const bool evaluate_values,
245  const bool evaluate_gradients,
246  const bool evaluate_hessians)
247  {
248  Assert(shape_info.element_type <= internal::MatrixFreeFunctions::tensor_symmetric,
249  ExcInternalError());
250  Factory<dim, n_components, Number>::evaluate
251  (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad,
252  scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians);
253  }
254 
255 
256 
261  template<int dim, int n_components, typename Number>
262  void symmetric_selector_integrate (const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
263  Number *values_dofs_actual,
264  Number *values_quad,
265  Number *gradients_quad,
266  Number *scratch_data,
267  const bool integrate_values,
268  const bool integrate_gradients)
269  {
270  Assert(shape_info.element_type <= internal::MatrixFreeFunctions::tensor_symmetric,
271  ExcInternalError());
272  Factory<dim, n_components, Number>::integrate
273  (shape_info, values_dofs_actual, values_quad, gradients_quad,
274  scratch_data, integrate_values, integrate_gradients);
275  }
276 }
277 #endif
278 
279 
290 template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename Number>
292 {
300  static void evaluate(const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
301  Number *values_dofs_actual,
302  Number *values_quad,
303  Number *gradients_quad,
304  Number *hessians_quad,
305  Number *scratch_data,
306  const bool evaluate_values,
307  const bool evaluate_gradients,
308  const bool evaluate_hessians);
309 
317  static void integrate(const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
318  Number *values_dofs_actual,
319  Number *values_quad,
320  Number *gradients_quad,
321  Number *scratch_data,
322  const bool integrate_values,
323  const bool integrate_gradients);
324 };
325 
336 template <int dim, int n_q_points_1d, int n_components, typename Number>
337 struct SelectEvaluator<dim, -1, n_q_points_1d, n_components, Number>
338 {
347  static void evaluate(const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
348  Number *values_dofs_actual,
349  Number *values_quad,
350  Number *gradients_quad,
351  Number *hessians_quad,
352  Number *scratch_data,
353  const bool evaluate_values,
354  const bool evaluate_gradients,
355  const bool evaluate_hessians);
356 
365  static void integrate(const internal::MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
366  Number *values_dofs_actual,
367  Number *values_quad,
368  Number *gradients_quad,
369  Number *scratch_data,
370  const bool integrate_values,
371  const bool integrate_gradients);
372 };
373 
374 //----------------------Implementation for SelectEvaluator---------------------
375 #ifndef DOXYGEN
376 
377 template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename Number>
378 inline
379 void
382  Number *values_dofs_actual,
383  Number *values_quad,
384  Number *gradients_quad,
385  Number *hessians_quad,
386  Number *scratch_data,
387  const bool evaluate_values,
388  const bool evaluate_gradients,
389  const bool evaluate_hessians)
390 {
391  Assert(fe_degree>=0 && n_q_points_1d>0, ExcInternalError());
392 
393  if (fe_degree+1 == n_q_points_1d &&
394  shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation)
395  {
397  ::evaluate(shape_info, values_dofs_actual, values_quad,
398  gradients_quad, hessians_quad, scratch_data,
399  evaluate_values, evaluate_gradients, evaluate_hessians);
400  }
401  else if (fe_degree < n_q_points_1d &&
402  shape_info.element_type <= internal::MatrixFreeFunctions::tensor_symmetric)
403  {
405  ::evaluate(shape_info, values_dofs_actual, values_quad,
406  gradients_quad, hessians_quad, scratch_data,
407  evaluate_values, evaluate_gradients, evaluate_hessians);
408  }
409  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric)
410  {
411  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric,
412  dim, fe_degree, n_q_points_1d, n_components, Number>
413  ::evaluate(shape_info, values_dofs_actual, values_quad,
414  gradients_quad, hessians_quad, scratch_data,
415  evaluate_values, evaluate_gradients, evaluate_hessians);
416  }
417  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0)
418  {
419  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
420  dim, fe_degree, n_q_points_1d, n_components, Number>
421  ::evaluate(shape_info, values_dofs_actual, values_quad,
422  gradients_quad, hessians_quad, scratch_data,
423  evaluate_values, evaluate_gradients, evaluate_hessians);
424  }
425  else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor)
426  {
427  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
428  dim, fe_degree, n_q_points_1d, n_components, Number>
429  ::evaluate(shape_info, values_dofs_actual, values_quad,
430  gradients_quad, hessians_quad, scratch_data,
431  evaluate_values, evaluate_gradients, evaluate_hessians);
432  }
433  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general)
434  {
435  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
436  dim, fe_degree, n_q_points_1d, n_components, Number>
437  ::evaluate(shape_info, values_dofs_actual, values_quad,
438  gradients_quad, hessians_quad, scratch_data,
439  evaluate_values, evaluate_gradients, evaluate_hessians);
440  }
441  else
442  AssertThrow(false, ExcNotImplemented());
443 }
444 
445 
446 
447 template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename Number>
448 inline
449 void
452  Number *values_dofs_actual,
453  Number *values_quad,
454  Number *gradients_quad,
455  Number *scratch_data,
456  const bool integrate_values,
457  const bool integrate_gradients)
458 {
459  Assert(fe_degree>=0 && n_q_points_1d>0, ExcInternalError());
460 
461  if (fe_degree+1 == n_q_points_1d &&
462  shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation)
463  {
465  ::integrate(shape_info, values_dofs_actual, values_quad,
466  gradients_quad, scratch_data,
467  integrate_values, integrate_gradients, false);
468  }
469  else if (fe_degree < n_q_points_1d &&
470  shape_info.element_type <= internal::MatrixFreeFunctions::tensor_symmetric)
471  {
473  ::integrate(shape_info, values_dofs_actual, values_quad,
474  gradients_quad, scratch_data,
475  integrate_values, integrate_gradients, false);
476  }
477  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric)
478  {
479  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric,
480  dim, fe_degree, n_q_points_1d, n_components, Number>
481  ::integrate(shape_info, values_dofs_actual, values_quad,
482  gradients_quad, scratch_data,
483  integrate_values, integrate_gradients, false);
484  }
485  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0)
486  {
487  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
488  dim, fe_degree, n_q_points_1d, n_components, Number>
489  ::integrate(shape_info, values_dofs_actual, values_quad,
490  gradients_quad, scratch_data,
491  integrate_values, integrate_gradients, false);
492  }
493  else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor)
494  {
495  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
496  dim, fe_degree, n_q_points_1d, n_components, Number>
497  ::integrate(shape_info, values_dofs_actual, values_quad,
498  gradients_quad, scratch_data,
499  integrate_values, integrate_gradients, false);
500  }
501  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general)
502  {
503  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
504  dim, fe_degree, n_q_points_1d, n_components, Number>
505  ::integrate(shape_info, values_dofs_actual, values_quad,
506  gradients_quad, scratch_data,
507  integrate_values, integrate_gradients, false);
508  }
509  else
510  AssertThrow(false, ExcNotImplemented());
511 }
512 
513 
514 
515 template <int dim, int dummy, int n_components, typename Number>
516 inline
517 void
520  Number *values_dofs_actual,
521  Number *values_quad,
522  Number *gradients_quad,
523  Number *hessians_quad,
524  Number *scratch_data,
525  const bool evaluate_values,
526  const bool evaluate_gradients,
527  const bool evaluate_hessians)
528 {
529  if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0)
530  {
531  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
532  dim, -1, 0, n_components, Number>
533  ::evaluate(shape_info, values_dofs_actual, values_quad,
534  gradients_quad, hessians_quad, scratch_data,
535  evaluate_values, evaluate_gradients, evaluate_hessians);
536  }
537  else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor)
538  {
539  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
540  dim, -1, 0, n_components, Number>
541  ::evaluate(shape_info, values_dofs_actual, values_quad,
542  gradients_quad, hessians_quad, scratch_data,
543  evaluate_values, evaluate_gradients, evaluate_hessians);
544  }
545  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general)
546  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
547  dim, -1, 0, n_components, Number>
548  ::evaluate(shape_info, values_dofs_actual, values_quad,
549  gradients_quad, hessians_quad, scratch_data,
550  evaluate_values, evaluate_gradients, evaluate_hessians);
551  else
552  symmetric_selector_evaluate<dim, n_components, Number>
553  (shape_info, values_dofs_actual, values_quad,
554  gradients_quad, hessians_quad, scratch_data,
555  evaluate_values, evaluate_gradients, evaluate_hessians);
556 }
557 
558 
559 
560 template <int dim, int dummy, int n_components, typename Number>
561 inline
562 void
565  Number *values_dofs_actual,
566  Number *values_quad,
567  Number *gradients_quad,
568  Number *scratch_data,
569  const bool integrate_values,
570  const bool integrate_gradients)
571 {
572  if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0)
573  {
574  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0,
575  dim, -1, 0, n_components, Number>
576  ::integrate(shape_info, values_dofs_actual, values_quad,
577  gradients_quad, scratch_data,
578  integrate_values, integrate_gradients, false);
579  }
580  else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor)
581  {
582  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::truncated_tensor,
583  dim, -1, 0, n_components, Number>
584  ::integrate(shape_info, values_dofs_actual, values_quad,
585  gradients_quad, scratch_data,
586  integrate_values, integrate_gradients, false);
587  }
588  else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general)
589  internal::FEEvaluationImpl<internal::MatrixFreeFunctions::tensor_general,
590  dim, -1, 0, n_components, Number>
591  ::integrate(shape_info, values_dofs_actual, values_quad,
592  gradients_quad, scratch_data,
593  integrate_values, integrate_gradients, false);
594  else
595  symmetric_selector_integrate<dim, n_components, Number>
596  (shape_info, values_dofs_actual, values_quad,
597  gradients_quad, scratch_data,
598  integrate_values, integrate_gradients);
599 }
600 #endif //DOXYGEN
601 
602 DEAL_II_NAMESPACE_CLOSE
603 
604 #endif
static void integrate(const internal::MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *scratch_data, const bool integrate_values, const bool integrate_gradients)
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static void evaluate(const internal::MatrixFreeFunctions::ShapeInfo< Number > &shape_info, Number *values_dofs_actual, Number *values_quad, Number *gradients_quad, Number *hessians_quad, Number *scratch_data, const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians)
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcNotImplemented()
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
static ::ExceptionBase & ExcInternalError()