38 std::vector<unsigned int>
43 for (
unsigned int i = 0; i < functions.size(); ++i)
53 template <
int dim,
int spacedim>
54 std::vector<const FiniteElement<dim, spacedim> *>
59 std::vector<const FiniteElement<dim, spacedim> *>
fes;
60 fes.push_back(fe_base);
61 for (
unsigned int i = 0; i < fe_enriched.size(); ++i)
62 fes.push_back(fe_enriched[i]);
72 template <
int dim,
int spacedim>
78 const typename ::Triangulation<dim, spacedim>::cell_iterator
84 "FEs and multiplicities should have the same size"));
95 for (
unsigned int fe = 1; fe <
fes.
size(); ++fe)
101 fe_nothing->is_dominating(),
103 "Only dominating FE_Nothing can be used in FE_Enriched"));
108 "All elements must have the same number of components"));
118 template <
int dim,
int spacedim>
124 for (
unsigned int fe = 1; fe <
fes.
size(); ++fe)
136template <
int dim,
int spacedim>
140 FE_Nothing<dim, spacedim>(fe_base.n_components(),
146template <
int dim,
int spacedim>
165template <
int dim,
int spacedim>
178template <
int dim,
int spacedim>
186 FETools::Compositing::compute_restriction_is_additive_flags(
189 FETools::Compositing::compute_nonzero_components(
fes,
192 , enrichments(functions)
197 Assert(internal::FE_Enriched::consistency_check(
fes,
207 for (
unsigned int fe = 1; fe <
fes.
size(); ++fe)
212 this->n_base_elements()));
223 const unsigned int base_m =
228 "Size mismatch for base_no_mult_local_enriched_dofs: "
231 "; base_no = " + std::to_string(
base_no) +
232 "; base_m = " + std::to_string(
base_m) +
248 for (
unsigned int m = 0;
260template <
int dim,
int spacedim>
261const std::vector<std::vector<std::function<const Function<spacedim> *(
269template <
int dim,
int spacedim>
277 "For enriched finite elements shape_value() can not be defined on the reference element."));
278 return fe_system->shape_value(i, p);
282template <
int dim,
int spacedim>
283std::unique_ptr<FiniteElement<dim, spacedim>>
286 std::vector<const FiniteElement<dim, spacedim> *>
fes;
289 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
291 fes.push_back(&base_element(i));
295 return std::unique_ptr<FE_Enriched<dim, spacedim>>(
300template <
int dim,
int spacedim>
304 UpdateFlags out = fe_system->requires_update_flags(flags);
323template <
int dim,
int spacedim>
325std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
334 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
344 const unsigned int n_q_points = quadrature.
size();
346 for (
unsigned int base = 0; base < this->n_base_elements(); ++base)
348 data.enrichment[base].resize(this->element_multiplicity(base));
349 for (
unsigned int m = 0; m < this->element_multiplicity(base); ++m)
352 data.enrichment[base][m].values.resize(n_q_points);
355 data.enrichment[base][m].gradients.resize(n_q_points);
358 data.enrichment[base][m].hessians.resize(n_q_points);
366template <
int dim,
int spacedim>
367std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
378 fe_system->get_face_data(update_flags, mapping, quadrature, output_data);
387template <
int dim,
int spacedim>
388std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
398 fe_system->get_subface_data(update_flags, mapping, quadrature, output_data);
407template <
int dim,
int spacedim>
408std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
416 auto data = fe_system->get_data(flags, mapping, quadrature, output_data);
425template <
int dim,
int spacedim>
436 this->base_to_block_indices.reinit(0, 0);
438 for (
unsigned int i = 0; i <
fes.
size(); ++i)
445 this->system_to_component_table.resize(this->n_dofs_per_cell());
448 this->system_to_component_table,
449 this->component_to_base_table,
453 this->face_system_to_component_table.resize(this->n_unique_faces());
457 this->face_system_to_component_table[0].resize(
458 this->n_dofs_per_face(
face_no));
462 this->face_system_to_base_table[
face_no],
463 this->face_system_to_component_table[
face_no],
474 this->interface_constraints = fe_system->interface_constraints;
483 this->unit_support_points = fe_system->unit_support_points;
484 this->unit_face_support_points = fe_system->unit_face_support_points;
489 this->adjust_line_dof_index_for_line_orientation_table =
490 fe_system->adjust_line_dof_index_for_line_orientation_table;
495template <
int dim,
int spacedim>
502 for (
unsigned int i = 0; i < this->n_base_elements(); ++i)
504 namebuf << base_element(i).get_name();
505 if (this->element_multiplicity(i) != 1)
506 namebuf <<
'^' << this->element_multiplicity(i);
507 if (i != this->n_base_elements() - 1)
516template <
int dim,
int spacedim>
520 return fe_system->base_element(index);
524template <
int dim,
int spacedim>
543 fe_system->fill_fe_values(cell,
553 multiply_by_enrichment(
554 quadrature, fe_data, mapping_data, cell, output_data);
558template <
int dim,
int spacedim>
579 fe_system->fill_fe_face_values(cell,
589 multiply_by_enrichment(
590 quadrature[0], fe_data, mapping_data, cell, output_data);
594template <
int dim,
int spacedim>
599 const unsigned int sub_no,
614 fe_system->fill_fe_subface_values(cell,
625 multiply_by_enrichment(
626 quadrature, fe_data, mapping_data, cell, output_data);
630template <
int dim,
int spacedim>
652 const unsigned int n_q_points = quadrature.
size();
689 unsigned int out_index = 0;
691 out_index += this->n_nonzero_components(i);
692 unsigned int in_index = 0;
694 in_index +=
base_fe.n_nonzero_components(i);
700 for (
unsigned int s = 0;
705 for (
unsigned int q = 0;
q < n_q_points; ++
q)
710 for (
unsigned int q = 0;
q < n_q_points; ++
q)
715 for (
unsigned int q = 0;
q < n_q_points; ++
q)
722 Assert(base_no_mult_local_enriched_dofs.size() == fe_data.
enrichment.size(),
729 base_no_mult_local_enriched_dofs[
base_no].
size() ==
733 for (
unsigned int m = 0;
734 m < base_no_mult_local_enriched_dofs[
base_no].size();
740 if (base_no_mult_local_enriched_dofs[
base_no][m].
size() == 0)
745 "The pointer to the enrichment function is not set"));
749 "Only scalar-valued enrichment functions are allowed"));
758 for (
unsigned int q = 0;
q < n_q_points; ++
q)
760 enrichments[
base_no - 1][m](cell)->hessian(
771 for (
unsigned int q = 0;
q < n_q_points; ++
q)
773 enrichments[
base_no - 1][m](cell)->gradient(
783 for (
unsigned int q = 0;
q < n_q_points; ++
q)
785 enrichments[
base_no - 1][m](cell)->value(
802 for (
unsigned int m = 0;
803 m < base_no_mult_local_enriched_dofs[
base_no].size();
805 for (
unsigned int i = 0;
806 i < base_no_mult_local_enriched_dofs[
base_no][m].size();
810 base_no_mult_local_enriched_dofs[
base_no][m][i];
811 for (
unsigned int q = 0;
q < n_q_points; ++
q)
833 for (
unsigned int m = 0;
834 m < base_no_mult_local_enriched_dofs[
base_no].size();
836 for (
unsigned int i = 0;
837 i < base_no_mult_local_enriched_dofs[
base_no][m].size();
841 base_no_mult_local_enriched_dofs[
base_no][m][i];
842 for (
unsigned int q = 0;
q < n_q_points; ++
q)
856 for (
unsigned int m = 0;
857 m < base_no_mult_local_enriched_dofs[
base_no].size();
859 for (
unsigned int i = 0;
860 i < base_no_mult_local_enriched_dofs[
base_no][m].size();
864 base_no_mult_local_enriched_dofs[
base_no][m][i];
865 for (
unsigned int q = 0;
q < n_q_points; ++
q)
875template <
int dim,
int spacedim>
883template <
int dim,
int spacedim>
891template <
int dim,
int spacedim>
896 const unsigned int face_no)
const
901 fe_system->get_face_interpolation_matrix(
fe_enr_other->get_fe_system(),
910 spacedim>::ExcInterpolationNotImplemented()));
915template <
int dim,
int spacedim>
919 const unsigned int subface,
921 const unsigned int face_no)
const
926 fe_system->get_subface_interpolation_matrix(
fe_enr_other->get_fe_system(),
936 spacedim>::ExcInterpolationNotImplemented()));
941template <
int dim,
int spacedim>
942std::vector<std::pair<unsigned int, unsigned int>>
949 return fe_system->hp_vertex_dof_identities(
fe_enr_other->get_fe_system());
954 return std::vector<std::pair<unsigned int, unsigned int>>();
959template <
int dim,
int spacedim>
960std::vector<std::pair<unsigned int, unsigned int>>
967 return fe_system->hp_line_dof_identities(
fe_enr_other->get_fe_system());
972 return std::vector<std::pair<unsigned int, unsigned int>>();
977template <
int dim,
int spacedim>
978std::vector<std::pair<unsigned int, unsigned int>>
981 const unsigned int face_no)
const
986 return fe_system->hp_quad_dof_identities(
fe_enr_other->get_fe_system(),
992 return std::vector<std::pair<unsigned int, unsigned int>>();
997template <
int dim,
int spacedim>
1001 const unsigned int codim)
const
1020 return fe_system->compare_for_domination(
fe_enr_other->get_fe_system(),
1031template <
int dim,
int spacedim>
1034 const unsigned int child,
1037 return fe_system->get_prolongation_matrix(child, refinement_case);
1041template <
int dim,
int spacedim>
1044 const unsigned int child,
1047 return fe_system->get_restriction_matrix(child, refinement_case);
1054template <
int dim,
int spacedim>
1057 : fesystem_data(
std::
move(fesystem_data))
1061template <
int dim,
int spacedim>
1064 const unsigned int base_no)
const
1066 return fesystem_data->get_fe_data(
base_no);
1070template <
int dim,
int spacedim>
1073 const unsigned int base_no)
const
1075 return fesystem_data->get_fe_output_object(
base_no);
1083 template <
int dim,
int spacedim>
1092 dof_handler.get_triangulation().n_vertices(),
false);
1095 for (
const auto &cell : dof_handler.active_cell_iterators())
1101 for (
const auto &cell : dof_handler.active_cell_iterators())
1113 template <
int dim,
int spacedim>
1118 std::vector<unsigned int> & predicate_colors)
1134 if (internal::find_connection_between_subdomains(
mesh,
1153 template <
int dim,
int spacedim>
1158 const std::vector<unsigned int> & predicate_colors,
1159 std::map<
unsigned int, std::map<unsigned int, unsigned int>>
1160 & cellwise_color_predicate_map,
1161 std::vector<std::set<unsigned int>> &fe_sets)
1165 cellwise_color_predicate_map.clear();
1194 for (
const auto &cell : dof_handler.active_cell_iterators())
1197 cell->set_active_fe_index(0);
1215 std::map<unsigned int, unsigned int> &cell_map =
1216 cellwise_color_predicate_map[
map_index];
1217 for (
unsigned int i = 0; i < predicates.size(); ++i)
1219 if (predicates[i](cell))
1225 auto ret = cell_map.insert(
1226 std::pair<unsigned int, unsigned int>(predicate_colors[i],
1231 "Only one enrichment function per color"));
1253 std::find(fe_sets.begin(), fe_sets.end(),
color_list);
1255 if (
it == fe_sets.
end())
1258 cell->set_active_fe_index(fe_sets.size() - 1);
1263 cell->set_active_fe_index(std::distance(fe_sets.begin(),
it));
1308 for (
const auto &cell : dof_handler.active_cell_iterators())
1310 const unsigned int fe_index = cell->active_fe_index();
1311 const std::set<unsigned int>
fe_set = fe_sets.at(fe_index);
1318 if (!cell->at_boundary(face) &&
1319 cell->material_id() < cell->neighbor(face)->material_id())
1322 cell->neighbor(face)->active_fe_index();
1329 std::set_intersection(
1339 const auto it = std::find(fe_sets.begin(),
1343 if (
it == fe_sets.
end())
1355 template <
int dim,
int spacedim>
1358 const unsigned int n_colors,
1360 const std::map<
unsigned int, std::map<unsigned int, unsigned int>>
1361 &cellwise_color_predicate_map,
1366 color_enrichments.clear();
1382 color_enrichments.resize(n_colors);
1383 for (
unsigned int i = 0; i < n_colors; ++i)
1385 color_enrichments[i] =
1388 const unsigned int id = cell->material_id();
1395 return enrichments[cellwise_color_predicate_map.at(
id).at(i + 1)]
1403 template <
int dim,
int spacedim>
1406 const unsigned int n_colors,
1407 const std::vector<std::set<unsigned int>> &fe_sets,
1410 & color_enrichments,
1417 const std::function<const Function<spacedim> *(
1423 ExcMessage(
"Called enrichment function for FE_Nothing"));
1431 for (
const auto &
fe_set : fe_sets)
1434 n_colors, &fe_nothing);
1435 std::vector<std::vector<std::function<const Function<spacedim> *(
1458 functions[
ind][0] = color_enrichments[
ind];
1473 template <
int dim,
int spacedim>
1480 , fe_enriched(fe_enriched)
1481 , fe_nothing(fe_base.n_components(),
true)
1482 , predicates(predicates)
1483 , enrichments(enrichments)
1484 , n_colors(
numbers::invalid_unsigned_int)
1489 ExcMessage(
"Number of predicates should be positive"));
1494 template <
int dim,
int spacedim>
1508 cellwise_color_predicate_map,
1512 internal::make_colorwise_enrichment_functions<dim, spacedim>(
1513 n_colors, enrichments, cellwise_color_predicate_map, color_enrichments);
1524 return fe_collection;
1530#include "fe_enriched.inst"
value_type * data() const noexcept
void reinit(value_type *starting_element, const std::size_t n_elements)
std::vector< std::vector< EnrichmentValues > > enrichment
internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > & get_fe_output_object(const unsigned int base_no) const
InternalData(std::unique_ptr< typename FESystem< dim, spacedim >::InternalData > fesystem_data)
FiniteElement< dim, spacedim >::InternalDataBase & get_fe_data(const unsigned int base_no) const
std::unique_ptr< typename FESystem< dim, spacedim >::InternalData > fesystem_data
virtual std::string get_name() const override
std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > setup_data(std::unique_ptr< typename FESystem< dim, spacedim >::InternalData > fes_data, const UpdateFlags flags, const Quadrature< dim_1 > &quadrature) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other, const unsigned int face_no=0) const override
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 typename FiniteElement< dim, spacedim >::InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const override
std::vector< std::vector< std::vector< unsigned int > > > base_no_mult_local_enriched_dofs
void multiply_by_enrichment(const Quadrature< dim_1 > &quadrature, const InternalData &fe_data, const internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const typename Triangulation< dim, spacedim >::cell_iterator &cell, internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const override
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_face_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const hp::QCollection< dim - 1 > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const override
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const hp::QCollection< dim - 1 > &quadrature, const Mapping< dim, spacedim > &mapping, const typename Mapping< dim, spacedim >::InternalDataBase &mapping_internal, const internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const typename FiniteElement< dim, spacedim >::InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const override
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
virtual double shape_value(const unsigned int i, const Point< dim > &p) const override
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
virtual bool hp_constraints_are_implemented() const override
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 override
void initialize(const std::vector< const FiniteElement< dim, spacedim > * > &fes, const std::vector< unsigned int > &multiplicities)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
const FESystem< dim, spacedim > & get_fe_system() const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
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 typename FiniteElement< dim, spacedim >::InternalDataBase &fe_internal, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const override
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
FE_Enriched(const FiniteElement< dim, spacedim > &fe_base, const FiniteElement< dim, spacedim > &fe_enriched, const Function< spacedim > *enrichment_function)
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const override
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
unsigned int n_dofs_per_cell() const
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > system_to_base_table
unsigned int size() const
void push_back(const FiniteElement< dim, spacedim > &new_fe)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ update_hessians
Second derivatives of shape functions.
@ update_values
Shape function values.
@ update_3rd_derivatives
Third derivatives of shape functions.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
void set_cellwise_color_set_and_fe_index(DoFHandler< dim, spacedim > &dof_handler, const std::vector< predicate_function< dim, spacedim > > &predicates, const std::vector< unsigned int > &predicate_colors, std::map< unsigned int, std::map< unsigned int, unsigned int > > &cellwise_color_predicate_map, std::vector< std::set< unsigned int > > &fe_sets)
unsigned int color_predicates(const DoFHandler< dim, spacedim > &mesh, const std::vector< predicate_function< dim, spacedim > > &predicates, std::vector< unsigned int > &predicate_colors)
void make_colorwise_enrichment_functions(const unsigned int n_colors, const std::vector< std::shared_ptr< Function< spacedim > > > &enrichments, const std::map< unsigned int, std::map< unsigned int, unsigned int > > &cellwise_color_predicate_map, std::vector< std::function< const Function< spacedim > *(const typename Triangulation< dim, spacedim >::cell_iterator &)> > &color_enrichments)
bool find_connection_between_subdomains(const DoFHandler< dim, spacedim > &dof_handler, const predicate_function< dim, spacedim > &predicate_1, const predicate_function< dim, spacedim > &predicate_2)
void make_fe_collection_from_colored_enrichments(const unsigned int n_colors, const std::vector< std::set< unsigned int > > &fe_sets, const std::vector< std::function< const Function< spacedim > *(const typename Triangulation< dim, spacedim >::cell_iterator &)> > &color_enrichments, const FiniteElement< dim, spacedim > &fe_base, const FiniteElement< dim, spacedim > &fe_enriched, const FE_Nothing< dim, spacedim > &fe_nothing, hp::FECollection< dim, spacedim > &fe_collection)
@ neither_element_dominates
std::string dim_string(const int dim, const int spacedim)
std::unique_ptr< To > dynamic_unique_cast(std::unique_ptr< From > &&p)
const hp::FECollection< dim, spacedim > & build_fe_collection(DoFHandler< dim, spacedim > &dof_handler)
const FiniteElement< dim, spacedim > & fe_enriched
const std::vector< predicate_function< dim, spacedim > > predicates
const std::vector< std::shared_ptr< Function< spacedim > > > enrichments
const FiniteElement< dim, spacedim > & fe_base
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices()
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)