16 #include <deal.II/base/memory_consumption.h>
17 #include <deal.II/base/qprojector.h>
18 #include <deal.II/base/quadrature.h>
20 #include <deal.II/dofs/dof_accessor.h>
22 #include <deal.II/fe/fe.h>
23 #include <deal.II/fe/fe_values.h>
24 #include <deal.II/fe/mapping.h>
26 #include <deal.II/grid/tria.h>
27 #include <deal.II/grid/tria_iterator.h>
34 DEAL_II_NAMESPACE_OPEN
40 template <
int dim,
int spacedim>
42 : update_each(update_default)
47 template <
int dim,
int spacedim>
56 template <
int dim,
int spacedim>
59 const std::vector<bool> & r_i_a_f,
60 const std::vector<ComponentMask> &nonzero_c)
71 std::make_pair(std::make_pair(0U, 0U), 0U))
77 r_i_a_f.size() == 1 ? std::vector<bool>(fe_data.
dofs_per_cell, r_i_a_f[0]) :
80 nonzero_c.size() == 1 ?
86 std::bind(std::not_equal_to<unsigned int>(),
87 std::placeholders::_1,
132 ref < RefinementCase<dim>::isotropic_refinement + 1;
148 template <
int dim,
int spacedim>
149 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
unsigned int>
152 return {this->clone(), multiplicity};
157 template <
int dim,
int spacedim>
162 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
168 template <
int dim,
int spacedim>
172 const unsigned int)
const
174 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
180 template <
int dim,
int spacedim>
185 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
191 template <
int dim,
int spacedim>
195 const unsigned int)
const
197 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
203 template <
int dim,
int spacedim>
208 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
214 template <
int dim,
int spacedim>
219 const unsigned int)
const
221 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
227 template <
int dim,
int spacedim>
232 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
238 template <
int dim,
int spacedim>
243 const unsigned int)
const
245 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
251 template <
int dim,
int spacedim>
256 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
262 template <
int dim,
int spacedim>
267 const unsigned int)
const
269 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
274 template <
int dim,
int spacedim>
277 const bool isotropic_restriction_only,
278 const bool isotropic_prolongation_only)
281 ref_case <= RefinementCase<dim>::isotropic_refinement;
284 const unsigned int nc =
287 for (
unsigned int i = 0; i < nc; ++i)
289 if (this->restriction[ref_case - 1][i].m() != this->dofs_per_cell &&
290 (!isotropic_restriction_only ||
292 this->restriction[ref_case - 1][i].reinit(this->dofs_per_cell,
293 this->dofs_per_cell);
294 if (this->prolongation[ref_case - 1][i].m() != this->dofs_per_cell &&
295 (!isotropic_prolongation_only ||
297 this->prolongation[ref_case - 1][i].reinit(this->dofs_per_cell,
298 this->dofs_per_cell);
304 template <
int dim,
int spacedim>
307 const unsigned int child,
316 "Restriction matrices are only available for refined cells!"));
326 Assert(restriction[refinement_case - 1][child].n() == this->dofs_per_cell,
327 ExcProjectionVoid());
328 return restriction[refinement_case - 1][child];
333 template <
int dim,
int spacedim>
336 const unsigned int child,
345 "Prolongation matrices are only available for refined cells!"));
357 Assert(prolongation[refinement_case - 1][child].n() == this->dofs_per_cell,
359 return prolongation[refinement_case - 1][child];
364 template <
int dim,
int spacedim>
367 const unsigned int index)
const
372 return first_block_of_base(component_to_base_table[index].first.first) +
373 component_to_base_table[index].second;
377 template <
int dim,
int spacedim>
395 template <
int dim,
int spacedim>
401 this->n_components());
417 template <
int dim,
int spacedim>
424 this->n_components());
442 template <
int dim,
int spacedim>
453 std::vector<bool> component_mask(this->
n_components(),
false);
455 if (block_mask[component_to_block_index(c)] ==
true)
456 component_mask[c] =
true;
458 return component_mask;
463 template <
int dim,
int spacedim>
470 return block_mask(component_mask(scalar));
474 template <
int dim,
int spacedim>
481 return block_mask(component_mask(vector));
485 template <
int dim,
int spacedim>
492 return block_mask(component_mask(sym_tensor));
497 template <
int dim,
int spacedim>
518 std::vector<bool> block_mask(this->n_blocks(),
false);
521 const unsigned int block = component_to_block_index(c);
522 if (component_mask[c] ==
true)
523 block_mask[block] =
true;
530 (component_to_block_index(c) == block))
532 Assert(component_mask[c] == block_mask[block],
534 "The component mask argument given to this function "
535 "is not a mask where the individual components belonging "
536 "to one block of the finite element are either all "
537 "selected or not selected. You can't call this function "
538 "with a component mask that splits blocks."));
549 template <
int dim,
int spacedim>
552 const unsigned int face,
553 const bool face_orientation,
554 const bool face_flip,
555 const bool face_rotation)
const
557 Assert(face_index < this->dofs_per_face,
575 if ((face_orientation !=
true) || (face_flip !=
false) ||
576 (face_rotation !=
false))
577 Assert((this->dofs_per_line <= 1) && (this->dofs_per_quad <= 1),
579 "The function in this base class can not handle this case. "
580 "Rather, the derived class you are using must provide "
581 "an overloaded version but apparently hasn't done so. See "
582 "the documentation of this function for more information."));
586 if (face_index < this->first_face_line_index)
591 const unsigned int face_vertex = face_index / this->dofs_per_vertex;
592 const unsigned int dof_index_on_vertex =
593 face_index % this->dofs_per_vertex;
598 face, face_vertex, face_orientation, face_flip, face_rotation) *
599 this->dofs_per_vertex +
600 dof_index_on_vertex);
602 else if (face_index < this->first_face_quad_index)
607 const unsigned int index = face_index - this->first_face_line_index;
609 const unsigned int face_line = index / this->dofs_per_line;
610 const unsigned int dof_index_on_line = index % this->dofs_per_line;
612 return (this->first_line_index +
614 face, face_line, face_orientation, face_flip, face_rotation) *
615 this->dofs_per_line +
624 const unsigned int index = face_index - this->first_face_quad_index;
626 return (this->first_quad_index + face * this->dofs_per_quad + index);
632 template <
int dim,
int spacedim>
635 const unsigned int index,
636 const bool face_orientation,
637 const bool face_flip,
638 const bool face_rotation)
const
657 Assert(index < this->dofs_per_quad,
659 Assert(adjust_quad_dof_index_for_face_orientation_table.n_elements() ==
660 8 * this->dofs_per_quad,
662 return index + adjust_quad_dof_index_for_face_orientation_table(
663 index, 4 * face_orientation + 2 * face_flip + face_rotation);
668 template <
int dim,
int spacedim>
671 const unsigned int index,
672 const bool line_orientation)
const
681 Assert(index < this->dofs_per_line,
683 Assert(adjust_line_dof_index_for_line_orientation_table.size() ==
686 if (line_orientation)
689 return index + adjust_line_dof_index_for_line_orientation_table[index];
694 template <
int dim,
int spacedim>
699 ref_case < RefinementCase<dim>::isotropic_refinement + 1;
701 for (
unsigned int c = 0;
707 Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
708 (prolongation[ref_case - 1][c].m() == 0),
710 Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
711 (prolongation[ref_case - 1][c].n() == 0),
713 if ((prolongation[ref_case - 1][c].m() == 0) ||
714 (prolongation[ref_case - 1][c].n() == 0))
722 template <
int dim,
int spacedim>
727 ref_case < RefinementCase<dim>::isotropic_refinement + 1;
729 for (
unsigned int c = 0;
735 Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
736 (restriction[ref_case - 1][c].m() == 0),
738 Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
739 (restriction[ref_case - 1][c].n() == 0),
741 if ((restriction[ref_case - 1][c].m() == 0) ||
742 (restriction[ref_case - 1][c].n() == 0))
750 template <
int dim,
int spacedim>
757 for (
unsigned int c = 0;
763 Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
764 (prolongation[ref_case - 1][c].m() == 0),
766 Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
767 (prolongation[ref_case - 1][c].n() == 0),
769 if ((prolongation[ref_case - 1][c].m() == 0) ||
770 (prolongation[ref_case - 1][c].n() == 0))
778 template <
int dim,
int spacedim>
785 for (
unsigned int c = 0;
791 Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
792 (restriction[ref_case - 1][c].m() == 0),
794 Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
795 (restriction[ref_case - 1][c].n() == 0),
797 if ((restriction[ref_case - 1][c].m() == 0) ||
798 (restriction[ref_case - 1][c].n() == 0))
806 template <
int dim,
int spacedim>
812 return (this->dofs_per_face == 0) || (interface_constraints.m() != 0);
819 template <
int dim,
int spacedim>
828 template <
int dim,
int spacedim>
835 ExcMessage(
"Constraints for this element are only implemented "
836 "for the case that faces are refined isotropically "
837 "(which is always the case in 2d, and in 3d requires "
838 "that the neighboring cell of a coarse cell presents "
839 "exactly four children on the common face)."));
840 Assert((this->dofs_per_face == 0) || (interface_constraints.m() != 0),
841 ExcMessage(
"The finite element for which you try to obtain "
842 "hanging node constraints does not appear to "
846 Assert((interface_constraints.m() == 0) && (interface_constraints.n() == 0),
847 ExcWrongInterfaceMatrixSize(interface_constraints.m(),
848 interface_constraints.n()));
850 return interface_constraints;
855 template <
int dim,
int spacedim>
864 return {this->dofs_per_vertex + 2 * this->dofs_per_line,
865 this->dofs_per_face};
867 return {5 * this->dofs_per_vertex + 12 * this->dofs_per_line +
868 4 * this->dofs_per_quad,
869 this->dofs_per_face};
878 template <
int dim,
int spacedim>
894 template <
int dim,
int spacedim>
910 template <
int dim,
int spacedim>
927 template <
int dim,
int spacedim>
928 std::vector<std::pair<unsigned int, unsigned int>>
933 return std::vector<std::pair<unsigned int, unsigned int>>();
938 template <
int dim,
int spacedim>
939 std::vector<std::pair<unsigned int, unsigned int>>
944 return std::vector<std::pair<unsigned int, unsigned int>>();
949 template <
int dim,
int spacedim>
950 std::vector<std::pair<unsigned int, unsigned int>>
955 return std::vector<std::pair<unsigned int, unsigned int>>();
960 template <
int dim,
int spacedim>
965 return this->compare_for_domination(fe_other, 1);
970 template <
int dim,
int spacedim>
974 const unsigned int)
const
982 template <
int dim,
int spacedim>
989 return ((
typeid(*
this) ==
typeid(f)) && (this->get_name() == f.
get_name()) &&
997 template <
int dim,
int spacedim>
1002 return !(*
this == f);
1007 template <
int dim,
int spacedim>
1008 const std::vector<Point<dim>> &
1015 Assert((unit_support_points.size() == 0) ||
1016 (unit_support_points.size() == this->dofs_per_cell),
1018 return unit_support_points;
1023 template <
int dim,
int spacedim>
1027 return (unit_support_points.size() != 0);
1032 template <
int dim,
int spacedim>
1033 const std::vector<Point<dim>> &
1038 return ((generalized_support_points.size() == 0) ?
1039 unit_support_points :
1040 generalized_support_points);
1045 template <
int dim,
int spacedim>
1049 return (get_generalized_support_points().size() != 0);
1054 template <
int dim,
int spacedim>
1058 Assert(index < this->dofs_per_cell,
1060 Assert(unit_support_points.size() == this->dofs_per_cell,
1061 ExcFEHasNoSupportPoints());
1062 return unit_support_points[index];
1067 template <
int dim,
int spacedim>
1068 const std::vector<
Point<dim - 1>> &
1075 Assert((unit_face_support_points.size() == 0) ||
1076 (unit_face_support_points.size() == this->dofs_per_face),
1078 return unit_face_support_points;
1083 template <
int dim,
int spacedim>
1087 return (unit_face_support_points.size() != 0);
1092 template <
int dim,
int spacedim>
1093 const std::vector<
Point<dim - 1>> &
1100 return ((generalized_face_support_points.size() == 0) ?
1101 unit_face_support_points :
1102 generalized_face_support_points);
1107 template <
int dim,
int spacedim>
1111 return (generalized_face_support_points.size() != 0);
1116 template <
int dim,
int spacedim>
1119 const unsigned int index)
const
1121 Assert(index < this->dofs_per_face,
1123 Assert(unit_face_support_points.size() == this->dofs_per_face,
1124 ExcFEHasNoSupportPoints());
1125 return unit_face_support_points[index];
1130 template <
int dim,
int spacedim>
1133 const unsigned int)
const
1140 template <
int dim,
int spacedim>
1146 const unsigned int n_total_components = this->
n_components();
1147 Assert((n_total_components == mask.
size()) || (mask.
size() == 0),
1148 ExcMessage(
"The given ComponentMask has the wrong size."));
1150 const unsigned int n_selected =
1153 ExcMessage(
"You need at least one selected component."));
1155 const unsigned int first_selected =
1160 for (
unsigned int c = 0; c < n_total_components; ++c)
1161 Assert((c < first_selected && (!mask[c])) ||
1162 (c >= first_selected && c < first_selected + n_selected &&
1164 (c >= first_selected + n_selected && !mask[c]),
1165 ExcMessage(
"Error: the given ComponentMask is not contiguous!"));
1168 return get_sub_fe(first_selected, n_selected);
1173 template <
int dim,
int spacedim>
1176 const unsigned int first_component,
1177 const unsigned int n_selected_components)
const
1183 "You can only select a whole FiniteElement, not a part of one."));
1185 (void)first_component;
1186 (void)n_selected_components;
1192 template <
int dim,
int spacedim>
1193 std::pair<Table<2, bool>, std::vector<unsigned int>>
1197 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1204 template <
int dim,
int spacedim>
1209 std::vector<double> &)
const
1211 Assert(has_generalized_support_points(),
1212 ExcMessage(
"The element for which you are calling the current "
1213 "function does not have generalized support points (see "
1214 "the glossary for a definition of generalized support "
1215 "points). Consequently, the current function can not "
1216 "be defined and is not implemented by the element."));
1222 template <
int dim,
int spacedim>
1243 template <
int dim,
int spacedim>
1244 std::vector<unsigned int>
1246 const std::vector<ComponentMask> &nonzero_components)
1248 std::vector<unsigned int> retval(nonzero_components.size());
1249 for (
unsigned int i = 0; i < nonzero_components.size(); ++i)
1250 retval[i] = nonzero_components[i].n_selected_components();
1258 template <
int dim,
int spacedim>
1259 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1261 const UpdateFlags flags,
1268 return get_data(flags,
1276 template <
int dim,
int spacedim>
1277 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1279 const UpdateFlags flags,
1286 return get_data(flags,
1294 template <
int dim,
int spacedim>
1312 DEAL_II_NAMESPACE_CLOSE