Reference documentation for deal.II version 8.4.2
dof_accessor_get.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2015 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 #include <deal.II/lac/vector.h>
17 #include <deal.II/lac/block_vector.h>
18 #include <deal.II/lac/parallel_vector.h>
19 #include <deal.II/lac/parallel_block_vector.h>
20 #include <deal.II/lac/petsc_vector.h>
21 #include <deal.II/lac/petsc_block_vector.h>
22 #include <deal.II/lac/trilinos_vector.h>
23 #include <deal.II/lac/trilinos_block_vector.h>
24 #include <deal.II/lac/sparse_matrix.h>
25 
26 #include <deal.II/dofs/dof_accessor.h>
27 #include <deal.II/dofs/dof_handler.h>
28 #include <deal.II/dofs/dof_levels.h>
29 #include <deal.II/hp/dof_handler.h>
30 #include <deal.II/grid/tria_boundary.h>
31 #include <deal.II/grid/tria_iterator.h>
32 #include <deal.II/grid/tria_iterator.templates.h>
33 #include <deal.II/fe/fe.h>
34 
35 #include <vector>
36 
37 DEAL_II_NAMESPACE_OPEN
38 
39 
40 template <typename DoFHandlerType, bool lda>
41 template <class InputVector, typename number>
42 void
44 get_interpolated_dof_values (const InputVector &values,
45  Vector<number> &interpolated_values,
46  const unsigned int fe_index) const
47 {
48  if (!this->has_children())
49  // if this cell has no children: simply return the exact values on this
50  // cell unless the finite element we need to interpolate to is different than
51  // the one we have on the current cell
52  {
54  (this->dof_handler)
55  != 0)
56  ||
57  // for hp-DoFHandlers, we need to require that on
58  // active cells, you either don't specify an fe_index,
59  // or that you specify the correct one
60  (fe_index == this->active_fe_index())
61  ||
62  (fe_index == DoFHandlerType::default_fe_index))
63  this->get_dof_values (values, interpolated_values);
64  else
65  {
66  // well, here we need to first get the values from the current
67  // cell and then interpolate it to the element requested. this
68  // can clearly only happen for hp::DoFHandler objects
69  Vector<number> tmp (this->get_fe().dofs_per_cell);
70  this->get_dof_values (values, tmp);
71 
72  FullMatrix<double> interpolation (this->dof_handler->get_fe()[fe_index].dofs_per_cell,
73  this->get_fe().dofs_per_cell);
74  this->dof_handler->get_fe()[fe_index].get_interpolation_matrix (this->get_fe(),
75  interpolation);
76  interpolation.vmult (interpolated_values, tmp);
77  }
78  }
79  else
80  // otherwise obtain them from the children
81  {
82  // we are on a non-active cell. these do not have any finite
83  // element associated with them in the hp context (in the non-hp
84  // context, we can simply assume that the FE space to which we
85  // want to interpolate is the same as for all elements in the
86  // mesh). consequently, we cannot interpolate from children's FE
87  // space to this cell's (unknown) FE space unless an explicit
88  // fe_index is given
90  (this->dof_handler)
91  != 0)
92  ||
93  (fe_index != DoFHandlerType::default_fe_index),
94  ExcMessage ("You cannot call this function on non-active cells "
95  "of hp::DoFHandler objects unless you provide an explicit "
96  "finite element index because they do not have naturally "
97  "associated finite element spaces associated: degrees "
98  "of freedom are only distributed on active cells for which "
99  "the active_fe_index has been set."));
100 
101  const FiniteElement<dim,spacedim> &fe = this->get_dof_handler().get_fe()[fe_index];
102  const unsigned int dofs_per_cell = fe.dofs_per_cell;
103 
104  Assert (this->dof_handler != 0,
105  typename BaseClass::ExcInvalidObject());
106  Assert (interpolated_values.size() == dofs_per_cell,
107  typename BaseClass::ExcVectorDoesNotMatch());
108  Assert (values.size() == this->dof_handler->n_dofs(),
109  typename BaseClass::ExcVectorDoesNotMatch());
110 
111 
112  // see if the finite element we have on the current cell has any
113  // degrees of freedom to begin with; if not (e.g., when
114  // interpolating FE_Nothing), then simply skip all of the
115  // following since the output vector would be of size zero
116  // anyway (and in fact is of size zero, see the assertion above)
117  if (fe.dofs_per_cell > 0)
118  {
119  Vector<number> tmp1(dofs_per_cell);
120  Vector<number> tmp2(dofs_per_cell);
121 
122  interpolated_values = 0;
123 
124  // later on we will have to push the values interpolated from the child
125  // to the mother cell into the output vector. unfortunately, there are
126  // two types of elements: ones where you add up the contributions from
127  // the different child cells, and ones where you overwrite.
128  //
129  // an example for the first is piecewise constant (and discontinuous)
130  // elements, where we build the value on the coarse cell by averaging
131  // the values from the cell (i.e. by adding up a fraction of the values
132  // of their values)
133  //
134  // an example for the latter are the usual continuous elements. the
135  // value on a vertex of a coarse cell must there be the same,
136  // irrespective of the adjacent cell we are presently on. so we always
137  // overwrite. in fact, we must, since we cannot know in advance how many
138  // neighbors there will be, so there is no way to compute the average
139  // with fixed factors
140  //
141  // so we have to find out to which type this element belongs. the
142  // difficulty is: the finite element may be a composed one, so we can
143  // only hope to do this for each shape function individually. in fact,
144  // there are even weird finite elements (for example the Raviart-Thomas
145  // element) which have shape functions that are additive (interior ones)
146  // and others that are overwriting (face degrees of freedom that need to
147  // be continuous across the face).
148  for (unsigned int child=0; child<this->n_children(); ++child)
149  {
150  // get the values from the present child, if necessary by
151  // interpolation itself either from its own children or
152  // by interpolating from the finite element on an active
153  // child to the finite element space requested here
154  this->child(child)->get_interpolated_dof_values (values,
155  tmp1,
156  fe_index);
157  // interpolate these to the mother cell
158  fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
159 
160  // and add up or set them in the output vector
161  for (unsigned int i=0; i<dofs_per_cell; ++i)
162  if (fe.restriction_is_additive(i))
163  interpolated_values(i) += tmp2(i);
164  else if (tmp2(i) != number())
165  interpolated_values(i) = tmp2(i);
166  }
167  }
168  }
169 }
170 
171 
172 // --------------------------------------------------------------------------
173 // explicit instantiations
174 #include "dof_accessor_get.inst"
175 
176 DEAL_II_NAMESPACE_CLOSE
bool restriction_is_additive(const unsigned int index) const
Definition: fe.h:2903
::ExceptionBase & ExcMessage(std::string arg1)
void get_interpolated_dof_values(const InputVector &values, Vector< number > &interpolated_values, const unsigned int fe_index=DoFHandlerType::default_fe_index) const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
#define Assert(cond, exc)
Definition: exceptions.h:294
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
Definition: fe.cc:306
std::size_t size() const
const unsigned int dofs_per_cell
Definition: fe_base.h:283