]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Patch by Denis Davydov: Add Tensor extractors for FEValues objects.
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 2 Jul 2013 21:08:25 +0000 (21:08 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 2 Jul 2013 21:08:25 +0000 (21:08 +0000)
git-svn-id: https://svn.dealii.org/trunk@29921 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/changes.h
deal.II/include/deal.II/fe/fe_values.h
deal.II/include/deal.II/fe/fe_values_extractors.h
deal.II/source/fe/fe_values.cc
deal.II/source/fe/fe_values.inst.in

index 1049ce5462006d1f5d5c46fe614b73532d694973..e2b2a59a3643fb705920accce4eb39765a8b64e3 100644 (file)
@@ -147,6 +147,14 @@ this function.
 
 <ol>
 
+<li> New: In addition to the FEValuesExtractors::Scalar,
+FEValuesExtractors::Vector, and FEValuesExtractors::SymmetricTensor classes,
+there are now also fully featured FEValuesExtractors::Tensor extractors
+for non-symmetric tensors of rank 2.
+<br>
+(Denis Davydov, 2013/07/02)
+</li>
+
 <li> New: There are now functions Tensor::component_to_unrolled_index()
 and Tensor::unrolled_to_component_indices() in the same way as they
 already exist for the SymmetricTensor class.
index 42498edbec04e8616d132f6b58c3405737a8e0c6..4da0529a08abf0bf02ab692b82ccc8089fa2ceca 100644 (file)
@@ -166,7 +166,7 @@ namespace FEValuesViews
      * gradient is a
      * <code>Tensor@<1,dim@></code>.
      */
-    typedef Tensor<1,spacedim> gradient_type;
+    typedef dealii::Tensor<1,spacedim> gradient_type;
 
     /**
      * A typedef for the type of second
@@ -176,7 +176,7 @@ namespace FEValuesViews
      * Hessian is a
      * <code>Tensor@<2,dim@></code>.
      */
-    typedef Tensor<2,spacedim> hessian_type;
+    typedef dealii::Tensor<2,spacedim> hessian_type;
 
     /**
      * A structure where for each shape
@@ -453,7 +453,7 @@ namespace FEValuesViews
      * of <code>dim</code> components, the
      * value type is a Tensor<1,spacedim>.
      */
-    typedef Tensor<1,spacedim>          value_type;
+    typedef dealii::Tensor<1,spacedim>          value_type;
 
     /**
      * A typedef for the type of gradients
@@ -463,7 +463,7 @@ namespace FEValuesViews
      * finite element, the gradient is a
      * <code>Tensor@<2,spacedim@></code>.
      */
-    typedef Tensor<2,spacedim>          gradient_type;
+    typedef dealii::Tensor<2,spacedim>          gradient_type;
 
     /**
      * A typedef for the type of
@@ -512,7 +512,7 @@ namespace FEValuesViews
      * finite element, the Hessian is a
      * <code>Tensor@<3,dim@></code>.
      */
-    typedef Tensor<3,spacedim>          hessian_type;
+    typedef dealii::Tensor<3,spacedim>          hessian_type;
 
     /**
      * A structure where for each shape
@@ -985,7 +985,7 @@ namespace FEValuesViews
      * definition of the
      * divergence.
      */
-    typedef Tensor<1, spacedim> divergence_type;
+    typedef dealii::Tensor<1, spacedim> divergence_type;
 
     /**
      * A structure where for each shape
@@ -1198,6 +1198,270 @@ namespace FEValuesViews
      */
     std::vector<ShapeFunctionData> shape_function_data;
   };
