]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Use AlignedVector to manage Vector's memory.
authorDavid Wells <drwells@email.unc.edu>
Mon, 21 Jan 2019 03:32:32 +0000 (22:32 -0500)
committerDavid Wells <drwells@email.unc.edu>
Tue, 29 Jan 2019 14:04:31 +0000 (09:04 -0500)
Vector already requires that the underlying buffer be aligned and uses
exactly the same function (posix_memalign) as AlignedVector to do it: we
can simplify the implementation of Vector a lot by just using an
AlignedVector to manage the data instead.

include/deal.II/lac/vector.h
include/deal.II/lac/vector.templates.h
tests/serialization/vector.output

index d44d28ee3b27449f0adfcd2f3e2c3b721a00c96a..2dadf1da5e10b66d873a3d6e6ac85399af3ac110 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <deal.II/base/config.h>
 
+#include <deal.II/base/aligned_vector.h>
 #include <deal.II/base/exceptions.h>
 #include <deal.II/base/index_set.h>
 #include <deal.II/base/logstream.h>
 #include <deal.II/lac/vector_operation.h>
 #include <deal.II/lac/vector_type_traits.h>
 
-// boost::serialization::make_array used to be in array.hpp, but was
-// moved to a different file in BOOST 1.64
-#include <boost/version.hpp>
-#if BOOST_VERSION >= 106400
-#  include <boost/serialization/array_wrapper.hpp>
-#else
-#  include <boost/serialization/array.hpp>
-#endif
 #include <boost/serialization/split_member.hpp>
 
 #include <cstdio>
@@ -152,6 +145,8 @@ public:
    *
    * We would like to make this constructor explicit, but standard containers
    * insist on using it implicitly.
+   *
+   * @dealiiOperationIsMultithreaded
    */
   Vector(const Vector<Number> &v);
 
@@ -159,19 +154,13 @@ public:
    * Move constructor. Creates a new vector by stealing the internal data of
    * the vector @p v.
    */
-  Vector(Vector<Number> &&v) noexcept;
+  Vector(Vector<Number> &&v) noexcept = default;
 
   /**
    * Copy constructor taking a vector of another data type. This will fail if
    * there is no conversion path from @p OtherNumber to @p Number. Note that
    * you may lose accuracy when copying to a vector with data elements with
    * less accuracy.
-   *
-   * Older versions of gcc did not honor the @p explicit keyword on template
-   * constructors. In such cases, it is easy to accidentally write code that
-   * can be very inefficient, since the compiler starts performing hidden
-   * conversions. To avoid this, this function is disabled if we have detected
-   * a broken compiler during configuration.
    */
   template <typename OtherNumber>
   explicit Vector(const Vector<OtherNumber> &v);
@@ -365,7 +354,7 @@ public:
    * have after being newly default-constructed.
    */
   Vector<Number> &
-  operator=(Vector<Number> &&v) noexcept;
+  operator=(Vector<Number> &&v) noexcept = default;
 
   /**
    * Copy the given vector. Resize the present vector if necessary.
@@ -993,27 +982,9 @@ public:
 
 private:
   /**
-   * Dimension. Actual number of components contained in the vector. Get this
-   * number by calling <tt>size()</tt>.
-   */
-  size_type vec_size;
-
-  /**
-   * Amount of memory actually reserved for this vector. This number may be
-   * greater than @p vec_size if a @p reinit was called with less memory
-   * requirements than the vector needed last time. At present @p reinit does
-   * not free memory when the number of needed elements is reduced.
-   */
-  size_type max_vec_size;
-
-  /**
-   * Pointer to the array of elements of this vector.
-   *
-   * Because we allocate these arrays via Utilities::System::posix_memalign,
-   * we need to use a custom deleter for this object that does not call
-   * <code>delete[]</code>, but instead calls @p free().
+   * Array of elements owned by this vector.
    */
-  std::unique_ptr<Number[], decltype(&free)> values;
+  AlignedVector<Number> values;
 
   /**
    * For parallel loops with TBB, this member variable stores the affinity
@@ -1022,25 +993,11 @@ private:
   mutable std::shared_ptr<parallel::internal::TBBPartitioner>
     thread_loop_partitioner;
 
-  /**
-   * Allocate and align @p values along 64-byte boundaries. The size of the
-   * allocated memory is determined by @p max_vec_size . Copy first
-   * @p copy_n_el from the old values.
-   */
-  void
-  allocate(const size_type copy_n_el = 0);
-
   /**
    * Make all other vector types friends.
    */
   template <typename Number2>
   friend class Vector;
