46 std::vector<unsigned int>
47 get_rt_dpo_vector(
const unsigned int dim,
const unsigned int degree)
49 std::vector<unsigned int> dpo(dim + 1);
52 unsigned int dofs_per_face = 1;
53 for (
unsigned int d = 1;
d < dim; ++
d)
54 dofs_per_face *= (degree + 1);
56 dpo[dim - 1] = dofs_per_face;
57 dpo[dim] = dim * degree * dofs_per_face;
90 this->n_dofs_per_cell());
92 const unsigned int face_no = 0;
99 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face; ++i)
102 FETools::compute_face_embedding_matrices<dim, double>(*
this,
109 unsigned int target_row = 0;
110 for (
unsigned int d = 0; d < GeometryInfo<dim>::max_children_per_face; ++d)
111 for (
unsigned int i = 0; i < face_embeddings[d].
m(); ++i)
113 for (
unsigned int j = 0; j < face_embeddings[d].
n(); ++j)
135 return "FE_RaviartThomasNodal<" + std::to_string(dim) +
">(" +
136 std::to_string(this->degree - 1) +
")";
141std::unique_ptr<FiniteElement<dim, dim>>
144 return std::make_unique<FE_RaviartThomasNodal<dim>>(*this);
157 dim>::initialize_quad_dof_index_permutation_and_sign_change()
163 const unsigned int n = this->degree;
164 const unsigned int face_no = 0;
166 for (
unsigned int local = 0; local < this->n_dofs_per_quad(face_no); ++local)
170 unsigned int i = local % n, j = local / n;
173 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
177 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
179 i + (n - 1 - j) * n - local;
181 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
183 (n - 1 - j) + (n - 1 - i) * n - local;
185 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
187 (n - 1 - i) + j * n - local;
189 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
192 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
194 j + (n - 1 - i) * n - local;
196 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
198 (n - 1 - i) + (n - 1 - j) * n - local;
200 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
202 (n - 1 - j) + i * n - local;
205 for (
const bool rotation : {
false,
true})
206 for (
const bool flip : {
false,
true})
207 this->adjust_quad_dof_sign_for_face_orientation_table[face_no](
218 const unsigned int shape_index,
219 const unsigned int face_index)
const
226 const unsigned int support_face = shape_index / this->n_dofs_per_face();
244 std::vector<double> &nodal_values)
const
246 Assert(support_point_values.size() == this->generalized_support_points.size(),
248 this->generalized_support_points.size()));
249 Assert(nodal_values.size() == this->n_dofs_per_cell(),
251 Assert(support_point_values[0].
size() == this->n_components(),
253 this->n_components()));
257 unsigned int fbase = 0;
259 for (; f < GeometryInfo<dim>::faces_per_cell;
260 ++f, fbase += this->n_dofs_per_face(f))
262 for (
unsigned int i = 0; i < this->n_dofs_per_face(f); ++i)
264 nodal_values[fbase + i] = support_point_values[fbase + i](
270 const unsigned int istep = (this->n_dofs_per_cell() - fbase) / dim;
274 while (fbase < this->n_dofs_per_cell())
276 for (
unsigned int i = 0; i < istep; ++i)
278 nodal_values[fbase + i] = support_point_values[fbase + i](f);
303std::vector<std::pair<unsigned int, unsigned int>>
311 return std::vector<std::pair<unsigned int, unsigned int>>();
313 return std::vector<std::pair<unsigned int, unsigned int>>();
317 return std::vector<std::pair<unsigned int, unsigned int>>();
324std::vector<std::pair<unsigned int, unsigned int>>
335 return std::vector<std::pair<unsigned int, unsigned int>>();
350 const unsigned int p = this->degree - 1;
351 const unsigned int q = fe_q_other->degree - 1;
353 std::vector<std::pair<unsigned int, unsigned int>> identities;
356 for (
unsigned int i = 0; i < p + 1; ++i)
357 identities.emplace_back(i, i);
359 else if (p % 2 == 0 && q % 2 == 0)
360 identities.emplace_back(p / 2, q / 2);
368 return std::vector<std::pair<unsigned int, unsigned int>>();
373 return std::vector<std::pair<unsigned int, unsigned int>>();
379std::vector<std::pair<unsigned int, unsigned int>>
382 const unsigned int face_no)
const
391 return std::vector<std::pair<unsigned int, unsigned int>>();
394 const unsigned int p = this->n_dofs_per_quad(face_no);
397 const unsigned int q = fe_q_other->n_dofs_per_quad(0);
399 std::vector<std::pair<unsigned int, unsigned int>> identities;
402 for (
unsigned int i = 0; i < p; ++i)
403 identities.emplace_back(i, i);
405 else if (p % 2 != 0 && q % 2 != 0)
406 identities.emplace_back(p / 2, q / 2);
414 return std::vector<std::pair<unsigned int, unsigned int>>();
419 return std::vector<std::pair<unsigned int, unsigned int>>();
428 const unsigned int codim)
const
438 if (this->degree < fe_rt_nodal_other->degree)
440 else if (this->degree == fe_rt_nodal_other->degree)
448 if (fe_nothing->is_dominating())
468 const unsigned int)
const
480 const unsigned int)
const
492 const unsigned int face_no)
const
499 &x_source_fe) !=
nullptr),
502 Assert(interpolation_matrix.
n() == this->n_dofs_per_face(face_no),
504 this->n_dofs_per_face(face_no)));
530 double eps = 2e-13 * this->degree * (dim - 1);
541 const Point<dim> &p = face_projection.point(i);
543 for (
unsigned int j = 0; j < this->n_dofs_per_face(face_no); ++j)
545 double matrix_entry =
546 this->shape_value_component(this->face_to_cell_index(j, 0), p, 0);
551 if (std::fabs(matrix_entry - 1.0) < eps)
553 if (std::fabs(matrix_entry) < eps)
556 interpolation_matrix(i, j) = matrix_entry;
567 for (
unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i)
568 sum += interpolation_matrix(j, i);
570 Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1),
581 const unsigned int subface,
583 const unsigned int face_no)
const
589 &x_source_fe) !=
nullptr),
592 Assert(interpolation_matrix.
n() == this->n_dofs_per_face(face_no),
594 this->n_dofs_per_face(face_no)));
620 double eps = 2e-13 * this->degree * (dim - 1);
632 const Point<dim> &p = subface_projection.point(i);
634 for (
unsigned int j = 0; j < this->n_dofs_per_face(face_no); ++j)
636 double matrix_entry =
637 this->shape_value_component(this->face_to_cell_index(j, 0), p, 0);
642 if (std::fabs(matrix_entry - 1.0) < eps)
644 if (std::fabs(matrix_entry) < eps)
647 interpolation_matrix(i, j) = matrix_entry;
658 for (
unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i)
659 sum += interpolation_matrix(j, i);
661 Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1),
672 const unsigned int child,
679 "Prolongation matrices are only available for refined cells!"));
683 if (this->prolongation[refinement_case - 1][child].n() == 0)
685 std::lock_guard<std::mutex> lock(prolongation_matrix_mutex);
688 if (this->prolongation[refinement_case - 1][child].n() ==
689 this->n_dofs_per_cell())
690 return this->prolongation[refinement_case - 1][child];
698 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
700 isotropic_matrices.back().resize(
703 this->n_dofs_per_cell()));
706 std::move(isotropic_matrices.back());
722 return this->prolongation[refinement_case - 1][child];
730 const unsigned int child,
737 "Restriction matrices are only available for refined cells!"));
741 if (this->restriction[refinement_case - 1][child].n() == 0)
743 std::lock_guard<std::mutex> lock(restriction_matrix_mutex);
746 if (this->restriction[refinement_case - 1][child].n() ==
747 this->n_dofs_per_cell())
748 return this->restriction[refinement_case - 1][child];
756 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
758 isotropic_matrices.back().resize(
761 this->n_dofs_per_cell()));
764 std::move(isotropic_matrices.back());
780 return this->restriction[refinement_case - 1][child];
786#include "fe_raviart_thomas_nodal.inst"
std::vector< MappingKind > mapping_kind
virtual std::unique_ptr< FiniteElement< dim, dim > > clone() const override
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 bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
void initialize_quad_dof_index_permutation_and_sign_change()
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim > &fe_other) const override
virtual void get_face_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
virtual std::string get_name() const override
virtual bool hp_constraints_are_implemented() const override
virtual void get_subface_interpolation_matrix(const FiniteElement< dim > &source, const unsigned int subface, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim > &fe_other, const unsigned int codim=0) const override final
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim > &fe_other) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim > &fe_other, const unsigned int face_no=0) const override
FE_RaviartThomasNodal(const unsigned int p)
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 void project_to_subface(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, std::vector< Point< dim > > &q_points, const RefinementCase< dim - 1 > &ref_case=RefinementCase< dim - 1 >::isotropic_refinement)
static void project_to_face(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, std::vector< Point< dim > > &q_points)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#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)
#define DEAL_II_NOT_IMPLEMENTED()
@ 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)
unsigned char combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)