+
+
+  template <int rank, int dim, int spacedim = dim>
+  class Tensor;
+
+  /**
+   * A class representing a view to a set of
+   * <code>dim*dim</code> components forming a
+   * second-order tensor from a
+   * vector-valued finite
+   * element. Views are discussed in the
+   * @ref vector_valued module.
+   *
+   * This class allows to query the
+   * value and divergence of
+   * (components of) shape functions
+   * and solutions representing
+   * tensors. The
+   * divergence of a tensor
+   * $T_{ij}, 0\le i,j<\text{dim}$ is
+   * defined as
+   * $d_i = \sum_j \frac{\partial T_{ji}}{\partial x_j},
+   * 0\le i<\text{dim}$.
+   *
+   * You get an object of this type if you
+   * apply a
+   * FEValuesExtractors::Tensor to
+   * an FEValues, FEFaceValues or
+   * FESubfaceValues object.
+   *
+   * @ingroup feaccess vector_valued
+   *
+   * @author Denis Davydov, 2013
+   */
+  template <int dim, int spacedim>
+  class Tensor<2,dim,spacedim>
+  {
+  public:
+
+    /**
+     * Data type for what you get when you apply an extractor
+     * of this kind to a vector-valued finite element.
+     */
+    typedef dealii::Tensor<2, spacedim> value_type;
+
+    /**
+     * Data type for taking the divergence of a tensor: a vector.
+     */
+    typedef dealii::Tensor<1, spacedim> divergence_type;
+
+      /**
+       * A structure where for each shape
+       * function we pre-compute a bunch of
+       * data that will make later accesses
+       * much cheaper.
+       */
+      struct ShapeFunctionData
+      {
+      /**
+       * For each pair (shape
+       * function,component within
+       * vector), store whether the
+       * selected vector component may be
+       * nonzero. For primitive shape
+       * functions we know for sure
+       * whether a certain scalar
+       * component of a given shape
+       * function is nonzero, whereas for
+       * non-primitive shape functions
+       * this may not be entirely clear
+       * (e.g. for RT elements it depends
+       * on the shape of a cell).
+       */
+        bool is_nonzero_shape_function_component[value_type::n_independent_components];
+
+      /**
+       * For each pair (shape function,
+       * component within vector), store
+       * the row index within the
+       * shape_values, shape_gradients,
+       * and shape_hessians tables (the
+       * column index is the quadrature
+       * point index). If the shape
+       * function is primitive, then we
+       * can get this information from
+       * the shape_function_to_row_table
+       * of the FEValues object;
+       * otherwise, we have to work a bit
+       * harder to compute this
+       * information.
+       */
+        unsigned int row_index[value_type::n_independent_components];
+
+      /**
+       * For each shape function say the
+       * following: if only a single
+       * entry in
+       * is_nonzero_shape_function_component
+       * for this shape function is
+       * nonzero, then store the
+       * corresponding value of row_index
+       * and
+       * single_nonzero_component_index
+       * represents the index between 0
+       * and (dim^2) for which it is
+       * attained. If multiple components
+       * are nonzero, then store -1. If
+       * no components are nonzero then
+       * store -2.
+       */
+        int single_nonzero_component;
+        unsigned int single_nonzero_component_index;
+      };
+
+    /**
+     * Default constructor. Creates an
+     * invalid object.
+     */
+      Tensor();
+
+
+    /**
+     * Constructor for an object that
+     * represents <code>(dim*dim)</code>
+     * components of a
+     * FEValuesBase object (or of one of
+     * the classes derived from
+     * FEValuesBase), representing the unique
+     * components comprising a second-order
+     * tensor valued variable.
+     *
+     * The second argument denotes the
+     * index of the first component of the
+     * selected symmetric second order tensor.
+     */
+      Tensor(const FEValuesBase<dim, spacedim> &fe_values_base,
+            const unsigned int first_tensor_component);
+
+
+    /**
+     * Copy operator. This is not a
+     * lightweight object so we don't allow
+     * copying and generate an exception if
+     * this function is called.
+     */
+      Tensor &operator=(const Tensor<2, dim, spacedim> &);
+
+    /**
+     * Return the value of the vector
+     * components selected by this view,
+     * for the shape function and
+     * quadrature point selected by the
+     * arguments. Here, since the view
+     * represents a vector-valued part of
+     * the FEValues object with
+     * <code>(dim*dim)</code> components
+     * (the unique components of a second-order tensor),
+     * the return type is a tensor of rank 2.
+     *
+     * @param shape_function Number
+     * of the shape function to be
+     * evaluated. Note that this
+     * number runs from zero to
+     * dofs_per_cell, even in the
+     * case of an FEFaceValues or
+     * FESubfaceValues object.
+     *
+     * @param q_point Number of
+     * the quadrature point at which
+     * function is to be evaluated
+     */
+      value_type
+      value (const unsigned int shape_function,
+             const unsigned int q_point) const;
+
+    /**
+     * Return the vector divergence of
+     * the vector components selected by
+     * this view, for the shape function
+     * and quadrature point selected by the
+     * arguments.
+     *
+     * See the general discussion
+     * of this class for a
+     * definition of the
+     * divergence.
+     *
+     * @note The meaning of the arguments
+     * is as documented for the value()
+     * function.
+     */
+      divergence_type
+      divergence (const unsigned int shape_function,
+                  const unsigned int q_point) const;
+
+    /**
+     * Return the values of the selected
+     * vector components of the finite
+     * element function characterized by
+     * <tt>fe_function</tt> at the
+     * quadrature points of the cell, face
+     * or subface selected the last time
+     * the <tt>reinit</tt> function of the
+     * FEValues object was called.
+     *
+     * This function is the equivalent of
+     * the
+     * FEValuesBase::get_function_values
+     * function but it only works on the
+     * selected vector components.
+     */
+      template <class InputVector>
+      void get_function_values (const InputVector &fe_function,
+                                std::vector<value_type> &values) const;
+
+
+    /**
+     * Return the divergence of the selected
+     * vector components of the finite
+     * element function characterized by
+     * <tt>fe_function</tt> at the
+     * quadrature points of the cell, face
+     * or subface selected the last time
+     * the <tt>reinit</tt> function of the
+     * FEValues object was called.
+     *
+     * There is no equivalent function such
+     * as
+     * FEValuesBase::get_function_divergences
+     * in the FEValues classes but the
+     * information can be obtained from
+     * FEValuesBase::get_function_gradients,
+     * of course.
+     *
+     * See the general discussion
+     * of this class for a
+     * definition of the
+     * divergence.
+     */
+      template <class InputVector>
+      void get_function_divergences (const InputVector &fe_function,
+                                     std::vector<divergence_type> &divergences) const;
+
+    private:
+      /**
+       * A reference to the FEValuesBase object
+       * we operate on.
+       */
+      const FEValuesBase<dim, spacedim> &fe_values;
+
+      /**
+       * The first component of the vector
+       * this view represents of the
+       * FEValuesBase object.
+       */
+      const unsigned int first_tensor_component;
+
+      /**
+       * Store the data about shape
+       * functions.
+       */
+      std::vector<ShapeFunctionData> shape_function_data;
+    };
+
 }
 
 
@@ -1229,6 +1493,8 @@ namespace internal
       std::vector<dealii::FEValuesViews::Vector<dim,spacedim> > vectors;
       std::vector<dealii::FEValuesViews::SymmetricTensor<2,dim,spacedim> >
       symmetric_second_order_tensors;
+      std::vector<dealii::FEValuesViews::Tensor<2,dim,spacedim> >
+      second_order_tensors;
 
       /**
        * Constructor.
@@ -2832,6 +3098,21 @@ public:
   const FEValuesViews::SymmetricTensor<2,dim,spacedim> &
   operator[] (const FEValuesExtractors::SymmetricTensor<2> &tensor) const;
 
+
+  /**
+   * Create a view of the current FEValues
+   * object that represents a set of
+   * <code>(dim*dim)</code> scalar components
+   * (i.e. a 2nd order tensor)
+   * of the vector-valued
+   * finite element. The concept of views
+   * is explained in the documentation of
+   * the namespace FEValuesViews and in particular
+   * in the @ref vector_valued module.
+   */
+  const FEValuesViews::Tensor<2,dim,spacedim> &
+  operator[] (const FEValuesExtractors::Tensor<2> &tensor) const;
+
   //@}
 
   /// @name Access to the raw data
@@ -3134,6 +3415,7 @@ private:
   template <int, int> friend class FEValuesViews::Scalar;
   template <int, int> friend class FEValuesViews::Vector;
   template <int, int, int> friend class FEValuesViews::SymmetricTensor;
+  template <int, int, int> friend class FEValuesViews::Tensor;
 };
 
 
