39 count_nonzeros(
const std::vector<unsigned int> &vec)
41 return std::count_if(vec.begin(), vec.end(), [](
const unsigned int i) {
49 template <
int dim,
int spacedim>
51 const unsigned int n_base_elements)
52 : base_fe_datas(n_base_elements)
53 , base_fe_output_objects(n_base_elements)
58 template <
int dim,
int spacedim>
62 for (
unsigned int i = 0; i < base_fe_datas.size(); ++i)
63 base_fe_datas[i].reset();
67 template <
int dim,
int spacedim>
70 const unsigned int base_no)
const
73 return *base_fe_datas[base_no];
78 template <
int dim,
int spacedim>
81 const unsigned int base_no,
85 base_fe_datas[base_no] = std::move(ptr);
90 template <
int dim,
int spacedim>
93 const unsigned int base_no)
const
96 return base_fe_output_objects[base_no];
104 template <
int dim,
int spacedim>
108 template <
int dim,
int spacedim>
110 const unsigned int n_elements)
118 std::vector<const FiniteElement<dim, spacedim> *> fes;
120 std::vector<unsigned int> multiplicities;
121 multiplicities.push_back(n_elements);
127 template <
int dim,
int spacedim>
129 const unsigned int n1,
131 const unsigned int n2)
139 , base_elements((n1 > 0) + (n2 > 0))
141 std::vector<const FiniteElement<dim, spacedim> *> fes;
144 std::vector<unsigned int> multiplicities;
145 multiplicities.push_back(n1);
146 multiplicities.push_back(n2);
152 template <
int dim,
int spacedim>
154 const unsigned int n1,
156 const unsigned int n2,
158 const unsigned int n3)
173 , base_elements((n1 > 0) + (n2 > 0) + (n3 > 0))
175 std::vector<const FiniteElement<dim, spacedim> *> fes;
179 std::vector<unsigned int> multiplicities;
180 multiplicities.push_back(n1);
181 multiplicities.push_back(n2);
182 multiplicities.push_back(n3);
188 template <
int dim,
int spacedim>
190 const unsigned int n1,
192 const unsigned int n2,
194 const unsigned int n3,
196 const unsigned int n4)
222 , base_elements((n1 > 0) + (n2 > 0) + (n3 > 0) + (n4 > 0))
224 std::vector<const FiniteElement<dim, spacedim> *> fes;
229 std::vector<unsigned int> multiplicities;
230 multiplicities.push_back(n1);
231 multiplicities.push_back(n2);
232 multiplicities.push_back(n3);
233 multiplicities.push_back(n4);
239 template <
int dim,
int spacedim>
241 const unsigned int n1,
243 const unsigned int n2,
245 const unsigned int n3,
247 const unsigned int n4,
249 const unsigned int n5)
252 multiply_dof_numbers(&fe1, n1, &fe2, n2, &fe3, n3, &fe4, n4, &fe5, n5),
273 , base_elements((n1 > 0) + (n2 > 0) + (n3 > 0) + (n4 > 0) + (n5 > 0))
275 std::vector<const FiniteElement<dim, spacedim> *> fes;
281 std::vector<unsigned int> multiplicities;
282 multiplicities.push_back(n1);
283 multiplicities.push_back(n2);
284 multiplicities.push_back(n3);
285 multiplicities.push_back(n4);
286 multiplicities.push_back(n5);
292 template <
int dim,
int spacedim>
295 const std::vector<unsigned int> & multiplicities)
302 , base_elements(count_nonzeros(multiplicities))
309 template <
int dim,
int spacedim>
320 std::ostringstream namebuf;
323 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
325 namebuf << base_element(i).get_name();
326 if (this->element_multiplicity(i) != 1)
327 namebuf <<
'^' << this->element_multiplicity(i);
328 if (i != this->n_base_elements() - 1)
333 return namebuf.str();
338 template <
int dim,
int spacedim>
339 std::unique_ptr<FiniteElement<dim, spacedim>>
342 std::vector<const FiniteElement<dim, spacedim> *> fes;
343 std::vector<unsigned int> multiplicities;
345 for (
unsigned int i = 0; i < this->n_base_elements(); i++)
347 fes.push_back(&base_element(i));
348 multiplicities.push_back(this->element_multiplicity(i));
350 return std_cxx14::make_unique<FESystem<dim, spacedim>>(fes, multiplicities);
355 template <
int dim,
int spacedim>
358 const unsigned int first_component,
359 const unsigned int n_selected_components)
const
362 ExcMessage(
"Invalid arguments (not a part of this FiniteElement)."));
364 const unsigned int base_index =
365 this->component_to_base_table[first_component].first.first;
366 const unsigned int component_in_base =
367 this->component_to_base_table[first_component].first.second;
368 const unsigned int base_components =
369 this->base_element(base_index).n_components();
373 if (n_selected_components <= base_components)
374 return this->base_element(base_index)
375 .get_sub_fe(component_in_base, n_selected_components);
378 ExcMessage(
"You can not select a part of a FiniteElement."));
384 template <
int dim,
int spacedim>
390 Assert(this->is_primitive(i),
394 return (base_element(this->system_to_base_table[i].
first.first)
395 .shape_value(this->system_to_base_table[i].second, p));
400 template <
int dim,
int spacedim>
403 const unsigned int i,
405 const unsigned int component)
const
412 if (this->nonzero_components[i][component] ==
false)
420 const unsigned int base = this->component_to_base_index(component).first;
421 const unsigned int component_in_base =
422 this->component_to_base_index(component).second;
430 return (base_element(base).shape_value_component(
431 this->system_to_base_table[i].
second, p, component_in_base));
436 template <
int dim,
int spacedim>
442 Assert(this->is_primitive(i),
446 return (base_element(this->system_to_base_table[i].
first.first)
447 .shape_grad(this->system_to_base_table[i].second, p));
452 template <
int dim,
int spacedim>
455 const unsigned int i,
457 const unsigned int component)
const
463 if (this->nonzero_components[i][component] ==
false)
468 const unsigned int base = this->component_to_base_index(component).first;
469 const unsigned int component_in_base =
470 this->component_to_base_index(component).second;
475 return (base_element(base).shape_grad_component(
476 this->system_to_base_table[i].
second, p, component_in_base));
481 template <
int dim,
int spacedim>
487 Assert(this->is_primitive(i),
491 return (base_element(this->system_to_base_table[i].
first.first)
492 .shape_grad_grad(this->system_to_base_table[i].second, p));
497 template <
int dim,
int spacedim>
500 const unsigned int i,
502 const unsigned int component)
const
508 if (this->nonzero_components[i][component] ==
false)
513 const unsigned int base = this->component_to_base_index(component).first;
514 const unsigned int component_in_base =
515 this->component_to_base_index(component).second;
520 return (base_element(base).shape_grad_grad_component(
521 this->system_to_base_table[i].
second, p, component_in_base));
526 template <
int dim,
int spacedim>
532 Assert(this->is_primitive(i),
536 return (base_element(this->system_to_base_table[i].
first.first)
537 .shape_3rd_derivative(this->system_to_base_table[i].second, p));
542 template <
int dim,
int spacedim>
545 const unsigned int i,
547 const unsigned int component)
const
553 if (this->nonzero_components[i][component] ==
false)
558 const unsigned int base = this->component_to_base_index(component).first;
559 const unsigned int component_in_base =
560 this->component_to_base_index(component).second;
565 return (base_element(base).shape_3rd_derivative_component(
566 this->system_to_base_table[i].
second, p, component_in_base));
571 template <
int dim,
int spacedim>
577 Assert(this->is_primitive(i),
581 return (base_element(this->system_to_base_table[i].
first.first)
582 .shape_4th_derivative(this->system_to_base_table[i].second, p));
587 template <
int dim,
int spacedim>
590 const unsigned int i,
592 const unsigned int component)
const
598 if (this->nonzero_components[i][component] ==
false)
603 const unsigned int base = this->component_to_base_index(component).first;
604 const unsigned int component_in_base =
605 this->component_to_base_index(component).second;
610 return (base_element(base).shape_4th_derivative_component(
611 this->system_to_base_table[i].
second, p, component_in_base));
616 template <
int dim,
int spacedim>
626 Assert((interpolation_matrix.
m() == this->dofs_per_cell) ||
630 (this->dofs_per_cell == 0),
640 (x_source_fe.
get_name().find(
"FESystem<") == 0) ||
650 this->n_base_elements() == source_fe.n_base_elements(),
654 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
656 this->element_multiplicity(i) == source_fe.element_multiplicity(i),
658 spacedim>::ExcInterpolationNotImplemented()));
667 std::vector<FullMatrix<double>> base_matrices(this->n_base_elements());
668 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
670 base_matrices[i].reinit(base_element(i).dofs_per_cell,
672 base_element(i).get_interpolation_matrix(source_fe.
base_element(i),
679 interpolation_matrix = 0;
680 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
681 for (
unsigned int j = 0; j < source_fe.dofs_per_cell; ++j)
682 if (this->system_to_base_table[i].
first ==
683 source_fe.system_to_base_table[j].first)
684 interpolation_matrix(i, j) =
685 (base_matrices[this->system_to_base_table[i].first.first](
686 this->system_to_base_table[i].second,
687 source_fe.system_to_base_table[j].second));
692 template <
int dim,
int spacedim>
695 const unsigned int child,
702 "Restriction matrices are only available for refined cells!"));
706 if (this->restriction[refinement_case - 1][child].n() == 0)
708 std::lock_guard<std::mutex> lock(this->mutex);
711 if (this->restriction[refinement_case - 1][child].n() ==
713 return this->restriction[refinement_case - 1][child];
716 bool do_restriction =
true;
719 std::vector<const FullMatrix<double> *> base_matrices(
720 this->n_base_elements());
722 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
725 &base_element(i).get_restriction_matrix(child, refinement_case);
726 if (base_matrices[i]->n() != base_element(i).dofs_per_cell)
727 do_restriction =
false;
736 this->dofs_per_cell);
746 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
747 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
754 if (this->system_to_base_table[i].
first !=
755 this->system_to_base_table[j].
first)
759 const unsigned int base =
760 this->system_to_base_table[i].first.first;
762 const unsigned int base_index_i =
763 this->system_to_base_table[i].second,
765 this->system_to_base_table[j].second;
770 (*base_matrices[base])(base_index_i, base_index_j);
774 this->restriction[refinement_case - 1][child]));
778 return this->restriction[refinement_case - 1][child];
783 template <
int dim,
int spacedim>
786 const unsigned int child,
793 "Restriction matrices are only available for refined cells!"));
798 if (this->prolongation[refinement_case - 1][child].n() == 0)
800 std::lock_guard<std::mutex> lock(this->mutex);
802 if (this->prolongation[refinement_case - 1][child].n() ==
804 return this->prolongation[refinement_case - 1][child];
806 bool do_prolongation =
true;
807 std::vector<const FullMatrix<double> *> base_matrices(
808 this->n_base_elements());
809 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
812 &base_element(i).get_prolongation_matrix(child, refinement_case);
813 if (base_matrices[i]->n() != base_element(i).dofs_per_cell)
814 do_prolongation =
false;
822 this->dofs_per_cell);
824 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
825 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
827 if (this->system_to_base_table[i].
first !=
828 this->system_to_base_table[j].
first)
830 const unsigned int base =
831 this->system_to_base_table[i].first.first;
833 const unsigned int base_index_i =
834 this->system_to_base_table[i].second,
836 this->system_to_base_table[j].second;
838 (*base_matrices[base])(base_index_i, base_index_j);
841 this->prolongation[refinement_case - 1][child]));
845 return this->prolongation[refinement_case - 1][child];
849 template <
int dim,
int spacedim>
852 const unsigned int face,
853 const bool face_orientation,
854 const bool face_flip,
855 const bool face_rotation)
const
860 const std::pair<std::pair<unsigned int, unsigned int>,
unsigned int>
861 face_base_index = this->face_system_to_base_index(face_dof_index);
863 const unsigned int base_face_to_cell_index =
864 this->base_element(face_base_index.first.first)
865 .face_to_cell_index(face_base_index.second,
876 const std::pair<std::pair<unsigned int, unsigned int>,
unsigned int> target =
877 std::make_pair(face_base_index.first, base_face_to_cell_index);
878 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
879 if (this->system_to_base_index(i) == target)
894 template <
int dim,
int spacedim>
901 for (
unsigned int base_no = 0; base_no < this->n_base_elements(); ++base_no)
902 out |= base_element(base_no).requires_update_flags(flags);
908 template <
int dim,
int spacedim>
909 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
925 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
926 data_ptr = std_cxx14::make_unique<InternalData>(this->n_base_elements());
927 auto &data =
dynamic_cast<InternalData &
>(*data_ptr);
928 data.update_each = requires_update_flags(flags);
942 for (
unsigned int base_no = 0; base_no < this->n_base_elements(); ++base_no)
945 &base_fe_output_object = data.get_fe_output_object(base_no);
948 base_element(base_no),
949 flags | base_element(base_no).requires_update_flags(flags));
957 auto base_fe_data = base_element(base_no).get_data(flags,
960 base_fe_output_object);
962 data.set_fe_data(base_no, std::move(base_fe_data));
971 template <
int dim,
int spacedim>
972 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
988 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
989 data_ptr = std_cxx14::make_unique<InternalData>(this->n_base_elements());
990 auto &data =
dynamic_cast<InternalData &
>(*data_ptr);
991 data.update_each = requires_update_flags(flags);
1005 for (
unsigned int base_no = 0; base_no < this->n_base_elements(); ++base_no)
1008 &base_fe_output_object = data.get_fe_output_object(base_no);
1011 base_element(base_no),
1012 flags | base_element(base_no).requires_update_flags(flags));
1020 auto base_fe_data = base_element(base_no).get_face_data(
1021 flags, mapping, quadrature, base_fe_output_object);
1023 data.set_fe_data(base_no, std::move(base_fe_data));
1034 template <
int dim,
int spacedim>
1035 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1051 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1052 data_ptr = std_cxx14::make_unique<InternalData>(this->n_base_elements());
1053 auto &data =
dynamic_cast<InternalData &
>(*data_ptr);
1055 data.update_each = requires_update_flags(flags);
1069 for (
unsigned int base_no = 0; base_no < this->n_base_elements(); ++base_no)
1072 &base_fe_output_object = data.get_fe_output_object(base_no);
1075 base_element(base_no),
1076 flags | base_element(base_no).requires_update_flags(flags));
1084 auto base_fe_data = base_element(base_no).get_subface_data(
1085 flags, mapping, quadrature, base_fe_output_object);
1087 data.set_fe_data(base_no, std::move(base_fe_data));
1095 template <
int dim,
int spacedim>
1103 const ::internal::FEValuesImplementation::MappingRelatedData<dim,
1111 compute_fill(mapping,
1113 invalid_face_number,
1114 invalid_face_number,
1125 template <
int dim,
int spacedim>
1129 const unsigned int face_no,
1133 const ::internal::FEValuesImplementation::MappingRelatedData<dim,
1141 compute_fill(mapping,
1144 invalid_face_number,
1155 template <
int dim,
int spacedim>
1159 const unsigned int face_no,
1160 const unsigned int sub_no,
1164 const ::internal::FEValuesImplementation::MappingRelatedData<dim,
1172 compute_fill(mapping,
1186 template <
int dim,
int spacedim>
1187 template <
int dim_1>
1192 const unsigned int face_no,
1193 const unsigned int sub_no,
1207 Assert(
dynamic_cast<const InternalData *
>(&fe_internal) !=
nullptr,
1209 const InternalData &fe_data =
static_cast<const InternalData &
>(fe_internal);
1230 for (
unsigned int base_no = 0; base_no < this->n_base_elements(); ++base_no)
1234 fe_data.get_fe_data(base_no);
1237 &base_data = fe_data.get_fe_output_object(base_no);
1242 const Quadrature<dim - 1> *face_quadrature =
nullptr;
1243 const unsigned int n_q_points = quadrature.
size();
1247 const Subscriptor *quadrature_base_pointer = &quadrature;
1249 if (face_no == invalid_face_number)
1253 quadrature_base_pointer) !=
nullptr,
1263 quadrature_base_pointer) !=
nullptr,
1267 static_cast<const Quadrature<dim - 1
> *>(quadrature_base_pointer);
1278 if (face_no == invalid_face_number)
1287 else if (sub_no == invalid_face_number)
1327 for (
unsigned int system_index = 0; system_index < this->dofs_per_cell;
1329 if (this->system_to_base_table[system_index].
first.first == base_no)
1331 const unsigned int base_index =
1332 this->system_to_base_table[system_index].second;
1341 unsigned int out_index = 0;
1342 for (
unsigned int i = 0; i < system_index; ++i)
1343 out_index += this->n_nonzero_components(i);
1344 unsigned int in_index = 0;
1345 for (
unsigned int i = 0; i < base_index; ++i)
1349 Assert(this->n_nonzero_components(system_index) ==
1354 for (
unsigned int s = 0;
1355 s < this->n_nonzero_components(system_index);
1357 for (
unsigned int q = 0; q < n_q_points; ++q)
1359 base_data.shape_values(in_index + s, q);
1362 for (
unsigned int s = 0;
1363 s < this->n_nonzero_components(system_index);
1365 for (
unsigned int q = 0; q < n_q_points; ++q)
1367 base_data.shape_gradients[in_index + s][q];
1370 for (
unsigned int s = 0;
1371 s < this->n_nonzero_components(system_index);
1373 for (
unsigned int q = 0; q < n_q_points; ++q)
1375 base_data.shape_hessians[in_index + s][q];
1378 for (
unsigned int s = 0;
1379 s < this->n_nonzero_components(system_index);
1381 for (
unsigned int q = 0; q < n_q_points; ++q)
1383 base_data.shape_3rd_derivatives[in_index + s][q];
1389 template <
int dim,
int spacedim>
1397 for (
unsigned int base = 0; base < this->n_base_elements(); ++base)
1398 if (base_element(base).constraints_are_implemented() ==
false)
1401 this->interface_constraints.TableBase<2, double>::reinit(
1402 this->interface_constraints_size());
1412 for (
unsigned int n = 0; n < this->interface_constraints.n(); ++n)
1413 for (
unsigned int m = 0; m < this->interface_constraints.m(); ++m)
1422 const std::pair<std::pair<unsigned int, unsigned int>,
unsigned int>
1423 n_index = this->face_system_to_base_table[n];
1427 std::pair<std::pair<unsigned int, unsigned int>,
unsigned int> m_index;
1444 if (m < this->dofs_per_vertex)
1445 m_index = this->system_to_base_table[m];
1449 const unsigned int index_in_line =
1450 (m - this->dofs_per_vertex) % this->dofs_per_line;
1451 const unsigned int sub_line =
1452 (m - this->dofs_per_vertex) / this->dofs_per_line;
1459 const unsigned int tmp1 =
1460 2 * this->dofs_per_vertex + index_in_line;
1461 m_index.first = this->face_system_to_base_table[tmp1].first;
1473 this->face_system_to_base_table[tmp1].
second >=
1474 2 * base_element(m_index.first.first).dofs_per_vertex,
1476 const unsigned int tmp2 =
1477 this->face_system_to_base_table[tmp1].second -
1478 2 * base_element(m_index.first.first).dofs_per_vertex;
1480 base_element(m_index.first.first).dofs_per_line,
1483 base_element(m_index.first.first).dofs_per_vertex +
1484 base_element(m_index.first.first).dofs_per_line *
1498 if (m < 5 * this->dofs_per_vertex)
1499 m_index = this->system_to_base_table[m];
1502 if (m < 5 * this->dofs_per_vertex + 12 * this->dofs_per_line)
1505 const unsigned int index_in_line =
1506 (m - 5 * this->dofs_per_vertex) % this->dofs_per_line;
1507 const unsigned int sub_line =
1508 (m - 5 * this->dofs_per_vertex) / this->dofs_per_line;
1511 const unsigned int tmp1 =
1512 4 * this->dofs_per_vertex + index_in_line;
1513 m_index.first = this->face_system_to_base_table[tmp1].first;
1516 this->face_system_to_base_table[tmp1].
second >=
1517 4 * base_element(m_index.first.first).dofs_per_vertex,
1519 const unsigned int tmp2 =
1520 this->face_system_to_base_table[tmp1].second -
1521 4 * base_element(m_index.first.first).dofs_per_vertex;
1523 base_element(m_index.first.first).dofs_per_line,
1526 5 * base_element(m_index.first.first).dofs_per_vertex +
1527 base_element(m_index.first.first).dofs_per_line *
1535 const unsigned int index_in_quad =
1536 (m - 5 * this->dofs_per_vertex -
1537 12 * this->dofs_per_line) %
1538 this->dofs_per_quad;
1539 Assert(index_in_quad < this->dofs_per_quad,
1541 const unsigned int sub_quad =
1542 ((m - 5 * this->dofs_per_vertex -
1543 12 * this->dofs_per_line) /
1544 this->dofs_per_quad);
1547 const unsigned int tmp1 = 4 * this->dofs_per_vertex +
1548 4 * this->dofs_per_line +
1550 Assert(tmp1 < this->face_system_to_base_table.size(),
1552 m_index.first = this->face_system_to_base_table[tmp1].first;
1555 this->face_system_to_base_table[tmp1].
second >=
1556 4 * base_element(m_index.first.first).dofs_per_vertex +
1557 4 * base_element(m_index.first.first).dofs_per_line,
1559 const unsigned int tmp2 =
1560 this->face_system_to_base_table[tmp1].second -
1561 4 * base_element(m_index.first.first).dofs_per_vertex -
1562 4 * base_element(m_index.first.first).dofs_per_line;
1564 base_element(m_index.first.first).dofs_per_quad,
1567 5 * base_element(m_index.first.first).dofs_per_vertex +
1568 12 * base_element(m_index.first.first).dofs_per_line +
1569 base_element(m_index.first.first).dofs_per_quad *
1584 if (n_index.first == m_index.first)
1585 this->interface_constraints(m, n) =
1586 (base_element(n_index.first.first)
1587 .constraints()(m_index.second, n_index.second));
1593 template <
int dim,
int spacedim>
1597 const std::vector<unsigned int> & multiplicities)
1599 Assert(fes.size() == multiplicities.size(),
1602 ExcMessage(
"Need to pass at least one finite element."));
1603 Assert(count_nonzeros(multiplicities) > 0,
1604 ExcMessage(
"You only passed FiniteElements with multiplicity 0."));
1609 this->base_to_block_indices.reinit(0, 0);
1611 for (
unsigned int i = 0; i < fes.size(); i++)
1612 if (multiplicities[i] > 0)
1613 this->base_to_block_indices.push_back(multiplicities[i]);
1618 unsigned int ind = 0;
1619 for (
unsigned int i = 0; i < fes.size(); i++)
1620 if (multiplicities[i] > 0)
1623 base_elements[ind] = {fes[i]->clone(), multiplicities[i]};
1637 this->system_to_component_table.resize(this->dofs_per_cell);
1638 this->face_system_to_component_table.resize(this->dofs_per_face);
1641 this->system_to_component_table,
1642 this->component_to_base_table,
1646 this->face_system_to_base_table,
1647 this->face_system_to_component_table,
1665 for (
unsigned int base_el = 0; base_el < this->n_base_elements(); ++base_el)
1666 if (!base_element(base_el).has_support_points() &&
1667 base_element(base_el).dofs_per_cell != 0)
1669 this->unit_support_points.resize(0);
1674 this->unit_support_points.resize(this->dofs_per_cell);
1676 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
1678 const unsigned int base = this->system_to_base_table[i].first.first,
1679 base_index = this->system_to_base_table[i].second;
1681 Assert(base_index < base_element(base).unit_support_points.size(),
1683 this->unit_support_points[i] =
1684 base_element(base).unit_support_points[base_index];
1701 for (
unsigned int base_el = 0; base_el < this->n_base_elements();
1703 if (!base_element(base_el).has_support_points() &&
1704 (base_element(base_el).dofs_per_face > 0))
1706 this->unit_face_support_points.resize(0);
1713 this->unit_face_support_points.resize(this->dofs_per_face);
1715 for (
unsigned int i = 0; i < this->dofs_per_face; ++i)
1717 const unsigned int base_i =
1718 this->face_system_to_base_table[i].first.first;
1719 const unsigned int index_in_base =
1720 this->face_system_to_base_table[i].second;
1723 base_element(base_i).unit_face_support_points.size(),
1726 this->unit_face_support_points[i] =
1727 base_element(base_i).unit_face_support_points[index_in_base];
1739 generalized_support_points_index_table.resize(this->n_base_elements());
1741 for (
unsigned int base = 0; base < this->n_base_elements(); ++base)
1752 if (!base_element(base).has_generalized_support_points())
1755 for (
const auto &
point :
1756 base_element(base).get_generalized_support_points())
1760 std::find(
std::begin(this->generalized_support_points),
1761 std::end(this->generalized_support_points),
1764 if (p ==
std::end(this->generalized_support_points))
1767 const auto n = this->generalized_support_points.size();
1768 generalized_support_points_index_table[base].push_back(n);
1769 this->generalized_support_points.push_back(
point);
1774 const auto n = p -
std::begin(this->generalized_support_points);
1775 generalized_support_points_index_table[base].push_back(n);
1782 for (
unsigned int i = 0; i < base_elements.size(); ++i)
1784 if (!base_element(i).has_generalized_support_points())
1787 const auto &points =
1788 base_elements[i].first->get_generalized_support_points();
1789 for (
unsigned int j = 0; j < points.size(); ++j)
1791 const auto n = generalized_support_points_index_table[i][j];
1792 Assert(this->generalized_support_points[n] == points[j],
1804 Assert(this->adjust_quad_dof_index_for_face_orientation_table
1805 .n_elements() == 8 * this->dofs_per_quad,
1810 unsigned int index = 0;
1811 for (
unsigned int b = 0;
b < this->n_base_elements(); ++
b)
1814 this->base_element(
b)
1815 .adjust_quad_dof_index_for_face_orientation_table;
1816 for (
unsigned int c = 0; c < this->element_multiplicity(
b); ++c)
1818 for (
unsigned int i = 0; i < temp.
size(0); ++i)
1819 for (
unsigned int j = 0; j < 8; ++j)
1820 this->adjust_quad_dof_index_for_face_orientation_table(
1821 index + i, j) = temp(i, j);
1822 index += temp.
size(0);
1828 Assert(this->adjust_line_dof_index_for_line_orientation_table.size() ==
1829 this->dofs_per_line,
1832 for (
unsigned int b = 0;
b < this->n_base_elements(); ++
b)
1834 const std::vector<int> &temp2 =
1835 this->base_element(
b)
1836 .adjust_line_dof_index_for_line_orientation_table;
1837 for (
unsigned int c = 0; c < this->element_multiplicity(
b); ++c)
1842 this->adjust_line_dof_index_for_line_orientation_table.begin() +
1844 index += temp2.size();
1851 init_tasks.join_all();
1856 template <
int dim,
int spacedim>
1860 for (
unsigned int b = 0;
b < this->n_base_elements(); ++
b)
1861 if (base_element(
b).hp_constraints_are_implemented() ==
false)
1869 template <
int dim,
int spacedim>
1875 Assert(interpolation_matrix.
n() == this->dofs_per_face,
1891 if (
const auto *fe_other_system =
1895 interpolation_matrix = 0;
1899 unsigned int base_index = 0, base_index_other = 0;
1900 unsigned int multiplicity = 0, multiplicity_other = 0;
1915 base_to_base_interpolation.
reinit(base_other.dofs_per_face,
1918 base_to_base_interpolation);
1923 for (
unsigned int i = 0; i < this->dofs_per_face; ++i)
1924 if (this->face_system_to_base_index(i).
first ==
1925 std::make_pair(base_index, multiplicity))
1926 for (
unsigned int j = 0; j < fe_other_system->dofs_per_face; ++j)
1927 if (fe_other_system->face_system_to_base_index(j).first ==
1928 std::make_pair(base_index_other, multiplicity_other))
1929 interpolation_matrix(j, i) = base_to_base_interpolation(
1930 fe_other_system->face_system_to_base_index(j).second,
1931 this->face_system_to_base_index(i).second);
1937 if (multiplicity == this->element_multiplicity(base_index))
1942 ++multiplicity_other;
1943 if (multiplicity_other ==
1944 fe_other_system->element_multiplicity(base_index_other))
1946 multiplicity_other = 0;
1952 if (base_index == this->n_base_elements())
1954 Assert(base_index_other == fe_other_system->n_base_elements(),
1961 Assert(base_index_other != fe_other_system->n_base_elements(),
1972 spacedim>::ExcInterpolationNotImplemented()));
1978 template <
int dim,
int spacedim>
1982 const unsigned int subface,
1986 (x_source_fe.
get_name().find(
"FESystem<") == 0) ||
1990 Assert(interpolation_matrix.
n() == this->dofs_per_face,
2008 if (fe_other_system !=
nullptr)
2011 interpolation_matrix = 0;
2015 unsigned int base_index = 0, base_index_other = 0;
2016 unsigned int multiplicity = 0, multiplicity_other = 0;
2031 base_to_base_interpolation.
reinit(base_other.dofs_per_face,
2035 base_to_base_interpolation);
2040 for (
unsigned int i = 0; i < this->dofs_per_face; ++i)
2041 if (this->face_system_to_base_index(i).
first ==
2042 std::make_pair(base_index, multiplicity))
2043 for (
unsigned int j = 0; j < fe_other_system->dofs_per_face; ++j)
2044 if (fe_other_system->face_system_to_base_index(j).first ==
2045 std::make_pair(base_index_other, multiplicity_other))
2046 interpolation_matrix(j, i) = base_to_base_interpolation(
2047 fe_other_system->face_system_to_base_index(j).second,
2048 this->face_system_to_base_index(i).second);
2054 if (multiplicity == this->element_multiplicity(base_index))
2059 ++multiplicity_other;
2060 if (multiplicity_other ==
2061 fe_other_system->element_multiplicity(base_index_other))
2063 multiplicity_other = 0;
2069 if (base_index == this->n_base_elements())
2071 Assert(base_index_other == fe_other_system->n_base_elements(),
2078 Assert(base_index_other != fe_other_system->n_base_elements(),
2086 fe_other_system !=
nullptr,
2088 spacedim>::ExcInterpolationNotImplemented()));
2094 template <
int dim,
int spacedim>
2095 template <
int structdim>
2096 std::vector<std::pair<unsigned int, unsigned int>>
2117 unsigned int base_index = 0, base_index_other = 0;
2118 unsigned int multiplicity = 0, multiplicity_other = 0;
2122 unsigned int dof_offset = 0, dof_offset_other = 0;
2124 std::vector<std::pair<unsigned int, unsigned int>> identities;
2138 std::vector<std::pair<unsigned int, unsigned int>> base_identities;
2154 for (
const auto &base_identity : base_identities)
2155 identities.emplace_back(base_identity.first + dof_offset,
2156 base_identity.second + dof_offset_other);
2159 dof_offset += base.template n_dofs_per_object<structdim>();
2161 base_other.template n_dofs_per_object<structdim>();
2167 if (multiplicity == this->element_multiplicity(base_index))
2172 ++multiplicity_other;
2173 if (multiplicity_other ==
2174 fe_other_system->element_multiplicity(base_index_other))
2176 multiplicity_other = 0;
2182 if (base_index == this->n_base_elements())
2184 Assert(base_index_other == fe_other_system->n_base_elements(),
2191 Assert(base_index_other != fe_other_system->n_base_elements(),
2200 return std::vector<std::pair<unsigned int, unsigned int>>();
2206 template <
int dim,
int spacedim>
2207 std::vector<std::pair<unsigned int, unsigned int>>
2211 return hp_object_dof_identities<0>(fe_other);
2214 template <
int dim,
int spacedim>
2215 std::vector<std::pair<unsigned int, unsigned int>>
2219 return hp_object_dof_identities<1>(fe_other);
2224 template <
int dim,
int spacedim>
2225 std::vector<std::pair<unsigned int, unsigned int>>
2229 return hp_object_dof_identities<2>(fe_other);
2234 template <
int dim,
int spacedim>
2238 const unsigned int codim)
const
2251 Assert(this->n_base_elements() == fe_sys_other->n_base_elements(),
2258 for (
unsigned int b = 0;
b < this->n_base_elements(); ++
b)
2261 fe_sys_other->base_element(
b).n_components(),
2263 Assert(this->element_multiplicity(
b) ==
2264 fe_sys_other->element_multiplicity(
b),
2270 (this->base_element(
b).compare_for_domination(
2271 fe_sys_other->base_element(
b), codim));
2272 domination = domination & base_domination;
2284 template <
int dim,
int spacedim>
2289 return *base_elements[index].first;
2294 template <
int dim,
int spacedim>
2297 const unsigned int shape_index,
2298 const unsigned int face_index)
const
2300 return (base_element(this->system_to_base_index(shape_index).
first.first)
2301 .has_support_on_face(this->system_to_base_index(shape_index).second,
2307 template <
int dim,
int spacedim>
2312 Assert((this->unit_support_points.size() == this->dofs_per_cell) ||
2313 (this->unit_support_points.size() == 0),
2317 if (this->unit_support_points.size() != 0)
2318 return this->unit_support_points[index];
2322 return (base_element(this->system_to_base_index(index).
first.first)
2323 .unit_support_point(this->system_to_base_index(index).second));
2328 template <
int dim,
int spacedim>
2333 Assert((this->unit_face_support_points.size() == this->dofs_per_face) ||
2334 (this->unit_face_support_points.size() == 0),
2338 if (this->unit_face_support_points.size() != 0)
2339 return this->unit_face_support_points[index];
2343 return (base_element(this->face_system_to_base_index(index).
first.first)
2344 .unit_face_support_point(
2345 this->face_system_to_base_index(index).second));
2350 template <
int dim,
int spacedim>
2351 std::pair<Table<2, bool>, std::vector<unsigned int>>
2358 std::vector<unsigned int> components;
2359 for (
unsigned int i = 0; i < base_elements.size(); ++i)
2361 const std::pair<Table<2, bool>, std::vector<unsigned int>> base_table =
2362 base_elements[i].first->get_constant_modes();
2364 const unsigned int element_multiplicity = this->element_multiplicity(i);
2369 const unsigned int comp = components.size();
2370 if (constant_modes.n_rows() <
2371 comp + base_table.first.n_rows() * element_multiplicity)
2373 Table<2, bool> new_constant_modes(comp + base_table.first.n_rows() *
2374 element_multiplicity,
2375 constant_modes.n_cols());
2376 for (
unsigned int r = 0; r < comp; ++r)
2377 for (
unsigned int c = 0; c < this->dofs_per_cell; ++c)
2378 new_constant_modes(r, c) = constant_modes(r, c);
2379 constant_modes.
swap(new_constant_modes);
2384 for (
unsigned int k = 0; k < this->dofs_per_cell; ++k)
2386 std::pair<std::pair<unsigned int, unsigned int>,
unsigned int> ind =
2387 this->system_to_base_index(k);
2388 if (ind.first.first == i)
2389 for (
unsigned int c = 0; c < base_table.first.n_rows(); ++c)
2390 constant_modes(comp +
2391 ind.first.second * base_table.first.n_rows() + c,
2392 k) = base_table.first(c, ind.second);
2394 for (
unsigned int r = 0; r < element_multiplicity; ++r)
2395 for (
const unsigned int c : base_table.second)
2396 components.push_back(
2397 comp + r * this->base_elements[i].
first->n_components() + c);
2400 return std::pair<Table<2, bool>, std::vector<unsigned int>>(constant_modes,
2406 template <
int dim,
int spacedim>
2410 std::vector<double> & dof_values)
const
2412 Assert(this->has_generalized_support_points(),
2413 ExcMessage(
"The FESystem does not have generalized support points"));
2416 this->get_generalized_support_points().size());
2419 std::vector<double> base_dof_values;
2420 std::vector<Vector<double>> base_point_values;
2425 unsigned int current_vector_component = 0;
2426 for (
unsigned int base = 0; base < base_elements.size(); ++base)
2431 const auto & base_element = this->base_element(base);
2432 const unsigned int multiplicity = this->element_multiplicity(base);
2433 const unsigned int n_base_dofs = base_element.dofs_per_cell;
2434 const unsigned int n_base_components = base_element.n_components();
2439 if (n_base_dofs == 0)
2441 current_vector_component += multiplicity * n_base_components;
2445 if (base_element.has_generalized_support_points())
2447 const unsigned int n_base_points =
2448 base_element.get_generalized_support_points().size();
2450 base_dof_values.resize(n_base_dofs);
2451 base_point_values.resize(n_base_points);
2453 for (
unsigned int m = 0; m < multiplicity;
2454 ++m, current_vector_component += n_base_components)
2458 for (
unsigned int j = 0; j < base_point_values.size(); ++j)
2460 base_point_values[j].reinit(n_base_components,
false);
2463 generalized_support_points_index_table[base][j];
2468 std::begin(point_values[n]) + current_vector_component;
2469 const auto end =
begin + n_base_components;
2474 .convert_generalized_support_point_values_to_dof_values(
2475 base_point_values, base_dof_values);
2484 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
2485 if (this->system_to_base_index(i).
first ==
2486 std::make_pair(base, m))
2488 base_dof_values[this->system_to_base_index(i).second];
2500 for (
unsigned int m = 0; m < multiplicity; ++m)
2501 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
2502 if (this->system_to_base_index(i).
first ==
2503 std::make_pair(base, m))
2504 dof_values[i] = std::numeric_limits<double>::signaling_NaN();
2506 current_vector_component += multiplicity * n_base_components;
2513 template <
int dim,
int spacedim>
2521 sizeof(base_elements));
2522 for (
unsigned int i = 0; i < base_elements.size(); ++i)
2530 #include "fe_system.inst"