44 std::vector<unsigned int>
45 get_rt_dpo_vector(
const unsigned int dim,
const unsigned int degree)
47 std::vector<unsigned int> dpo(dim + 1);
50 unsigned int dofs_per_face = 1;
51 for (
unsigned int d = 1;
d < dim; ++
d)
52 dofs_per_face *= (degree + 1);
54 dpo[dim - 1] = dofs_per_face;
55 dpo[dim] = dim * degree * dofs_per_face;
65template <
int dim,
int spacedim>
67 const unsigned int degree)
86 const std::vector<unsigned int> numbering =
95 this->n_dofs_per_cell());
97 const unsigned int face_no = 0;
108 if constexpr (dim == spacedim)
112 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
116 FETools::compute_face_embedding_matrices<dim, double>(*
this,
124 unsigned int target_row = 0;
125 for (
unsigned int d = 0; d < GeometryInfo<dim>::max_children_per_face;
127 for (
unsigned int i = 0; i < face_embeddings[d].
m(); ++i)
129 for (
unsigned int j = 0; j < face_embeddings[d].
n(); ++j)
131 face_embeddings[d](i, j);
143template <
int dim,
int spacedim>
154 ">(" + std::to_string(this->degree - 1) +
")";
158template <
int dim,
int spacedim>
159std::unique_ptr<FiniteElement<dim, spacedim>>
162 return std::make_unique<FE_RaviartThomasNodal<dim, spacedim>>(*this);
172template <
int dim,
int spacedim>
181 const unsigned int n = this->degree;
182 const unsigned int face_no = 0;
184 for (
unsigned int local = 0; local < this->n_dofs_per_quad(face_no); ++local)
188 unsigned int i = local % n, j = local / n;
191 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
195 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
197 i + (n - 1 - j) * n - local;
199 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
201 (n - 1 - j) + (n - 1 - i) * n - local;
203 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
205 (n - 1 - i) + j * n - local;
207 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
210 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
212 j + (n - 1 - i) * n - local;
214 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
216 (n - 1 - i) + (n - 1 - j) * n - local;
218 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
220 (n - 1 - j) + i * n - local;
223 for (
const bool rotation : {
false,
true})
224 for (
const bool flip : {
false,
true})
225 this->adjust_quad_dof_sign_for_face_orientation_table[face_no](
233template <
int dim,
int spacedim>
236 const unsigned int shape_index,
237 const unsigned int face_index)
const
244 const unsigned int support_face = shape_index / this->n_dofs_per_face();
257template <
int dim,
int spacedim>
262 std::vector<double> &nodal_values)
const
264 if constexpr (dim != spacedim)
270 (void)support_point_values;
275 Assert(support_point_values.size() == this->generalized_support_points.size(),
277 this->generalized_support_points.size()));
278 Assert(nodal_values.size() == this->n_dofs_per_cell(),
280 Assert(support_point_values[0].
size() == this->n_components(),
282 this->n_components()));
286 unsigned int fbase = 0;
288 for (; f < GeometryInfo<dim>::faces_per_cell;
289 ++f, fbase += this->n_dofs_per_face(f))
291 for (
unsigned int i = 0; i < this->n_dofs_per_face(f); ++i)
293 nodal_values[fbase + i] = support_point_values[fbase + i](
299 const unsigned int istep = (this->n_dofs_per_cell() - fbase) / dim;
303 while (fbase < this->n_dofs_per_cell())
305 for (
unsigned int i = 0; i < istep; ++i)
307 nodal_values[fbase + i] = support_point_values[fbase + i](f);
323template <
int dim,
int spacedim>
331template <
int dim,
int spacedim>
332std::vector<std::pair<unsigned int, unsigned int>>
341 return std::vector<std::pair<unsigned int, unsigned int>>();
344 return std::vector<std::pair<unsigned int, unsigned int>>();
348 return std::vector<std::pair<unsigned int, unsigned int>>();
354template <
int dim,
int spacedim>
355std::vector<std::pair<unsigned int, unsigned int>>
366 return std::vector<std::pair<unsigned int, unsigned int>>();
381 const unsigned int p = this->degree - 1;
382 const unsigned int q = fe_q_other->degree - 1;
384 std::vector<std::pair<unsigned int, unsigned int>> identities;
387 for (
unsigned int i = 0; i < p + 1; ++i)
388 identities.emplace_back(i, i);
390 else if (p % 2 == 0 && q % 2 == 0)
391 identities.emplace_back(p / 2, q / 2);
400 return std::vector<std::pair<unsigned int, unsigned int>>();
405 return std::vector<std::pair<unsigned int, unsigned int>>();
410template <
int dim,
int spacedim>
411std::vector<std::pair<unsigned int, unsigned int>>
414 const unsigned int face_no)
const
423 return std::vector<std::pair<unsigned int, unsigned int>>();
426 const unsigned int p = this->n_dofs_per_quad(face_no);
429 const unsigned int q = fe_q_other->n_dofs_per_quad(0);
431 std::vector<std::pair<unsigned int, unsigned int>> identities;
434 for (
unsigned int i = 0; i < p; ++i)
435 identities.emplace_back(i, i);
437 else if (p % 2 != 0 && q % 2 != 0)
438 identities.emplace_back(p / 2, q / 2);
447 return std::vector<std::pair<unsigned int, unsigned int>>();
452 return std::vector<std::pair<unsigned int, unsigned int>>();
457template <
int dim,
int spacedim>
461 const unsigned int codim)
const
471 if (this->degree < fe_rt_nodal_other->degree)
473 else if (this->degree == fe_rt_nodal_other->degree)
481 if (fe_nothing->is_dominating())
501 const unsigned int)
const
513 const unsigned int)
const
520template <
int dim,
int spacedim>
525 const unsigned int face_no)
const
531 (x_source_fe.
get_name().find(
"FE_RaviartThomasNodal<") == 0) ||
533 &x_source_fe) !=
nullptr),
536 Assert(interpolation_matrix.
n() == this->n_dofs_per_face(face_no),
538 this->n_dofs_per_face(face_no)));
565 double eps = 2e-13 * this->degree * (dim - 1);
577 const Point<dim> &p = face_projection.point(i);
579 for (
unsigned int j = 0; j < this->n_dofs_per_face(face_no); ++j)
581 double matrix_entry =
582 this->shape_value_component(this->face_to_cell_index(j, 0), p, 0);
587 if (std::fabs(matrix_entry - 1.0) < eps)
589 if (std::fabs(matrix_entry) < eps)
592 interpolation_matrix(i, j) = matrix_entry;
604 for (
unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i)
605 sum += interpolation_matrix(j, i);
607 Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1),
614template <
int dim,
int spacedim>
618 const unsigned int subface,
620 const unsigned int face_no)
const
625 (x_source_fe.
get_name().find(
"FE_RaviartThomasNodal<") == 0) ||
627 &x_source_fe) !=
nullptr),
630 Assert(interpolation_matrix.
n() == this->n_dofs_per_face(face_no),
632 this->n_dofs_per_face(face_no)));
659 double eps = 2e-13 * this->degree * (dim - 1);
665 this->reference_cell(),
674 const Point<dim> &p = subface_projection.point(i);
676 for (
unsigned int j = 0; j < this->n_dofs_per_face(face_no); ++j)
678 double matrix_entry =
679 this->shape_value_component(this->face_to_cell_index(j, 0), p, 0);
684 if (std::fabs(matrix_entry - 1.0) < eps)
686 if (std::fabs(matrix_entry) < eps)
689 interpolation_matrix(i, j) = matrix_entry;
701 for (
unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i)
702 sum += interpolation_matrix(j, i);
704 Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1),
712template <
int dim,
int spacedim>
715 const unsigned int child,
722 "Prolongation matrices are only available for refined cells!"));
723 AssertIndexRange(child, this->reference_cell().n_children(refinement_case));
726 if (this->prolongation[refinement_case - 1][child].n() == 0)
728 std::scoped_lock lock(prolongation_matrix_mutex);
731 if (this->prolongation[refinement_case - 1][child].n() ==
732 this->n_dofs_per_cell())
733 return this->prolongation[refinement_case - 1][child];
741 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
743 isotropic_matrices.back().resize(
744 this->reference_cell().n_children(
747 this->n_dofs_per_cell()));
750 std::move(isotropic_matrices.back());
766 return this->prolongation[refinement_case - 1][child];
771template <
int dim,
int spacedim>
774 const unsigned int child,
781 "Restriction matrices are only available for refined cells!"));
782 AssertIndexRange(child, this->reference_cell().n_children(refinement_case));
785 if (this->restriction[refinement_case - 1][child].n() == 0)
787 std::scoped_lock lock(restriction_matrix_mutex);
790 if (this->restriction[refinement_case - 1][child].n() ==
791 this->n_dofs_per_cell())
792 return this->restriction[refinement_case - 1][child];
800 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
802 isotropic_matrices.back().resize(
803 this->reference_cell().n_children(
806 this->n_dofs_per_cell()));
809 std::move(isotropic_matrices.back());
825 return this->restriction[refinement_case - 1][child];
831#include "fe/fe_raviart_thomas_nodal.inst"
std::vector< MappingKind > mapping_kind
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 bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
virtual bool hp_constraints_are_implemented() const override
void initialize_quad_dof_index_permutation_and_sign_change()
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) 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
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
virtual std::string get_name() const override
FE_RaviartThomasNodal(const unsigned int p)
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const override
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) 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 FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
static std::vector< unsigned int > get_lexicographic_numbering(const unsigned int degree)
const unsigned int degree
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
virtual std::string get_name() const =0
std::vector< std::vector< FullMatrix< double > > > restriction
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
std::vector< std::vector< Point< dim - 1 > > > generalized_face_support_points
FullMatrix< double > interface_constraints
std::vector< Point< dim > > generalized_support_points
std::vector< std::vector< FullMatrix< double > > > prolongation
std::vector< Point< dim > > get_polynomial_support_points() const
static Quadrature< dim > project_to_face(const ReferenceCell< dim > &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const types::geometric_orientation combined_orientation)
static Quadrature< dim > project_to_subface(const ReferenceCell< dim > &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, const types::geometric_orientation combined_orientation, const RefinementCase< dim - 1 > &ref_case)
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
#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)
@ either_element_can_dominate
@ other_element_dominates
@ neither_element_dominates
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::string dim_string(const int dim, const int spacedim)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr types::geometric_orientation default_geometric_orientation