@@ -4098,7 +4380,7 @@ namespace FEValuesViews
     inline
     dealii::SymmetricTensor<2,1>
     symmetrize_single_row (const unsigned int n,
-                           const Tensor<1,1> &t)
+                           const dealii::Tensor<1,1> &t)
     {
       Assert (n < 1, ExcIndexRange (n, 0, 1));
       (void)n; // removes -Wunused-parameter warning in optimized mode
@@ -4111,7 +4393,7 @@ namespace FEValuesViews
     inline
     dealii::SymmetricTensor<2,2>
     symmetrize_single_row (const unsigned int n,
-                           const Tensor<1,2> &t)
+                           const dealii::Tensor<1,2> &t)
     {
       switch (n)
         {
@@ -4137,7 +4419,7 @@ namespace FEValuesViews
     inline
     dealii::SymmetricTensor<2,3>
     symmetrize_single_row (const unsigned int n,
-                           const Tensor<1,3> &t)
+                           const dealii::Tensor<1,3> &t)
     {
       switch (n)
         {
@@ -4318,7 +4600,7 @@ namespace FEValuesViews
         // b_jj := \dfrac{\partial phi_{ii,jj}}{\partial x_jj}.
         // again, all other entries of 'b' are
         // zero
-        const Tensor<1, spacedim> phi_grad = fe_values.shape_gradients[snc][q_point];
+        const dealii::Tensor<1, spacedim> phi_grad = fe_values.shape_gradients[snc][q_point];
 
         divergence_type return_value;
         return_value[ii] = phi_grad[jj];
@@ -4388,6 +4670,21 @@ operator[] (const FEValuesExtractors::SymmetricTensor<2> &tensor) const
   return fe_values_views_cache.symmetric_second_order_tensors[tensor.first_tensor_component];
 }
 
+template <int dim, int spacedim>
+inline
+const FEValuesViews::Tensor<2,dim,spacedim> &
+FEValuesBase<dim,spacedim>::
+operator[] (const FEValuesExtractors::Tensor<2> &tensor) const
+{
+  Assert (tensor.first_tensor_component <
+          fe_values_views_cache.second_order_tensors.size(),
+          ExcIndexRange (tensor.first_tensor_component,
+                         0, fe_values_views_cache.second_order_tensors.size()));
+
+  return fe_values_views_cache.second_order_tensors[tensor.first_tensor_component];
+}
+
+
 
 
 template <int dim, int spacedim>
index 5d85836b08635eab48258ebe43fe5b185b7451d6..6aed40676cff8d6c25c8098a3664735379d2eb2e 100644 (file)
@@ -200,6 +200,61 @@ namespace FEValuesExtractors
      */
     SymmetricTensor (const unsigned int first_tensor_component);
   };
+
+
+  /**
+   * Extractor for a (possible non-)symmetric tensor of a
+   * rank specified by the template
+   * argument. For a second order
+   * tensor, this represents a collection of
+   * <code>(dim*dim)</code>
+   * components of a vector-valued
+   * element. The value of <code>dim</code>
+   * is defined by the FEValues object the
+   * extractor is applied to. The result of
+   * applying an object of this type to an
+   * FEValues, FEFaceValues or
+   * FESubfaceValues object is of type
+   * FEValuesViews::Tensor.
+   *
+   * The concept of
+   * extractors is defined in the
+   * documentation of the namespace
+   * FEValuesExtractors and in the @ref
+   * vector_valued module.
+   *
+   * @ingroup feaccess vector_valued
+   *
+   * @author Denis Davydov, 2013
+   */
+  template <int rank>
+  struct Tensor
+  {
+    /**
+     * The first component of the tensor
+     * view.
+     */
+    unsigned int first_tensor_component;
+
+    /**
+     * Default constructor. Initialize the
+     * object with an invalid component. This leads to
+     * an object that can not be used, but it allows
+     * objects of this kind to be put into arrays that
+     * require a default constructor upon resizing the
+     * array, and then later assigning a suitable
+     * object to each element of the array.
+     */
+    Tensor ();
+
+    /**
+     * Constructor. Take the first
+     * component of the selected tensor
+     * inside the FEValues object as
+     * argument.
+     */
+    Tensor (const unsigned int first_tensor_component);
+  };
 }
 
 
@@ -251,6 +306,22 @@ namespace FEValuesExtractors
     :
     first_tensor_component (first_tensor_component)
   {}
+
+
+  template <int rank>
+  inline
+  Tensor<rank>::Tensor ()
+    :
+    first_tensor_component(numbers::invalid_unsigned_int)
+  {}
+
+
+  template <int rank>
+  inline
+  Tensor<rank>::Tensor (const unsigned int first_tensor_component)
+    :
+    first_tensor_component (first_tensor_component)
+  {}
 }
 
 
index b482eba8436f73f5021baa07c52c331a325bf31a..7957a09afcc0154827ad8643fe0e745c12651c4a 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998-2012 by the deal.II authors
+//    Copyright (C) 1998-2013 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -342,6 +342,104 @@ namespace FEValuesViews
   }
 
 
+  template <int dim, int spacedim>
+  Tensor<2, dim, spacedim>::
+  Tensor(const FEValuesBase<dim, spacedim> &fe_values,
+                  const unsigned int first_tensor_component)
+    :
+    fe_values(fe_values),
+    first_tensor_component(first_tensor_component),
+    shape_function_data(fe_values.fe->dofs_per_cell)
+  {
+    Assert(first_tensor_component + dim*dim - 1
+           <
+           fe_values.fe->n_components(),
+           ExcIndexRange(first_tensor_component +
+                         dim*dim - 1,
+                         0,
+                         fe_values.fe->n_components()));
+//TODO: we'd like to use the fields with the same name as these
+// variables from FEValuesData, but they aren't initialized yet
+// at the time we get here, so re-create it all
+    const std::vector<unsigned int> shape_function_to_row_table
+      = make_shape_function_to_row_table (*fe_values.fe);
+
+    for (unsigned int d = 0; d < dim*dim; ++d)
+      {
+        const unsigned int component = first_tensor_component + d;
+
+        for (unsigned int i = 0; i < fe_values.fe->dofs_per_cell; ++i)
+          {
+            const bool is_primitive = (fe_values.fe->is_primitive() ||
+                                       fe_values.fe->is_primitive(i));
+
+            if (is_primitive == true)
+              shape_function_data[i].is_nonzero_shape_function_component[d]
+                = (component ==
+                   fe_values.fe->system_to_component_index(i).first);
+            else
+              shape_function_data[i].is_nonzero_shape_function_component[d]
+                = (fe_values.fe->get_nonzero_components(i)[component]
+                   == true);
+
+            if (shape_function_data[i].is_nonzero_shape_function_component[d]
+                == true)
+              shape_function_data[i].row_index[d]
+                = shape_function_to_row_table[i*fe_values.fe->n_components()+component];
+            else
+              shape_function_data[i].row_index[d]
+                = numbers::invalid_unsigned_int;
+          }
+      }
+
+    for (unsigned int i = 0; i < fe_values.fe->dofs_per_cell; ++i)
+      {
+        unsigned int n_nonzero_components = 0;
+        for (unsigned int d = 0; d < dim*dim; ++d)
+          if (shape_function_data[i].is_nonzero_shape_function_component[d]
+              == true)
+            ++n_nonzero_components;
+
+        if (n_nonzero_components == 0)
+          shape_function_data[i].single_nonzero_component = -2;
+        else if (n_nonzero_components > 1)
+          shape_function_data[i].single_nonzero_component = -1;
+        else
+          {
+            for (unsigned int d = 0; d < dim*dim; ++d)
+              if (shape_function_data[i].is_nonzero_shape_function_component[d]
+                  == true)
+                {
+                  shape_function_data[i].single_nonzero_component
+                    = shape_function_data[i].row_index[d];
+                  shape_function_data[i].single_nonzero_component_index
+                    = d;
+                  break;
+                }
+          }
+      }
+  }
+
+
+
+  template <int dim, int spacedim>
+  Tensor<2, dim, spacedim>::Tensor()
+    :
+    fe_values(*static_cast<dealii::FEValuesBase<dim, spacedim>*> (0)),
+    first_tensor_component(numbers::invalid_unsigned_int)
+  {}
+
+
+
+  template <int dim, int spacedim>
+  Tensor<2, dim, spacedim> &
+  Tensor<2, dim, spacedim>::operator=(const Tensor<2, dim, spacedim> &)
+  {
+    // we shouldn't be copying these objects
+    Assert(false, ExcInternalError());
+    return *this;
+  }
+
 
   namespace internal
   {
@@ -391,9 +489,9 @@ namespace FEValuesViews
     template <int order, int dim, int spacedim>
     void
     do_function_derivatives (const ::dealii::Vector<double> &dof_values,
-                             const std::vector<std::vector<Tensor<order,spacedim> > > &shape_derivatives,
+                             const std::vector<std::vector<dealii::Tensor<order,spacedim> > > &shape_derivatives,
                              const std::vector<typename Scalar<dim,spacedim>::ShapeFunctionData> &shape_function_data,
-                             std::vector<Tensor<order,spacedim> > &derivatives)
+                             std::vector<dealii::Tensor<order,spacedim> > &derivatives)
     {
       const unsigned int dofs_per_cell = dof_values.size();
       const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
@@ -401,7 +499,7 @@ namespace FEValuesViews
       AssertDimension (derivatives.size(), n_quadrature_points);
 
       std::fill (derivatives.begin(), derivatives.end(),
-                 Tensor<order,spacedim>());
+                 dealii::Tensor<order,spacedim>());
 
       for (unsigned int shape_function=0;
            shape_function<dofs_per_cell; ++shape_function)
