38#include <boost/container/small_vector.hpp>
50template <
int dim,
int spacedim>
54 , polynomial_degree(fe.tensor_degree())
55 , n_shape_functions(fe.n_dofs_per_cell())
60template <
int dim,
int spacedim>
79template <
int dim,
int spacedim>
86 this->update_each = update_flags;
88 const unsigned int n_q_points = q.
size();
91 covariant.resize(n_q_points);
94 contravariant.resize(n_q_points);
97 volume_elements.resize(n_q_points);
102 shape_values.resize(n_shape_functions * n_q_points);
104 if (this->update_each &
112 shape_derivatives.resize(n_shape_functions * n_q_points);
114 if (this->update_each &
116 shape_second_derivatives.resize(n_shape_functions * n_q_points);
120 shape_third_derivatives.resize(n_shape_functions * n_q_points);
124 shape_fourth_derivatives.resize(n_shape_functions * n_q_points);
127 compute_shape_function_values(q.
get_points());
135template <
int dim,
int spacedim>
140 const unsigned int n_original_q_points)
142 reinit(update_flags, q);
144 if (this->update_each &
153 if constexpr (dim > 1)
155 const auto reference_cell = this->
fe.reference_cell();
156 const auto n_faces = reference_cell.n_faces();
158 for (
unsigned int i = 0; i < n_faces; ++i)
160 unit_tangentials[i].resize(n_original_q_points);
161 std::fill(unit_tangentials[i].
begin(),
162 unit_tangentials[i].
end(),
163 reference_cell.face_tangent_vector(i, 0));
164 if constexpr (dim > 2)
166 unit_tangentials[n_faces + i].resize(n_original_q_points);
167 std::fill(unit_tangentials[n_faces + i].
begin(),
168 unit_tangentials[n_faces + i].
end(),
169 reference_cell.face_tangent_vector(i, 1));
178template <
int dim,
int spacedim>
187 const auto &tensor_pols = fe_poly->get_poly_space();
189 const unsigned int n_shape_functions =
fe.n_dofs_per_cell();
190 const unsigned int n_points = unit_points.size();
192 std::vector<double> values;
193 std::vector<Tensor<1, dim>> grads;
194 if (shape_values.size() != 0)
196 Assert(shape_values.size() == n_shape_functions * n_points,
198 values.resize(n_shape_functions);
200 if (shape_derivatives.size() != 0)
202 Assert(shape_derivatives.size() == n_shape_functions * n_points,
204 grads.resize(n_shape_functions);
207 std::vector<Tensor<2, dim>> grad2;
208 if (shape_second_derivatives.size() != 0)
210 Assert(shape_second_derivatives.size() == n_shape_functions * n_points,
212 grad2.resize(n_shape_functions);
215 std::vector<Tensor<3, dim>> grad3;
216 if (shape_third_derivatives.size() != 0)
218 Assert(shape_third_derivatives.size() == n_shape_functions * n_points,
220 grad3.resize(n_shape_functions);
223 std::vector<Tensor<4, dim>> grad4;
224 if (shape_fourth_derivatives.size() != 0)
226 Assert(shape_fourth_derivatives.size() == n_shape_functions * n_points,
228 grad4.resize(n_shape_functions);
232 if (shape_values.size() != 0 || shape_derivatives.size() != 0 ||
233 shape_second_derivatives.size() != 0 ||
234 shape_third_derivatives.size() != 0 ||
235 shape_fourth_derivatives.size() != 0)
236 for (
unsigned int point = 0; point < n_points; ++point)
238 tensor_pols.evaluate(
239 unit_points[point], values, grads, grad2, grad3, grad4);
241 if (shape_values.size() != 0)
242 for (
unsigned int i = 0; i < n_shape_functions; ++i)
243 shape(point, i) = values[i];
245 if (shape_derivatives.size() != 0)
246 for (
unsigned int i = 0; i < n_shape_functions; ++i)
247 derivative(point, i) = grads[i];
249 if (shape_second_derivatives.size() != 0)
250 for (
unsigned int i = 0; i < n_shape_functions; ++i)
251 second_derivative(point, i) = grad2[i];
253 if (shape_third_derivatives.size() != 0)
254 for (
unsigned int i = 0; i < n_shape_functions; ++i)
255 third_derivative(point, i) = grad3[i];
257 if (shape_fourth_derivatives.size() != 0)
258 for (
unsigned int i = 0; i < n_shape_functions; ++i)
259 fourth_derivative(point, i) = grad4[i];
266 namespace MappingFEImplementation
276 template <
int dim,
int spacedim>
278 maybe_compute_q_points(
280 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
282 const unsigned int n_q_points)
287 for (
unsigned int point = 0; point < n_q_points; ++point)
289 const double *shape = &
data.shape(point + data_set, 0);
291 (shape[0] *
data.mapping_support_points[0]);
292 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
293 for (
unsigned int i = 0; i < spacedim; ++i)
294 result[i] += shape[k] *
data.mapping_support_points[k][i];
295 quadrature_points[point] = result;
309 template <
int dim,
int spacedim>
311 maybe_update_Jacobians(
313 const typename ::QProjector<dim>::DataSetDescriptor data_set,
314 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
315 const unsigned int n_q_points)
325 std::fill(
data.contravariant.begin(),
326 data.contravariant.end(),
331 for (
unsigned int point = 0; point < n_q_points; ++point)
333 double result[spacedim][dim];
337 for (
unsigned int i = 0; i < spacedim; ++i)
338 for (
unsigned int j = 0; j < dim; ++j)
339 result[i][j] =
data.derivative(point + data_set, 0)[j] *
340 data.mapping_support_points[0][i];
341 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
342 for (
unsigned int i = 0; i < spacedim; ++i)
343 for (
unsigned int j = 0; j < dim; ++j)
345 data.derivative(point + data_set, k)[j] *
346 data.mapping_support_points[k][i];
353 for (
unsigned int i = 0; i < spacedim; ++i)
354 for (
unsigned int j = 0; j < dim; ++j)
355 data.contravariant[point][i][j] = result[i][j];
362 for (
unsigned int point = 0; point < n_q_points; ++point)
364 data.covariant[point] =
365 (
data.contravariant[point]).covariant_form();
372 for (
unsigned int point = 0; point < n_q_points; ++point)
373 data.volume_elements[point] =
374 data.contravariant[point].determinant();
384 template <
int dim,
int spacedim>
386 maybe_update_jacobian_grads(
389 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
391 const unsigned int n_q_points)
399 for (
unsigned int point = 0; point < n_q_points; ++point)
402 &
data.second_derivative(point + data_set, 0);
403 double result[spacedim][dim][dim];
404 for (
unsigned int i = 0; i < spacedim; ++i)
405 for (
unsigned int j = 0; j < dim; ++j)
406 for (
unsigned int l = 0; l < dim; ++l)
408 (
second[0][j][l] *
data.mapping_support_points[0][i]);
409 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
410 for (
unsigned int i = 0; i < spacedim; ++i)
411 for (
unsigned int j = 0; j < dim; ++j)
412 for (
unsigned int l = 0; l < dim; ++l)
415 data.mapping_support_points[k][i]);
417 for (
unsigned int i = 0; i < spacedim; ++i)
418 for (
unsigned int j = 0; j < dim; ++j)
419 for (
unsigned int l = 0; l < dim; ++l)
420 jacobian_grads[point][i][j][l] = result[i][j][l];
431 template <
int dim,
int spacedim>
433 maybe_update_jacobian_pushed_forward_grads(
436 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
438 const unsigned int n_q_points)
444 jacobian_pushed_forward_grads.size() + 1);
448 double tmp[spacedim][spacedim][spacedim];
449 for (
unsigned int point = 0; point < n_q_points; ++point)
452 &
data.second_derivative(point + data_set, 0);
453 double result[spacedim][dim][dim];
454 for (
unsigned int i = 0; i < spacedim; ++i)
455 for (
unsigned int j = 0; j < dim; ++j)
456 for (
unsigned int l = 0; l < dim; ++l)
457 result[i][j][l] = (
second[0][j][l] *
458 data.mapping_support_points[0][i]);
459 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
460 for (
unsigned int i = 0; i < spacedim; ++i)
461 for (
unsigned int j = 0; j < dim; ++j)
462 for (
unsigned int l = 0; l < dim; ++l)
465 data.mapping_support_points[k][i]);
468 for (
unsigned int i = 0; i < spacedim; ++i)
469 for (
unsigned int j = 0; j < spacedim; ++j)
470 for (
unsigned int l = 0; l < dim; ++l)
473 result[i][0][l] *
data.covariant[point][j][0];
474 for (
unsigned int jr = 1; jr < dim; ++jr)
476 tmp[i][j][l] += result[i][jr][l] *
477 data.covariant[point][j][jr];
482 for (
unsigned int i = 0; i < spacedim; ++i)
483 for (
unsigned int j = 0; j < spacedim; ++j)
484 for (
unsigned int l = 0; l < spacedim; ++l)
486 jacobian_pushed_forward_grads[point][i][j][l] =
487 tmp[i][j][0] *
data.covariant[point][l][0];
488 for (
unsigned int lr = 1; lr < dim; ++lr)
490 jacobian_pushed_forward_grads[point][i][j][l] +=
491 tmp[i][j][lr] *
data.covariant[point][l][lr];
505 template <
int dim,
int spacedim>
507 maybe_update_jacobian_2nd_derivatives(
510 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
512 const unsigned int n_q_points)
521 for (
unsigned int point = 0; point < n_q_points; ++point)
524 &
data.third_derivative(point + data_set, 0);
525 double result[spacedim][dim][dim][dim];
526 for (
unsigned int i = 0; i < spacedim; ++i)
527 for (
unsigned int j = 0; j < dim; ++j)
528 for (
unsigned int l = 0; l < dim; ++l)
529 for (
unsigned int m = 0; m < dim; ++m)
532 data.mapping_support_points[0][i]);
533 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
534 for (
unsigned int i = 0; i < spacedim; ++i)
535 for (
unsigned int j = 0; j < dim; ++j)
536 for (
unsigned int l = 0; l < dim; ++l)
537 for (
unsigned int m = 0; m < dim; ++m)
538 result[i][j][l][m] +=
540 data.mapping_support_points[k][i]);
542 for (
unsigned int i = 0; i < spacedim; ++i)
543 for (
unsigned int j = 0; j < dim; ++j)
544 for (
unsigned int l = 0; l < dim; ++l)
545 for (
unsigned int m = 0; m < dim; ++m)
546 jacobian_2nd_derivatives[point][i][j][l][m] =
560 template <
int dim,
int spacedim>
562 maybe_update_jacobian_pushed_forward_2nd_derivatives(
565 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
567 &jacobian_pushed_forward_2nd_derivatives,
568 const unsigned int n_q_points)
574 jacobian_pushed_forward_2nd_derivatives.size() +
579 double tmp[spacedim][spacedim][spacedim][spacedim];
580 for (
unsigned int point = 0; point < n_q_points; ++point)
583 &
data.third_derivative(point + data_set, 0);
584 double result[spacedim][dim][dim][dim];
585 for (
unsigned int i = 0; i < spacedim; ++i)
586 for (
unsigned int j = 0; j < dim; ++j)
587 for (
unsigned int l = 0; l < dim; ++l)
588 for (
unsigned int m = 0; m < dim; ++m)
591 data.mapping_support_points[0][i]);
592 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
593 for (
unsigned int i = 0; i < spacedim; ++i)
594 for (
unsigned int j = 0; j < dim; ++j)
595 for (
unsigned int l = 0; l < dim; ++l)
596 for (
unsigned int m = 0; m < dim; ++m)
597 result[i][j][l][m] +=
599 data.mapping_support_points[k][i]);
602 for (
unsigned int i = 0; i < spacedim; ++i)
603 for (
unsigned int j = 0; j < spacedim; ++j)
604 for (
unsigned int l = 0; l < dim; ++l)
605 for (
unsigned int m = 0; m < dim; ++m)
607 jacobian_pushed_forward_2nd_derivatives
608 [point][i][j][l][m] =
610 data.covariant[point][j][0];
611 for (
unsigned int jr = 1; jr < dim; ++jr)
612 jacobian_pushed_forward_2nd_derivatives[point]
615 result[i][jr][l][m] *
616 data.covariant[point][j][jr];
620 for (
unsigned int i = 0; i < spacedim; ++i)
621 for (
unsigned int j = 0; j < spacedim; ++j)
622 for (
unsigned int l = 0; l < spacedim; ++l)
623 for (
unsigned int m = 0; m < dim; ++m)
626 jacobian_pushed_forward_2nd_derivatives[point]
629 data.covariant[point][l][0];
630 for (
unsigned int lr = 1; lr < dim; ++lr)
632 jacobian_pushed_forward_2nd_derivatives
633 [point][i][j][lr][m] *
634 data.covariant[point][l][lr];
638 for (
unsigned int i = 0; i < spacedim; ++i)
639 for (
unsigned int j = 0; j < spacedim; ++j)
640 for (
unsigned int l = 0; l < spacedim; ++l)
641 for (
unsigned int m = 0; m < spacedim; ++m)
643 jacobian_pushed_forward_2nd_derivatives
644 [point][i][j][l][m] =
645 tmp[i][j][l][0] *
data.covariant[point][m][0];
646 for (
unsigned int mr = 1; mr < dim; ++mr)
647 jacobian_pushed_forward_2nd_derivatives[point]
651 data.covariant[point][m][mr];
664 template <
int dim,
int spacedim>
666 maybe_update_jacobian_3rd_derivatives(
669 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
671 const unsigned int n_q_points)
680 for (
unsigned int point = 0; point < n_q_points; ++point)
683 &
data.fourth_derivative(point + data_set, 0);
684 double result[spacedim][dim][dim][dim][dim];
685 for (
unsigned int i = 0; i < spacedim; ++i)
686 for (
unsigned int j = 0; j < dim; ++j)
687 for (
unsigned int l = 0; l < dim; ++l)
688 for (
unsigned int m = 0; m < dim; ++m)
689 for (
unsigned int n = 0; n < dim; ++n)
690 result[i][j][l][m][n] =
691 (fourth[0][j][l][m][n] *
692 data.mapping_support_points[0][i]);
693 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
694 for (
unsigned int i = 0; i < spacedim; ++i)
695 for (
unsigned int j = 0; j < dim; ++j)
696 for (
unsigned int l = 0; l < dim; ++l)
697 for (
unsigned int m = 0; m < dim; ++m)
698 for (
unsigned int n = 0; n < dim; ++n)
699 result[i][j][l][m][n] +=
700 (fourth[k][j][l][m][n] *
701 data.mapping_support_points[k][i]);
703 for (
unsigned int i = 0; i < spacedim; ++i)
704 for (
unsigned int j = 0; j < dim; ++j)
705 for (
unsigned int l = 0; l < dim; ++l)
706 for (
unsigned int m = 0; m < dim; ++m)
707 for (
unsigned int n = 0; n < dim; ++n)
708 jacobian_3rd_derivatives[point][i][j][l][m][n] =
709 result[i][j][l][m][n];
722 template <
int dim,
int spacedim>
724 maybe_update_jacobian_pushed_forward_3rd_derivatives(
727 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
729 &jacobian_pushed_forward_3rd_derivatives,
730 const unsigned int n_q_points)
736 jacobian_pushed_forward_3rd_derivatives.size() +
741 double tmp[spacedim][spacedim][spacedim][spacedim][spacedim];
742 for (
unsigned int point = 0; point < n_q_points; ++point)
745 &
data.fourth_derivative(point + data_set, 0);
746 double result[spacedim][dim][dim][dim][dim];
747 for (
unsigned int i = 0; i < spacedim; ++i)
748 for (
unsigned int j = 0; j < dim; ++j)
749 for (
unsigned int l = 0; l < dim; ++l)
750 for (
unsigned int m = 0; m < dim; ++m)
751 for (
unsigned int n = 0; n < dim; ++n)
752 result[i][j][l][m][n] =
753 (fourth[0][j][l][m][n] *
754 data.mapping_support_points[0][i]);
755 for (
unsigned int k = 1; k <
data.n_shape_functions; ++k)
756 for (
unsigned int i = 0; i < spacedim; ++i)
757 for (
unsigned int j = 0; j < dim; ++j)
758 for (
unsigned int l = 0; l < dim; ++l)
759 for (
unsigned int m = 0; m < dim; ++m)
760 for (
unsigned int n = 0; n < dim; ++n)
761 result[i][j][l][m][n] +=
762 (fourth[k][j][l][m][n] *
763 data.mapping_support_points[k][i]);
766 for (
unsigned int i = 0; i < spacedim; ++i)
767 for (
unsigned int j = 0; j < spacedim; ++j)
768 for (
unsigned int l = 0; l < dim; ++l)
769 for (
unsigned int m = 0; m < dim; ++m)
770 for (
unsigned int n = 0; n < dim; ++n)
773 result[i][0][l][m][n] *
774 data.covariant[point][j][0];
775 for (
unsigned int jr = 1; jr < dim; ++jr)
776 tmp[i][j][l][m][n] +=
777 result[i][jr][l][m][n] *
778 data.covariant[point][j][jr];
782 for (
unsigned int i = 0; i < spacedim; ++i)
783 for (
unsigned int j = 0; j < spacedim; ++j)
784 for (
unsigned int l = 0; l < spacedim; ++l)
785 for (
unsigned int m = 0; m < dim; ++m)
786 for (
unsigned int n = 0; n < dim; ++n)
788 jacobian_pushed_forward_3rd_derivatives
789 [point][i][j][l][m][n] =
791 data.covariant[point][l][0];
792 for (
unsigned int lr = 1; lr < dim; ++lr)
793 jacobian_pushed_forward_3rd_derivatives
794 [point][i][j][l][m][n] +=
795 tmp[i][j][lr][m][n] *
796 data.covariant[point][l][lr];
800 for (
unsigned int i = 0; i < spacedim; ++i)
801 for (
unsigned int j = 0; j < spacedim; ++j)
802 for (
unsigned int l = 0; l < spacedim; ++l)
803 for (
unsigned int m = 0; m < spacedim; ++m)
804 for (
unsigned int n = 0; n < dim; ++n)
807 jacobian_pushed_forward_3rd_derivatives
808 [point][i][j][l][0][n] *
809 data.covariant[point][m][0];
810 for (
unsigned int mr = 1; mr < dim; ++mr)
811 tmp[i][j][l][m][n] +=
812 jacobian_pushed_forward_3rd_derivatives
813 [point][i][j][l][mr][n] *
814 data.covariant[point][m][mr];
818 for (
unsigned int i = 0; i < spacedim; ++i)
819 for (
unsigned int j = 0; j < spacedim; ++j)
820 for (
unsigned int l = 0; l < spacedim; ++l)
821 for (
unsigned int m = 0; m < spacedim; ++m)
822 for (
unsigned int n = 0; n < spacedim; ++n)
824 jacobian_pushed_forward_3rd_derivatives
825 [point][i][j][l][m][n] =
827 data.covariant[point][n][0];
828 for (
unsigned int nr = 1; nr < dim; ++nr)
829 jacobian_pushed_forward_3rd_derivatives
830 [point][i][j][l][m][n] +=
831 tmp[i][j][l][m][nr] *
832 data.covariant[point][n][nr];
844template <
int dim,
int spacedim>
850 ExcMessage(
"It only makes sense to create polynomial mappings "
851 "with a polynomial degree greater or equal to one."));
856 const auto &mapping_support_points =
fe.get_unit_support_points();
858 const auto reference_cell =
fe.reference_cell();
860 const unsigned int n_points = mapping_support_points.size();
861 const unsigned int n_shape_functions = reference_cell.n_vertices();
866 for (
unsigned int point = 0; point < n_points; ++point)
867 for (
unsigned int i = 0; i < n_shape_functions; ++i)
869 reference_cell.d_linear_shape_function(mapping_support_points[point],
875template <
int dim,
int spacedim>
877 : fe(mapping.fe->clone())
878 , polynomial_degree(mapping.polynomial_degree)
879 , mapping_support_point_weights(mapping.mapping_support_point_weights)
884template <
int dim,
int spacedim>
885std::unique_ptr<Mapping<dim, spacedim>>
888 return std::make_unique<MappingFE<dim, spacedim>>(*this);
893template <
int dim,
int spacedim>
897 return polynomial_degree;
902template <
int dim,
int spacedim>
908 const auto support_points = this->compute_mapping_support_points(cell);
912 for (
unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
913 mapped_point += support_points[i] * this->fe->shape_value(i, p);
920template <
int dim,
int spacedim>
926 const auto support_points = this->compute_mapping_support_points(cell);
928 const double eps = 1.e-12 * cell->diameter();
929 const unsigned int loop_limit = 10;
933 unsigned int loop = 0;
949 for (
unsigned int i = 0; i < this->fe->n_dofs_per_cell(); ++i)
951 mapped_point += support_points[i] * this->fe->shape_value(i, p_unit);
952 const auto grad_F_i = this->fe->shape_grad(i, p_unit);
953 const auto hessian_F_i = this->fe->shape_grad_grad(i, p_unit);
954 for (
unsigned int j = 0; j < dim; ++j)
956 grad_FT[j] += grad_F_i[j] * support_points[i];
957 for (
unsigned int l = 0; l < dim; ++l)
958 hess_FT[j][l] += hessian_F_i[j][l] * support_points[i];
963 const auto residual = p - mapped_point;
970 if (grad_FT_residual.norm() <= eps)
975 for (
unsigned int j = 0; j < dim; ++j)
976 for (
unsigned int l = 0; l < dim; ++l)
977 corrected_metric_tensor[j][l] =
978 -grad_FT[j] * grad_FT[l] + hess_FT[j][l] * residual;
981 const auto g_inverse =
invert(corrected_metric_tensor);
982 p_unit -=
Point<dim>(g_inverse * grad_FT_residual);
986 while (loop < loop_limit);
1000template <
int dim,
int spacedim>
1011 for (
unsigned int i = 0; i < 5; ++i)
1056template <
int dim,
int spacedim>
1057std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
1061 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
1062 std::make_unique<InternalData>(*this->fe);
1063 data_ptr->reinit(this->requires_update_flags(update_flags), q);
1069template <
int dim,
int spacedim>
1070std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
1075 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
1076 std::make_unique<InternalData>(*this->fe);
1080 this->fe->reference_cell(), quadrature),
1088template <
int dim,
int spacedim>
1089std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
1094 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
1095 std::make_unique<InternalData>(*this->fe);
1099 this->fe->reference_cell(), quadrature),
1107template <
int dim,
int spacedim>
1122 const unsigned int n_q_points = quadrature.
size();
1134 const auto support_points = this->compute_mapping_support_points(cell);
1135 data.mapping_support_points.assign(support_points.begin(),
1136 support_points.end());
1145 internal::MappingFEImplementation::maybe_compute_q_points<dim, spacedim>(
1151 internal::MappingFEImplementation::maybe_update_Jacobians<dim, spacedim>(
1152 computed_cell_similarity,
1157 internal::MappingFEImplementation::maybe_update_jacobian_grads<dim, spacedim>(
1158 computed_cell_similarity,
1164 internal::MappingFEImplementation::maybe_update_jacobian_pushed_forward_grads<
1166 spacedim>(computed_cell_similarity,
1172 internal::MappingFEImplementation::maybe_update_jacobian_2nd_derivatives<
1174 spacedim>(computed_cell_similarity,
1180 internal::MappingFEImplementation::
1181 maybe_update_jacobian_pushed_forward_2nd_derivatives<dim, spacedim>(
1182 computed_cell_similarity,
1188 internal::MappingFEImplementation::maybe_update_jacobian_3rd_derivatives<
1190 spacedim>(computed_cell_similarity,
1196 internal::MappingFEImplementation::
1197 maybe_update_jacobian_pushed_forward_3rd_derivatives<dim, spacedim>(
1198 computed_cell_similarity,
1205 const std::vector<double> &weights = quadrature.
get_weights();
1221 for (
unsigned int point = 0; point < n_q_points; ++point)
1223 if (dim == spacedim)
1225 const double det =
data.contravariant[point].determinant();
1233 1e-12 * Utilities::fixed_power<dim>(
1234 cell->diameter() /
std::sqrt(
double(dim))),
1236 cell->center(), det, point)));
1238 output_data.
JxW_values[point] = weights[point] * det;
1246 for (
unsigned int i = 0; i < spacedim; ++i)
1247 for (
unsigned int j = 0; j < dim; ++j)
1248 DX_t[j][i] =
data.contravariant[point][i][j];
1251 for (
unsigned int i = 0; i < dim; ++i)
1252 for (
unsigned int j = 0; j < dim; ++j)
1253 G[i][j] = DX_t[i] * DX_t[j];
1258 if (computed_cell_similarity ==
1269 Assert(spacedim == dim + 1,
1271 "There is no (unique) cell normal for " +
1273 "-dimensional cells in " +
1275 "-dimensional space. This only works if the "
1276 "space dimension is one greater than the "
1277 "dimensionality of the mesh cells."));
1281 cross_product_2d(-DX_t[0]);
1284 cross_product_3d(DX_t[0], DX_t[1]);
1289 if (cell->direction_flag() ==
false)
1304 for (
unsigned int point = 0; point < n_q_points; ++point)
1313 for (
unsigned int point = 0; point < n_q_points; ++point)
1315 data.covariant[point].transpose();
1318 return computed_cell_similarity;
1325 namespace MappingFEImplementation
1339 template <
int dim,
int spacedim>
1341 maybe_compute_face_data(
1342 const ::MappingFE<dim, spacedim> &mapping,
1343 const typename ::Triangulation<dim, spacedim>::cell_iterator
1345 const unsigned int face_no,
1346 const unsigned int subface_no,
1347 const unsigned int n_q_points,
1349 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
1376 for (
unsigned int d = 0; d != dim - 1; ++d)
1378 Assert(face_no + cell->n_faces() * d <
1379 data.unit_tangentials.size(),
1382 data.aux[d].size() <=
1383 data.unit_tangentials[face_no + cell->n_faces() * d].size(),
1388 data.unit_tangentials[face_no + cell->n_faces() * d]),
1399 if (dim == spacedim)
1401 for (
unsigned int i = 0; i < n_q_points; ++i)
1411 (face_no == 0 ? -1 : +1);
1415 cross_product_2d(
data.aux[0][i]);
1419 cross_product_3d(
data.aux[0][i],
data.aux[1][i]);
1435 for (
unsigned int point = 0;
point < n_q_points; ++
point)
1441 data.contravariant[
point].transpose()[0];
1443 (face_no == 0 ? -1. : +1.) *
1453 cross_product_3d(DX_t[0], DX_t[1]);
1454 cell_normal /= cell_normal.
norm();
1459 cross_product_3d(
data.aux[0][point], cell_normal);
1466 for (
unsigned int i = 0; i < n_q_points; ++i)
1470 data.quadrature_weights[i + data_set];
1476 const double area_ratio =
1477 1. / cell->reference_cell()
1478 .face_reference_cell(face_no)
1479 .n_isotropic_children();
1488 for (
unsigned int i = 0; i < n_q_points; ++i)
1494 for (
unsigned int point = 0;
point < n_q_points; ++
point)
1498 for (
unsigned int point = 0;
point < n_q_points; ++
point)
1500 data.covariant[point].transpose();
1511 template <
int dim,
int spacedim>
1514 const ::MappingFE<dim, spacedim> &mapping,
1515 const typename ::Triangulation<dim, spacedim>::cell_iterator
1517 const unsigned int face_no,
1518 const unsigned int subface_no,
1521 const typename ::MappingFE<dim, spacedim>::InternalData &
data,
1525 const unsigned int n_q_points = quadrature.
size();
1527 maybe_compute_q_points<dim, spacedim>(data_set,
1540 maybe_update_jacobian_pushed_forward_grads<dim, spacedim>(
1546 maybe_update_jacobian_2nd_derivatives<dim, spacedim>(
1552 maybe_update_jacobian_pushed_forward_2nd_derivatives<dim, spacedim>(
1558 maybe_update_jacobian_3rd_derivatives<dim, spacedim>(
1564 maybe_update_jacobian_pushed_forward_3rd_derivatives<dim, spacedim>(
1586template <
int dim,
int spacedim>
1590 const unsigned int face_no,
1601 const auto support_points = this->compute_mapping_support_points(cell);
1602 data.mapping_support_points.assign(support_points.begin(),
1603 support_points.end());
1605 internal::MappingFEImplementation::do_fill_fe_face_values(
1612 cell->combined_face_orientation(
1615 quadrature[quadrature.
size() == 1 ? 0 : face_no],
1622template <
int dim,
int spacedim>
1626 const unsigned int face_no,
1627 const unsigned int subface_no,
1638 const auto support_points = this->compute_mapping_support_points(cell);
1639 data.mapping_support_points.assign(support_points.begin(),
1640 support_points.end());
1642 internal::MappingFEImplementation::do_fill_fe_face_values(
1650 cell->combined_face_orientation(
1653 cell->subface_case(face_no)),
1663 namespace MappingFEImplementation
1667 template <
int dim,
int spacedim,
int rank>
1684 const typename ::MappingFE<dim, spacedim>::InternalData *
>(
1685 &mapping_data) !=
nullptr),
1687 const typename ::MappingFE<dim, spacedim>::InternalData &
data =
1689 const typename ::MappingFE<dim, spacedim>::InternalData &
>(
1692 switch (mapping_kind)
1699 "update_contravariant_transformation"));
1701 for (
unsigned int i = 0; i < input.size(); ++i)
1713 "update_contravariant_transformation"));
1717 "update_volume_elements"));
1722 for (
unsigned int i = 0; i < input.size(); ++i)
1726 output[i] /=
data.volume_elements[i];
1738 "update_covariant_transformation"));
1740 for (
unsigned int i = 0; i < input.size(); ++i)
1752 template <
int dim,
int spacedim,
int rank>
1763 const typename ::MappingFE<dim, spacedim>::InternalData *
>(
1764 &mapping_data) !=
nullptr),
1766 const typename ::MappingFE<dim, spacedim>::InternalData &
data =
1768 const typename ::MappingFE<dim, spacedim>::InternalData &
>(
1771 switch (mapping_kind)
1778 "update_covariant_transformation"));
1782 "update_contravariant_transformation"));
1785 for (
unsigned int i = 0; i < output.size(); ++i)
1802 "update_covariant_transformation"));
1805 for (
unsigned int i = 0; i < output.size(); ++i)
1806 if constexpr (dim == spacedim)
1826 "update_covariant_transformation"));
1830 "update_contravariant_transformation"));
1834 "update_volume_elements"));
1837 for (
unsigned int i = 0; i < output.size(); ++i)
1840 data.contravariant[i],
1841 data.volume_elements[i],
1854 template <
int dim,
int spacedim>
1865 const typename ::MappingFE<dim, spacedim>::InternalData *
>(
1866 &mapping_data) !=
nullptr),
1868 const typename ::MappingFE<dim, spacedim>::InternalData &
data =
1870 const typename ::MappingFE<dim, spacedim>::InternalData &
>(
1873 switch (mapping_kind)
1880 "update_covariant_transformation"));
1884 "update_contravariant_transformation"));
1886 for (
unsigned int q = 0; q < output.size(); ++q)
1889 data.contravariant[q],
1900 "update_covariant_transformation"));
1902 for (
unsigned int q = 0; q < output.size(); ++q)
1915 "update_covariant_transformation"));
1919 "update_contravariant_transformation"));
1923 "update_volume_elements"));
1925 for (
unsigned int q = 0; q < output.size(); ++q)
1928 data.contravariant[q],
1929 data.volume_elements[q],
1942 template <
int dim,
int spacedim,
int rank>
1953 const typename ::MappingFE<dim, spacedim>::InternalData *
>(
1954 &mapping_data) !=
nullptr),
1956 const typename ::MappingFE<dim, spacedim>::InternalData &
data =
1958 const typename ::MappingFE<dim, spacedim>::InternalData &
>(
1961 switch (mapping_kind)
1968 "update_covariant_transformation"));
1970 for (
unsigned int i = 0; i < output.size(); ++i)
1985template <
int dim,
int spacedim>
1993 internal::MappingFEImplementation::transform_fields(input,
2001template <
int dim,
int spacedim>
2009 internal::MappingFEImplementation::transform_differential_forms(input,
2017template <
int dim,
int spacedim>
2025 switch (mapping_kind)
2028 internal::MappingFEImplementation::transform_fields(input,
2037 internal::MappingFEImplementation::transform_gradients(input,
2049template <
int dim,
int spacedim>
2062 switch (mapping_kind)
2068 "update_covariant_transformation"));
2070 for (
unsigned int q = 0; q < output.size(); ++q)
2084template <
int dim,
int spacedim>
2092 switch (mapping_kind)
2097 internal::MappingFEImplementation::transform_hessians(input,
2111 template <
int spacedim>
2113 check_all_manifold_ids_identical(
2121 template <
int spacedim>
2123 check_all_manifold_ids_identical(
2126 const auto m_id = cell->manifold_id();
2128 for (
const auto f : cell->face_indices())
2137 template <
int spacedim>
2139 check_all_manifold_ids_identical(
2142 const auto m_id = cell->manifold_id();
2144 for (
const auto f : cell->face_indices())
2148 for (
const auto l : cell->line_indices())
2158template <
int dim,
int spacedim>
2159boost::container::small_vector<Point<spacedim>, 200>
2163 boost::container::small_vector<Point<spacedim>, 200> points;
2165 ReferenceCells::max_n_vertices<dim>()>
2166 vertices(cell->n_vertices());
2167 for (
const unsigned int i : cell->vertex_indices())
2168 vertices[i] = cell->vertex(i);
2170 points.resize(mapping_support_point_weights.size(0));
2171 if (check_all_manifold_ids_identical(cell))
2176 mapping_support_point_weights,
2188 const auto process = [&](
const auto &manifold,
2189 const auto &indices,
2190 const unsigned n_points) {
2191 if ((indices.size() == 0) || (n_points == 0))
2194 const unsigned int n_shape_functions =
2195 this->fe->reference_cell().n_vertices();
2199 std::vector<Point<spacedim>> mapping_support_points_local(n_points);
2201 for (
unsigned int p = 0; p < n_points; ++p)
2202 for (
unsigned int i = 0; i < n_shape_functions; ++i)
2203 mapping_support_point_weights_local(p, i) =
2204 mapping_support_point_weights(
2205 indices[p + (indices.size() - n_points)], i);
2208 mapping_support_point_weights_local,
2210 mapping_support_points_local));
2212 for (
unsigned int p = 0; p < n_points; ++p)
2213 points[indices[p + (indices.size() - n_points)]] =
2214 mapping_support_points_local[p];
2218 const auto &fe = *this->fe;
2225 std::vector<types::global_dof_index> indices;
2228 for (
const unsigned int i : cell->vertex_indices())
2229 points[i] = vertices[i];
2232 for (
unsigned int l = 0; l < cell_ref->n_lines(); ++l)
2234 const auto accessor = cell_ref->line(l);
2235 indices.
resize(fe.n_dofs_per_line() + 2 * fe.n_dofs_per_vertex());
2236 accessor->get_dof_indices(indices);
2237 process(cell->line(l)->get_manifold(), indices, fe.n_dofs_per_line());
2241 if constexpr (dim >= 3)
2243 for (
unsigned int f = 0; f < cell_ref->n_faces(); ++f)
2245 const auto accessor = cell_ref->face(f);
2246 indices.resize(fe.n_dofs_per_face());
2247 accessor->get_dof_indices(indices);
2248 process(cell->face(f)->get_manifold(),
2250 fe.n_dofs_per_quad());
2255 if constexpr (dim >= 2)
2257 indices.resize(fe.n_dofs_per_cell());
2258 cell_ref->get_dof_indices(indices);
2259 process(cell->get_manifold(),
2261 (dim == 2) ? fe.n_dofs_per_quad() : fe.n_dofs_per_hex());
2270template <
int dim,
int spacedim>
2280template <
int dim,
int spacedim>
2285 Assert(dim == reference_cell.get_dimension(),
2286 ExcMessage(
"The dimension of your mapping (" +
2288 ") and the reference cell cell_type (" +
2290 " ) do not agree."));
2292 return fe->reference_cell() == reference_cell;
2298#include "fe/mapping_fe.inst"
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
active_cell_iterator begin_active(const unsigned int level=0) const
void initialize_face(const UpdateFlags update_flags, const Quadrature< dim > &quadrature, const unsigned int n_original_q_points)
void compute_shape_function_values(const std::vector< Point< dim > > &unit_points)
virtual std::size_t memory_consumption() const override
InternalData(const FiniteElement< dim, spacedim > &fe)
virtual void reinit(const UpdateFlags update_flags, const Quadrature< dim > &quadrature) override
virtual CellSimilarity::Similarity fill_fe_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellSimilarity::Similarity cell_similarity, const Quadrature< dim > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
const unsigned int polynomial_degree
MappingFE(const FiniteElement< dim, spacedim > &fe)
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_face_data(const UpdateFlags flags, const hp::QCollection< dim - 1 > &quadrature) const override
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const override
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const override
virtual boost::container::small_vector< Point< spacedim >, 200 > compute_mapping_support_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const hp::QCollection< dim - 1 > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
Table< 2, double > mapping_support_point_weights
virtual void transform(const ArrayView< const Tensor< 1, dim > > &input, const MappingKind kind, const typename Mapping< dim, spacedim >::InternalDataBase &internal, const ArrayView< Tensor< 1, spacedim > > &output) const override
virtual BoundingBox< spacedim > get_bounding_box(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const override
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags, const Quadrature< dim > &quadrature) const override
virtual bool is_compatible_with(const ReferenceCell< dim > &reference_cell) const override
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_subface_data(const UpdateFlags flags, const Quadrature< dim - 1 > &quadrature) const override
unsigned int get_degree() const
virtual void fill_fe_subface_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const Quadrature< dim - 1 > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
virtual std::unique_ptr< Mapping< dim, spacedim > > clone() const override
virtual Point< spacedim > transform_unit_to_real_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< dim > &p) const override
const std::unique_ptr< FiniteElement< dim, spacedim > > fe
Abstract base class for mapping classes.
Class storing the offset index into a Quadrature rule created by project_to_all_faces() or project_to...
static DataSetDescriptor cell()
Class which transforms dim - 1-dimensional quadrature rules to dim-dimensional face quadratures.
const std::vector< double > & get_weights() const
const std::vector< Point< dim > > & get_points() const
unsigned int size() const
numbers::NumberTraits< Number >::real_type norm() const
unsigned int size() const
unsigned int max_n_quadrature_points() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ update_jacobian_pushed_forward_2nd_derivatives
@ update_volume_elements
Determinant of the Jacobian.
@ update_contravariant_transformation
Contravariant transformation.
@ update_jacobian_pushed_forward_grads
@ update_jacobian_3rd_derivatives
@ update_jacobian_grads
Gradient of volume element.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_covariant_transformation
Covariant transformation.
@ update_jacobians
Volume element.
@ update_inverse_jacobians
Volume element.
@ update_quadrature_points
Transformed quadrature points.
@ update_jacobian_pushed_forward_3rd_derivatives
@ update_boundary_forms
Outer normal vector, not normalized.
@ update_jacobian_2nd_derivatives
@ mapping_covariant_gradient
@ mapping_contravariant_hessian
@ mapping_covariant_hessian
@ mapping_contravariant_gradient
std::vector< index_type > data
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
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)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
void transform_differential_forms(const ArrayView< const DerivativeForm< rank, dim, spacedim > > &input, const MappingKind mapping_kind, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_data, const ArrayView< Tensor< rank+1, spacedim > > &output)
void do_fill_fe_face_values(const ::MappingQ< dim, spacedim > &mapping, const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const typename QProjector< dim >::DataSetDescriptor data_set, const Quadrature< dim - 1 > &quadrature, const typename ::MappingQ< dim, spacedim >::InternalData &data, const std::vector< Polynomials::Polynomial< double > > &polynomials_1d, const std::vector< unsigned int > &renumber_lexicographic_to_hierarchic, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data)
void transform_gradients(const ArrayView< const Tensor< rank, dim > > &input, const MappingKind mapping_kind, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_data, const ArrayView< Tensor< rank, spacedim > > &output)
void transform_hessians(const ArrayView< const Tensor< 3, dim > > &input, const MappingKind mapping_kind, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_data, const ArrayView< Tensor< 3, spacedim > > &output)
void maybe_compute_face_data(const ::MappingQ< dim, spacedim > &mapping, const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const unsigned int n_q_points, const std::vector< double > &weights, const typename ::MappingQ< dim, spacedim >::InternalData &data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data)
Tensor< 3, spacedim, Number > apply_contravariant_hessian(const DerivativeForm< 1, dim, spacedim, Number > &covariant, const DerivativeForm< 1, dim, spacedim, Number > &contravariant, const Tensor< 3, dim, Number > &input)
Tensor< 3, spacedim, Number > apply_piola_hessian(const DerivativeForm< 1, dim, spacedim, Number > &covariant, const DerivativeForm< 1, dim, spacedim, Number > &contravariant, const Number &volume_element, const Tensor< 3, dim, Number > &input)
Tensor< 2, spacedim, Number > apply_piola_gradient(const DerivativeForm< 1, dim, spacedim, Number > &covariant, const DerivativeForm< 1, dim, spacedim, Number > &contravariant, const Number &volume_element, const Tensor< 2, dim, Number > &input)
Tensor< 3, spacedim, Number > apply_covariant_gradient(const DerivativeForm< 1, dim, spacedim, Number > &covariant, const DerivativeForm< 2, dim, spacedim, Number > &input)
Tensor< 3, spacedim, Number > apply_covariant_hessian(const DerivativeForm< 1, dim, spacedim, Number > &covariant, const Tensor< 3, dim, Number > &input)
constexpr unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)