17 #include <deal.II/fe/fe_enriched.h> 19 #ifdef DEAL_II_WITH_CXX14 21 #include <deal.II/fe/fe_tools.h> 23 DEAL_II_NAMESPACE_OPEN
31 std::vector<unsigned int>
32 build_multiplicities(
const std::vector<std::vector<T > > &functions )
34 std::vector<unsigned int> multiplicities;
35 multiplicities.push_back(1);
36 for (
unsigned int i = 0; i < functions.size(); i++)
37 multiplicities.push_back(functions[i].size());
39 return multiplicities;
46 template <
int dim,
int spacedim>
47 std::vector< const FiniteElement< dim, spacedim > * >
51 std::vector< const FiniteElement< dim, spacedim > * > fes;
52 fes.push_back(fe_base);
53 for (
unsigned int i = 0; i < fe_enriched.size(); i++)
54 fes.push_back(fe_enriched[i]);
64 template <
int dim,
int spacedim>
67 const std::vector< unsigned int > &multiplicities,
73 ExcMessage(
"FEs and multiplicities should have the same size"));
81 const unsigned int n_comp_base = fes[0]->n_components();
84 for (
unsigned int fe=1; fe < fes.size(); fe++)
89 ExcMessage(
"Only dominating FE_Nothing can be used in FE_Enriched"));
92 ExcMessage(
"All elements must have the same number of components"));
101 template <
int dim,
int spacedim>
106 for (
unsigned int fe=1; fe < fes.size(); fe++)
116 template <
int dim,
int spacedim>
126 template <
int dim,
int spacedim>
140 return enrichment_function;
147 template <
int dim,
int spacedim>
152 FE_Enriched<dim,spacedim> (build_fes(fe_base,fe_enriched),
153 build_multiplicities(functions),
158 template <
int dim,
int spacedim>
160 const std::vector< unsigned int > &multiplicities,
163 FiniteElement<dim,spacedim> (
FETools::Compositing::multiply_dof_numbers(fes,multiplicities,false),
164 FETools::Compositing::compute_restriction_is_additive_flags(fes,multiplicities),
165 FETools::Compositing::compute_nonzero_components(fes,multiplicities,false)),
166 enrichments(functions),
167 is_enriched(check_if_enriched(fes)),
168 fe_system(fes,multiplicities)
171 Assert(consistency_check(fes,multiplicities,functions),
179 for (
unsigned int fe=1; fe < fes.size(); fe++)
187 for (
unsigned int system_index=0; system_index<this->
dofs_per_cell;
197 ExcMessage(
"Size mismatch for base_no_mult_local_enriched_dofs: " 199 "; base_no = " + std::to_string(base_no) +
200 "; base_m = " + std::to_string(base_m) +
201 "; system_index = " + std::to_string(system_index)));
222 template <
int dim,
int spacedim>
230 template <
int dim,
int spacedim>
235 Assert(!is_enriched,
ExcMessage(
"For enriched finite elements shape_value() can not be defined on the reference element."));
236 return fe_system.shape_value(i,p);
240 template <
int dim,
int spacedim>
244 std::vector< const FiniteElement< dim, spacedim > * > fes;
245 std::vector< unsigned int > multiplicities;
247 for (
unsigned int i=0; i<this->n_base_elements(); i++)
249 fes.push_back( & base_element(i) );
250 multiplicities.push_back(this->element_multiplicity(i) );
257 template <
int dim,
int spacedim>
261 UpdateFlags out = fe_system.requires_update_flags(flags);
281 template <
int dim,
int spacedim>
302 data->
enrichment.resize(this->n_base_elements());
304 const unsigned int n_q_points = quadrature.
size();
306 for (
unsigned int base=0; base < this->n_base_elements(); ++base)
308 data->
enrichment[base].resize(this->element_multiplicity(base));
309 for (
unsigned int m = 0; m < this->element_multiplicity(base); ++m)
312 data->
enrichment[base][m].values.resize(n_q_points);
315 data->
enrichment[base][m].gradients.resize(n_q_points);
318 data->
enrichment[base][m].hessians.resize(n_q_points);
326 template <
int dim,
int spacedim>
339 template <
int dim,
int spacedim>
352 template <
int dim,
int spacedim>
365 template <
int dim,
int spacedim>
367 const std::vector<unsigned int> &multiplicities)
369 Assert (fes.size() == multiplicities.size(),
373 this->base_to_block_indices.reinit(0, 0);
375 for (
unsigned int i=0; i<fes.size(); i++)
376 if (multiplicities[i]>0)
377 this->base_to_block_indices.push_back( multiplicities[i] );
382 this->system_to_component_table.resize(this->dofs_per_cell);
383 this->face_system_to_component_table.resize(this->dofs_per_face);
386 this->system_to_component_table,
387 this->component_to_base_table,
392 this->face_system_to_component_table,
401 this->interface_constraints = fe_system.interface_constraints;
410 this->unit_support_points = fe_system.unit_support_points;
411 this->unit_face_support_points = fe_system.unit_face_support_points;
416 this->adjust_line_dof_index_for_line_orientation_table = fe_system.adjust_line_dof_index_for_line_orientation_table;
421 template <
int dim,
int spacedim>
425 std::ostringstream namebuf;
427 namebuf <<
"FE_Enriched<" 430 for (
unsigned int i=0; i< this->n_base_elements(); ++i)
432 namebuf << base_element(i).get_name();
433 if (this->element_multiplicity(i) != 1)
434 namebuf <<
'^' << this->element_multiplicity(i);
435 if (i != this->n_base_elements()-1)
440 return namebuf.str();
444 template <
int dim,
int spacedim>
448 return fe_system.base_element(index);
452 template <
int dim,
int spacedim>
459 const ::internal::FEValues::MappingRelatedData< dim, spacedim > &mapping_data,
464 Assert (dynamic_cast<const InternalData *> (&fe_internal) != NULL,
466 const InternalData &fe_data =
static_cast<const InternalData &
> (fe_internal);
469 fe_system.fill_fe_values(cell,
475 *fe_data.fesystem_data,
479 multiply_by_enrichment(quadrature,
487 template <
int dim,
int spacedim>
491 const unsigned int face_no,
495 const ::internal::FEValues::MappingRelatedData< dim, spacedim > &mapping_data,
500 Assert (dynamic_cast<const InternalData *> (&fe_internal) != NULL,
502 const InternalData &fe_data =
static_cast<const InternalData &
> (fe_internal);
505 fe_system.fill_fe_face_values(cell,
511 *fe_data.fesystem_data,
515 multiply_by_enrichment(quadrature,
523 template <
int dim,
int spacedim>
527 const unsigned int face_no,
528 const unsigned int sub_no,
532 const ::internal::FEValues::MappingRelatedData< dim, spacedim > &mapping_data,
537 Assert (dynamic_cast<const InternalData *> (&fe_internal) != NULL,
539 const InternalData &fe_data =
static_cast<const InternalData &
> (fe_internal);
542 fe_system.fill_fe_subface_values(cell,
549 *fe_data.fesystem_data,
553 multiply_by_enrichment(quadrature,
562 template <
int dim,
int spacedim>
582 const unsigned int n_q_points = quadrature.
size();
592 for (
unsigned int base_no = 1; base_no < this->n_base_elements(); base_no++)
595 base_fe = base_element(base_no);
603 for (
unsigned int system_index=0; system_index<this->dofs_per_cell;
605 if (this->system_to_base_table[system_index].first.first == base_no)
608 base_index = this->system_to_base_table[system_index].second;
617 unsigned int out_index = 0;
618 for (
unsigned int i=0; i<system_index; ++i)
619 out_index += this->n_nonzero_components(i);
620 unsigned int in_index = 0;
621 for (
unsigned int i=0; i<base_index; ++i)
625 Assert (this->n_nonzero_components(system_index) ==
628 for (
unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
631 for (
unsigned int q=0; q<n_q_points; ++q)
636 for (
unsigned int q=0; q<n_q_points; ++q)
641 for (
unsigned int q=0; q<n_q_points; ++q)
648 Assert (base_no_mult_local_enriched_dofs.size() == fe_data.
enrichment.size(),
652 for (
unsigned int base_no = 1; base_no < this->n_base_elements(); base_no++)
654 Assert (base_no_mult_local_enriched_dofs[base_no].size() == fe_data.
enrichment[base_no].size(),
657 for (
unsigned int m=0; m < base_no_mult_local_enriched_dofs[base_no].size(); m++)
659 Assert (enrichments[base_no-1][m](cell) !=NULL,
660 ExcMessage(
"The pointer to the enrichment function is NULL"));
663 ExcMessage(
"Only scalar-valued enrichment functions are allowed"));
670 for (
unsigned int q=0; q<n_q_points; q++)
679 for (
unsigned int q=0; q<n_q_points; q++)
688 for (
unsigned int q=0; q<n_q_points; q++)
701 for (
unsigned int base_no = 1; base_no < this->n_base_elements(); base_no++)
703 for (
unsigned int m=0; m < base_no_mult_local_enriched_dofs[base_no].size(); m++)
704 for (
unsigned int i=0; i < base_no_mult_local_enriched_dofs[base_no][m].size(); i++)
706 const unsigned int enriched_dof = base_no_mult_local_enriched_dofs[base_no][m][i];
707 for (
unsigned int q=0; q<n_q_points; ++q)
723 for (
unsigned int base_no = 1; base_no < this->n_base_elements(); base_no++)
725 for (
unsigned int m=0; m < base_no_mult_local_enriched_dofs[base_no].size(); m++)
726 for (
unsigned int i=0; i < base_no_mult_local_enriched_dofs[base_no][m].size(); i++)
728 const unsigned int enriched_dof = base_no_mult_local_enriched_dofs[base_no][m][i];
729 for (
unsigned int q=0; q<n_q_points; ++q)
739 for (
unsigned int base_no = 1; base_no < this->n_base_elements(); base_no++)
741 for (
unsigned int m=0; m < base_no_mult_local_enriched_dofs[base_no].size(); m++)
742 for (
unsigned int i=0; i < base_no_mult_local_enriched_dofs[base_no][m].size(); i++)
744 const unsigned int enriched_dof = base_no_mult_local_enriched_dofs[base_no][m][i];
745 for (
unsigned int q=0; q<n_q_points; ++q)
754 template <
int dim,
int spacedim>
763 template <
int dim,
int spacedim>
772 template <
int dim,
int spacedim>
781 fe_system.get_face_interpolation_matrix(fe_enr_other->get_fe_system(),
787 AssertThrow(
false,
typename FEL::ExcInterpolationNotImplemented());
792 template <
int dim,
int spacedim>
796 const unsigned int subface,
802 fe_system.get_subface_interpolation_matrix(fe_enr_other->get_fe_system(),
809 AssertThrow(
false,
typename FEL::ExcInterpolationNotImplemented());
814 template <
int dim,
int spacedim>
815 std::vector<std::pair<unsigned int, unsigned int> >
822 return fe_system.hp_vertex_dof_identities(fe_enr_other->get_fe_system());
827 return std::vector<std::pair<unsigned int, unsigned int> >();
832 template <
int dim,
int spacedim>
833 std::vector<std::pair<unsigned int, unsigned int> >
840 return fe_system.hp_line_dof_identities(fe_enr_other->get_fe_system());
845 return std::vector<std::pair<unsigned int, unsigned int> >();
850 template <
int dim,
int spacedim>
851 std::vector<std::pair<unsigned int, unsigned int> >
858 return fe_system.hp_quad_dof_identities(fe_enr_other->get_fe_system());
863 return std::vector<std::pair<unsigned int, unsigned int> >();
868 template <
int dim,
int spacedim>
886 return fe_system.compare_for_face_domination(fe_enr_other->get_fe_system());
895 template <
int dim,
int spacedim>
900 return fe_system.get_prolongation_matrix(child, refinement_case);
904 template <
int dim,
int spacedim>
909 return fe_system.get_restriction_matrix(child, refinement_case);
916 template <
int dim,
int spacedim>
919 fesystem_data(
std::move(fesystem_data))
923 template <
int dim,
int spacedim>
928 return fesystem_data->get_fe_data(base_no);
932 template <
int dim,
int spacedim>
937 return fesystem_data->get_fe_output_object(base_no);
942 #include "fe_enriched.inst" 944 DEAL_II_NAMESPACE_CLOSE
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
bool is_dominating() const
InternalData(std::unique_ptr< typename FESystem< dim, spacedim >::InternalData > fesystem_data)
unsigned int n_nonzero_components(const unsigned int i) const
FE_Enriched(const FiniteElement< dim, spacedim > &fe_base, const FiniteElement< dim, spacedim > &fe_enriched, const Function< spacedim > *enrichment_function)
void initialize(const std::vector< const FiniteElement< dim, spacedim > *> &fes, const std::vector< unsigned int > &multiplicities)
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
std::vector< std::vector< EnrichmentValues > > enrichment
Transformed quadrature points.
#define AssertThrow(cond, exc)
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
const FESystem< dim, spacedim > & get_fe_system() const
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const
static ::ExceptionBase & ExcMessage(std::string arg1)
virtual bool hp_constraints_are_implemented() const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
Third derivatives of shape functions.
#define Assert(cond, exc)
internal::FEValues::FiniteElementRelatedData< dim, spacedim > & get_fe_output_object(const unsigned int base_no) const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
FiniteElement< dim, spacedim >::InternalDataBase & get_fe_data(const unsigned int base_no) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
virtual std::string get_name() const
void multiply_by_enrichment(const Quadrature< dim_1 > &quadrature, const InternalData &fe_data, const internal::FEValues::MappingRelatedData< dim, spacedim > &mapping_data, const typename Triangulation< dim, spacedim >::cell_iterator &cell, internal::FEValues::FiniteElementRelatedData< dim, spacedim > &output_data) const
SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
Second derivatives of shape functions.
std::string dim_string(const int dim, const int spacedim)
FiniteElement< dim, spacedim >::InternalDataBase * setup_data(std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > fes_data, const UpdateFlags flags, const Quadrature< dim_1 > &quadrature) const
virtual FiniteElement< dim, spacedim >::InternalDataBase * get_data(const UpdateFlags flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature, ::internal::FEValues::FiniteElementRelatedData< dim, spacedim > &output_data) const
unsigned int size() const
const unsigned int dofs_per_cell
virtual FiniteElement< dim, spacedim >::InternalDataBase * get_face_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature, ::internal::FEValues::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual FiniteElement< dim, spacedim >::InternalDataBase * get_subface_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature, ::internal::FEValues::FiniteElementRelatedData< dim, spacedim > &output_data) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Shape function gradients.
std::vector< std::vector< std::vector< unsigned int > > > base_no_mult_local_enriched_dofs
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
static ::ExceptionBase & ExcNotImplemented()
virtual FiniteElement< dim, spacedim > * clone() 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 FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > system_to_base_table
static ::ExceptionBase & ExcInternalError()