@@ -411,7 +509,7 @@ namespace FEValuesViews
             if (value == 0.)
               continue;
 
-            const Tensor<order,spacedim> *shape_derivative_ptr =
+            const dealii::Tensor<order,spacedim> *shape_derivative_ptr =
               &shape_derivatives[shape_function_data[shape_function].row_index][0];
             for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
               derivatives[q_point] += value * *shape_derivative_ptr++;
@@ -423,7 +521,7 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_laplacians (const ::dealii::Vector<double> &dof_values,
-                            const std::vector<std::vector<Tensor<2,spacedim> > > &shape_hessians,
+                            const std::vector<std::vector<dealii::Tensor<2,spacedim> > > &shape_hessians,
                             const std::vector<typename Scalar<dim,spacedim>::ShapeFunctionData> &shape_function_data,
                             std::vector<double>           &laplacians)
     {
@@ -442,7 +540,7 @@ namespace FEValuesViews
             if (value == 0.)
               continue;
 
-            const Tensor<2,spacedim> *shape_hessian_ptr =
+            const dealii::Tensor<2,spacedim> *shape_hessian_ptr =
               &shape_hessians[shape_function_data[shape_function].row_index][0];
             for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
               laplacians[q_point] += value * trace(*shape_hessian_ptr++);
@@ -457,14 +555,14 @@ namespace FEValuesViews
     void do_function_values (const ::dealii::Vector<double> &dof_values,
                              const Table<2,double>          &shape_values,
                              const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
-                             std::vector<Tensor<1,spacedim> > &values)
+                             std::vector<dealii::Tensor<1,spacedim> > &values)
     {
       const unsigned int dofs_per_cell = dof_values.size();
       const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
                                                shape_values.n_cols() : values.size();
       AssertDimension (values.size(), n_quadrature_points);
 
-      std::fill (values.begin(), values.end(), Tensor<1,spacedim>());
+      std::fill (values.begin(), values.end(), dealii::Tensor<1,spacedim>());
 
       for (unsigned int shape_function=0;
            shape_function<dofs_per_cell; ++shape_function)
@@ -504,9 +602,9 @@ namespace FEValuesViews
     template <int order, int dim, int spacedim>
     void
     do_function_derivatives (const ::dealii::Vector<double> &dof_values,
-                             const std::vector<std::vector<Tensor<order,spacedim> > > &shape_derivatives,
+                             const std::vector<std::vector<dealii::Tensor<order,spacedim> > > &shape_derivatives,
                              const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
-                             std::vector<Tensor<order+1,spacedim> > &derivatives)
+                             std::vector<dealii::Tensor<order+1,spacedim> > &derivatives)
     {
       const unsigned int dofs_per_cell = dof_values.size();
       const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
@@ -514,7 +612,7 @@ namespace FEValuesViews
       AssertDimension (derivatives.size(), n_quadrature_points);
 
       std::fill (derivatives.begin(), derivatives.end(),
-                 Tensor<order+1,spacedim>());
+                 dealii::Tensor<order+1,spacedim>());
 
       for (unsigned int shape_function=0;
            shape_function<dofs_per_cell; ++shape_function)