-
-  /**
-   * LAPACK matrices need access to the data.
-   */
-  template <typename Number2>
-  friend class LAPACKFullMatrix;
 };
 
 /*@}*/
@@ -1060,9 +1017,6 @@ Vector<int>::lp_norm(const real_type) const;
 
 template <typename Number>
 inline Vector<Number>::Vector()
-  : vec_size(0)
-  , max_vec_size(0)
-  , values(nullptr, &free)
 {
   // virtual functions called in constructors and destructors never use the
   // override in a derived class
@@ -1075,9 +1029,6 @@ inline Vector<Number>::Vector()
 template <typename Number>
 template <typename InputIterator>
 Vector<Number>::Vector(const InputIterator first, const InputIterator last)
-  : vec_size(0)
-  , max_vec_size(0)
-  , values(nullptr, &free)
 {
   // allocate memory. do not initialize it, as we will copy over to it in a
   // second
@@ -1089,9 +1040,6 @@ Vector<Number>::Vector(const InputIterator first, const InputIterator last)
 
 template <typename Number>
 inline Vector<Number>::Vector(const size_type n)
-  : vec_size(0)
-  , max_vec_size(0)
-  , values(nullptr, &free)
 {
   // virtual functions called in constructors and destructors never use the
   // override in a derived class
@@ -1105,7 +1053,7 @@ template <typename Number>
 inline typename Vector<Number>::size_type
 Vector<Number>::size() const
 {
-  return vec_size;
+  return values.size();
 }
 
 
@@ -1122,7 +1070,7 @@ template <typename Number>
 inline typename Vector<Number>::pointer
 Vector<Number>::data()
 {
-  return values.get();
+  return values.data();
 }
 
 
@@ -1131,7 +1079,7 @@ template <typename Number>
 inline typename Vector<Number>::const_pointer
 Vector<Number>::data() const
 {
-  return values.get();
+  return values.data();
 }
 
 
@@ -1140,7 +1088,7 @@ template <typename Number>
 inline typename Vector<Number>::iterator
 Vector<Number>::begin()
 {
-  return values.get();
+  return values.begin();
 }
 
 
@@ -1149,7 +1097,7 @@ template <typename Number>
 inline typename Vector<Number>::const_iterator
 Vector<Number>::begin() const
 {
-  return values.get();
+  return values.begin();
 }
 
 
@@ -1158,7 +1106,7 @@ template <typename Number>
 inline typename Vector<Number>::iterator
 Vector<Number>::end()
 {
-  return values.get() + vec_size;
+  return values.end();
 }
 
 
@@ -1167,7 +1115,7 @@ template <typename Number>
 inline typename Vector<Number>::const_iterator
 Vector<Number>::end() const
 {
-  return values.get() + vec_size;
+  return values.end();
 }
 
 
@@ -1176,7 +1124,7 @@ template <typename Number>
 inline Number
 Vector<Number>::operator()(const size_type i) const
 {
-  Assert(i < vec_size, ExcIndexRange(i, 0, vec_size));
+  Assert(i < size(), ExcIndexRange(i, 0, size()));
   return values[i];
 }
 
@@ -1186,7 +1134,7 @@ template <typename Number>
 inline Number &
 Vector<Number>::operator()(const size_type i)
 {
-  Assert(i < vec_size, ExcIndexRangeType<size_type>(i, 0, vec_size));
+  Assert(i < size(), ExcIndexRangeType<size_type>(i, 0, size()));
   return values[i];
 }
 
@@ -1271,7 +1219,7 @@ Vector<Number>::add(const std::vector<size_type> &indices,
 {
   Assert(indices.size() == values.size(),
          ExcDimensionMismatch(indices.size(), values.size()));
-  add(indices.size(), indices.data(), values.values.get());
+  add(indices.size(), indices.data(), values.values.begin());
 }
 
 
@@ -1285,7 +1233,7 @@ Vector<Number>::add(const size_type    n_indices,
 {
   for (size_type i = 0; i < n_indices; ++i)
     {
-      Assert(indices[i] < vec_size, ExcIndexRange(indices[i], 0, vec_size));
+      Assert(indices[i] < size(), ExcIndexRange(indices[i], 0, size()));
       Assert(
         numbers::is_finite(values[i]),
         ExcMessage(
@@ -1327,8 +1275,6 @@ template <typename Number>
 inline void
 Vector<Number>::swap(Vector<Number> &v)
 {
-  std::swap(vec_size, v.vec_size);
-  std::swap(max_vec_size, v.max_vec_size);
   std::swap(values, v.values);
 }
 
@@ -1341,9 +1287,7 @@ Vector<Number>::save(Archive &ar, const unsigned int) const
 {
   // forward to serialization function in the base class.
   ar &static_cast<const Subscriptor &>(*this);
-
-  ar &vec_size &max_vec_size;
-  ar &          boost::serialization::make_array(values.get(), max_vec_size);
+  ar &values;
 }
 
 
@@ -1353,15 +1297,9 @@ template <class Archive>
 inline void
 Vector<Number>::load(Archive &ar, const unsigned int)
 {
-  // get rid of previous content
-  values.reset();
-
   // the load stuff again from the archive
   ar &static_cast<Subscriptor &>(*this);
-  ar &vec_size &max_vec_size;
-
-  allocate();
-  ar &boost::serialization::make_array(values.get(), max_vec_size);
+  ar &values;
 }
 
 #endif
index e67ffd71ae183f84c068a4b1ff7700d5061aecca..87c126c8b8b4a25cc1e1aad3c1b74ea73bcfea00 100644 (file)
@@ -46,15 +46,8 @@ DEAL_II_NAMESPACE_OPEN
 template <typename Number>
 Vector<Number>::Vector(const Vector<Number> &v)
   : Subscriptor()
-  , vec_size(v.size())
-  , max_vec_size(v.size())
-  , values(nullptr, &free)
 {
-  if (vec_size != 0)
-    {
-      allocate();
-      *this = v;
-    }
+  *this = v;
 }
 
 
@@ -73,34 +66,11 @@ Vector<Number>::apply_givens_rotation(const std::array<Number, 3> &csr,
 
 
 
-template <typename Number>
-Vector<Number>::Vector(Vector<Number> &&v) noexcept
-  : Subscriptor(std::move(v))
-  , vec_size(v.vec_size)
-  , max_vec_size(v.max_vec_size)
-  , values(std::move(v.values))
-  , thread_loop_partitioner(std::move(v.thread_loop_partitioner))
-{
-  v.vec_size     = 0;
-  v.max_vec_size = 0;
-  v.values       = nullptr;
-}
-
-
-
 template <typename Number>
 template <typename OtherNumber>
 Vector<Number>::Vector(const Vector<OtherNumber> &v)
-  : Subscriptor()
-  , vec_size(v.size())
-  , max_vec_size(v.size())
-  , values(nullptr, &free)
 {
-  if (vec_size != 0)
-    {
-      allocate();
-      *this = v;
-    }
+  *this = v;
 }
 
 
@@ -154,10 +124,6 @@ namespace internal
 
 template <typename Number>
 Vector<Number>::Vector(const PETScWrappers::VectorBase &v)
-  : Subscriptor()
-  , vec_size(0)
-  , max_vec_size(0)
-  , values(nullptr, &free)
 {
   if (v.size() != 0)
     {
@@ -171,15 +137,10 @@ Vector<Number>::Vector(const PETScWrappers::VectorBase &v)
 
 template <typename Number>
 Vector<Number>::Vector(const TrilinosWrappers::MPI::Vector &v)
-  : Subscriptor()
-  , vec_size(v.size())
-  , max_vec_size(v.size())
-  , values(nullptr, &free)
+  : values(v.size())
 {
-  if (vec_size != 0)
+  if (size() != 0)
     {
-      allocate();
-
       // Copy the distributed vector to
       // a local one at all processors
       // that know about the original vector.
@@ -188,12 +149,12 @@ Vector<Number>::Vector(const TrilinosWrappers::MPI::Vector &v)
       // this, but it has not yet been
       // found.
       TrilinosWrappers::MPI::Vector localized_vector;
-      localized_vector.reinit(complete_index_set(vec_size),
+      localized_vector.reinit(complete_index_set(size()),
                               v.get_mpi_communicator());
       localized_vector.reinit(v, false, true);
 
-      Assert(localized_vector.size() == vec_size,
-             ExcDimensionMismatch(localized_vector.size(), vec_size));
+      Assert(localized_vector.size() == size(),
+             ExcDimensionMismatch(localized_vector.size(), size()));
 
       // get a representation of the vector
       // and copy it
@@ -202,7 +163,7 @@ Vector<Number>::Vector(const TrilinosWrappers::MPI::Vector &v)
       int ierr = localized_vector.trilinos_vector().ExtractView(&start_ptr);
       AssertThrow(ierr == 0, ExcTrilinosError(ierr));
 
-      std::copy(start_ptr[0], start_ptr[0] + vec_size, begin());
+      std::copy(start_ptr[0], start_ptr[0] + size(), begin());
     }
 }
 
@@ -217,16 +178,16 @@ Vector<Number>::operator=(const Vector<Number> &v)
     return *this;
 
   thread_loop_partitioner = v.thread_loop_partitioner;
-  if (vec_size != v.vec_size)
+  if (size() != v.size())
     reinit(v, true);
 
-  if (vec_size > 0)
+  if (0 < size())
     {
       dealii::internal::VectorOperations::Vector_copy<Number, Number> copier(
-        v.values.get(), values.get());
+        v.begin(), begin());
       internal::VectorOperations::parallel_for(copier,
                                                0,
-                                               vec_size,
+                                               size(),
                                                thread_loop_partitioner);
     }
 
@@ -235,39 +196,20 @@ Vector<Number>::operator=(const Vector<Number> &v)
 
 
 
-template <typename Number>
-inline Vector<Number> &
-Vector<Number>::operator=(Vector<Number> &&v) noexcept
-{
-  Subscriptor::operator=(std::move(v));
-
-  vec_size                = v.vec_size;
-  max_vec_size            = v.max_vec_size;
-  values                  = std::move(v.values);
-  thread_loop_partitioner = std::move(v.thread_loop_partitioner);
-
-  v.vec_size     = 0;
-  v.max_vec_size = 0;
-
-  return *this;
-}
-
-
-
 template <typename Number>
 template <typename Number2>
 inline Vector<Number> &
 Vector<Number>::operator=(const Vector<Number2> &v)
 {
   thread_loop_partitioner = v.thread_loop_partitioner;
-  if (vec_size != v.vec_size)
+  if (size() != v.size())
     reinit(v, true);
 
   dealii::internal::VectorOperations::Vector_copy<Number, Number2> copier(
-    v.values.get(), values.get());
+    v.begin(), begin());
   internal::VectorOperations::parallel_for(copier,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 
   return *this;
@@ -279,35 +221,41 @@ template <typename Number>
 inline void
 Vector<Number>::reinit(const size_type n, const bool omit_zeroing_entries)
 {
-  if (n == 0)
+  const std::size_t old_size = size();
+
+  // avoid allocating if the new size is not larger than the old size
+  if (n <= size())
     {
-      values.reset();
-      max_vec_size = vec_size = 0;
       thread_loop_partitioner =
         std::make_shared<parallel::internal::TBBPartitioner>();
+      if (n == 0)
+        {
+          values.clear();
+        }
+      else if (n != size())
+        values.resize_fast(n);
+
+      if (!omit_zeroing_entries)
+        values.fill();
       return;
     }
 
-  if (n > max_vec_size)
-    {
-      max_vec_size = n;
-      allocate();
-    }
+  // otherwise size() < n and we must allocate
+  AlignedVector<Number> new_values;
+  new_values.resize_fast(n);
+  if (!omit_zeroing_entries)
+    new_values.fill();
+  new_values.swap(values);
 
-  if (vec_size != n)
+  if (old_size != size())
     {
-      vec_size = n;
-
       // only reset the partitioner if we actually expect a significant vector
       // size
-      if (vec_size >=
+      if (size() >=
           4 * internal::VectorImplementation::minimum_parallel_grain_size)
         thread_loop_partitioner =
           std::make_shared<parallel::internal::TBBPartitioner>();
     }
-
-  if (omit_zeroing_entries == false)
-    *this = Number();
 }
 
 
@@ -316,37 +264,26 @@ template <typename Number>
 inline void
 Vector<Number>::grow_or_shrink(const size_type n)
 {
+  const std::size_t old_size = size();
   if (n == 0)
     {
-      values.reset();
-      max_vec_size = vec_size = 0;
+      values.clear();
       thread_loop_partitioner =
         std::make_shared<parallel::internal::TBBPartitioner>();
       return;
     }
 
-  const size_type s = std::min(vec_size, n);
-  if (n > max_vec_size)
-    {
-      max_vec_size = n;
-      allocate(s);
-    }
+  values.resize(n);
 
-  if (vec_size != n)
+  if (old_size != n)
     {
-      vec_size = n;
-
       // only reset the partitioner if we actually expect a significant vector
       // size
-      if (vec_size >=
+      if (size() >=
           4 * internal::VectorImplementation::minimum_parallel_grain_size)
         thread_loop_partitioner =
           std::make_shared<parallel::internal::TBBPartitioner>();
     }
-
-  // pad with zeroes
-  for (size_type i = s; i < vec_size; ++i)
-    values[i] = Number();
 }
 
 
@@ -359,21 +296,7 @@ Vector<Number>::reinit(const Vector<Number2> &v,
 {
   thread_loop_partitioner = v.thread_loop_partitioner;
 
-  if (v.vec_size == 0)
-    {
-      values.reset();
-      max_vec_size = vec_size = 0;
-      return;
-    }
-
-  if (v.vec_size > max_vec_size)
-    {
-      max_vec_size = v.vec_size;
-      allocate();
-    }
-  vec_size = v.vec_size;
-  if (omit_zeroing_entries == false)
-    *this = Number();
+  reinit(v.size(), omit_zeroing_entries);
 }
 
 
@@ -382,9 +305,9 @@ template <typename Number>
 bool
 Vector<Number>::all_zero() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     if (values[i] != Number())
       return false;
   return true;
@@ -396,9 +319,9 @@ template <typename Number>
 bool
 Vector<Number>::is_non_negative() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     if (!internal::VectorOperations::is_non_negative(values[i]))
       return false;
 
@@ -413,14 +336,14 @@ Vector<Number>::operator=(const Number s)
 {
   AssertIsFinite(s);
   if (s != Number())
-    Assert(vec_size != 0, ExcEmptyObject());
+    Assert(size() != 0, ExcEmptyObject());
 
-  if (vec_size > 0)
+  if (size() > 0)
     {
-      internal::VectorOperations::Vector_set<Number> setter(s, values.get());
+      internal::VectorOperations::Vector_set<Number> setter(s, values.begin());
       internal::VectorOperations::parallel_for(setter,
                                                0,
-                                               vec_size,
+                                               size(),
                                                thread_loop_partitioner);
     }
 
@@ -435,14 +358,14 @@ Vector<Number>::operator*=(const Number factor)
 {
   AssertIsFinite(factor);
 
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   internal::VectorOperations::Vectorization_multiply_factor<Number>
-    vector_multiply(values.get(), factor);
+    vector_multiply(values.begin(), factor);
 
   internal::VectorOperations::parallel_for(vector_multiply,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 
   return *this;
@@ -456,14 +379,14 @@ Vector<Number>::add(const Number a, const Vector<Number> &v)
 {
   AssertIsFinite(a);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   internal::VectorOperations::Vectorization_add_av<Number> vector_add_av(
-    values.get(), v.values.get(), a);
+    values.begin(), v.values.begin(), a);
   internal::VectorOperations::parallel_for(vector_add_av,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -476,14 +399,14 @@ Vector<Number>::sadd(const Number x, const Number a, const Vector<Number> &v)
   AssertIsFinite(x);
   AssertIsFinite(a);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   internal::VectorOperations::Vectorization_sadd_xav<Number> vector_sadd_xav(
-    values.get(), v.values.get(), a, x);
+    values.begin(), v.values.begin(), a, x);
   internal::VectorOperations::parallel_for(vector_sadd_xav,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -493,18 +416,18 @@ template <typename Number>
 template <typename Number2>
 Number Vector<Number>::operator*(const Vector<Number2> &v) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   if (PointerComparison::equal(this, &v))
     return norm_sqr();
 
-  Assert(vec_size == v.size(), ExcDimensionMismatch(vec_size, v.size()));
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   Number                                           sum;
-  internal::VectorOperations::Dot<Number, Number2> dot(values.get(),
-                                                       v.values.get());
+  internal::VectorOperations::Dot<Number, Number2> dot(values.begin(),
+                                                       v.values.begin());
   internal::VectorOperations::parallel_reduce(
-    dot, 0, vec_size, sum, thread_loop_partitioner);
+    dot, 0, size(), sum, thread_loop_partitioner);
   AssertIsFinite(sum);
 
   return sum;
@@ -516,12 +439,12 @@ template <typename Number>
 typename Vector<Number>::real_type
 Vector<Number>::norm_sqr() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   real_type                                            sum;
-  internal::VectorOperations::Norm2<Number, real_type> norm2(values.get());
+  internal::VectorOperations::Norm2<Number, real_type> norm2(values.begin());
   internal::VectorOperations::parallel_reduce(
-    norm2, 0, vec_size, sum, thread_loop_partitioner);
+    norm2, 0, size(), sum, thread_loop_partitioner);
 
   AssertIsFinite(sum);
 
@@ -534,12 +457,12 @@ template <typename Number>
 Number
 Vector<Number>::mean_value() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   Number                                        sum;
-  internal::VectorOperations::MeanValue<Number> mean(values.get());
+  internal::VectorOperations::MeanValue<Number> mean(values.begin());
   internal::VectorOperations::parallel_reduce(
-    mean, 0, vec_size, sum, thread_loop_partitioner);
+    mean, 0, size(), sum, thread_loop_partitioner);
 
   return sum / real_type(size());
 }
@@ -550,12 +473,12 @@ template <typename Number>
 typename Vector<Number>::real_type
 Vector<Number>::l1_norm() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   real_type                                            sum;
-  internal::VectorOperations::Norm1<Number, real_type> norm1(values.get());
+  internal::VectorOperations::Norm1<Number, real_type> norm1(values.begin());
   internal::VectorOperations::parallel_reduce(
-    norm1, 0, vec_size, sum, thread_loop_partitioner);
+    norm1, 0, size(), sum, thread_loop_partitioner);
 
   return sum;
 }
@@ -571,12 +494,12 @@ Vector<Number>::l2_norm() const
   // might still be finite. In that case, recompute it (this is a rare case,
   // so working on the vector twice is uncritical and paid off by the extended
   // precision) using the BLAS approach with a weight, see e.g. dnrm2.f.
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   real_type                                            norm_square;
-  internal::VectorOperations::Norm2<Number, real_type> norm2(values.get());
+  internal::VectorOperations::Norm2<Number, real_type> norm2(values.begin());
   internal::VectorOperations::parallel_reduce(
-    norm2, 0, vec_size, norm_square, thread_loop_partitioner);
+    norm2, 0, size(), norm_square, thread_loop_partitioner);
   if (numbers::is_finite(norm_square) &&
       norm_square >= std::numeric_limits<real_type>::min())
     return static_cast<typename Vector<Number>::real_type>(
@@ -585,7 +508,7 @@ Vector<Number>::l2_norm() const
     {
       real_type scale = 0.;
       real_type sum   = 1.;
-      for (size_type i = 0; i < vec_size; ++i)
+      for (size_type i = 0; i < size(); ++i)
         {
           if (values[i] != Number())
             {
@@ -612,7 +535,7 @@ template <typename Number>
 typename Vector<Number>::real_type
 Vector<Number>::lp_norm(const real_type p) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   if (p == 1.)
     return l1_norm();
@@ -620,9 +543,9 @@ Vector<Number>::lp_norm(const real_type p) const
     return l2_norm();
 
   real_type                                            sum;
-  internal::VectorOperations::NormP<Number, real_type> normp(values.get(), p);
+  internal::VectorOperations::NormP<Number, real_type> normp(values.begin(), p);
   internal::VectorOperations::parallel_reduce(
-    normp, 0, vec_size, sum, thread_loop_partitioner);
+    normp, 0, size(), sum, thread_loop_partitioner);
 
   if (numbers::is_finite(sum) && sum >= std::numeric_limits<real_type>::min())
     return std::pow(sum, static_cast<real_type>(1. / p));
@@ -630,7 +553,7 @@ Vector<Number>::lp_norm(const real_type p) const
     {
       real_type scale = 0.;
       real_type sum   = 1.;
-      for (size_type i = 0; i < vec_size; ++i)
+      for (size_type i = 0; i < size(); ++i)
         {
           if (values[i] != Number())
             {
@@ -655,11 +578,11 @@ template <typename Number>
 typename Vector<Number>::real_type
 Vector<Number>::linfty_norm() const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   real_type max = 0.;
 
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     max = std::max(numbers::NumberTraits<Number>::abs(values[i]), max);
 
   return max;
@@ -673,17 +596,17 @@ Vector<Number>::add_and_dot(const Number          a,
                             const Vector<Number> &V,
                             const Vector<Number> &W)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  AssertDimension(vec_size, V.size());
-  AssertDimension(vec_size, W.size());
+  Assert(size() != 0, ExcEmptyObject());
+  AssertDimension(size(), V.size());
+  AssertDimension(size(), W.size());
 
   Number                                        sum;
-  internal::VectorOperations::AddAndDot<Number> adder(this->values.get(),
-                                                      V.values.get(),
-                                                      W.values.get(),
+  internal::VectorOperations::AddAndDot<Number> adder(values.begin(),
+                                                      V.values.begin(),
+                                                      W.values.begin(),
                                                       a);
   internal::VectorOperations::parallel_reduce(
-    adder, 0, vec_size, sum, thread_loop_partitioner);
+    adder, 0, size(), sum, thread_loop_partitioner);
   AssertIsFinite(sum);
 
   return sum;
@@ -695,14 +618,14 @@ template <typename Number>
 Vector<Number> &
 Vector<Number>::operator+=(const Vector<Number> &v)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   internal::VectorOperations::Vectorization_add_v<Number> vector_add(
-    values.get(), v.values.get());
+    values.begin(), v.values.begin());
   internal::VectorOperations::parallel_for(vector_add,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
   return *this;
 }
@@ -713,14 +636,14 @@ template <typename Number>
 Vector<Number> &
 Vector<Number>::operator-=(const Vector<Number> &v)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   internal::VectorOperations::Vectorization_subtract_v<Number> vector_subtract(
-    values.get(), v.values.get());
+    values.begin(), v.values.begin());
   internal::VectorOperations::parallel_for(vector_subtract,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 
   return *this;
@@ -732,13 +655,13 @@ template <typename Number>
 void
 Vector<Number>::add(const Number v)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   internal::VectorOperations::Vectorization_add_factor<Number> vector_add(
-    values.get(), v);
+    values.begin(), v);
   internal::VectorOperations::parallel_for(vector_add,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -754,15 +677,15 @@ Vector<Number>::add(const Number          a,
   AssertIsFinite(a);
   AssertIsFinite(b);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
-  Assert(vec_size == w.vec_size, ExcDimensionMismatch(vec_size, w.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
+  Assert(size() == w.size(), ExcDimensionMismatch(size(), w.size()));
 
   internal::VectorOperations::Vectorization_add_avpbw<Number> vector_add(
-    values.get(), v.values.get(), w.values.get(), a, b);
+    values.begin(), v.values.begin(), w.values.begin(), a, b);
   internal::VectorOperations::parallel_for(vector_add,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -774,14 +697,14 @@ Vector<Number>::sadd(const Number x, const Vector<Number> &v)
 {
   AssertIsFinite(x);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.vec_size, ExcDimensionMismatch(vec_size, v.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   internal::VectorOperations::Vectorization_sadd_xv<Number> vector_sadd(
-    values.get(), v.values.get(), x);
+    values.begin(), v.values.begin(), x);
   internal::VectorOperations::parallel_for(vector_sadd,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -791,14 +714,14 @@ template <typename Number>
 void
 Vector<Number>::scale(const Vector<Number> &s)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == s.vec_size, ExcDimensionMismatch(vec_size, s.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == s.size(), ExcDimensionMismatch(size(), s.size()));
 
   internal::VectorOperations::Vectorization_scale<Number> vector_scale(
-    values.get(), s.values.get());
+    values.begin(), s.values.begin());
   internal::VectorOperations::parallel_for(vector_scale,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -809,10 +732,10 @@ template <typename Number2>
 void
 Vector<Number>::scale(const Vector<Number2> &s)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == s.vec_size, ExcDimensionMismatch(vec_size, s.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == s.size(), ExcDimensionMismatch(size(), s.size()));
 
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     values[i] *= Number(s.values[i]);
 }
 
@@ -824,14 +747,14 @@ Vector<Number>::equ(const Number a, const Vector<Number> &u)
 {
   AssertIsFinite(a);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == u.vec_size, ExcDimensionMismatch(vec_size, u.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == u.size(), ExcDimensionMismatch(size(), u.size()));
 
   internal::VectorOperations::Vectorization_equ_au<Number> vector_equ(
-    values.get(), u.values.get(), a);
+    values.begin(), u.values.begin(), a);
   internal::VectorOperations::parallel_for(vector_equ,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -844,8 +767,8 @@ Vector<Number>::equ(const Number a, const Vector<Number2> &u)
 {
   AssertIsFinite(a);
 
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == u.vec_size, ExcDimensionMismatch(vec_size, u.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(size() == u.size(), ExcDimensionMismatch(size(), u.size()));
 
   // set the result vector to a*u. we have to
   // convert the elements of u to the type of
@@ -853,7 +776,7 @@ Vector<Number>::equ(const Number a, const Vector<Number2> &u)
   // because
   // operator*(complex<float>,complex<double>)
   // is not defined by default
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     values[i] = a * Number(u.values[i]);
 }
 
@@ -863,19 +786,18 @@ template <typename Number>
 void
 Vector<Number>::ratio(const Vector<Number> &a, const Vector<Number> &b)
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(a.vec_size == b.vec_size,
-         ExcDimensionMismatch(a.vec_size, b.vec_size));
+  Assert(size() != 0, ExcEmptyObject());
+  Assert(a.size() == b.size(), ExcDimensionMismatch(a.size(), b.size()));
 
   // no need to reinit with zeros, since
   // we overwrite them anyway
   reinit(a.size(), true);
 
   internal::VectorOperations::Vectorization_ratio<Number> vector_ratio(
-    values.get(), a.values.get(), b.values.get());
+    values.begin(), a.begin(), b.begin());
   internal::VectorOperations::parallel_for(vector_ratio,
                                            0,
-                                           vec_size,
+                                           size(),
                                            thread_loop_partitioner);
 }
 
@@ -885,7 +807,7 @@ template <typename Number>
 Vector<Number> &
 Vector<Number>::operator=(const BlockVector<Number> &v)
 {
-  if (v.size() != vec_size)
+  if (v.size() != size())
     reinit(v.size(), true);
 
   size_type this_index = 0;
@@ -915,9 +837,9 @@ template <typename Number>
 Vector<Number> &
 Vector<Number>::operator=(const TrilinosWrappers::MPI::Vector &v)
 {
-  if (v.size() != vec_size)
+  if (v.size() != size())
     reinit(v.size(), true);
-  if (vec_size != 0)
+  if (size() != 0)
     {
       // Copy the distributed vector to
       // a local one at all processors
@@ -927,12 +849,12 @@ Vector<Number>::operator=(const TrilinosWrappers::MPI::Vector &v)
       // this, but it has not yet been
       // found.
       TrilinosWrappers::MPI::Vector localized_vector;
-      localized_vector.reinit(complete_index_set(vec_size),
+      localized_vector.reinit(complete_index_set(size()),
                               v.get_mpi_communicator());
       localized_vector.reinit(v, false, true);
 
-      Assert(localized_vector.size() == vec_size,
-             ExcDimensionMismatch(localized_vector.size(), vec_size));
+      Assert(localized_vector.size() == size(),
+             ExcDimensionMismatch(localized_vector.size(), size()));
 
       // get a representation of the vector
       // and copy it
@@ -941,7 +863,7 @@ Vector<Number>::operator=(const TrilinosWrappers::MPI::Vector &v)
       int ierr = localized_vector.trilinos_vector().ExtractView(&start_ptr);
       AssertThrow(ierr == 0, ExcTrilinosError(ierr));
 
-      std::copy(start_ptr[0], start_ptr[0] + vec_size, begin());
+      std::copy(start_ptr[0], start_ptr[0] + size(), begin());
     }
 
   return *this;
@@ -954,8 +876,7 @@ template <typename Number2>
 bool
 Vector<Number>::operator==(const Vector<Number2> &v) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
-  Assert(vec_size == v.size(), ExcDimensionMismatch(vec_size, v.size()));
+  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
 
   // compare the two vector. we have to
   // convert the elements of v to the type of
@@ -963,7 +884,7 @@ Vector<Number>::operator==(const Vector<Number2> &v) const
   // because
   // operator==(complex<float>,complex<double>)
   // is not defined by default
-  for (size_type i = 0; i < vec_size; ++i)
+  for (size_type i = 0; i < size(); ++i)
     if (values[i] != Number(v.values[i]))
       return false;
 
@@ -976,7 +897,7 @@ template <typename Number>
 void
 Vector<Number>::print(const char *format) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   for (size_type j = 0; j < size(); ++j)
     internal::VectorOperations::print(values[j], format);
@@ -992,7 +913,7 @@ Vector<Number>::print(std::ostream &     out,
                       const bool         scientific,
                       const bool         across) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
   AssertThrow(out, ExcIO());
 
   std::ios::fmtflags old_flags     = out.flags();
@@ -1026,7 +947,7 @@ Vector<Number>::print(LogStream &        out,
                       const unsigned int width,
                       const bool         across) const
 {
-  Assert(vec_size != 0, ExcEmptyObject());
+  Assert(size() != 0, ExcEmptyObject());
 
   if (across)
     for (size_type i = 0; i < size(); ++i)
@@ -1121,28 +1042,10 @@ template <typename Number>
 std::size_t
 Vector<Number>::memory_consumption() const
 {
-  return sizeof(*this) + (max_vec_size * sizeof(Number));
+  return sizeof(*this) + values.memory_consumption() - sizeof(values);
 }
 
 
-
-template <typename Number>
-void
-Vector<Number>::allocate(const size_type copy_n_el)
-{
-  // allocate memory with the proper alignment requirements of 64 bytes
-  Number *new_values;
-  Utilities::System::posix_memalign(reinterpret_cast<void **>(&new_values),
-                                    64,
-                                    sizeof(Number) * max_vec_size);
-  // copy:
-  for (size_type i = 0; i < copy_n_el; ++i)
-    new_values[i] = values[i];
-  values.reset(new_values);
-}
-
-
-
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index 2fc4d411cf08f20c3958c2130ad2b0a1c948c574..d51d6c2c02229e0ad159e632e4038cfe01705fb2 100644 (file)
@@ -1,6 +1,6 @@
 
-DEAL::0 0 0 0 5 5 0 1 2 3 4
+DEAL::0 0 0 0 0 0 5 0 1 2 3 4
 
-DEAL::0 0 0 0 5 5 0 1 2 3 4
+DEAL::0 0 0 0 0 0 5 0 1 2 3 4
 
 DEAL::OK

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.