40 template <
int dim,
int spacedim>
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(0
U, 0
U), 0
U))
80 nonzero_c.size() == 1 ?
88 }) == n_nonzero_components_table.end())
90 Assert(restriction_is_additive_flags.size() == this->dofs_per_cell,
92 this->dofs_per_cell));
94 for (
unsigned int i = 0; i < nonzero_components.size(); ++i)
98 Assert(nonzero_components[i].n_selected_components() >= 1,
108 if (this->is_primitive())
110 system_to_component_table.resize(this->dofs_per_cell);
111 face_system_to_component_table.resize(this->dofs_per_face);
112 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
113 system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
114 for (
unsigned int j = 0; j < this->dofs_per_face; ++j)
115 face_system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
118 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
119 system_to_base_table[j] = std::make_pair(std::make_pair(0
U, 0
U), j);
120 for (
unsigned int j = 0; j < this->dofs_per_face; ++j)
121 face_system_to_base_table[j] = std::make_pair(std::make_pair(0
U, 0
U), j);
124 base_to_block_indices.reinit(1, 1);
131 ref < RefinementCase<dim>::isotropic_refinement + 1;
142 adjust_quad_dof_index_for_face_orientation_table.fill(0);
147 template <
int dim,
int spacedim>
148 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
unsigned int>
151 return {this->clone(), multiplicity};
156 template <
int dim,
int spacedim>
161 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
167 template <
int dim,
int spacedim>
171 const unsigned int)
const
173 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
179 template <
int dim,
int spacedim>
184 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
190 template <
int dim,
int spacedim>
194 const unsigned int)
const
196 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
202 template <
int dim,
int spacedim>
207 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
213 template <
int dim,
int spacedim>
218 const unsigned int)
const
220 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
226 template <
int dim,
int spacedim>
231 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
237 template <
int dim,
int spacedim>
242 const unsigned int)
const
244 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
250 template <
int dim,
int spacedim>
255 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
261 template <
int dim,
int spacedim>
266 const unsigned int)
const
268 AssertThrow(
false, ExcUnitShapeValuesDoNotExist());
273 template <
int dim,
int spacedim>
276 const bool isotropic_restriction_only,
277 const bool isotropic_prolongation_only)
280 ref_case <= RefinementCase<dim>::isotropic_refinement;
283 const unsigned int nc =
286 for (
unsigned int i = 0; i < nc; ++i)
288 if (this->restriction[ref_case - 1][i].m() != this->dofs_per_cell &&
289 (!isotropic_restriction_only ||
291 this->restriction[ref_case - 1][i].reinit(this->dofs_per_cell,
292 this->dofs_per_cell);
293 if (this->prolongation[ref_case - 1][i].m() != this->dofs_per_cell &&
294 (!isotropic_prolongation_only ||
296 this->prolongation[ref_case - 1][i].reinit(this->dofs_per_cell,
297 this->dofs_per_cell);
303 template <
int dim,
int spacedim>
306 const unsigned int child,
313 "Restriction matrices are only available for refined cells!"));
319 Assert(restriction[refinement_case - 1][child].n() == this->dofs_per_cell,
320 ExcProjectionVoid());
321 return restriction[refinement_case - 1][child];
326 template <
int dim,
int spacedim>
329 const unsigned int child,
336 "Prolongation matrices are only available for refined cells!"));
344 Assert(prolongation[refinement_case - 1][child].n() == this->dofs_per_cell,
346 return prolongation[refinement_case - 1][child];
351 template <
int dim,
int spacedim>
354 const unsigned int index)
const
358 return first_block_of_base(component_to_base_table[index].
first.first) +
359 component_to_base_table[index].second;
363 template <
int dim,
int spacedim>
381 template <
int dim,
int spacedim>
387 this->n_components());
403 template <
int dim,
int spacedim>
410 this->n_components());
428 template <
int dim,
int spacedim>
439 std::vector<bool> component_mask(this->
n_components(),
false);
441 if (block_mask[component_to_block_index(c)] ==
true)
442 component_mask[c] =
true;
444 return component_mask;
449 template <
int dim,
int spacedim>
456 return block_mask(component_mask(scalar));
460 template <
int dim,
int spacedim>
467 return block_mask(component_mask(vector));
471 template <
int dim,
int spacedim>
478 return block_mask(component_mask(sym_tensor));
483 template <
int dim,
int spacedim>
504 std::vector<bool> block_mask(this->
n_blocks(),
false);
507 const unsigned int block = component_to_block_index(c);
508 if (component_mask[c] ==
true)
509 block_mask[block] =
true;
516 (component_to_block_index(c) == block))
518 Assert(component_mask[c] == block_mask[block],
520 "The component mask argument given to this function "
521 "is not a mask where the individual components belonging "
522 "to one block of the finite element are either all "
523 "selected or not selected. You can't call this function "
524 "with a component mask that splits blocks."));
535 template <
int dim,
int spacedim>
538 const unsigned int face,
539 const bool face_orientation,
540 const bool face_flip,
541 const bool face_rotation)
const
559 if ((face_orientation !=
true) || (face_flip !=
false) ||
560 (face_rotation !=
false))
561 Assert((this->dofs_per_line <= 1) && (this->dofs_per_quad <= 1),
563 "The function in this base class can not handle this case. "
564 "Rather, the derived class you are using must provide "
565 "an overloaded version but apparently hasn't done so. See "
566 "the documentation of this function for more information."));
570 if (face_index < this->first_face_line_index)
575 const unsigned int face_vertex = face_index / this->dofs_per_vertex;
576 const unsigned int dof_index_on_vertex =
577 face_index % this->dofs_per_vertex;
582 face, face_vertex, face_orientation, face_flip, face_rotation) *
583 this->dofs_per_vertex +
584 dof_index_on_vertex);
586 else if (face_index < this->first_face_quad_index)
591 const unsigned int index = face_index - this->first_face_line_index;
593 const unsigned int face_line = index / this->dofs_per_line;
594 const unsigned int dof_index_on_line = index % this->dofs_per_line;
596 return (this->first_line_index +
598 face, face_line, face_orientation, face_flip, face_rotation) *
599 this->dofs_per_line +
608 const unsigned int index = face_index - this->first_face_quad_index;
610 return (this->first_quad_index + face * this->dofs_per_quad + index);
616 template <
int dim,
int spacedim>
619 const unsigned int index,
620 const bool face_orientation,
621 const bool face_flip,
622 const bool face_rotation)
const
642 Assert(adjust_quad_dof_index_for_face_orientation_table.n_elements() ==
643 8 * this->dofs_per_quad,
645 return index + adjust_quad_dof_index_for_face_orientation_table(
646 index, 4 * face_orientation + 2 * face_flip + face_rotation);
651 template <
int dim,
int spacedim>
654 const unsigned int index,
655 const bool line_orientation)
const
665 Assert(adjust_line_dof_index_for_line_orientation_table.size() ==
668 if (line_orientation)
671 return index + adjust_line_dof_index_for_line_orientation_table[index];
676 template <
int dim,
int spacedim>
681 ref_case < RefinementCase<dim>::isotropic_refinement + 1;
683 for (
unsigned int c = 0;
689 Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
690 (prolongation[ref_case - 1][c].m() == 0),
692 Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
693 (prolongation[ref_case - 1][c].n() == 0),
695 if ((prolongation[ref_case - 1][c].m() == 0) ||
696 (prolongation[ref_case - 1][c].n() == 0))
704 template <
int dim,
int spacedim>
709 ref_case < RefinementCase<dim>::isotropic_refinement + 1;
711 for (
unsigned int c = 0;
717 Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
718 (restriction[ref_case - 1][c].m() == 0),
720 Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
721 (restriction[ref_case - 1][c].n() == 0),
723 if ((restriction[ref_case - 1][c].m() == 0) ||
724 (restriction[ref_case - 1][c].n() == 0))
732 template <
int dim,
int spacedim>
739 for (
unsigned int c = 0;
745 Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
746 (prolongation[ref_case - 1][c].m() == 0),
748 Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
749 (prolongation[ref_case - 1][c].n() == 0),
751 if ((prolongation[ref_case - 1][c].m() == 0) ||
752 (prolongation[ref_case - 1][c].n() == 0))
760 template <
int dim,
int spacedim>
767 for (
unsigned int c = 0;
773 Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
774 (restriction[ref_case - 1][c].m() == 0),
776 Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
777 (restriction[ref_case - 1][c].n() == 0),
779 if ((restriction[ref_case - 1][c].m() == 0) ||
780 (restriction[ref_case - 1][c].n() == 0))
788 template <
int dim,
int spacedim>
794 return (this->dofs_per_face == 0) || (interface_constraints.m() != 0);
801 template <
int dim,
int spacedim>
810 template <
int dim,
int spacedim>
817 ExcMessage(
"Constraints for this element are only implemented "
818 "for the case that faces are refined isotropically "
819 "(which is always the case in 2d, and in 3d requires "
820 "that the neighboring cell of a coarse cell presents "
821 "exactly four children on the common face)."));
822 Assert((this->dofs_per_face == 0) || (interface_constraints.m() != 0),
823 ExcMessage(
"The finite element for which you try to obtain "
824 "hanging node constraints does not appear to "
828 Assert((interface_constraints.m() == 0) && (interface_constraints.n() == 0),
829 ExcWrongInterfaceMatrixSize(interface_constraints.m(),
830 interface_constraints.n()));
832 return interface_constraints;
837 template <
int dim,
int spacedim>
846 return {this->dofs_per_vertex + 2 * this->dofs_per_line,
847 this->dofs_per_face};
849 return {5 * this->dofs_per_vertex + 12 * this->dofs_per_line +
850 4 * this->dofs_per_quad,
851 this->dofs_per_face};
860 template <
int dim,
int spacedim>
876 template <
int dim,
int spacedim>
892 template <
int dim,
int spacedim>
909 template <
int dim,
int spacedim>
910 std::vector<std::pair<unsigned int, unsigned int>>
915 return std::vector<std::pair<unsigned int, unsigned int>>();
920 template <
int dim,
int spacedim>
921 std::vector<std::pair<unsigned int, unsigned int>>
926 return std::vector<std::pair<unsigned int, unsigned int>>();
931 template <
int dim,
int spacedim>
932 std::vector<std::pair<unsigned int, unsigned int>>
937 return std::vector<std::pair<unsigned int, unsigned int>>();
942 template <
int dim,
int spacedim>
947 return this->compare_for_domination(fe_other, 1);
952 template <
int dim,
int spacedim>
956 const unsigned int)
const
964 template <
int dim,
int spacedim>
971 return ((
typeid(*
this) ==
typeid(f)) && (this->get_name() == f.
get_name()) &&
979 template <
int dim,
int spacedim>
984 return !(*
this == f);
989 template <
int dim,
int spacedim>
990 const std::vector<Point<dim>> &
997 Assert((unit_support_points.size() == 0) ||
998 (unit_support_points.size() == this->dofs_per_cell),
1000 return unit_support_points;
1005 template <
int dim,
int spacedim>
1009 return (unit_support_points.size() != 0);
1014 template <
int dim,
int spacedim>
1015 const std::vector<Point<dim>> &
1020 return ((generalized_support_points.size() == 0) ?
1021 unit_support_points :
1022 generalized_support_points);
1027 template <
int dim,
int spacedim>
1031 return (get_generalized_support_points().size() != 0);
1036 template <
int dim,
int spacedim>
1041 Assert(unit_support_points.size() == this->dofs_per_cell,
1042 ExcFEHasNoSupportPoints());
1043 return unit_support_points[index];
1048 template <
int dim,
int spacedim>
1049 const std::vector<
Point<dim - 1>> &
1056 Assert((unit_face_support_points.size() == 0) ||
1057 (unit_face_support_points.size() == this->dofs_per_face),
1059 return unit_face_support_points;
1064 template <
int dim,
int spacedim>
1068 return (unit_face_support_points.size() != 0);
1073 template <
int dim,
int spacedim>
1076 const unsigned int index)
const
1079 Assert(unit_face_support_points.size() == this->dofs_per_face,
1080 ExcFEHasNoSupportPoints());
1081 return unit_face_support_points[index];
1086 template <
int dim,
int spacedim>
1089 const unsigned int)
const
1096 template <
int dim,
int spacedim>
1102 const unsigned int n_total_components = this->
n_components();
1103 Assert((n_total_components == mask.
size()) || (mask.
size() == 0),
1104 ExcMessage(
"The given ComponentMask has the wrong size."));
1106 const unsigned int n_selected =
1109 ExcMessage(
"You need at least one selected component."));
1111 const unsigned int first_selected =
1116 for (
unsigned int c = 0; c < n_total_components; ++c)
1117 Assert((c < first_selected && (!mask[c])) ||
1118 (c >= first_selected && c < first_selected + n_selected &&
1120 (c >= first_selected + n_selected && !mask[c]),
1121 ExcMessage(
"Error: the given ComponentMask is not contiguous!"));
1124 return get_sub_fe(first_selected, n_selected);
1129 template <
int dim,
int spacedim>
1132 const unsigned int first_component,
1133 const unsigned int n_selected_components)
const
1139 "You can only select a whole FiniteElement, not a part of one."));
1141 (void)first_component;
1142 (void)n_selected_components;
1148 template <
int dim,
int spacedim>
1149 std::pair<Table<2, bool>, std::vector<unsigned int>>
1153 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1160 template <
int dim,
int spacedim>
1165 std::vector<double> &)
const
1167 Assert(has_generalized_support_points(),
1168 ExcMessage(
"The element for which you are calling the current "
1169 "function does not have generalized support points (see "
1170 "the glossary for a definition of generalized support "
1171 "points). Consequently, the current function can not "
1172 "be defined and is not implemented by the element."));
1178 template <
int dim,
int spacedim>
1199 template <
int dim,
int spacedim>
1200 std::vector<unsigned int>
1202 const std::vector<ComponentMask> &nonzero_components)
1204 std::vector<unsigned int> retval(nonzero_components.size());
1205 for (
unsigned int i = 0; i < nonzero_components.size(); ++i)
1206 retval[i] = nonzero_components[i].n_selected_components();
1214 template <
int dim,
int spacedim>
1215 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1224 return get_data(flags,
1232 template <
int dim,
int spacedim>
1233 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1242 return get_data(flags,
1250 template <
int dim,
int spacedim>