@@ -533,7 +631,7 @@ namespace FEValuesViews
             {
               const unsigned int comp =
                 shape_function_data[shape_function].single_nonzero_component_index;
-              const Tensor<order,spacedim> *shape_derivative_ptr =
+              const dealii::Tensor<order,spacedim> *shape_derivative_ptr =
                 &shape_derivatives[snc][0];
               for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
                 derivatives[q_point][comp] += value * *shape_derivative_ptr++;
@@ -542,7 +640,7 @@ namespace FEValuesViews
             for (unsigned int d=0; d<spacedim; ++d)
               if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
                 {
-                  const Tensor<order,spacedim> *shape_derivative_ptr =
+                  const dealii::Tensor<order,spacedim> *shape_derivative_ptr =
                     &shape_derivatives[shape_function_data[shape_function].
                                        row_index[d]][0];
                   for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
@@ -556,7 +654,7 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_symmetric_gradients (const ::dealii::Vector<double> &dof_values,
-                                     const std::vector<std::vector<Tensor<1,spacedim> > > &shape_gradients,
+                                     const std::vector<std::vector<dealii::Tensor<1,spacedim> > > &shape_gradients,
                                      const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
                                      std::vector<dealii::SymmetricTensor<2,spacedim> > &symmetric_gradients)
     {
@@ -585,7 +683,7 @@ namespace FEValuesViews
             {
               const unsigned int comp =
                 shape_function_data[shape_function].single_nonzero_component_index;
-              const Tensor<1,spacedim> *shape_gradient_ptr =
+              const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                 &shape_gradients[snc][0];
               for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
                 symmetric_gradients[q_point] += value *
@@ -594,7 +692,7 @@ namespace FEValuesViews
           else
             for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
               {
-                Tensor<2,spacedim> grad;
+                dealii::Tensor<2,spacedim> grad;
                 for (unsigned int d=0; d<spacedim; ++d)
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
                     grad[d] = value *
@@ -609,7 +707,7 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_divergences (const ::dealii::Vector<double> &dof_values,
-                             const std::vector<std::vector<Tensor<1,spacedim> > > &shape_gradients,
+                             const std::vector<std::vector<dealii::Tensor<1,spacedim> > > &shape_gradients,
                              const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
                              std::vector<double> &divergences)
     {
@@ -637,7 +735,7 @@ namespace FEValuesViews
             {
               const unsigned int comp =
                 shape_function_data[shape_function].single_nonzero_component_index;
-              const Tensor<1,spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
+              const dealii::Tensor<1,spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
               for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
                 divergences[q_point] += value * (*shape_gradient_ptr++)[comp];
             }
@@ -645,7 +743,7 @@ namespace FEValuesViews
             for (unsigned int d=0; d<spacedim; ++d)
               if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
                 {
-                  const Tensor<1,spacedim> *shape_gradient_ptr =
+                  const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                     &shape_gradients[shape_function_data[shape_function].
                                      row_index[d]][0];
                   for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
@@ -659,7 +757,7 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_curls (const ::dealii::Vector<double> &dof_values,
-                       const std::vector<std::vector<Tensor<1,spacedim> > > &shape_gradients,
+                       const std::vector<std::vector<dealii::Tensor<1,spacedim> > > &shape_gradients,
                        const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
                        std::vector<typename dealii::internal::CurlType<spacedim>::type> &curls)
     {
@@ -696,7 +794,7 @@ namespace FEValuesViews
 
               if (snc != -1)
                 {
-                  const Tensor<1, spacedim> *shape_gradient_ptr =
+                  const dealii::Tensor<1, spacedim> *shape_gradient_ptr =
                     &shape_gradients[snc][0];
 
                   switch (shape_function_data[shape_function].single_nonzero_component_index)
@@ -720,7 +818,7 @@ namespace FEValuesViews
                 {
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
                     {
-                      const Tensor<1,spacedim> *shape_gradient_ptr =
+                      const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                         &shape_gradients[shape_function_data[shape_function].row_index[0]][0];
 
                       for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
@@ -729,7 +827,7 @@ namespace FEValuesViews
 
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
                     {
-                      const Tensor<1,spacedim> *shape_gradient_ptr =
+                      const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                         &shape_gradients[shape_function_data[shape_function].row_index[1]][0];
 
                       for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
@@ -758,7 +856,7 @@ namespace FEValuesViews
 
               if (snc != -1)
                 {
-                  const Tensor<1, spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
+                  const dealii::Tensor<1, spacedim> *shape_gradient_ptr = &shape_gradients[snc][0];
 
                   switch (shape_function_data[shape_function].single_nonzero_component_index)
                     {
@@ -800,7 +898,7 @@ namespace FEValuesViews
                 {
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
                     {
-                      const Tensor<1,spacedim> *shape_gradient_ptr =
+                      const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                         &shape_gradients[shape_function_data[shape_function].row_index[0]][0];
 
                       for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
@@ -812,7 +910,7 @@ namespace FEValuesViews
 
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
                     {
-                      const Tensor<1,spacedim> *shape_gradient_ptr =
+                      const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                         &shape_gradients[shape_function_data[shape_function].row_index[1]][0];
 
                       for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
@@ -824,7 +922,7 @@ namespace FEValuesViews
 
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[2])
                     {
-                      const Tensor<1,spacedim> *shape_gradient_ptr =
+                      const dealii::Tensor<1,spacedim> *shape_gradient_ptr =
                         &shape_gradients[shape_function_data[shape_function].row_index[2]][0];
 
                       for (unsigned int q_point = 0; q_point < n_quadrature_points; ++q_point)
@@ -844,16 +942,17 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_laplacians (const ::dealii::Vector<double> &dof_values,
-                            const std::vector<std::vector<Tensor<2,spacedim> > > &shape_hessians,
+                            const std::vector<std::vector<dealii::Tensor<2,spacedim> > > &shape_hessians,
                             const std::vector<typename Vector<dim,spacedim>::ShapeFunctionData> &shape_function_data,
-                            std::vector<Tensor<1,spacedim> > &laplacians)
+                            std::vector<dealii::Tensor<1,spacedim> > &laplacians)
     {
       const unsigned int dofs_per_cell = dof_values.size();
       const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
                                                shape_hessians[0].size() : laplacians.size();
       AssertDimension (laplacians.size(), n_quadrature_points);
 
-      std::fill (laplacians.begin(), laplacians.end(), Tensor<1,spacedim>());
+      std::fill (laplacians.begin(), laplacians.end(),
+                dealii::Tensor<1,spacedim>());
 
       for (unsigned int shape_function=0;
            shape_function<dofs_per_cell; ++shape_function)
@@ -873,7 +972,7 @@ namespace FEValuesViews
               {
                 const unsigned int comp =
                   shape_function_data[shape_function].single_nonzero_component_index;
-                const Tensor<2,spacedim> *shape_hessian_ptr =
+                const dealii::Tensor<2,spacedim> *shape_hessian_ptr =
                   &shape_hessians[snc][0];
                 for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
                   laplacians[q_point][comp] += value * trace(*shape_hessian_ptr++);
@@ -882,7 +981,7 @@ namespace FEValuesViews
               for (unsigned int d=0; d<spacedim; ++d)
                 if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
                   {
-                    const Tensor<2,spacedim> *shape_hessian_ptr =
+                    const dealii::Tensor<2,spacedim> *shape_hessian_ptr =
                       &shape_hessians[shape_function_data[shape_function].
                                       row_index[d]][0];
                     for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
@@ -952,16 +1051,17 @@ namespace FEValuesViews
     template <int dim, int spacedim>
     void
     do_function_divergences (const ::dealii::Vector<double> &dof_values,
-                             const std::vector<std::vector<Tensor<1,spacedim> > > &shape_gradients,
+                             const std::vector<std::vector<dealii::Tensor<1,spacedim> > > &shape_gradients,
                              const std::vector<typename SymmetricTensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
-                             std::vector<Tensor<1,spacedim> > &divergences)
+                             std::vector<dealii::Tensor<1,spacedim> > &divergences)
     {
       const unsigned int dofs_per_cell = dof_values.size();
       const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
                                                shape_gradients[0].size() : divergences.size();
       AssertDimension (divergences.size(), n_quadrature_points);
 
-      std::fill (divergences.begin(), divergences.end(), Tensor<1,spacedim>());
+      std::fill (divergences.begin(), divergences.end(),
+                dealii::Tensor<1,spacedim>());
 
       for (unsigned int shape_function=0;
            shape_function<dofs_per_cell; ++shape_function)
@@ -981,7 +1081,7 @@ namespace FEValuesViews
               const unsigned int comp =
                 shape_function_data[shape_function].single_nonzero_component_index;
 
-              const Tensor < 1, spacedim> *shape_gradient_ptr =
+              const dealii::Tensor < 1, spacedim> *shape_gradient_ptr =
                 &shape_gradients[snc][0];
 
               const unsigned int ii = dealii::SymmetricTensor<2,spacedim>::
@@ -1017,7 +1117,7 @@ namespace FEValuesViews
                     const unsigned int comp =
                       shape_function_data[shape_function].single_nonzero_component_index;
 
-                    const Tensor < 1, spacedim> *shape_gradient_ptr =
+                    const dealii::Tensor < 1, spacedim> *shape_gradient_ptr =
                       &shape_gradients[shape_function_data[shape_function].
                                        row_index[d]][0];
                     for (unsigned int q_point = 0; q_point < n_quadrature_points;
@@ -1034,6 +1134,129 @@ namespace FEValuesViews
         }
     }
 
+    // ---------------------- non-symmetric tensor part ------------------------
+
+        template <int dim, int spacedim>
+        void
+        do_function_values (const ::dealii::Vector<double> &dof_values,
+                            const Table<2,double>          &shape_values,
+                            const std::vector<typename Tensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
+                            std::vector<dealii::Tensor<2,spacedim> > &values)
+        {
+          const unsigned int dofs_per_cell = dof_values.size();
+          const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
+                                                   shape_values.n_cols() : values.size();
+          AssertDimension (values.size(), n_quadrature_points);
+
+          std::fill (values.begin(), values.end(),
+                     dealii::Tensor<2,spacedim>());
+
+          for (unsigned int shape_function=0;
+               shape_function<dofs_per_cell; ++shape_function)
+            {
+              const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+              if (snc == -2)
+                // shape function is zero for the selected components
+                continue;
+
+              const double value = dof_values(shape_function);
+              if (value == 0.)
+                continue;
+
+              if (snc != -1)
+                {
+                  const unsigned int comp =
+                    shape_function_data[shape_function].single_nonzero_component_index;
+
+                  const TableIndices<2> indices = dealii::Tensor<2,spacedim>::unrolled_to_component_indices(comp);
+                  const unsigned int i = indices[0],
+                                     j = indices[1];
+
+                  const double *shape_value_ptr = &shape_values(snc,0);
+                  for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
+                    values[q_point][i][j] += value * *shape_value_ptr++;
+                }
+              else
+                for (unsigned int d=0;
+                     d<dim*dim; ++d)
+                  if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+                    {
+                      const TableIndices<2> indices = dealii::Tensor<2,spacedim>::unrolled_to_component_indices(d);
+                      const unsigned int i = indices[0],
+                                         j = indices[1];
+
+                      const double *shape_value_ptr =
+                        &shape_values(shape_function_data[shape_function].row_index[d],0);
+                      for (unsigned int q_point=0; q_point<n_quadrature_points; ++q_point)
+                        values[q_point][i][j] += value * *shape_value_ptr++;
+                    }
+            }
+        }
+
+
+
+        template <int dim, int spacedim>
+        void
+        do_function_divergences (const ::dealii::Vector<double> &dof_values,
+                                 const std::vector<std::vector<dealii::Tensor<1,spacedim> > > &shape_gradients,
+                                 const std::vector<typename Tensor<2,dim,spacedim>::ShapeFunctionData> &shape_function_data,
+                                 std::vector<dealii::Tensor<1,spacedim> > &divergences)
+        {
+          const unsigned int dofs_per_cell = dof_values.size();
+          const unsigned int n_quadrature_points = dofs_per_cell > 0 ?
+                                                   shape_gradients[0].size() : divergences.size();
+          AssertDimension (divergences.size(), n_quadrature_points);
+
+          std::fill (divergences.begin(), divergences.end(),
+                    dealii::Tensor<1,spacedim>());
+
+          for (unsigned int shape_function=0;
+               shape_function<dofs_per_cell; ++shape_function)
+            {
+              const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+              if (snc == -2)
+                // shape function is zero for the selected components
+                continue;
+
+              const double value = dof_values(shape_function);
+              if (value == 0.)
+                continue;
+
+              if (snc != -1)
+                {
+                  const unsigned int comp =
+                    shape_function_data[shape_function].single_nonzero_component_index;
+
+                  const dealii::Tensor < 1, spacedim> *shape_gradient_ptr =
+                    &shape_gradients[snc][0];
+
+                  const TableIndices<2> indices = dealii::Tensor<2,spacedim>::unrolled_to_component_indices(comp);
+                  const unsigned int ii = indices[0];
+                  const unsigned int jj = indices[1];
+
+                  for (unsigned int q_point = 0; q_point < n_quadrature_points;
+                       ++q_point, ++shape_gradient_ptr)
+                    {
+                      divergences[q_point][ii] += value * (*shape_gradient_ptr)[jj];
+
+                      if (ii != jj)
+                        divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
+                    }
+                }
+              else
+                {
+                  for (unsigned int d = 0;
+                       d < dim*dim; ++d)
+                    if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+                      {
+                        Assert (false, ExcNotImplemented());
+                      }
+                }
+            }
+        }
+
   } // end of namespace internal
 
 
@@ -1352,6 +1575,53 @@ namespace FEValuesViews
     internal::do_function_divergences<dim,spacedim>
     (dof_values, fe_values.shape_gradients, shape_function_data, divergences);
   }
+
+  template <int dim, int spacedim>
+  template <class InputVector>
+  void
+  Tensor<2, dim, spacedim>::
+  get_function_values(const InputVector &fe_function,
+                      std::vector<value_type> &values) const
+  {
+    typedef FEValuesBase<dim, spacedim> FVB;
+    Assert(fe_values.update_flags & update_values,
+           typename FVB::ExcAccessToUninitializedField());
+    Assert(fe_values.present_cell.get() != 0,
+           ExcMessage("FEValues object is not reinit'ed to any cell"));
+    AssertDimension(fe_function.size(),
+                    fe_values.present_cell->n_dofs_for_dof_handler());
+
+    // get function values of dofs on this cell
+    dealii::Vector<double> dof_values(fe_values.dofs_per_cell);
+    fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
+    internal::do_function_values<dim,spacedim>
+    (dof_values, fe_values.shape_values, shape_function_data, values);
+  }
+
+
+
+  template <int dim, int spacedim>
+  template <class InputVector>
+  void
+  Tensor<2, dim, spacedim>::
+  get_function_divergences(const InputVector &fe_function,
+                           std::vector<divergence_type> &divergences) const
+  {
+    typedef FEValuesBase<dim, spacedim> FVB;
+    Assert(fe_values.update_flags & update_gradients,
+           typename FVB::ExcAccessToUninitializedField());
+    Assert(fe_values.present_cell.get() != 0,
+           ExcMessage("FEValues object is not reinit'ed to any cell"));
+    AssertDimension(fe_function.size(),
+                    fe_values.present_cell->n_dofs_for_dof_handler());
+
+    // get function values of dofs
+    // on this cell
+    dealii::Vector<double> dof_values(fe_values.dofs_per_cell);
+    fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
+    internal::do_function_divergences<dim,spacedim>
+    (dof_values, fe_values.shape_gradients, shape_function_data, divergences);
+  }
 }
 
 
@@ -1431,6 +1701,28 @@ namespace internal
           dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim > (fe_values,
                                                                      component);
         }
+
+
+      // compute number of symmetric
+      // tensors in the same way as above
+      const unsigned int n_second_order_tensors
+        = (fe.n_components() >= dim*dim ?
+           fe.n_components() - dim*dim + 1 :
+           0);
+      second_order_tensors.resize(n_second_order_tensors);
+      for (unsigned int component = 0; component < n_second_order_tensors; ++component)
+        {
+#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
+          second_order_tensors[component]
+          .dealii::FEValuesViews::Tensor<2, dim, spacedim>::~Tensor();
+#else
+          typedef dealii::FEValuesViews::Tensor<2, dim, spacedim> TensorView;
+          second_order_tensors[component].TensorView::~TensorView();
+#endif
+          new (&second_order_tensors[component])
+          dealii::FEValuesViews::Tensor<2, dim, spacedim > (fe_values,
+                                                           component);
+        }
     }
   }
 }
index fb01f675dc7fc943a9bdb767431422c9107ca5a6..8298609ef166e1e7275dc5322ee2e7ca93473e55 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 by the deal.II authors
 //
 //    This file is subject to QPL and may not be  distributed
 //    without copyright and license information. Please refer
@@ -36,6 +36,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
       template class Scalar<deal_II_dimension, deal_II_space_dimension>;
       template class Vector<deal_II_dimension, deal_II_space_dimension>;
       template class SymmetricTensor<2, deal_II_dimension, deal_II_space_dimension>;
+      template class Tensor<2, deal_II_dimension, deal_II_space_dimension>;
       \}
 #endif
 #endif
@@ -70,11 +71,11 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
     template
       void FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>
       ::get_function_gradients<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<1,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> >&) const;
     template
       void FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>
       ::get_function_hessians<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<2,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<2,deal_II_space_dimension> >&) const;
     template
       void FEValuesViews::Scalar<deal_II_dimension, deal_II_space_dimension>
       ::get_function_laplacians<dealii::VEC>
@@ -83,11 +84,11 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
     template
       void FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>
       ::get_function_values<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<1,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> >&) const;
     template
       void FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>
       ::get_function_gradients<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<2,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<2,deal_II_space_dimension> >&) const;
     template
       void FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>
       ::get_function_symmetric_gradients<dealii::VEC>
@@ -103,11 +104,11 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
     template
       void FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>
       ::get_function_hessians<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<3,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<3,deal_II_space_dimension> >&) const;
     template
       void FEValuesViews::Vector<deal_II_dimension, deal_II_space_dimension>
       ::get_function_laplacians<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<1,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> >&) const;
 
     template
       void FEValuesViews::SymmetricTensor<2, deal_II_dimension, deal_II_space_dimension>
@@ -116,7 +117,16 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
     template
       void FEValuesViews::SymmetricTensor<2, deal_II_dimension, deal_II_space_dimension>
       ::get_function_divergences<dealii::VEC>
-      (const dealii::VEC&, std::vector<Tensor<1,deal_II_space_dimension> >&) const;
+      (const dealii::VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> >&) const;
+
+    template
+      void FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>
+      ::get_function_values<dealii::VEC>
+      (const dealii::VEC&, std::vector<dealii::Tensor<2,deal_II_space_dimension> >&) const;
+    template
+      void FEValuesViews::Tensor<2, deal_II_dimension, deal_II_space_dimension>
+      ::get_function_divergences<dealii::VEC>
+      (const dealii::VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> >&) const;
 #endif
 #endif
   }
@@ -168,35 +178,35 @@ for (VEC : SERIAL_VECTORS; deal_II_dimension : DIMENSIONS; deal_II_space_dimensi
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_gradients<VEC>
-      (const VEC&, std::vector<Tensor<1,deal_II_space_dimension> > &) const;
+      (const VEC&, std::vector<dealii::Tensor<1,deal_II_space_dimension> > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_gradients<VEC>
       (const VEC&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<1,deal_II_space_dimension> > &) const;
+       std::vector<dealii::Tensor<1,deal_II_space_dimension> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_gradients<VEC>
-      (const VEC&, std::vector<std::vector<Tensor<1,deal_II_space_dimension> > > &) const;
+      (const VEC&, std::vector<std::vector<dealii::Tensor<1,deal_II_space_dimension> > > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_gradients<VEC>
       (const VEC&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<1,deal_II_space_dimension> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<1,deal_II_space_dimension> > > >, bool) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_hessians<VEC>
-      (const VEC&, std::vector<Tensor<2,deal_II_space_dimension> > &) const;
+      (const VEC&, std::vector<dealii::Tensor<2,deal_II_space_dimension> > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_hessians<VEC>
       (const VEC&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<2,deal_II_space_dimension> > &) const;
+       std::vector<dealii::Tensor<2,deal_II_space_dimension> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_hessians<VEC>
-      (const VEC&, std::vector<std::vector<Tensor<2,deal_II_space_dimension> > > &, bool) const;
+      (const VEC&, std::vector<std::vector<dealii::Tensor<2,deal_II_space_dimension> > > &, bool) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_hessians<VEC>
       (const VEC&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<2,deal_II_space_dimension> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<2,deal_II_space_dimension> > > >, bool) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_space_dimension>::get_function_laplacians<VEC>
@@ -251,20 +261,20 @@ for (deal_II_dimension : DIMENSIONS)
        (const dealii::IndexSet&, std::vector<double>&) const;
     template
        void FEValuesViews::Scalar<deal_II_dimension>::get_function_gradients<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> >&) const;
     template
        void FEValuesViews::Scalar<deal_II_dimension>::get_function_hessians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<2,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension> >&) const;
     template
        void FEValuesViews::Scalar<deal_II_dimension>::get_function_laplacians<dealii::IndexSet>
        (const dealii::IndexSet&, std::vector<double>&) const;
 
     template
        void FEValuesViews::Vector<deal_II_dimension>::get_function_values<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension>::get_function_gradients<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<2,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension>::get_function_symmetric_gradients<dealii::IndexSet>
        (const dealii::IndexSet&, std::vector<dealii::SymmetricTensor<2,deal_II_dimension> >&) const;
@@ -276,17 +286,24 @@ for (deal_II_dimension : DIMENSIONS)
        (const dealii::IndexSet&, std::vector<double>&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension>::get_function_hessians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<3,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<3,deal_II_dimension> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension>::get_function_laplacians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> >&) const;
 
     template
        void FEValuesViews::SymmetricTensor<2,deal_II_dimension,deal_II_dimension>::get_function_values<dealii::IndexSet>
        (const dealii::IndexSet&, std::vector<dealii::SymmetricTensor<2,deal_II_dimension> >&) const;
     template
        void FEValuesViews::SymmetricTensor<2,deal_II_dimension,deal_II_dimension>::get_function_divergences<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> >&) const;
+
+       template
+       void FEValuesViews::Tensor<2,deal_II_dimension,deal_II_dimension>::get_function_values<dealii::IndexSet>
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension> >&) const;
+    template
+       void FEValuesViews::Tensor<2,deal_II_dimension,deal_II_dimension>::get_function_divergences<dealii::IndexSet>
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> >&) const;
 
 
 #if deal_II_dimension != 3
@@ -297,11 +314,11 @@ for (deal_II_dimension : DIMENSIONS)
     template
        void FEValuesViews::Scalar<deal_II_dimension, deal_II_dimension+1>
        ::get_function_gradients<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> >&) const;
     template
        void FEValuesViews::Scalar<deal_II_dimension, deal_II_dimension+1>
        ::get_function_hessians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<2,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension+1> >&) const;
     template
        void FEValuesViews::Scalar<deal_II_dimension, deal_II_dimension+1>
        ::get_function_laplacians<dealii::IndexSet>
