Reference documentation for deal.II version 8.4.2
fe_dgp_nonparametric.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2002 - 2016 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/quadrature.h>
18 #include <deal.II/grid/tria.h>
19 #include <deal.II/grid/tria_iterator.h>
20 #include <deal.II/dofs/dof_accessor.h>
21 #include <deal.II/fe/fe.h>
22 #include <deal.II/fe/mapping.h>
23 #include <deal.II/fe/fe_dgp_nonparametric.h>
24 #include <deal.II/fe/fe_values.h>
25 
26 #include <sstream>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 template <int dim, int spacedim>
32  :
33  FiniteElement<dim,spacedim> (
34  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree,
35  FiniteElementData<dim>::L2),
36  std::vector<bool>(
37  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
38  std::vector<ComponentMask>(
39  FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
40  std::vector<bool>(1,true))),
41  degree(degree),
42  polynomial_space (Polynomials::Legendre::generate_complete_basis(degree))
43 {
44  const unsigned int n_dofs = this->dofs_per_cell;
45  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
46  ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
47  {
48  if (dim!=2 && ref_case!=RefinementCase<dim>::isotropic_refinement)
49  // do nothing, as anisotropic
50  // refinement is not
51  // implemented so far
52  continue;
53 
54  const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
55  for (unsigned int i=0; i<nc; ++i)
56  {
57  this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
58  // Fill prolongation matrices with
59  // embedding operators
60  for (unsigned int j=0; j<n_dofs; ++j)
61  this->prolongation[ref_case-1][i](j,j) = 1.;
62  }
63  }
64 
65  // restriction can be defined
66  // through projection for
67  // discontinuous elements, but is
68  // presently not implemented for DGPNonparametric
69  // elements.
70  //
71  // if it were, then the following
72  // snippet would be the right code
73 // if ((degree < Matrices::n_projection_matrices) &&
74 // (Matrices::projection_matrices[degree] != 0))
75 // {
76 // restriction[0].fill (Matrices::projection_matrices[degree]);
77 // }
78 // else
79 // // matrix undefined, set size to zero
80 // for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
81 // restriction[i].reinit(0, 0);
82  // since not implemented, set to
83  // "empty". however, that is done in the
84  // default constructor already, so do nothing
85 // for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
86 // this->restriction[i].reinit(0, 0);
87 
88  // note further, that these
89  // elements have neither support
90  // nor face-support points, so
91  // leave these fields empty
92 }
93 
94 
95 
96 template <int dim, int spacedim>
97 std::string
99 {
100  // note that the
101  // FETools::get_fe_from_name
102  // function depends on the
103  // particular format of the string
104  // this function returns, so they
105  // have to be kept in synch
106 
107  std::ostringstream namebuf;
108  namebuf << "FE_DGPNonparametric<"
109  << Utilities::dim_string(dim,spacedim)
110  << ">(" << degree << ")";
111 
112  return namebuf.str();
113 }
114 
115 
116 
117 template <int dim, int spacedim>
120 {
121  return new FE_DGPNonparametric<dim,spacedim>(*this);
122 }
123 
124 
125 
126 template <int dim, int spacedim>
127 double
129  const Point<dim> &p) const
130 {
131  (void)i;
132  (void)p;
133  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
135  return 0;
136 }
137 
138 
139 
140 template <int dim, int spacedim>
141 double
143  const Point<dim> &p,
144  const unsigned int component) const
145 {
146  (void)i;
147  (void)p;
148  (void)component;
149  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
150  Assert (component == 0, ExcIndexRange (component, 0, 1));
152  return 0;
153 }
154 
155 
156 
157 template <int dim, int spacedim>
160  const Point<dim> &p) const
161 {
162  (void)i;
163  (void)p;
164  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
166  return Tensor<1,dim>();
167 }
168 
169 
170 template <int dim, int spacedim>
173  const Point<dim> &p,
174  const unsigned int component) const
175 {
176  (void)i;
177  (void)p;
178  (void)component;
179  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
180  Assert (component == 0, ExcIndexRange (component, 0, 1));
182  return Tensor<1,dim>();
183 }
184 
185 
186 
187 template <int dim, int spacedim>
190  const Point<dim> &p) const
191 {
192  (void)i;
193  (void)p;
194  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
196  return Tensor<2,dim>();
197 }
198 
199 
200 
201 template <int dim, int spacedim>
204  const Point<dim> &p,
205  const unsigned int component) const
206 {
207  (void)i;
208  (void)p;
209  (void)component;
210  Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
211  Assert (component == 0, ExcIndexRange (component, 0, 1));
213  return Tensor<2,dim>();
214 }
215 
216 
217 //---------------------------------------------------------------------------
218 // Auxiliary functions
219 //---------------------------------------------------------------------------
220 
221 
222 template <int dim, int spacedim>
223 std::vector<unsigned int>
225 {
226  std::vector<unsigned int> dpo(dim+1, static_cast<unsigned int>(0));
227  dpo[dim] = deg+1;
228  for (unsigned int i=1; i<dim; ++i)
229  {
230  dpo[dim] *= deg+1+i;
231  dpo[dim] /= i+1;
232  }
233  return dpo;
234 }
235 
236 
237 
238 template <int dim, int spacedim>
241 {
242  UpdateFlags out = flags;
243 
245  out |= update_quadrature_points ;
246 
247  return out;
248 }
249 
250 
251 
252 //---------------------------------------------------------------------------
253 // Data field initialization
254 //---------------------------------------------------------------------------
255 
256 template <int dim, int spacedim>
259 get_data (const UpdateFlags update_flags,
260  const Mapping<dim,spacedim> &,
261  const Quadrature<dim> &,
263 {
264  // generate a new data object
267  data->update_each = requires_update_flags(update_flags);
268 
269  // other than that, there is nothing we can add here as discussed
270  // in the general documentation of this class
271 
272  return data;
273 }
274 
275 
276 
277 //---------------------------------------------------------------------------
278 // Fill data of FEValues
279 //---------------------------------------------------------------------------
280 
281 template <int dim, int spacedim>
282 void
285  const CellSimilarity::Similarity ,
286  const Quadrature<dim> &,
287  const Mapping<dim,spacedim> &,
289  const ::internal::FEValues::MappingRelatedData<dim, spacedim> &mapping_data,
290  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
292 {
293  Assert (fe_internal.update_each & update_quadrature_points, ExcInternalError());
294 
295  const unsigned int n_q_points = mapping_data.quadrature_points.size();
296 
297  std::vector<double> values(fe_internal.update_each & update_values ? this->dofs_per_cell : 0);
298  std::vector<Tensor<1,dim> > grads(fe_internal.update_each & update_gradients ? this->dofs_per_cell : 0);
299  std::vector<Tensor<2,dim> > grad_grads(fe_internal.update_each & update_hessians ? this->dofs_per_cell : 0);
300  std::vector<Tensor<3,dim> > empty_vector_of_3rd_order_tensors;
301  std::vector<Tensor<4,dim> > empty_vector_of_4th_order_tensors;
302 
303  if (fe_internal.update_each & (update_values | update_gradients))
304  for (unsigned int i=0; i<n_q_points; ++i)
305  {
306  polynomial_space.compute(mapping_data.quadrature_points[i],
307  values, grads, grad_grads,
308  empty_vector_of_3rd_order_tensors,
309  empty_vector_of_4th_order_tensors);
310 
311  if (fe_internal.update_each & update_values)
312  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
313  output_data.shape_values[k][i] = values[k];
314 
315  if (fe_internal.update_each & update_gradients)
316  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
317  output_data.shape_gradients[k][i] = grads[k];
318 
319  if (fe_internal.update_each & update_hessians)
320  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
321  output_data.shape_hessians[k][i] = grad_grads[k];
322  }
323 }
324 
325 
326 
327 template <int dim, int spacedim>
328 void
331  const unsigned int ,
332  const Quadrature<dim-1> &,
333  const Mapping<dim,spacedim> &,
335  const ::internal::FEValues::MappingRelatedData<dim, spacedim> &mapping_data,
336  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
338 {
339  Assert (fe_internal.update_each & update_quadrature_points, ExcInternalError());
340 
341  const unsigned int n_q_points = mapping_data.quadrature_points.size();
342 
343  std::vector<double> values(fe_internal.update_each & update_values ? this->dofs_per_cell : 0);
344  std::vector<Tensor<1,dim> > grads(fe_internal.update_each & update_gradients ? this->dofs_per_cell : 0);
345  std::vector<Tensor<2,dim> > grad_grads(fe_internal.update_each & update_hessians ? this->dofs_per_cell : 0);
346  std::vector<Tensor<3,dim> > empty_vector_of_3rd_order_tensors;
347  std::vector<Tensor<4,dim> > empty_vector_of_4th_order_tensors;
348 
349  if (fe_internal.update_each & (update_values | update_gradients))
350  for (unsigned int i=0; i<n_q_points; ++i)
351  {
352  polynomial_space.compute(mapping_data.quadrature_points[i],
353  values, grads, grad_grads,
354  empty_vector_of_3rd_order_tensors,
355  empty_vector_of_4th_order_tensors);
356 
357  if (fe_internal.update_each & update_values)
358  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
359  output_data.shape_values[k][i] = values[k];
360 
361  if (fe_internal.update_each & update_gradients)
362  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
363  output_data.shape_gradients[k][i] = grads[k];
364 
365  if (fe_internal.update_each & update_hessians)
366  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
367  output_data.shape_hessians[k][i] = grad_grads[k];
368  }
369 }
370 
371 
372 
373 template <int dim, int spacedim>
374 void
377  const unsigned int ,
378  const unsigned int ,
379  const Quadrature<dim-1> &,
380  const Mapping<dim,spacedim> &,
382  const ::internal::FEValues::MappingRelatedData<dim, spacedim> &mapping_data,
383  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
385 {
386  Assert (fe_internal.update_each & update_quadrature_points, ExcInternalError());
387 
388  const unsigned int n_q_points = mapping_data.quadrature_points.size();
389 
390  std::vector<double> values(fe_internal.update_each & update_values ? this->dofs_per_cell : 0);
391  std::vector<Tensor<1,dim> > grads(fe_internal.update_each & update_gradients ? this->dofs_per_cell : 0);
392  std::vector<Tensor<2,dim> > grad_grads(fe_internal.update_each & update_hessians ? this->dofs_per_cell : 0);
393  std::vector<Tensor<3,dim> > empty_vector_of_3rd_order_tensors;
394  std::vector<Tensor<4,dim> > empty_vector_of_4th_order_tensors;
395 
396  if (fe_internal.update_each & (update_values | update_gradients))
397  for (unsigned int i=0; i<n_q_points; ++i)
398  {
399  polynomial_space.compute(mapping_data.quadrature_points[i],
400  values, grads, grad_grads,
401  empty_vector_of_3rd_order_tensors,
402  empty_vector_of_4th_order_tensors);
403 
404  if (fe_internal.update_each & update_values)
405  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
406  output_data.shape_values[k][i] = values[k];
407 
408  if (fe_internal.update_each & update_gradients)
409  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
410  output_data.shape_gradients[k][i] = grads[k];
411 
412  if (fe_internal.update_each & update_hessians)
413  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
414  output_data.shape_hessians[k][i] = grad_grads[k];
415  }
416 }
417 
418 
419 
420 template <int dim, int spacedim>
421 void
424  FullMatrix<double> &interpolation_matrix) const
425 {
426  // this is only implemented, if the source
427  // FE is also a DGPNonparametric element. in that case,
428  // both elements have no dofs on their
429  // faces and the face interpolation matrix
430  // is necessarily empty -- i.e. there isn't
431  // much we need to do here.
432  (void)interpolation_matrix;
433  typedef FiniteElement<dim,spacedim> FEE;
434  AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
435  ||
436  (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
437  typename FEE::
438  ExcInterpolationNotImplemented());
439 
440  Assert (interpolation_matrix.m() == 0,
441  ExcDimensionMismatch (interpolation_matrix.m(),
442  0));
443  Assert (interpolation_matrix.n() == 0,
444  ExcDimensionMismatch (interpolation_matrix.n(),
445  0));
446 }
447 
448 
449 
450 template <int dim, int spacedim>
451 void
454  const unsigned int ,
455  FullMatrix<double> &interpolation_matrix) const
456 {
457  // this is only implemented, if the source
458  // FE is also a DGPNonparametric element. in that case,
459  // both elements have no dofs on their
460  // faces and the face interpolation matrix
461  // is necessarily empty -- i.e. there isn't
462  // much we need to do here.
463  (void)interpolation_matrix;
464  typedef FiniteElement<dim,spacedim> FEE;
465  AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
466  ||
467  (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
468  typename FEE::
469  ExcInterpolationNotImplemented());
470 
471  Assert (interpolation_matrix.m() == 0,
472  ExcDimensionMismatch (interpolation_matrix.m(),
473  0));
474  Assert (interpolation_matrix.n() == 0,
475  ExcDimensionMismatch (interpolation_matrix.n(),
476  0));
477 }
478 
479 
480 
481 template <int dim, int spacedim>
482 bool
484 {
485  return true;
486 }
487 
488 
489 
490 template <int dim, int spacedim>
491 std::vector<std::pair<unsigned int, unsigned int> >
494 {
495  // there are no such constraints for DGPNonparametric
496  // elements at all
497  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
498  return
499  std::vector<std::pair<unsigned int, unsigned int> > ();
500  else
501  {
502  Assert (false, ExcNotImplemented());
503  return std::vector<std::pair<unsigned int, unsigned int> > ();
504  }
505 }
506 
507 
508 
509 template <int dim, int spacedim>
510 std::vector<std::pair<unsigned int, unsigned int> >
513 {
514  // there are no such constraints for DGPNonparametric
515  // elements at all
516  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
517  return
518  std::vector<std::pair<unsigned int, unsigned int> > ();
519  else
520  {
521  Assert (false, ExcNotImplemented());
522  return std::vector<std::pair<unsigned int, unsigned int> > ();
523  }
524 }
525 
526 
527 
528 template <int dim, int spacedim>
529 std::vector<std::pair<unsigned int, unsigned int> >
532 {
533  // there are no such constraints for DGPNonparametric
534  // elements at all
535  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
536  return
537  std::vector<std::pair<unsigned int, unsigned int> > ();
538  else
539  {
540  Assert (false, ExcNotImplemented());
541  return std::vector<std::pair<unsigned int, unsigned int> > ();
542  }
543 }
544 
545 
546 
547 template <int dim, int spacedim>
551 {
552  // check whether both are discontinuous
553  // elements, see the description of
554  // FiniteElementDomination::Domination
555  if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
556  return FiniteElementDomination::no_requirements;
557 
558  Assert (false, ExcNotImplemented());
559  return FiniteElementDomination::neither_element_dominates;
560 }
561 
562 
563 
564 template <int dim, int spacedim>
565 bool
567  const unsigned int) const
568 {
569  return true;
570 }
571 
572 
573 
574 template <int dim, int spacedim>
575 std::size_t
577 {
578  Assert (false, ExcNotImplemented ());
579  return 0;
580 }
581 
582 
583 
584 template <int dim, int spacedim>
585 unsigned int
587 {
588  return degree;
589 }
590 
591 
592 
593 // explicit instantiations
594 #include "fe_dgp_nonparametric.inst"
595 
596 
597 DEAL_II_NAMESPACE_CLOSE
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
Shape function values.
virtual FiniteElement< dim, spacedim >::InternalDataBase * get_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature, ::internal::FEValues::FiniteElementRelatedData< dim, spacedim > &output_data) const
size_type m() const
friend class FE_DGPNonparametric
virtual std::size_t memory_consumption() const
const PolynomialSpace< dim > polynomial_space
STL namespace.
Transformed quadrature points.
virtual bool hp_constraints_are_implemented() const
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
virtual FiniteElement< dim, spacedim > * clone() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
size_type n() const
unsigned int get_degree() const
std::vector< std::vector< FullMatrix< double > > > prolongation
Definition: fe.h:2120
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
#define Assert(cond, exc)
Definition: exceptions.h:294
UpdateFlags
Abstract base class for mapping classes.
Definition: dof_tools.h:52
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
virtual std::string get_name() const =0
Second derivatives of shape functions.
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:158
const unsigned int dofs_per_cell
Definition: fe_base.h:283
Shape function gradients.
virtual Tensor< 2, dim > shape_grad_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
virtual Tensor< 1, dim > shape_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
const unsigned int degree
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
UpdateFlags update_each
Definition: fe.h:644
virtual std::string get_name() const