17 #ifndef dealii_matrix_free_evaluation_kernels_h 18 #define dealii_matrix_free_evaluation_kernels_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/vectorization.h> 22 #include <deal.II/base/utilities.h> 23 #include <deal.II/matrix_free/tensor_product_kernels.h> 24 #include <deal.II/matrix_free/shape_info.h> 27 DEAL_II_NAMESPACE_OPEN
34 template <MatrixFreeFunctions::ElementType element,
bool is_
long>
35 struct EvaluatorSelector {};
37 template <
bool is_
long>
38 struct EvaluatorSelector<MatrixFreeFunctions::tensor_general,is_long>
44 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric,false>
49 template <>
struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric,true>
54 template <
bool is_
long>
55 struct EvaluatorSelector<MatrixFreeFunctions::truncated_tensor,is_long>
61 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_plus_dg0,false>
67 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_plus_dg0,true>
72 template <
bool is_
long>
73 struct EvaluatorSelector<MatrixFreeFunctions::tensor_symmetric_collocation,is_long>
98 template <MatrixFreeFunctions::ElementType type,
int dim,
int fe_degree,
104 const Number *values_dofs_actual,
106 Number *gradients_quad,
107 Number *hessians_quad,
108 Number *scratch_data,
109 const bool evaluate_values,
110 const bool evaluate_gradients,
111 const bool evaluate_hessians);
115 Number *values_dofs_actual,
117 Number *gradients_quad,
118 Number *scratch_data,
119 const bool integrate_values,
120 const bool integrate_gradients,
121 const bool add_into_values_array);
126 template <MatrixFreeFunctions::ElementType type,
int dim,
int fe_degree,
127 int n_q_points_1d,
int n_components,
typename Number>
132 const Number *values_dofs_actual,
134 Number *gradients_quad,
135 Number *hessians_quad,
136 Number *scratch_data,
137 const bool evaluate_values,
138 const bool evaluate_gradients,
139 const bool evaluate_hessians)
141 if (evaluate_values ==
false && evaluate_gradients ==
false && evaluate_hessians ==
false)
145 EvaluatorSelector<type,(fe_degree+n_q_points_1d>4)>::variant;
158 : (Eval::n_rows_of_product > Eval::n_columns_of_product ?
159 Eval::n_rows_of_product : Eval::n_columns_of_product);
164 temp1 = scratch_data;
165 temp2 = temp1 + std::max(Utilities::fixed_power<dim>(shape_info.
fe_degree+1),
170 temp1 = scratch_data;
171 temp2 = temp1 + temp_size;
174 const unsigned int n_q_points = temp_size == 0 ? shape_info.
n_q_points : Eval::n_columns_of_product;
175 const unsigned int dofs_per_comp = (type == MatrixFreeFunctions::truncated_tensor) ?
177 const Number *values_dofs = values_dofs_actual;
178 if (type == MatrixFreeFunctions::truncated_tensor)
181 const int degree = fe_degree != -1 ? fe_degree : shape_info.
fe_degree;
182 unsigned int count_p = 0, count_q = 0;
183 for (
int i=0; i<(dim>2?degree+1:1); ++i)
185 for (
int j=0; j<(dim>1?degree+1-i:1); ++j)
187 for (
int k=0; k<degree+1-j-i; ++k, ++count_p, ++count_q)
190 for (
int k=degree+1-j-i; k<degree+1; ++k, ++count_q)
192 values_dofs_tmp[c*dofs_per_comp+count_q] = Number();
194 for (
int j=degree+1-i; j<degree+1; ++j)
195 for (
int k=0; k<degree+1; ++k, ++count_q)
197 values_dofs_tmp[c*dofs_per_comp+count_q] = Number();
200 values_dofs = values_dofs_tmp;
208 if (evaluate_values ==
true)
209 eval.template values<0,true,false> (values_dofs, values_quad);
210 if (evaluate_gradients ==
true)
211 eval.template gradients<0,true,false>(values_dofs, gradients_quad);
212 if (evaluate_hessians ==
true)
213 eval.template hessians<0,true,false> (values_dofs, hessians_quad);
216 values_dofs += dofs_per_comp;
217 values_quad += n_q_points;
218 gradients_quad += n_q_points;
219 hessians_quad += n_q_points;
227 if (evaluate_gradients ==
true)
229 eval.template gradients<0,true,false> (values_dofs, temp1);
230 eval.template values<1,true,false> (temp1, gradients_quad);
232 if (evaluate_hessians ==
true)
235 if (evaluate_gradients ==
false)
236 eval.template gradients<0,true,false>(values_dofs, temp1);
237 eval.template gradients<1,true,false> (temp1, hessians_quad+2*n_q_points);
240 eval.template hessians<0,true,false>(values_dofs, temp1);
241 eval.template values<1,true,false> (temp1, hessians_quad);
245 eval.template values<0,true,false> (values_dofs, temp1);
246 if (evaluate_gradients ==
true)
247 eval.template gradients<1,true,false> (temp1, gradients_quad+n_q_points);
250 if (evaluate_hessians ==
true)
251 eval.template hessians<1,true,false> (temp1, hessians_quad+n_q_points);
254 if (evaluate_values ==
true)
255 eval.template values<1,true,false> (temp1, values_quad);
258 values_dofs += dofs_per_comp;
259 values_quad += n_q_points;
260 gradients_quad += 2*n_q_points;
261 hessians_quad += 3*n_q_points;
268 if (evaluate_gradients ==
true)
271 eval.template gradients<0,true,false> (values_dofs, temp1);
272 eval.template values<1,true,false> (temp1, temp2);
273 eval.template values<2,true,false> (temp2, gradients_quad);
276 if (evaluate_hessians ==
true)
279 if (evaluate_gradients ==
false)
281 eval.template gradients<0,true,false> (values_dofs, temp1);
282 eval.template values<1,true,false> (temp1, temp2);
284 eval.template gradients<2,true,false> (temp2, hessians_quad+4*n_q_points);
287 eval.template gradients<1,true,false> (temp1, temp2);
288 eval.template values<2,true,false> (temp2, hessians_quad+3*n_q_points);
291 eval.template hessians<0,true,false>(values_dofs, temp1);
292 eval.template values<1,true,false> (temp1, temp2);
293 eval.template values<2,true,false> (temp2, hessians_quad);
297 eval.template values<0,true,false> (values_dofs, temp1);
298 if (evaluate_gradients ==
true)
300 eval.template gradients<1,true,false>(temp1, temp2);
301 eval.template values<2,true,false> (temp2, gradients_quad+n_q_points);
304 if (evaluate_hessians ==
true)
307 if (evaluate_gradients ==
false)
308 eval.template gradients<1,true,false>(temp1, temp2);
309 eval.template gradients<2,true,false> (temp2, hessians_quad+5*n_q_points);
312 eval.template hessians<1,true,false> (temp1, temp2);
313 eval.template values<2,true,false> (temp2, hessians_quad+n_q_points);
317 eval.template values<1,true,false> (temp1, temp2);
318 if (evaluate_gradients ==
true)
319 eval.template gradients<2,true,false> (temp2, gradients_quad+2*n_q_points);
323 if (evaluate_hessians ==
true)
324 eval.template hessians<2,true,false>(temp2, hessians_quad+2*n_q_points);
327 if (evaluate_values ==
true)
328 eval.template values<2,true,false> (temp2, values_quad);
331 values_dofs += dofs_per_comp;
332 values_quad += n_q_points;
333 gradients_quad += 3*n_q_points;
334 hessians_quad += 6*n_q_points;
344 if (type == MatrixFreeFunctions::tensor_symmetric_plus_dg0 && evaluate_values)
349 for (
unsigned int q=0; q<shape_info.
n_q_points; ++q)
357 template <MatrixFreeFunctions::ElementType type,
int dim,
int fe_degree,
361 FEEvaluationImpl<type,dim,fe_degree,n_q_points_1d,n_components,Number>
362 ::integrate (
const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
363 Number *values_dofs_actual,
365 Number *gradients_quad,
366 Number *scratch_data,
367 const bool integrate_values,
368 const bool integrate_gradients,
369 const bool add_into_values_array)
372 EvaluatorSelector<type,(fe_degree+n_q_points_1d>4)>::variant;
373 typedef EvaluatorTensorProduct<variant, dim, fe_degree+1, n_q_points_1d,
376 shape_info.shape_values,
378 shape_info.shape_gradients,
380 shape_info.shape_hessians,
381 shape_info.fe_degree+1,
382 shape_info.n_q_points_1d);
385 : (Eval::n_rows_of_product > Eval::n_columns_of_product ?
386 Eval::n_rows_of_product : Eval::n_columns_of_product);
391 temp1 = scratch_data;
392 temp2 = temp1 + std::max(Utilities::fixed_power<dim>(shape_info.fe_degree+1),
393 Utilities::fixed_power<dim>(shape_info.n_q_points_1d));
397 temp1 = scratch_data;
398 temp2 = temp1 + temp_size;
401 const unsigned int n_q_points = temp_size == 0 ? shape_info.n_q_points : Eval::n_columns_of_product;
402 const unsigned int dofs_per_comp = (type == MatrixFreeFunctions::truncated_tensor) ?
403 Utilities::fixed_power<dim>(shape_info.fe_degree+1) : shape_info.dofs_per_component_on_cell;
405 Number *values_dofs = (type == MatrixFreeFunctions::truncated_tensor) ?
406 scratch_data+2*(std::max(shape_info.dofs_per_component_on_cell,
407 shape_info.n_q_points)) :
415 if (integrate_values ==
true)
417 if (add_into_values_array ==
false)
418 eval.template values<0,false,false> (values_quad, values_dofs);
420 eval.template values<0,false,true> (values_quad, values_dofs);
422 if (integrate_gradients ==
true)
424 if (integrate_values ==
true || add_into_values_array ==
true)
425 eval.template gradients<0,false,true> (gradients_quad, values_dofs);
427 eval.template gradients<0,false,false> (gradients_quad, values_dofs);
431 values_dofs += dofs_per_comp;
432 values_quad += n_q_points;
433 gradients_quad += n_q_points;
440 if (integrate_values ==
true &&
441 integrate_gradients ==
false)
443 eval.template values<1,false,false> (values_quad, temp1);
444 if (add_into_values_array ==
false)
445 eval.template values<0,false,false>(temp1, values_dofs);
447 eval.template values<0,false,true>(temp1, values_dofs);
449 if (integrate_gradients ==
true)
451 eval.template gradients<1,false,false> (gradients_quad+n_q_points, temp1);
452 if (integrate_values)
453 eval.template values<1,false,true> (values_quad, temp1);
454 if (add_into_values_array ==
false)
455 eval.template values<0,false,false>(temp1, values_dofs);
457 eval.template values<0,false,true>(temp1, values_dofs);
458 eval.template values<1,false,false> (gradients_quad, temp1);
459 eval.template gradients<0,false,true> (temp1, values_dofs);
463 values_dofs += dofs_per_comp;
464 values_quad += n_q_points;
465 gradients_quad += 2*n_q_points;
472 if (integrate_values ==
true &&
473 integrate_gradients ==
false)
475 eval.template values<2,false,false> (values_quad, temp1);
476 eval.template values<1,false,false> (temp1, temp2);
477 if (add_into_values_array ==
false)
478 eval.template values<0,false,false>(temp2, values_dofs);
480 eval.template values<0,false,true> (temp2, values_dofs);
482 if (integrate_gradients ==
true)
484 eval.template gradients<2,false,false>(gradients_quad+2*n_q_points, temp1);
485 if (integrate_values)
486 eval.template values<2,false,true> (values_quad, temp1);
487 eval.template values<1,false,false> (temp1, temp2);
488 eval.template values<2,false,false> (gradients_quad+n_q_points, temp1);
489 eval.template gradients<1,false,true> (temp1, temp2);
490 if (add_into_values_array ==
false)
491 eval.template values<0,false,false> (temp2, values_dofs);
493 eval.template values<0,false,true> (temp2, values_dofs);
494 eval.template values<2,false,false> (gradients_quad, temp1);
495 eval.template values<1,false,false> (temp1, temp2);
496 eval.template gradients<0,false,true> (temp2, values_dofs);
500 values_dofs += dofs_per_comp;
501 values_quad += n_q_points;
502 gradients_quad += 3*n_q_points;
511 if (type == MatrixFreeFunctions::tensor_symmetric_plus_dg0)
513 values_dofs -=
n_components * dofs_per_comp - shape_info.dofs_per_component_on_cell + 1;
515 if (integrate_values)
518 values_dofs[0] = values_quad[0];
519 for (
unsigned int q=1; q<shape_info.n_q_points; ++q)
520 values_dofs[0] += values_quad[q];
521 values_dofs += dofs_per_comp;
522 values_quad += n_q_points;
527 values_dofs[c*shape_info.dofs_per_component_on_cell] = Number();
528 values_dofs +=
n_components*shape_info.dofs_per_component_on_cell;
532 if (type == MatrixFreeFunctions::truncated_tensor)
535 unsigned int count_p = 0, count_q = 0;
536 const int degree = fe_degree != -1 ? fe_degree : shape_info.fe_degree;
537 for (
int i=0; i<(dim>2?degree+1:1); ++i)
539 for (
int j=0; j<(dim>1?degree+1-i:1); ++j)
541 for (
int k=0; k<degree+1-j-i; ++k, ++count_p, ++count_q)
544 values_dofs_actual[c*shape_info.dofs_per_component_on_cell+count_p] = values_dofs[c*dofs_per_comp+count_q];
548 count_q += i*(degree+1);
550 AssertDimension(count_q, Utilities::fixed_power<dim>(shape_info.fe_degree+1));
568 typename Number,
typename Number2>
571 static_assert(basis_size_1 == 0 || basis_size_1 <= basis_size_2,
572 "The second dimension must not be smaller than the first");
597 DEAL_II_ALWAYS_INLINE
600 const Number *values_in,
605 Assert(basis_size_1 != 0 ||
606 basis_size_1_variable <= basis_size_2_variable,
607 ExcMessage(
"The second dimension must not be smaller than the first"));
613 constexpr
int next_dim = (dim > 2 || ((basis_size_1 == 0 || basis_size_2>basis_size_1)
614 && dim>1)) ? dim-1 : dim;
617 Number,Number2> eval_val (transformation_matrix,
620 basis_size_1_variable,
621 basis_size_2_variable);
622 const unsigned int np_1 = basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
623 const unsigned int np_2 = basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
625 ExcMessage(
"Cannot transform with 0-point basis"));
627 ExcMessage(
"Cannot transform with 0-point basis"));
631 values_in = values_in + n_components*Utilities::fixed_power<dim>(np_1);
632 values_out = values_out + n_components*Utilities::fixed_power<dim>(np_2);
633 for (
unsigned int c=n_components; c!=0; --c)
635 values_in -= Utilities::fixed_power<dim>(np_1);
636 values_out -= Utilities::fixed_power<dim>(np_2);
638 for (
unsigned int q=np_1; q!=0; --q)
641 values_in + (q-1)*Utilities::fixed_power<next_dim>(np_1),
642 values_out + (q-1)*Utilities::fixed_power<next_dim>(np_2),
643 basis_size_1_variable,
644 basis_size_2_variable);
649 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
651 eval_val.template values<0,true,false>(values_in, values_out);
652 eval_val.template values<1,true,false>(values_out, values_out);
655 eval_val.template values<dim-1,
true,
false>(values_in, values_out);
657 eval_val.template values<dim-1,
true,
false>(values_out, values_out);
692 DEAL_II_ALWAYS_INLINE
695 const bool add_into_result,
701 Assert(basis_size_1 != 0 ||
702 basis_size_1_variable <= basis_size_2_variable,
703 ExcMessage(
"The second dimension must not be smaller than the first"));
704 Assert(add_into_result ==
false || values_in != values_out,
705 ExcMessage(
"Input and output cannot alias with each other when " 706 "adding the result of the basis change to existing data"));
708 constexpr
int next_dim = (dim > 2 || ((basis_size_1 == 0 || basis_size_2>basis_size_1)
709 && dim>1)) ? dim-1 : dim;
711 Number,Number2> eval_val (transformation_matrix,
714 basis_size_1_variable,
715 basis_size_2_variable);
716 const unsigned int np_1 = basis_size_1 > 0 ? basis_size_1 : basis_size_1_variable;
717 const unsigned int np_2 = basis_size_1 > 0 ? basis_size_2 : basis_size_2_variable;
719 ExcMessage(
"Cannot transform with 0-point basis"));
721 ExcMessage(
"Cannot transform with 0-point basis"));
723 for (
unsigned int c=0; c<n_components; ++c)
725 if (basis_size_1 > 0 && basis_size_2 == basis_size_1 && dim == 2)
727 eval_val.template values<1,false,false>(values_in, values_in);
729 eval_val.template values<0,false,true>(values_in, values_out);
731 eval_val.template values<0,false,false>(values_in, values_out);
735 if (dim==1 && add_into_result)
736 eval_val.template values<0,false,true>(values_in, values_out);
738 eval_val.template values<0,false,false>(values_in, values_out);
740 eval_val.template values<dim-1,
false,
false>(values_in, values_in);
743 for (
unsigned int q=0; q<np_1; ++q)
747 values_in + q*Utilities::fixed_power<next_dim>(np_2),
748 values_out + q*Utilities::fixed_power<next_dim>(np_1),
749 basis_size_1_variable, basis_size_2_variable);
751 values_in += Utilities::fixed_power<dim>(np_2);
752 values_out += Utilities::fixed_power<dim>(np_1);
777 const Number *values_in,
778 Number *scratch_data,
781 constexpr
int next_dim = dim > 1 ? dim-1 : dim;
782 Number *my_scratch = basis_size_1 != basis_size_2 ? scratch_data : values_out;
783 for (
unsigned int q=basis_size_1; q!=0; --q)
789 Number,Number2> eval_val (transformation_matrix);
790 const unsigned int n_inner_blocks = (dim > 1 && basis_size_2 < 10) ? basis_size_2 : 1;
791 const unsigned int n_blocks =
Utilities::pow(basis_size_2, dim-1);
792 for (
unsigned int ii=0; ii<n_blocks; ii+=n_inner_blocks)
793 for (
unsigned int c=0; c<n_components; ++c)
795 for (
unsigned int i=ii; i<ii+n_inner_blocks; ++i)
796 eval_val.template values_one_line<dim-1,true,false> (my_scratch+i, my_scratch+i);
797 for (
unsigned int q=0; q<basis_size_2; ++q)
798 for (
unsigned int i=ii; i<ii+n_inner_blocks; ++i)
799 my_scratch[i+q*n_blocks] *= coefficients[i+q*n_blocks];
800 for (
unsigned int i=ii; i<ii+n_inner_blocks; ++i)
801 eval_val.template values_one_line<dim-1,false,false>(my_scratch+i, my_scratch+i);
803 for (
unsigned int q=0; q<basis_size_1; ++q)
827 template <
int dim,
int fe_degree,
int n_components,
typename Number>
832 const Number *values_dofs,
834 Number *gradients_quad,
835 Number *hessians_quad,
836 Number *scratch_data,
837 const bool evaluate_values,
838 const bool evaluate_gradients,
839 const bool evaluate_hessians);
845 Number *gradients_quad,
846 Number *scratch_data,
847 const bool integrate_values,
848 const bool integrate_gradients,
849 const bool add_into_values_array);
854 template <
int dim,
int fe_degree,
int n_components,
typename Number>
859 const Number *values_dofs,
861 Number *gradients_quad,
862 Number *hessians_quad,
864 const bool evaluate_values,
865 const bool evaluate_gradients,
866 const bool evaluate_hessians)
869 (fe_degree+2)/2*(fe_degree+1));
875 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree+1, dim);
877 for (
unsigned int c=0; c<n_components; c++)
879 if (evaluate_values ==
true)
880 for (
unsigned int i=0; i<n_q_points; ++i)
881 values_quad[i] = values_dofs[i];
882 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
884 eval.template gradients<0,true,false>(values_dofs, gradients_quad);
886 eval.template gradients<1,true,false>(values_dofs, gradients_quad+n_q_points);
888 eval.template gradients<2,true,false>(values_dofs, gradients_quad+2*n_q_points);
890 if (evaluate_hessians ==
true)
892 eval.template hessians<0,true,false> (values_dofs, hessians_quad);
895 eval.template gradients<1,true,false> (gradients_quad, hessians_quad+dim*n_q_points);
896 eval.template hessians<1,true,false> (values_dofs, hessians_quad+n_q_points);
900 eval.template gradients<2,true,false> (gradients_quad, hessians_quad+4*n_q_points);
901 eval.template gradients<2,true,false> (gradients_quad+n_q_points, hessians_quad+5*n_q_points);
902 eval.template hessians<2,true,false> (values_dofs, hessians_quad+2*n_q_points);
904 hessians_quad += (dim*(dim+1))/2*n_q_points;
906 gradients_quad += dim*n_q_points;
907 values_quad += n_q_points;
908 values_dofs += n_q_points;
914 template <
int dim,
int fe_degree,
int n_components,
typename Number>
917 FEEvaluationImplCollocation<dim, fe_degree, n_components, Number>
918 ::integrate (
const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
921 Number *gradients_quad,
923 const bool integrate_values,
924 const bool integrate_gradients,
925 const bool add_into_values_array)
928 (fe_degree+2)/2*(fe_degree+1));
930 EvaluatorTensorProduct<evaluate_evenodd, dim, fe_degree+1, fe_degree+1, Number>
932 shape_info.shape_gradients_collocation_eo,
933 shape_info.shape_hessians_collocation_eo);
934 constexpr
unsigned int n_q_points =
Utilities::pow(fe_degree+1, dim);
938 if (integrate_values ==
true && add_into_values_array ==
false)
939 for (
unsigned int i=0; i<n_q_points; ++i)
940 values_dofs[i] = values_quad[i];
941 else if (integrate_values ==
true)
942 for (
unsigned int i=0; i<n_q_points; ++i)
943 values_dofs[i] += values_quad[i];
944 if (integrate_gradients ==
true)
946 if (integrate_values ==
true || add_into_values_array ==
true)
947 eval.template gradients<0,false,true>(gradients_quad, values_dofs);
949 eval.template gradients<0,false,false>(gradients_quad, values_dofs);
951 eval.template gradients<1,false,true>(gradients_quad+n_q_points, values_dofs);
953 eval.template gradients<2,false,true>(gradients_quad+2*n_q_points, values_dofs);
955 gradients_quad += dim*n_q_points;
956 values_quad += n_q_points;
957 values_dofs += n_q_points;
976 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename Number>
981 const Number *values_dofs,
983 Number *gradients_quad,
984 Number *hessians_quad,
985 Number *scratch_data,
986 const bool evaluate_values,
987 const bool evaluate_gradients,
988 const bool evaluate_hessians);
994 Number *gradients_quad,
995 Number *scratch_data,
996 const bool integrate_values,
997 const bool integrate_gradients,
998 const bool add_into_values_array);
1003 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename Number>
1008 const Number *values_dofs,
1009 Number *values_quad,
1010 Number *gradients_quad,
1011 Number *hessians_quad,
1014 const bool evaluate_gradients,
1015 const bool evaluate_hessians)
1017 Assert(n_q_points_1d > fe_degree,
1018 ExcMessage(
"You lose information when going to a collocation space " 1019 "of lower degree, so the evaluation results would be " 1020 "wrong. Thus, this class does not permit the desired " 1022 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1024 for (
unsigned int c=0; c<n_components; c++)
1027 (fe_degree>=n_q_points_1d?n_q_points_1d:fe_degree+1),
1028 n_q_points_1d,1,Number,Number>
1030 values_dofs, values_quad);
1033 if (evaluate_gradients ==
true || evaluate_hessians ==
true)
1035 evaluate(shape_info, values_quad,
nullptr, gradients_quad, hessians_quad,
1036 nullptr,
false, evaluate_gradients, evaluate_hessians);
1039 values_quad += n_q_points;
1040 gradients_quad += dim*n_q_points;
1041 hessians_quad += (dim*(dim+1))/2*n_q_points;
1047 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename Number>
1050 FEEvaluationImplTransformToCollocation<dim, fe_degree, n_q_points_1d, n_components, Number>
1051 ::integrate (
const MatrixFreeFunctions::ShapeInfo<Number> &shape_info,
1052 Number *values_dofs,
1053 Number *values_quad,
1054 Number *gradients_quad,
1056 const bool integrate_values,
1057 const bool integrate_gradients,
1058 const bool add_into_values_array)
1060 Assert(n_q_points_1d > fe_degree,
1061 ExcMessage(
"You lose information when going to a collocation space " 1062 "of lower degree, so the evaluation results would be " 1063 "wrong. Thus, this class does not permit the desired " 1066 (n_q_points_1d+1)/2*n_q_points_1d);
1067 constexpr
unsigned int n_q_points =
Utilities::pow(n_q_points_1d, dim);
1073 if (integrate_gradients ==
true)
1074 FEEvaluationImplCollocation<dim,n_q_points_1d-1,1,Number>::
1075 integrate(shape_info, values_quad,
nullptr, gradients_quad,
nullptr,
false,
1076 integrate_gradients,integrate_values);
1080 (fe_degree>=n_q_points_1d?n_q_points_1d:fe_degree+1),
1081 n_q_points_1d,1,Number,Number>
1082 ::do_backward(shape_info.shape_values_eo,
1083 add_into_values_array,
1086 gradients_quad += dim*n_q_points;
1087 values_quad += n_q_points;
1088 values_dofs += shape_info.dofs_per_component_on_cell;
1094 template <
bool symmetric_evaluate,
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename Number>
1095 struct FEFaceEvaluationImpl
1098 void evaluate_in_face (
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1099 Number *values_dofs,
1100 Number *values_quad,
1101 Number *gradients_quad,
1102 Number *scratch_data,
1103 const bool evaluate_val,
1104 const bool evaluate_grad,
1105 const unsigned int subface_index)
1108 = symmetric_evaluate ? data.shape_values_eo :
1110 data.shape_values : data.values_within_subface[subface_index%2]);
1112 = symmetric_evaluate ? data.shape_values_eo :
1114 data.shape_values : data.values_within_subface[subface_index/2]);
1117 = symmetric_evaluate ? data.shape_gradients_eo :
1119 data.shape_gradients : data.gradients_within_subface[subface_index%2]);
1121 = symmetric_evaluate ? data.shape_gradients_eo :
1123 data.shape_gradients : data.gradients_within_subface[subface_index/2]);
1127 dim-1,fe_degree+1,n_q_points_1d,Number> Eval;
1129 data.fe_degree+1, data.n_q_points_1d);
1131 data.fe_degree+1, data.n_q_points_1d);
1133 const unsigned int size_deg = fe_degree > -1 ?
1137 const unsigned int n_q_points = fe_degree > -1 ?
1140 if (evaluate_grad ==
false)
1146 eval1.template values<0,true,false>(values_dofs, values_quad);
1147 eval2.template values<1,true,false>(values_quad, values_quad);
1150 eval1.template values<0,true,false>(values_dofs, values_quad);
1153 values_quad[c] = values_dofs[2*c];
1158 values_dofs += 2*size_deg;
1159 values_quad += n_q_points;
1167 if (symmetric_evaluate && n_q_points_1d > fe_degree)
1169 eval1.template values<0,true,false>(values_dofs, values_quad);
1170 eval1.template values<1,true,false>(values_quad, values_quad);
1174 data.shape_gradients_collocation_eo,
1176 eval_grad.template gradients<0,true,false>(values_quad, gradients_quad);
1177 eval_grad.template gradients<1,true,false>(values_quad,
1178 gradients_quad+n_q_points);
1182 eval1.template gradients<0,true,false>(values_dofs, scratch_data);
1183 eval2.template values<1,true,false>(scratch_data, gradients_quad);
1185 eval1.template values<0,true,false>(values_dofs, scratch_data);
1186 eval2.template gradients<1,true,false>(scratch_data, gradients_quad+n_q_points);
1188 if (evaluate_val ==
true)
1189 eval2.template values<1,true,false>(scratch_data, values_quad);
1191 eval1.template values<0,true,false>(values_dofs+size_deg, scratch_data);
1192 eval2.template values<1,true,false>(scratch_data,
1193 gradients_quad+(dim-1)*n_q_points);
1197 eval1.template values<0,true,false>(values_dofs+size_deg,
1198 gradients_quad+(dim-1)*n_q_points);
1199 eval1.template gradients<0,true,false>(values_dofs, gradients_quad);
1200 if (evaluate_val ==
true)
1201 eval1.template values<0,true,false>(values_dofs, values_quad);
1204 values_quad[0] = values_dofs[0];
1205 gradients_quad[0] = values_dofs[1];
1210 values_dofs += 2*size_deg;
1211 values_quad += n_q_points;
1212 gradients_quad += dim*n_q_points;
1217 void integrate_in_face (
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1218 Number *values_dofs,
1219 Number *values_quad,
1220 Number *gradients_quad,
1221 Number *scratch_data,
1222 const bool integrate_val,
1223 const bool integrate_grad,
1224 const unsigned int subface_index)
1227 = symmetric_evaluate ? data.shape_values_eo :
1229 data.shape_values : data.values_within_subface[subface_index%2]);
1231 = symmetric_evaluate ? data.shape_values_eo :
1233 data.shape_values : data.values_within_subface[subface_index/2]);
1236 = symmetric_evaluate ? data.shape_gradients_eo :
1238 data.shape_gradients : data.gradients_within_subface[subface_index%2]);
1240 = symmetric_evaluate ? data.shape_gradients_eo :
1242 data.shape_gradients : data.gradients_within_subface[subface_index/2]);
1246 dim-1,fe_degree+1,n_q_points_1d,Number> Eval;
1247 Eval eval1(val1,grad1,val1,data.fe_degree+1, data.n_q_points_1d);
1248 Eval eval2(val2,grad2,val1,data.fe_degree+1, data.n_q_points_1d);
1250 const unsigned int size_deg = fe_degree > -1 ?
1254 const unsigned int n_q_points = fe_degree > -1 ?
1257 if (integrate_grad ==
false)
1263 eval2.template values<1,false,false>(values_quad, values_quad);
1264 eval1.template values<0,false,false>(values_quad, values_dofs);
1267 eval1.template values<0,false,false>(values_quad, values_dofs);
1270 values_dofs[2*c] = values_quad[c][0];
1275 values_dofs += 2*size_deg;
1276 values_quad += n_q_points;
1284 eval2.template values<1,false,false> (gradients_quad+2*n_q_points,
1285 gradients_quad+2*n_q_points);
1286 eval1.template values<0,false,false> (gradients_quad+2*n_q_points,
1287 values_dofs+size_deg);
1288 if (symmetric_evaluate && n_q_points_1d > fe_degree)
1291 dim-1,n_q_points_1d,n_q_points_1d,Number> eval_grad
1293 data.shape_gradients_collocation_eo,
1296 eval_grad.template gradients<1,false,true>(gradients_quad+n_q_points,
1299 eval_grad.template gradients<1,false,false>(gradients_quad+n_q_points,
1301 eval_grad.template gradients<0,false,true>(gradients_quad,
1303 eval1.template values<1,false,false>(values_quad, values_quad);
1304 eval1.template values<0,false,false>(values_quad, values_dofs);
1310 eval2.template values<1,false,false> (values_quad, scratch_data);
1311 eval2.template gradients<1,false,true> (gradients_quad+n_q_points,
1315 eval2.template gradients<1,false,false> (gradients_quad+n_q_points,
1318 eval1.template values<0,false,false> (scratch_data, values_dofs);
1319 eval2.template values<1,false,false> (gradients_quad, scratch_data);
1320 eval1.template gradients<0,false,true> (scratch_data, values_dofs);
1324 eval1.template values<0,false,false>(gradients_quad+n_q_points,
1325 values_dofs+size_deg);
1326 eval1.template gradients<0,false,false>(gradients_quad, values_dofs);
1327 if (integrate_val ==
true)
1328 eval1.template values<0,false,true>(values_quad, values_dofs);
1331 values_dofs[0] = values_quad[0];
1332 values_dofs[1] = gradients_quad[0];
1337 values_dofs += 2*size_deg;
1338 values_quad += n_q_points;
1339 gradients_quad += dim*n_q_points;
1346 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1347 struct FEFaceNormalEvaluationImpl
1349 template <
bool do_evaluate,
bool add_
into_output>
1350 static void interpolate(
const MatrixFreeFunctions::ShapeInfo<Number> &data,
1351 const Number *input,
1353 const bool do_gradients,
1354 const unsigned int face_no)
1357 fe_degree+1,0,Number>
1358 evalf(data.shape_data_on_face[face_no%2],
1361 data.fe_degree+1, 0);
1363 const unsigned int in_stride = do_evaluate ? data.dofs_per_component_on_cell : 2*data.dofs_per_component_on_face;
1364 const unsigned int out_stride = do_evaluate ? 2*data.dofs_per_component_on_face : data.dofs_per_component_on_cell;
1365 const unsigned int face_direction = face_no / 2;
1370 if (face_direction == 0)
1371 evalf.template apply_face<0,do_evaluate,add_into_output,1>(input, output);
1372 else if (face_direction == 1)
1373 evalf.template apply_face<1,do_evaluate,add_into_output,1>(input, output);
1375 evalf.template apply_face<2,do_evaluate,add_into_output,1>(input, output);
1379 if (face_direction == 0)
1380 evalf.template apply_face<0,do_evaluate,add_into_output,0>(input, output);
1381 else if (face_direction == 1)
1382 evalf.template apply_face<1,do_evaluate,add_into_output,0>(input, output);
1384 evalf.template apply_face<2,do_evaluate,add_into_output,0>(input, output);
1387 output += out_stride;
1394 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
unsigned int dofs_per_component_on_cell
#define AssertDimension(dim1, dim2)
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
AlignedVector< Number > shape_values_eo
#define AssertThrow(cond, exc)
AlignedVector< Number > shape_hessians
static void do_forward(const AlignedVector< Number2 > &transformation_matrix, const Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
AlignedVector< Number > shape_values
static void do_mass(const AlignedVector< Number2 > &transformation_matrix, const AlignedVector< Number > &coefficients, const Number *values_in, Number *scratch_data, Number *values_out)
static ::ExceptionBase & ExcMessage(std::string arg1)
static void do_backward(const AlignedVector< Number2 > &transformation_matrix, const bool add_into_result, Number *values_in, Number *values_out, const unsigned int basis_size_1_variable=numbers::invalid_unsigned_int, const unsigned int basis_size_2_variable=numbers::invalid_unsigned_int)
#define Assert(cond, exc)
AlignedVector< Number > shape_gradients_collocation_eo
unsigned int n_q_points_1d
AlignedVector< Number > shape_hessians_eo
AlignedVector< Number > shape_gradients_eo
AlignedVector< Number > shape_gradients
static ::ExceptionBase & ExcNotImplemented()
AlignedVector< Number > shape_hessians_collocation_eo