@@ -310,11 +327,11 @@ for (deal_II_dimension : DIMENSIONS)
     template
        void FEValuesViews::Vector<deal_II_dimension, deal_II_dimension+1>
        ::get_function_values<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension, deal_II_dimension+1>
        ::get_function_gradients<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<2,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension+1> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension, deal_II_dimension+1>
        ::get_function_symmetric_gradients<dealii::IndexSet>
@@ -326,11 +343,11 @@ for (deal_II_dimension : DIMENSIONS)
     template
        void FEValuesViews::Vector<deal_II_dimension, deal_II_dimension+1>
        ::get_function_hessians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<3,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<3,deal_II_dimension+1> >&) const;
     template
        void FEValuesViews::Vector<deal_II_dimension, deal_II_dimension+1>
        ::get_function_laplacians<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> >&) const;
 
     template
        void FEValuesViews::SymmetricTensor<2, deal_II_dimension, deal_II_dimension+1>
@@ -339,7 +356,16 @@ for (deal_II_dimension : DIMENSIONS)
     template
        void FEValuesViews::SymmetricTensor<2, deal_II_dimension, deal_II_dimension+1>
         ::get_function_divergences<dealii::IndexSet>
-       (const dealii::IndexSet&, std::vector<Tensor<1,deal_II_dimension+1> >&) const;
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> >&) const;
+
+    template
+       void FEValuesViews::Tensor<2, deal_II_dimension, deal_II_dimension+1>
+        ::get_function_values<dealii::IndexSet>
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension+1> >&) const;
+    template
+       void FEValuesViews::Tensor<2, deal_II_dimension, deal_II_dimension+1>
+        ::get_function_divergences<dealii::IndexSet>
+       (const dealii::IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> >&) const;
 
 #endif
 #endif
