16 #include <deal.II/base/memory_consumption.h> 17 #include <deal.II/base/quadrature.h> 18 #include <deal.II/base/qprojector.h> 19 #include <deal.II/grid/tria.h> 20 #include <deal.II/grid/tria_iterator.h> 21 #include <deal.II/dofs/dof_accessor.h> 22 #include <deal.II/fe/mapping.h> 23 #include <deal.II/fe/fe_system.h> 24 #include <deal.II/fe/fe_values.h> 25 #include <deal.II/fe/fe_tools.h> 28 #include <deal.II/base/std_cxx14/memory.h> 31 DEAL_II_NAMESPACE_OPEN
35 namespace FESystemImplementation
39 unsigned int count_nonzeros(
const std::vector<unsigned int> &vec)
41 return std::count_if(vec.begin(), vec.end(), [](
const unsigned int i)
52 template <
int dim,
int spacedim>
55 base_fe_datas(n_base_elements),
56 base_fe_output_objects(n_base_elements)
61 template <
int dim,
int spacedim>
65 for (
unsigned int i=0; i<base_fe_datas.size(); ++i)
66 base_fe_datas[i].reset();
70 template <
int dim,
int spacedim>
75 Assert(base_no<base_fe_datas.size(),
77 return *base_fe_datas[base_no];
82 template <
int dim,
int spacedim>
88 Assert(base_no<base_fe_datas.size(),
90 base_fe_datas[base_no]=std::move(ptr);
95 template <
int dim,
int spacedim>
100 Assert(base_no<base_fe_output_objects.size(),
102 return base_fe_output_objects[base_no];
110 template <
int dim,
int spacedim>
114 template <
int dim,
int spacedim>
116 const unsigned int n_elements) :
118 FETools::Compositing::compute_restriction_is_additive_flags (&fe, n_elements),
119 FETools::Compositing::compute_nonzero_components(&fe, n_elements)),
122 std::vector<const FiniteElement<dim,spacedim>*> fes;
124 std::vector<unsigned int> multiplicities;
125 multiplicities.push_back(n_elements);
131 template <
int dim,
int spacedim>
133 const unsigned int n1,
135 const unsigned int n2) :
137 FETools::Compositing::compute_restriction_is_additive_flags (&fe1, n1,
139 FETools::Compositing::compute_nonzero_components(&fe1, n1,
141 base_elements((n1>0)+(n2>0))
143 std::vector<const FiniteElement<dim,spacedim>*> fes;
146 std::vector<unsigned int> multiplicities;
147 multiplicities.push_back(n1);
148 multiplicities.push_back(n2);
154 template <
int dim,
int spacedim>
156 const unsigned int n1,
158 const unsigned int n2,
160 const unsigned int n3) :
164 FETools::Compositing::compute_restriction_is_additive_flags (&fe1, n1,
167 FETools::Compositing::compute_nonzero_components(&fe1, n1,
170 base_elements((n1>0)+(n2>0)+(n3>0))
172 std::vector<const FiniteElement<dim,spacedim>*> fes;
176 std::vector<unsigned int> multiplicities;
177 multiplicities.push_back(n1);
178 multiplicities.push_back(n2);
179 multiplicities.push_back(n3);
185 template <
int dim,
int spacedim>
187 const unsigned int n1,
189 const unsigned int n2,
191 const unsigned int n3,
193 const unsigned int n4) :
198 FETools::Compositing::compute_restriction_is_additive_flags (&fe1, n1,
202 FETools::Compositing::compute_nonzero_components(&fe1, n1,
206 base_elements((n1>0)+(n2>0)+(n3>0)+(n4>0))
208 std::vector<const FiniteElement<dim,spacedim>*> fes;
213 std::vector<unsigned int> multiplicities;
214 multiplicities.push_back(n1);
215 multiplicities.push_back(n2);
216 multiplicities.push_back(n3);
217 multiplicities.push_back(n4);
223 template <
int dim,
int spacedim>
225 const unsigned int n1,
227 const unsigned int n2,
229 const unsigned int n3,
231 const unsigned int n4,
233 const unsigned int n5) :
239 FETools::Compositing::compute_restriction_is_additive_flags (&fe1, n1,
244 FETools::Compositing::compute_nonzero_components(&fe1, n1,
249 base_elements((n1>0)+(n2>0)+(n3>0)+(n4>0)+(n5>0))
251 std::vector<const FiniteElement<dim,spacedim>*> fes;
257 std::vector<unsigned int> multiplicities;
258 multiplicities.push_back(n1);
259 multiplicities.push_back(n2);
260 multiplicities.push_back(n3);
261 multiplicities.push_back(n4);
262 multiplicities.push_back(n5);
268 template <
int dim,
int spacedim>
271 const std::vector<unsigned int> &multiplicities)
274 FETools::Compositing::compute_restriction_is_additive_flags (fes, multiplicities),
275 FETools::Compositing::compute_nonzero_components(fes, multiplicities)),
276 base_elements(
internal::FESystemImplementation::count_nonzeros(multiplicities))
283 template <
int dim,
int spacedim>
294 std::ostringstream namebuf;
296 namebuf <<
"FESystem<" 299 for (
unsigned int i=0; i< this->n_base_elements(); ++i)
301 namebuf << base_element(i).get_name();
302 if (this->element_multiplicity(i) != 1)
303 namebuf <<
'^' << this->element_multiplicity(i);
304 if (i != this->n_base_elements()-1)
309 return namebuf.str();
314 template <
int dim,
int spacedim>
315 std::unique_ptr<FiniteElement<dim,spacedim> >
318 std::vector< const FiniteElement<dim,spacedim>* > fes;
319 std::vector<unsigned int> multiplicities;
321 for (
unsigned int i=0; i<this->n_base_elements(); i++)
323 fes.push_back( & base_element(i) );
324 multiplicities.push_back(this->element_multiplicity(i) );
326 return std_cxx14::make_unique<FESystem<dim,spacedim>>(fes, multiplicities);
331 template <
int dim,
int spacedim>
335 const unsigned int n_selected_components)
const 338 ExcMessage(
"Invalid arguments (not a part of this FiniteElement)."));
340 const unsigned int base_index = this->component_to_base_table[first_component].first.first;
341 const unsigned int component_in_base = this->component_to_base_table[first_component].first.second;
342 const unsigned int base_components = this->base_element(base_index).n_components();
346 if (n_selected_components<=base_components)
347 return this->base_element(base_index).get_sub_fe(component_in_base, n_selected_components);
350 ExcMessage(
"You can not select a part of a FiniteElement."));
356 template <
int dim,
int spacedim>
362 Assert (this->is_primitive(i),
365 return (base_element(this->system_to_base_table[i].first.first)
366 .shape_value(this->system_to_base_table[i].second, p));
371 template <
int dim,
int spacedim>
375 const unsigned int component)
const 383 if (this->nonzero_components[i][component] ==
false)
391 const unsigned int base = this->component_to_base_index(component).first;
392 const unsigned int component_in_base = this->component_to_base_index(component).second;
400 return (base_element(base).
401 shape_value_component(this->system_to_base_table[i].second,
408 template <
int dim,
int spacedim>
414 Assert (this->is_primitive(i),
417 return (base_element(this->system_to_base_table[i].first.first)
418 .shape_grad(this->system_to_base_table[i].second, p));
423 template <
int dim,
int spacedim>
427 const unsigned int component)
const 434 if (this->nonzero_components[i][component] ==
false)
439 const unsigned int base = this->component_to_base_index(component).first;
440 const unsigned int component_in_base = this->component_to_base_index(component).second;
445 return (base_element(base).
446 shape_grad_component(this->system_to_base_table[i].second,
453 template <
int dim,
int spacedim>
459 Assert (this->is_primitive(i),
462 return (base_element(this->system_to_base_table[i].first.first)
463 .shape_grad_grad(this->system_to_base_table[i].second, p));
468 template <
int dim,
int spacedim>
472 const unsigned int component)
const 479 if (this->nonzero_components[i][component] ==
false)
484 const unsigned int base = this->component_to_base_index(component).first;
485 const unsigned int component_in_base = this->component_to_base_index(component).second;
490 return (base_element(base).
491 shape_grad_grad_component(this->system_to_base_table[i].second,
498 template <
int dim,
int spacedim>
504 Assert (this->is_primitive(i),
507 return (base_element(this->system_to_base_table[i].first.first)
508 .shape_3rd_derivative(this->system_to_base_table[i].second, p));
513 template <
int dim,
int spacedim>
517 const unsigned int component)
const 524 if (this->nonzero_components[i][component] ==
false)
529 const unsigned int base = this->component_to_base_index(component).first;
530 const unsigned int component_in_base = this->component_to_base_index(component).second;
535 return (base_element(base).
536 shape_3rd_derivative_component(this->system_to_base_table[i].second,
543 template <
int dim,
int spacedim>
549 Assert (this->is_primitive(i),
552 return (base_element(this->system_to_base_table[i].first.first)
553 .shape_4th_derivative(this->system_to_base_table[i].second, p));
558 template <
int dim,
int spacedim>
562 const unsigned int component)
const 569 if (this->nonzero_components[i][component] ==
false)
574 const unsigned int base = this->component_to_base_index(component).first;
575 const unsigned int component_in_base = this->component_to_base_index(component).second;
580 return (base_element(base).
581 shape_4th_derivative_component(this->system_to_base_table[i].second,
588 template <
int dim,
int spacedim>
598 Assert ((interpolation_matrix.
m() == this->dofs_per_cell)
602 this->dofs_per_cell));
605 (this->dofs_per_cell == 0),
618 ExcInterpolationNotImplemented()));
630 for (
unsigned int i=0; i< this->n_base_elements(); ++i)
643 std::vector<FullMatrix<double> > base_matrices (this->n_base_elements());
644 for (
unsigned int i=0; i<this->n_base_elements(); ++i)
646 base_matrices[i].reinit (base_element(i).dofs_per_cell,
648 base_element(i).get_interpolation_matrix (source_fe.
base_element(i),
655 interpolation_matrix = 0;
656 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
658 if (this->system_to_base_table[i].first ==
660 interpolation_matrix(i,j)
661 = (base_matrices[this->system_to_base_table[i].first.first]
662 (this->system_to_base_table[i].second,
668 template <
int dim,
int spacedim>
677 ExcMessage(
"Restriction matrices are only available for refined cells!"));
682 if (this->restriction[refinement_case-1][child].n() == 0)
687 if (this->restriction[refinement_case-1][child].n() ==
689 return this->restriction[refinement_case-1][child];
692 bool do_restriction =
true;
695 std::vector<const FullMatrix<double> *>
696 base_matrices(this->n_base_elements());
698 for (
unsigned int i=0; i<this->n_base_elements(); ++i)
701 &base_element(i).get_restriction_matrix(child, refinement_case);
702 if (base_matrices[i]->n() != base_element(i).dofs_per_cell)
703 do_restriction =
false;
712 this->dofs_per_cell);
722 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
723 for (
unsigned int j=0; j<this->dofs_per_cell; ++j)
730 if (this->system_to_base_table[i].first !=
731 this->system_to_base_table[j].first)
736 base = this->system_to_base_table[i].first.first;
739 base_index_i = this->system_to_base_table[i].second,
740 base_index_j = this->system_to_base_table[j].second;
744 restriction(i,j) = (*base_matrices[base])(base_index_i,base_index_j);
748 (this->restriction[refinement_case-1][child]));
752 return this->restriction[refinement_case-1][child];
757 template <
int dim,
int spacedim>
766 ExcMessage(
"Restriction matrices are only available for refined cells!"));
772 if (this->prolongation[refinement_case-1][child].n() == 0)
776 if (this->prolongation[refinement_case-1][child].n() ==
778 return this->prolongation[refinement_case-1][child];
780 bool do_prolongation =
true;
781 std::vector<const FullMatrix<double> *>
782 base_matrices(this->n_base_elements());
783 for (
unsigned int i=0; i<this->n_base_elements(); ++i)
786 &base_element(i).get_prolongation_matrix(child, refinement_case);
787 if (base_matrices[i]->n() != base_element(i).dofs_per_cell)
788 do_prolongation =
false;
796 this->dofs_per_cell);
798 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
799 for (
unsigned int j=0; j<this->dofs_per_cell; ++j)
801 if (this->system_to_base_table[i].first !=
802 this->system_to_base_table[j].first)
805 base = this->system_to_base_table[i].first.first;
808 base_index_i = this->system_to_base_table[i].second,
809 base_index_j = this->system_to_base_table[j].second;
810 prolongate(i,j) = (*base_matrices[base])(base_index_i,base_index_j);
813 (this->prolongation[refinement_case-1][child]));
817 return this->prolongation[refinement_case-1][child];
821 template <
int dim,
int spacedim>
825 const unsigned int face,
826 const bool face_orientation,
827 const bool face_flip,
828 const bool face_rotation)
const 833 const std::pair<std::pair<unsigned int, unsigned int>,
unsigned int>
834 face_base_index = this->face_system_to_base_index(face_dof_index);
837 base_face_to_cell_index
838 = this->base_element(face_base_index.first.first).face_to_cell_index (face_base_index.second,
849 const std::pair<std::pair<unsigned int, unsigned int>,
unsigned int>
850 target = std::make_pair (face_base_index.first, base_face_to_cell_index);
851 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
852 if (this->system_to_base_index(i) == target)
867 template <
int dim,
int spacedim>
874 for (
unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
875 out |= base_element(base_no).requires_update_flags (flags);
881 template <
int dim,
int spacedim>
882 std::unique_ptr<typename FiniteElement<dim,spacedim>::InternalDataBase>
896 auto data = std_cxx14::make_unique<InternalData>(this->n_base_elements());
897 data->update_each = requires_update_flags(flags);
911 for (
unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
914 = data->get_fe_output_object(base_no);
915 base_fe_output_object.
initialize (quadrature.
size(), base_element(base_no),
916 flags | base_element(base_no).requires_update_flags(flags));
925 base_element(base_no).get_data (flags, mapping, quadrature,
926 base_fe_output_object);
928 data->set_fe_data(base_no, std::move(base_fe_data));
931 return std::move(data);
937 template <
int dim,
int spacedim>
938 std::unique_ptr<typename FiniteElement<dim,spacedim>::InternalDataBase>
952 auto data = std_cxx14::make_unique<InternalData>(this->n_base_elements());
953 data->update_each = requires_update_flags(flags);
967 for (
unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
970 = data->get_fe_output_object(base_no);
971 base_fe_output_object.
initialize (quadrature.
size(), base_element(base_no),
972 flags | base_element(base_no).requires_update_flags(flags));
981 base_element(base_no).get_face_data (flags, mapping, quadrature,
982 base_fe_output_object);
984 data->set_fe_data(base_no, std::move(base_fe_data));
987 return std::move(data);
995 template <
int dim,
int spacedim>
996 std::unique_ptr<typename FiniteElement<dim,spacedim>::InternalDataBase>
1010 auto data = std_cxx14::make_unique<InternalData>(this->n_base_elements());
1011 data->update_each = requires_update_flags(flags);
1025 for (
unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
1028 = data->get_fe_output_object(base_no);
1029 base_fe_output_object.
initialize (quadrature.
size(), base_element(base_no),
1030 flags | base_element(base_no).requires_update_flags(flags));
1039 base_element(base_no).get_subface_data (flags, mapping, quadrature,
1040 base_fe_output_object);
1042 data->set_fe_data(base_no, std::move(base_fe_data));
1045 return std::move(data);
1050 template <
int dim,
int spacedim>
1058 const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
1062 compute_fill(mapping, cell, invalid_face_number, invalid_face_number,
1063 quadrature, cell_similarity, mapping_internal, fe_internal,
1064 mapping_data, output_data);
1069 template <
int dim,
int spacedim>
1073 const unsigned int face_no,
1077 const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
1081 compute_fill (mapping, cell, face_no, invalid_face_number, quadrature,
1083 mapping_data, output_data);
1089 template <
int dim,
int spacedim>
1093 const unsigned int face_no,
1094 const unsigned int sub_no,
1098 const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
1102 compute_fill (mapping, cell, face_no, sub_no, quadrature,
1104 mapping_data, output_data);
1109 template <
int dim,
int spacedim>
1110 template <
int dim_1>
1115 const unsigned int face_no,
1116 const unsigned int sub_no,
1150 for (
unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
1153 base_fe = base_element(base_no);
1162 const Quadrature<dim-1> *face_quadrature =
nullptr;
1163 const unsigned int n_q_points = quadrature.
size();
1167 const Subscriptor *quadrature_base_pointer = &quadrature;
1169 if (face_no==invalid_face_number)
1181 Assert (
dynamic_cast<const Quadrature<dim-1
> *>(quadrature_base_pointer) !=
nullptr,
1185 =
static_cast<const Quadrature<dim-1
> *>(quadrature_base_pointer);
1196 if (face_no==invalid_face_number)
1199 mapping, mapping_internal, mapping_data,
1200 base_fe_data, base_data);
1201 else if (sub_no==invalid_face_number)
1204 mapping, mapping_internal, mapping_data,
1205 base_fe_data, base_data);
1209 mapping, mapping_internal, mapping_data,
1210 base_fe_data, base_data);
1231 for (
unsigned int system_index=0; system_index<this->dofs_per_cell;
1233 if (this->system_to_base_table[system_index].first.first == base_no)
1236 base_index = this->system_to_base_table[system_index].second;
1245 unsigned int out_index = 0;
1246 for (
unsigned int i=0; i<system_index; ++i)
1247 out_index += this->n_nonzero_components(i);
1248 unsigned int in_index = 0;
1249 for (
unsigned int i=0; i<base_index; ++i)
1253 Assert (this->n_nonzero_components(system_index) ==
1258 for (
unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
1259 for (
unsigned int q=0; q<n_q_points; ++q)
1264 for (
unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
1265 for (
unsigned int q=0; q<n_q_points; ++q)
1270 for (
unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
1271 for (
unsigned int q=0; q<n_q_points; ++q)
1276 for (
unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
1277 for (
unsigned int q=0; q<n_q_points; ++q)
1286 template <
int dim,
int spacedim>
1293 for (
unsigned int base=0; base<this->n_base_elements(); ++base)
1294 if (base_element(base).constraints_are_implemented() ==
false)
1297 this->interface_constraints.
1308 for (
unsigned int n=0; n<this->interface_constraints.n(); ++n)
1309 for (
unsigned int m=0; m<this->interface_constraints.m(); ++m)
1318 const std::pair<std::pair<unsigned int,unsigned int>,
unsigned int> n_index
1319 = this->face_system_to_base_table[n];
1323 std::pair<std::pair<unsigned int,unsigned int>,
unsigned int> m_index;
1340 if (m < this->dofs_per_vertex)
1341 m_index = this->system_to_base_table[m];
1345 const unsigned int index_in_line
1346 = (m-this->dofs_per_vertex) % this->dofs_per_line;
1347 const unsigned int sub_line
1348 = (m-this->dofs_per_vertex) / this->dofs_per_line;
1355 const unsigned int tmp1 = 2*this->dofs_per_vertex+index_in_line;
1356 m_index.first = this->face_system_to_base_table[tmp1].first;
1366 Assert (this->face_system_to_base_table[tmp1].second >=
1367 2*base_element(m_index.first.first).dofs_per_vertex,
1369 const unsigned int tmp2 = this->face_system_to_base_table[tmp1].second -
1370 2*base_element(m_index.first.first).dofs_per_vertex;
1371 Assert (tmp2 < base_element(m_index.first.first).dofs_per_line,
1373 m_index.second = base_element(m_index.first.first).dofs_per_vertex +
1374 base_element(m_index.first.first).dofs_per_line*sub_line +
1387 if (m < 5*this->dofs_per_vertex)
1388 m_index = this->system_to_base_table[m];
1391 if (m < 5*this->dofs_per_vertex + 12*this->dofs_per_line)
1394 const unsigned int index_in_line
1395 = (m-5*this->dofs_per_vertex) % this->dofs_per_line;
1396 const unsigned int sub_line
1397 = (m-5*this->dofs_per_vertex) / this->dofs_per_line;
1400 const unsigned int tmp1 = 4*this->dofs_per_vertex+index_in_line;
1401 m_index.first = this->face_system_to_base_table[tmp1].first;
1403 Assert (this->face_system_to_base_table[tmp1].second >=
1404 4*base_element(m_index.first.first).dofs_per_vertex,
1406 const unsigned int tmp2 = this->face_system_to_base_table[tmp1].second -
1407 4*base_element(m_index.first.first).dofs_per_vertex;
1408 Assert (tmp2 < base_element(m_index.first.first).dofs_per_line,
1410 m_index.second = 5*base_element(m_index.first.first).dofs_per_vertex +
1411 base_element(m_index.first.first).dofs_per_line*sub_line +
1418 const unsigned int index_in_quad
1419 = (m-5*this->dofs_per_vertex-12*this->dofs_per_line) %
1420 this->dofs_per_quad;
1421 Assert (index_in_quad < this->dofs_per_quad,
1423 const unsigned int sub_quad
1424 = ((m-5*this->dofs_per_vertex-12*this->dofs_per_line) /
1425 this->dofs_per_quad);
1428 const unsigned int tmp1 = 4*this->dofs_per_vertex +
1429 4*this->dofs_per_line +
1431 Assert (tmp1 < this->face_system_to_base_table.size(),
1433 m_index.first = this->face_system_to_base_table[tmp1].first;
1435 Assert (this->face_system_to_base_table[tmp1].second >=
1436 4*base_element(m_index.first.first).dofs_per_vertex +
1437 4*base_element(m_index.first.first).dofs_per_line,
1439 const unsigned int tmp2 = this->face_system_to_base_table[tmp1].second -
1440 4*base_element(m_index.first.first).dofs_per_vertex -
1441 4*base_element(m_index.first.first).dofs_per_line;
1442 Assert (tmp2 < base_element(m_index.first.first).dofs_per_quad,
1444 m_index.second = 5*base_element(m_index.first.first).dofs_per_vertex +
1445 12*base_element(m_index.first.first).dofs_per_line +
1446 base_element(m_index.first.first).dofs_per_quad*sub_quad +
1460 if (n_index.first == m_index.first)
1461 this->interface_constraints(m,n)
1462 = (base_element(n_index.first.first).constraints()(m_index.second,
1469 template <
int dim,
int spacedim>
1471 const std::vector<unsigned int> &multiplicities)
1473 Assert (fes.size() == multiplicities.size(),
1476 ExcMessage (
"Need to pass at least one finite element."));
1477 Assert (internal::FESystemImplementation::count_nonzeros(multiplicities) > 0,
1478 ExcMessage(
"You only passed FiniteElements with multiplicity 0."));
1482 this->base_to_block_indices.reinit(0, 0);
1484 for (
unsigned int i=0; i<fes.size(); i++)
1485 if (multiplicities[i]>0)
1486 this->base_to_block_indices.push_back( multiplicities[i] );
1492 for (
unsigned int i=0; i<fes.size(); i++)
1493 if (multiplicities[i]>0)
1497 base_elements[ind] = { fes[i]->clone(), multiplicities[i] };
1511 this->system_to_component_table.resize(this->dofs_per_cell);
1512 this->face_system_to_component_table.resize(this->dofs_per_face);
1515 this->system_to_component_table,
1516 this->component_to_base_table,
1520 this->face_system_to_component_table,
1533 this->build_interface_constraints ();
1541 for (
unsigned int base_el=0; base_el<this->n_base_elements(); ++base_el)
1542 if (!base_element(base_el).has_support_points() && base_element(base_el).dofs_per_cell!=0)
1544 this->unit_support_points.resize(0);
1549 this->unit_support_points.resize(this->dofs_per_cell);
1551 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
1554 base = this->system_to_base_table[i].first.first,
1555 base_index = this->system_to_base_table[i].second;
1557 Assert (base_index<base_element(base).unit_support_points.size(),
1559 this->unit_support_points[i] = base_element(base).unit_support_points[base_index];
1576 for (
unsigned int base_el=0; base_el<this->n_base_elements(); ++base_el)
1577 if (!base_element(base_el).has_support_points()
1579 (base_element(base_el).dofs_per_face > 0))
1581 this->unit_face_support_points.resize(0);
1588 this->unit_face_support_points.resize(this->dofs_per_face);
1590 for (
unsigned int i=0; i<this->dofs_per_face; ++i)
1592 const unsigned int base_i = this->face_system_to_base_table[i].first.first;
1593 const unsigned int index_in_base = this->face_system_to_base_table[i].second;
1595 Assert (index_in_base < base_element(base_i).unit_face_support_points.size(),
1598 this->unit_face_support_points[i]
1599 = base_element(base_i).unit_face_support_points[index_in_base];
1612 generalized_support_points_index_table.resize(this->n_base_elements());
1614 for (
unsigned int base = 0; base < this->n_base_elements(); ++base)
1625 if (!base_element(base).has_generalized_support_points())
1628 for (
const auto &point :
1629 base_element(base).get_generalized_support_points())
1633 std::find(std::begin(this->generalized_support_points),
1634 std::end(this->generalized_support_points),
1637 if (p == std::end(this->generalized_support_points))
1640 const auto n = this->generalized_support_points.size();
1641 generalized_support_points_index_table[base].push_back(n);
1642 this->generalized_support_points.push_back(point);
1647 const auto n = p - std::begin(this->generalized_support_points);
1648 generalized_support_points_index_table[base].push_back(n);
1655 for (
unsigned int i = 0; i < base_elements.size(); ++i)
1657 if (!base_element(i).has_generalized_support_points())
1660 const auto &points =
1661 base_elements[i].first->get_generalized_support_points();
1662 for (
unsigned int j = 0; j < points.size(); ++j)
1664 const auto n = generalized_support_points_index_table[i][j];
1665 Assert(this->generalized_support_points[n] == points[j],
1678 Assert (this->adjust_quad_dof_index_for_face_orientation_table.n_elements()==
1683 unsigned int index = 0;
1684 for (
unsigned int b=0; b<this->n_base_elements(); ++b)
1687 = this->base_element(b).adjust_quad_dof_index_for_face_orientation_table;
1688 for (
unsigned int c=0; c<this->element_multiplicity(b); ++c)
1690 for (
unsigned int i=0; i<temp.
size(0); ++i)
1691 for (
unsigned int j=0; j<8; ++j)
1692 this->adjust_quad_dof_index_for_face_orientation_table(index+i,j)=
1694 index += temp.
size(0);
1697 Assert (index == this->dofs_per_quad,
1701 Assert (this->adjust_line_dof_index_for_line_orientation_table.size()==
1704 for (
unsigned int b=0; b<this->n_base_elements(); ++b)
1706 const std::vector<int> &temp2
1707 = this->base_element(b).adjust_line_dof_index_for_line_orientation_table;
1708 for (
unsigned int c=0; c<this->element_multiplicity(b); ++c)
1710 std::copy(temp2.begin(), temp2.end(),
1711 this->adjust_line_dof_index_for_line_orientation_table.begin()
1713 index += temp2.size();
1716 Assert (index == this->dofs_per_line,
1721 init_tasks.join_all();
1726 template <
int dim,
int spacedim>
1731 for (
unsigned int b=0; b<this->n_base_elements(); ++b)
1732 if (base_element(b).hp_constraints_are_implemented() ==
false)
1740 template <
int dim,
int spacedim>
1746 Assert (interpolation_matrix.
n() == this->dofs_per_face,
1748 this->dofs_per_face));
1766 interpolation_matrix = 0;
1770 unsigned int base_index = 0,
1771 base_index_other = 0;
1772 unsigned int multiplicity = 0,
1773 multiplicity_other = 0;
1780 &base = base_element(base_index),
1781 &base_other = fe_other_system->
base_element(base_index_other);
1787 base_to_base_interpolation.
reinit (base_other.dofs_per_face,
1790 base_to_base_interpolation);
1795 for (
unsigned int i=0; i<this->dofs_per_face; ++i)
1796 if (this->face_system_to_base_index(i).first
1798 std::make_pair (base_index, multiplicity))
1799 for (
unsigned int j=0; j<fe_other_system->dofs_per_face; ++j)
1800 if (fe_other_system->face_system_to_base_index(j).first
1802 std::make_pair (base_index_other, multiplicity_other))
1803 interpolation_matrix(j, i)
1804 = base_to_base_interpolation(fe_other_system->face_system_to_base_index(j).second,
1805 this->face_system_to_base_index(i).second);
1811 if (multiplicity == this->element_multiplicity(base_index))
1816 ++multiplicity_other;
1817 if (multiplicity_other ==
1818 fe_other_system->element_multiplicity(base_index_other))
1820 multiplicity_other = 0;
1826 if (base_index == this->n_base_elements())
1828 Assert (base_index_other == fe_other_system->n_base_elements(),
1835 Assert (base_index_other != fe_other_system->n_base_elements(),
1844 ExcInterpolationNotImplemented()));
1850 template <
int dim,
int spacedim>
1854 const unsigned int subface,
1861 ExcInterpolationNotImplemented()));
1863 Assert (interpolation_matrix.
n() == this->dofs_per_face,
1865 this->dofs_per_face));
1882 if (fe_other_system !=
nullptr)
1885 interpolation_matrix = 0;
1889 unsigned int base_index = 0,
1890 base_index_other = 0;
1891 unsigned int multiplicity = 0,
1892 multiplicity_other = 0;
1899 &base = base_element(base_index),
1900 &base_other = fe_other_system->
base_element(base_index_other);
1906 base_to_base_interpolation.
reinit (base_other.dofs_per_face,
1910 base_to_base_interpolation);
1915 for (
unsigned int i=0; i<this->dofs_per_face; ++i)
1916 if (this->face_system_to_base_index(i).first
1918 std::make_pair (base_index, multiplicity))
1919 for (
unsigned int j=0; j<fe_other_system->
dofs_per_face; ++j)
1922 std::make_pair (base_index_other, multiplicity_other))
1923 interpolation_matrix(j, i)
1925 this->face_system_to_base_index(i).second);
1931 if (multiplicity == this->element_multiplicity(base_index))
1936 ++multiplicity_other;
1937 if (multiplicity_other ==
1940 multiplicity_other = 0;
1946 if (base_index == this->n_base_elements())
1963 ExcInterpolationNotImplemented()));
1969 template <
int dim,
int spacedim>
1970 template <
int structdim>
1971 std::vector<std::pair<unsigned int, unsigned int> >
1991 unsigned int base_index = 0,
1992 base_index_other = 0;
1993 unsigned int multiplicity = 0,
1994 multiplicity_other = 0;
1998 unsigned int dof_offset = 0,
1999 dof_offset_other = 0;
2001 std::vector<std::pair<unsigned int, unsigned int> > identities;
2006 &base = base_element(base_index),
2007 &base_other = fe_other_system->
base_element(base_index_other);
2014 std::vector<std::pair<unsigned int, unsigned int> > base_identities;
2030 for (
unsigned int i=0; i<base_identities.size(); ++i)
2031 identities.emplace_back (base_identities[i].first + dof_offset,
2032 base_identities[i].second + dof_offset_other);
2035 dof_offset += base.template n_dofs_per_object<structdim>();
2036 dof_offset_other += base_other.template n_dofs_per_object<structdim>();
2042 if (multiplicity == this->element_multiplicity(base_index))
2047 ++multiplicity_other;
2048 if (multiplicity_other ==
2049 fe_other_system->element_multiplicity(base_index_other))
2051 multiplicity_other = 0;
2057 if (base_index == this->n_base_elements())
2059 Assert (base_index_other == fe_other_system->n_base_elements(),
2066 Assert (base_index_other != fe_other_system->n_base_elements(),
2075 return std::vector<std::pair<unsigned int, unsigned int> >();
2081 template <
int dim,
int spacedim>
2082 std::vector<std::pair<unsigned int, unsigned int> >
2085 return hp_object_dof_identities<0> (fe_other);
2088 template <
int dim,
int spacedim>
2089 std::vector<std::pair<unsigned int, unsigned int> >
2092 return hp_object_dof_identities<1> (fe_other);
2097 template <
int dim,
int spacedim>
2098 std::vector<std::pair<unsigned int, unsigned int> >
2101 return hp_object_dof_identities<2> (fe_other);
2106 template <
int dim,
int spacedim>
2118 Assert (this->n_base_elements() == fe_sys_other->n_base_elements(),
2125 for (
unsigned int b=0; b<this->n_base_elements(); ++b)
2128 fe_sys_other->base_element(b).n_components(),
2130 Assert (this->element_multiplicity(b) ==
2131 fe_sys_other->element_multiplicity(b),
2137 base_domination = (this->base_element(b)
2138 .compare_for_face_domination (fe_sys_other->base_element(b)));
2139 domination = domination & base_domination;
2151 template <
int dim,
int spacedim>
2155 Assert (index < base_elements.size(),
2157 return *base_elements[index].first;
2162 template <
int dim,
int spacedim>
2165 const unsigned int face_index)
const 2167 return (base_element(this->system_to_base_index(shape_index).first.first)
2168 .has_support_on_face(this->system_to_base_index(shape_index).second,
2174 template <
int dim,
int spacedim>
2178 Assert (index < this->dofs_per_cell,
2180 Assert ((this->unit_support_points.size() == this->dofs_per_cell) ||
2181 (this->unit_support_points.size() == 0),
2185 if (this->unit_support_points.size() != 0)
2186 return this->unit_support_points[index];
2190 return (base_element(this->system_to_base_index(index).first.first)
2191 .unit_support_point(this->system_to_base_index(index).second));
2196 template <
int dim,
int spacedim>
2200 Assert (index < this->dofs_per_face,
2202 Assert ((this->unit_face_support_points.size() == this->dofs_per_face) ||
2203 (this->unit_face_support_points.size() == 0),
2207 if (this->unit_face_support_points.size() != 0)
2208 return this->unit_face_support_points[index];
2212 return (base_element(this->face_system_to_base_index(index).first.first)
2213 .unit_face_support_point(this->face_system_to_base_index(index).second));
2218 template <
int dim,
int spacedim>
2219 std::pair<Table<2,bool>, std::vector<unsigned int> >
2226 std::vector<unsigned int> components;
2227 for (
unsigned int i=0; i<base_elements.size(); ++i)
2229 const std::pair<Table<2,bool>, std::vector<unsigned int> >
2230 base_table = base_elements[i].first->get_constant_modes();
2232 const unsigned int element_multiplicity = this->element_multiplicity(i);
2237 const unsigned int comp = components.size();
2238 if (constant_modes.n_rows() < comp+base_table.first.n_rows()*element_multiplicity)
2240 Table<2,bool> new_constant_modes(comp+base_table.first.n_rows()*
2241 element_multiplicity,
2242 constant_modes.n_cols());
2243 for (
unsigned int r=0; r<comp; ++r)
2244 for (
unsigned int c=0; c<this->dofs_per_cell; ++c)
2245 new_constant_modes(r,c) = constant_modes(r,c);
2246 constant_modes.
swap(new_constant_modes);
2251 for (
unsigned int k=0; k<this->dofs_per_cell; ++k)
2253 std::pair<std::pair<unsigned int,unsigned int>,
unsigned int> ind
2254 = this->system_to_base_index(k);
2255 if (ind.first.first == i)
2256 for (
unsigned int c=0; c<base_table.first.n_rows(); ++c)
2257 constant_modes(comp+ind.first.second*base_table.first.n_rows()+c,k)
2258 = base_table.first(c,ind.second);
2260 for (
unsigned int r=0; r<element_multiplicity; ++r)
2261 for (
unsigned int c=0; c<base_table.second.size(); ++c)
2262 components.push_back(comp+r*this->base_elements[i].first->n_components()
2263 +base_table.second[c]);
2266 return std::pair<Table<2,bool>, std::vector<unsigned int> >(constant_modes,
2272 template <
int dim,
int spacedim>
2276 std::vector<double> &dof_values)
const 2278 Assert(this->has_generalized_support_points(),
2279 ExcMessage(
"The FESystem does not have generalized support points"));
2282 this->get_generalized_support_points().size());
2285 std::vector<double> base_dof_values;
2286 std::vector<Vector<double> > base_point_values;
2291 unsigned int current_vector_component = 0;
2292 for (
unsigned int base = 0; base < base_elements.size(); ++base)
2297 const auto &base_element = this->base_element(base);
2298 const unsigned int multiplicity = this->element_multiplicity(base);
2299 const unsigned int n_base_dofs = base_element.dofs_per_cell;
2300 const unsigned int n_base_components = base_element.n_components();
2305 if (n_base_dofs == 0)
2307 current_vector_component += multiplicity * n_base_components;
2311 if (base_element.has_generalized_support_points())
2313 const unsigned int n_base_points =
2314 base_element.get_generalized_support_points().size();
2316 base_dof_values.resize(n_base_dofs);
2317 base_point_values.resize(n_base_points);
2319 for (
unsigned int m = 0; m < multiplicity;
2320 ++m, current_vector_component += n_base_components)
2324 for (
unsigned int j = 0; j < base_point_values.size(); ++j)
2326 base_point_values[j].reinit(n_base_components,
false);
2329 generalized_support_points_index_table[base][j];
2334 std::begin(point_values[n]) + current_vector_component;
2335 const auto end = begin + n_base_components;
2336 std::copy(begin, end, std::begin(base_point_values[j]));
2340 .convert_generalized_support_point_values_to_dof_values(
2341 base_point_values, base_dof_values);
2350 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
2351 if (this->system_to_base_index(i).first ==
2352 std::make_pair(base, m))
2354 base_dof_values[this->system_to_base_index(i).second];
2366 for (
unsigned int m = 0; m < multiplicity; ++m)
2367 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
2368 if (this->system_to_base_index(i).first ==
2369 std::make_pair(base, m))
2370 dof_values[i] = std::numeric_limits<double>::signaling_NaN();
2372 current_vector_component += multiplicity * n_base_components;
2379 template <
int dim,
int spacedim>
2387 sizeof (base_elements));
2388 for (
unsigned int i=0; i<base_elements.size(); ++i)
2397 #include "fe_system.inst" 2399 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_face_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const
void build_interface_constraints()
#define AssertDimension(dim1, dim2)
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
void initialize(const std::vector< const FiniteElement< dim, spacedim > *> &fes, const std::vector< unsigned int > &multiplicities)
void swap(TableBase< N, T > &v)
std::vector< std::pair< unsigned int, unsigned int > > hp_object_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
unsigned int n_nonzero_components(const unsigned int i) const
Task< RT > new_task(const std::function< RT()> &function)
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual bool hp_constraints_are_implemented() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
std::vector< std::pair< std::unique_ptr< const FiniteElement< dim, spacedim > >, unsigned int > > base_elements
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
virtual Point< dim > unit_support_point(const unsigned int index) const
#define AssertThrow(cond, exc)
virtual void fill_fe_subface_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int sub_no, const Quadrature< dim-1 > &quadrature, const Mapping< dim, spacedim > &mapping, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const ::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const =0
static ::ExceptionBase & ExcInterpolationNotImplemented()
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
InternalData(const unsigned int n_base_elements)
virtual Tensor< 3, dim > shape_3rd_derivative(const unsigned int i, const Point< dim > &p) const
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const
virtual Tensor< 3, dim > shape_3rd_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual std::string get_name() const
static ::ExceptionBase & ExcMessage(std::string arg1)
virtual Tensor< 4, dim > shape_4th_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual std::size_t memory_consumption() const
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &dof_values) const
Third derivatives of shape functions.
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
unsigned int element_multiplicity(const unsigned int index) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
void set_fe_data(const unsigned int base_no, std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase >)
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const Quadrature< dim-1 > &quadrature, const Mapping< dim, spacedim > &mapping, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const ::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const =0
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual std::string get_name() const =0
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Second derivatives of shape functions.
std::string dim_string(const int dim, const int spacedim)
virtual Tensor< 1, dim > shape_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
unsigned int size() const
const unsigned int dofs_per_cell
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual std::size_t memory_consumption() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
size_type size(const unsigned int i) const
std::pair< std::pair< unsigned int, unsigned int >, unsigned int > face_system_to_base_index(const unsigned int index) const
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
unsigned int n_components() const
FiniteElement< dim, spacedim >::InternalDataBase & get_fe_data(const unsigned int base_no) const
virtual Point< dim-1 > unit_face_support_point(const unsigned int index) const
Shape function gradients.
FESystem(const FiniteElement< dim, spacedim > &fe, const unsigned int n_elements)
virtual Tensor< 4, dim > shape_4th_derivative(const unsigned int i, const Point< dim > &p) const
const unsigned int dofs_per_face
internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > & get_fe_output_object(const unsigned int base_no) const
static ::ExceptionBase & ExcNotImplemented()
void compute_fill(const Mapping< dim, spacedim > &mapping, const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int sub_no, const Quadrature< dim_1 > &quadrature, const CellSimilarity::Similarity cell_similarity, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const typename FiniteElement< dim, spacedim >::InternalDataBase &fe_data, const internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_subface_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
unsigned int n_base_elements() const
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
virtual void fill_fe_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellSimilarity::Similarity cell_similarity, const Quadrature< dim > &quadrature, const Mapping< dim, spacedim > &mapping, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const ::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const =0
virtual Tensor< 2, dim > shape_grad_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
virtual const FiniteElement< dim, spacedim > & get_sub_fe(const unsigned int first_component, const unsigned int n_selected_components) const
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > system_to_base_table
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
static ::ExceptionBase & ExcInternalError()