17 #include <deal.II/base/quadrature.h> 18 #include <deal.II/base/qprojector.h> 19 #include <deal.II/base/template_constraints.h> 20 #include <deal.II/fe/fe_q_bubbles.h> 21 #include <deal.II/fe/fe_nothing.h> 22 #include <deal.II/fe/fe_tools.h> 23 #include <deal.II/fe/fe_values.h> 24 #include <deal.II/fe/mapping_q1.h> 25 #include <deal.II/base/quadrature_lib.h> 26 #include <deal.II/dofs/dof_accessor.h> 27 #include <deal.II/dofs/dof_handler.h> 28 #include <deal.II/grid/tria.h> 30 #include <deal.II/grid/grid_generator.h> 36 #include <deal.II/base/std_cxx14/memory.h> 38 DEAL_II_NAMESPACE_OPEN
47 template <
int dim,
int spacedim>
52 const bool isotropic_only)
54 const unsigned int dpc = fe.dofs_per_cell;
55 const unsigned int degree = fe.degree;
58 std::unique_ptr<Quadrature<dim> > q_fine;
64 q_fine = std_cxx14::make_unique<QGauss<dim>>(degree+1);
66 q_fine = std_cxx14::make_unique<QAnisotropic<dim>>(
QGauss<1>(degree+1), q_dummy);
68 q_fine = std_cxx14::make_unique<QAnisotropic<dim>>(
QGauss<1>(degree+1), q_dummy, q_dummy);
72 q_fine = std_cxx14::make_unique<QGauss<dim>>(degree+1);
74 q_fine = std_cxx14::make_unique<QAnisotropic<dim>>(
QGauss<1>(degree+1),
QGauss<1>(degree+1), q_dummy);
77 q_fine = std_cxx14::make_unique<QGauss<dim>>(degree+1);
84 const unsigned int nq = q_fine->size();
87 unsigned int ref_case = (isotropic_only)
90 for (; ref_case <= RefinementCase<dim>::isotropic_refinement; ++ref_case)
95 for (
unsigned int i=0; i<nc; ++i)
97 Assert(matrices[ref_case-1][i].n() == dpc,
99 Assert(matrices[ref_case-1][i].m() == dpc,
110 dh.distribute_dofs(fe);
117 const unsigned int n_dofs = dh.n_dofs();
122 std::vector<std::vector<types::global_dof_index> > child_ldi
123 (nc, std::vector<types::global_dof_index>(fe.dofs_per_cell));
126 unsigned int child_no = 0;
127 typename ::DoFHandler<dim>::active_cell_iterator cell
129 for (; cell!=dh.end(); ++cell, ++child_no)
132 cell->get_dof_indices(child_ldi[child_no]);
134 for (
unsigned int q=0; q<nq; ++q)
135 for (
unsigned int i=0; i<dpc; ++i)
136 for (
unsigned int j=0; j<dpc; ++j)
138 const unsigned int gdi=child_ldi[child_no][i];
139 const unsigned int gdj=child_ldi[child_no][j];
140 fine_mass(gdi, gdj)+=fine.shape_value(i,q)
141 *fine.shape_value(j,q)
144 for (
unsigned int k=0; k<dim; ++k)
145 quad_tmp(k) = fine.quadrature_point(q)(k);
146 coarse_rhs_matrix(gdi, j)
147 +=fine.shape_value(i,q)
148 *fe.shape_value(j, quad_tmp)
155 fine_mass.gauss_jordan();
156 fine_mass.mmult(solution, coarse_rhs_matrix);
159 for (
unsigned int child_no=0; child_no<nc; ++child_no)
160 for (
unsigned int i=0; i<dpc; ++i)
161 for (
unsigned int j=0; j<dpc; ++j)
163 const unsigned int gdi=child_ldi[child_no][i];
165 if (std::fabs(solution(gdi, j)) > 1.e-12)
166 matrices[ref_case-1][child_no](i,j)=solution(gdi, j);
175 template <
int dim,
int spacedim>
183 get_riaf_vector(q_degree)),
184 n_bubbles((q_degree<=1)?1:dim)
187 ExcMessage (
"This element can only be used for polynomial degrees " 188 "greater than zero"));
194 for (
unsigned int d=0; d<dim; ++d)
203 internal::FE_Q_Bubbles::compute_embedding_matrices
213 template <
int dim,
int spacedim>
221 get_riaf_vector(points.size()-1)),
222 n_bubbles((points.size()-1<=1)?1:dim)
225 ExcMessage (
"This element can only be used for polynomial degrees " 232 for (
unsigned int d=0; d<dim; ++d)
234 for (
unsigned int i=0; i<
n_bubbles; ++i)
241 internal::FE_Q_Bubbles::compute_embedding_matrices
250 template <
int dim,
int spacedim>
258 std::ostringstream namebuf;
260 const unsigned int n_points = this->degree;
261 std::vector<double> points(n_points);
262 const unsigned int dofs_per_cell = this->dofs_per_cell;
263 const std::vector<Point<dim> > &unit_support_points = this->unit_support_points;
264 unsigned int index = 0;
267 for (
unsigned int j=0; j<dofs_per_cell; j++)
269 if ((dim>1) ? (unit_support_points[j](1)==0 &&
270 ((dim>2) ? unit_support_points[j](2)==0:
true)) :
true)
273 points[index] = unit_support_points[j](0);
275 points[n_points-1] = unit_support_points[j](0);
277 points[index-1] = unit_support_points[j](0);
283 Assert (index == n_points || (dim==1 && index == n_points+n_bubbles),
284 ExcMessage (
"Could not decode support points in one coordinate direction."));
287 for (
unsigned int j=0; j<n_points; j++)
288 if (std::fabs(points[j] - (
double)j/(this->degree-1)) > 1e-15)
296 if (this->degree > 3)
297 namebuf <<
"FE_Q_Bubbles<" 299 <<
">(QIterated(QTrapez()," << this->degree-1 <<
"))";
301 namebuf <<
"FE_Q_Bubbles<" 303 <<
">(" << this->degree-1 <<
")";
311 for (
unsigned int j=0; j<n_points; j++)
312 if (points[j] != points_gl.
point(j)(0))
318 namebuf <<
"FE_Q_Bubbles<" << dim <<
">(" << this->degree-1 <<
")";
320 namebuf <<
"FE_Q_Bubbles<" << dim <<
">(QUnknownNodes(" << this->degree <<
"))";
322 return namebuf.str();
327 template <
int dim,
int spacedim>
328 std::unique_ptr<FiniteElement<dim,spacedim> >
331 return std_cxx14::make_unique<FE_Q_Bubbles<dim,spacedim>>(*this);
336 template <
int dim,
int spacedim>
340 std::vector<double> &nodal_values)
const 342 Assert (support_point_values.size() == this->unit_support_points.size(),
344 this->unit_support_points.size()));
345 Assert (nodal_values.size() == this->dofs_per_cell,
350 for (
unsigned int i=0; i<this->dofs_per_cell-1; ++i)
352 const std::pair<unsigned int, unsigned int> index
353 = this->system_to_component_index(i);
354 nodal_values[i] = support_point_values[i](index.first);
358 for (
unsigned int i = 0; i<n_bubbles; ++i)
359 nodal_values[nodal_values.size()-i-1] = 0.;
364 template <
int dim,
int spacedim>
377 (dynamic_cast<const FEQBUBBLES *>(&x_source_fe) !=
nullptr)
380 ExcInterpolationNotImplemented()));
381 Assert (interpolation_matrix.
m() == this->dofs_per_cell,
383 this->dofs_per_cell));
389 auto casted_fe =
dynamic_cast<const FEQBUBBLES *
>(&x_source_fe);
390 if (casted_fe !=
nullptr && casted_fe->degree == this->degree)
391 for (
unsigned int i=0; i<interpolation_matrix.
m(); ++i)
392 interpolation_matrix.
set(i,i,1.);
396 ExcInterpolationNotImplemented()));
401 template <
int dim,
int spacedim>
405 unsigned int n_cont_dofs = Utilities::fixed_power<dim>(q_deg+1);
406 const unsigned int n_bubbles = (q_deg<=1?1:dim);
407 return std::vector<bool> (n_cont_dofs+n_bubbles,
true);
412 template <
int dim,
int spacedim>
413 std::vector<unsigned int>
416 std::vector<unsigned int> dpo(dim+1, 1U);
417 for (
unsigned int i=1; i<dpo.size(); ++i)
418 dpo[i]=dpo[i-1]*(q_deg-1);
420 dpo[dim]+=(q_deg<=1?1:dim);
426 template <
int dim,
int spacedim>
429 (
const unsigned int shape_index,
430 const unsigned int face_index)
const 433 if (shape_index >= this->n_dofs_per_cell()-n_bubbles)
441 template <
int dim,
int spacedim>
444 (
const unsigned int child,
450 ExcMessage(
"Prolongation matrices are only available for refined cells!"));
454 Assert (this->prolongation[refinement_case-1][child].n() != 0,
455 ExcMessage(
"This prolongation matrix has not been computed yet!"));
457 return this->prolongation[refinement_case-1][child];
462 template <
int dim,
int spacedim>
465 (
const unsigned int child,
471 ExcMessage(
"Restriction matrices are only available for refined cells!"));
475 Assert(this->restriction[refinement_case-1][child].n() != 0,
476 ExcMessage(
"This restriction matrix has not been computed yet!"));
479 return this->restriction[refinement_case-1][child];
483 #include "fe_q_bubbles.inst" 485 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
const unsigned int n_bubbles
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const
std::vector< std::vector< FullMatrix< double > > > restriction
#define AssertDimension(dim1, dim2)
const std::vector< Point< dim > > & get_points() const
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
const Point< dim > & point(const unsigned int i) const
active_cell_iterator begin_active(const unsigned int level=0) const
Transformed quadrature points.
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::vector< Point< dim > > unit_support_points
void set(const size_type i, const size_type j, const number value)
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const
virtual void execute_coarsening_and_refinement()
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case) const
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< std::vector< FullMatrix< double > > > prolongation
#define Assert(cond, exc)
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual std::string get_name() const =0
virtual std::string get_name() const
std::string dim_string(const int dim, const int spacedim)
unsigned int size() const
const unsigned int dofs_per_cell
void initialize(const std::vector< Point< 1 > > &support_points_1d)
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
static std::vector< bool > get_riaf_vector(const unsigned int degree)
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
FE_Q_Bubbles(const unsigned int p)
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
static ::ExceptionBase & ExcInternalError()