@@ -392,35 +418,35 @@ for (deal_II_dimension : DIMENSIONS)
 
     template
       void FEValuesBase<deal_II_dimension>::get_function_gradients<IndexSet>
-      (const IndexSet&, std::vector<Tensor<1,deal_II_dimension> > &) const;
+      (const IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension> > &) const;
     template
       void FEValuesBase<deal_II_dimension>::get_function_gradients<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<1,deal_II_dimension> > &) const;
+       std::vector<dealii::Tensor<1,deal_II_dimension> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension>::get_function_gradients<IndexSet>
-      (const IndexSet&, std::vector<std::vector<Tensor<1,deal_II_dimension> > > &) const;
+      (const IndexSet&, std::vector<std::vector<dealii::Tensor<1,deal_II_dimension> > > &) const;
     template
       void FEValuesBase<deal_II_dimension>::get_function_gradients<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<1,deal_II_dimension> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<1,deal_II_dimension> > > >, bool) const;
 
     template
       void FEValuesBase<deal_II_dimension>::get_function_hessians<IndexSet>
-      (const IndexSet&, std::vector<Tensor<2,deal_II_dimension> > &) const;
+      (const IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension> > &) const;
     template
       void FEValuesBase<deal_II_dimension>::get_function_hessians<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<2,deal_II_dimension> > &) const;
+       std::vector<dealii::Tensor<2,deal_II_dimension> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension>::get_function_hessians<IndexSet>
-      (const IndexSet&, std::vector<std::vector<Tensor<2,deal_II_dimension> > > &, bool) const;
+      (const IndexSet&, std::vector<std::vector<dealii::Tensor<2,deal_II_dimension> > > &, bool) const;
     template
       void FEValuesBase<deal_II_dimension>::get_function_hessians<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<2,deal_II_dimension> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<2,deal_II_dimension> > > >, bool) const;
 
     template
        void FEValuesBase<deal_II_dimension>::get_function_laplacians<IndexSet>
@@ -503,35 +529,35 @@ for (deal_II_dimension : DIMENSIONS)
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<IndexSet>
-      (const IndexSet&, std::vector<Tensor<1,deal_II_dimension+1> > &) const;
+      (const IndexSet&, std::vector<dealii::Tensor<1,deal_II_dimension+1> > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<1,deal_II_dimension+1> > &) const;
+       std::vector<dealii::Tensor<1,deal_II_dimension+1> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<IndexSet>
-      (const IndexSet&, std::vector<std::vector<Tensor<1,deal_II_dimension+1> > > &) const;
+      (const IndexSet&, std::vector<std::vector<dealii::Tensor<1,deal_II_dimension+1> > > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_gradients<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<1,deal_II_dimension+1> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<1,deal_II_dimension+1> > > >, bool) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<IndexSet>
-      (const IndexSet&, std::vector<Tensor<2,deal_II_dimension+1> > &) const;
+      (const IndexSet&, std::vector<dealii::Tensor<2,deal_II_dimension+1> > &) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       std::vector<Tensor<2,deal_II_dimension+1> > &) const;
+       std::vector<dealii::Tensor<2,deal_II_dimension+1> > &) const;
 
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<IndexSet>
-      (const IndexSet&, std::vector<std::vector<Tensor<2,deal_II_dimension+1> > > &, bool) const;
+      (const IndexSet&, std::vector<std::vector<dealii::Tensor<2,deal_II_dimension+1> > > &, bool) const;
     template
       void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_hessians<IndexSet>
       (const IndexSet&, const VectorSlice<const std::vector<types::global_dof_index> >&,
-       VectorSlice<std::vector<std::vector<Tensor<2,deal_II_dimension+1> > > >, bool) const;
+       VectorSlice<std::vector<std::vector<dealii::Tensor<2,deal_II_dimension+1> > > >, bool) const;
 
     template
        void FEValuesBase<deal_II_dimension,deal_II_dimension+1>::get_function_laplacians<IndexSet>

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.