1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2015 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_la_vector_h
17 #define dealii_la_vector_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/index_set.h>
24 #include <deal.II/base/logstream.h>
25 
26 #include <deal.II/lac/read_write_vector.h>
27 #include <deal.II/lac/vector_operation.h>
28 #include <deal.II/lac/vector_space_vector.h>
29 #include <deal.II/lac/vector_type_traits.h>
30 
31 // boost::serialization::make_array used to be in array.hpp, but was
32 // moved to a different file in BOOST 1.64
33 #include <boost/version.hpp>
34 #if BOOST_VERSION >= 106400
35 #  include <boost/serialization/array_wrapper.hpp>
36 #else
37 #  include <boost/serialization/array.hpp>
38 #endif
39 #include <boost/serialization/split_member.hpp>
40 
41 #include <cstdio>
42 #include <cstring>
43 #include <iostream>
44 #include <vector>
45 
46 
47 DEAL_II_NAMESPACE_OPEN
48 
49 /**
50  * A namespace for vector classes.
51  *
52  * This namespace contains various classes that provide wrappers to vector
53  * classes from different external libraries like Trilinos (EPetra) or PETSc
54  * and native implementations like LinearAlgebra::distributed::Vector.
55  *
56  * The different vector classes are derived from VectorSpaceVector to provide
57  * a joint interface for vector space operations, are derived from
58  * ReadWriteVector (or ReadWriteVector itself), or both. The separation of
59  * vector space operations (like norms or vector additions) through
60  * VectorSpaceVector and element access through ReadWriteVector are by design
61  * and improve performance.
62  */
63 namespace LinearAlgebra
64 {
65   /*! @addtogroup Vectors
66    *@{
67    */
68 
69   /**
70    * Numerical vector of data. This class derives from both
71    * ::dealii::LinearAlgebra::ReadWriteVector and
72    * ::dealii::LinearAlgebra::VectorSpaceVector. As opposed to the array of
73    * the C++ standard library, this class implements an element of a vector
74    * space suitable for numerical computations.
75    */
76   template <typename Number>
77   class Vector : public ReadWriteVector<Number>,
78                  public VectorSpaceVector<Number>
79   {
80   public:
81     using size_type  = types::global_dof_index;
82     using value_type = typename ReadWriteVector<Number>::value_type;
83 
84     /**
85      * Constructor. Create a vector of dimension zero.
86      */
87     Vector() = default;
88 
89     /**
90      * Copy constructor. Sets the dimension to that of the given vector and
91      * copies all elements.
92      */
93     Vector(const Vector<Number> &V);
94 
95     /**
96      * Constructor. Set dimension to @p n and initialize all elements with
97      * zero.
98      *
99      * The constructor is made explicit to avoid accident like this:
100      * <tt>v=0;</tt>. Presumably, the user wants to set every element of the
101      * vector to zero, but instead, what happens is this call:
102      * <tt>v=Vector@<Number@>(0);</tt>, i.e. the vector is replaced by one of
103      * length zero.
104      */
105     explicit Vector(const size_type n);
106 
107     /**
108      * Initialize the vector with a given range of values pointed to by the
109      * iterators. This function exists in analogy to the @p std::vector class.
110      */
111     template <typename InputIterator>
112     Vector(const InputIterator first, const InputIterator last);
113 
114     /**
115      * Set the global size of the vector to @p size. The stored elements have
116      * their index in [0,size).
117      *
118      * If the flag @p omit_zeroing_entries is set to false, the memory will be
119      * initialized with zero, otherwise the memory will be untouched (and the
120      * user must make sure to fill it with reasonable data before using it).
121      */
122     virtual void
123     reinit(const size_type size,
124            const bool      omit_zeroing_entries = false) override;
125 
126     /**
127      * Uses the same IndexSet as the one of the input vector @p in_vector and
128      * allocates memory for this vector.
129      *
130      * If the flag @p omit_zeroing_entries is set to false, the memory will be
131      * initialized with zero, otherwise the memory will be untouched (and the
132      * user must make sure to fill it with reasonable data before using it).
133      */
134     template <typename Number2>
135     void
136     reinit(const ReadWriteVector<Number2> &in_vector,
137            const bool                      omit_zeroing_entries = false);
138 
139     /**
140      * Initializes the vector. The indices are specified by @p
141      * locally_stored_indices.
142      *
143      * If the flag @p omit_zeroing_entries is set to false, the memory will be
144      * initialized with zero, otherwise the memory will be untouched (and the
145      * user must make sure to fill it with reasonable data before using it).
146      * locally_stored_indices.
147      */
148     virtual void
149     reinit(const IndexSet &locally_stored_indices,
150            const bool      omit_zeroing_entries = false) override;
151 
152 
153     /**
154      * Change the dimension to that of the vector V. The elements of V are not
155      * copied.
156      */
157     virtual void
158     reinit(const VectorSpaceVector<Number> &V,
159            const bool omit_zeroing_entries = false) override;
160 
161     /**
162      * Returns `false` as this is a serial vector.
163      *
164      * This functionality only needs to be called if using MPI based vectors and
165      * exists in other objects for compatibility.
166      */
167     bool
168     has_ghost_elements() const;
169 
170     /**
171      * Copies the data of the input vector @p in_vector.
172      */
173     Vector<Number> &
174     operator=(const Vector<Number> &in_vector);
175 
176     /**
177      * Copies the data of the input vector @p in_vector.
178      */
179     template <typename Number2>
180     Vector<Number> &
181     operator=(const Vector<Number2> &in_vector);
182 
183     /**
184      * Sets all elements of the vector to the scalar @p s. This operation is
185      * only allowed if @p s is equal to zero.
186      */
187     virtual Vector<Number> &
188     operator=(const Number s) override;
189 
190     /**
191      * Multiply the entire vector by a fixed factor.
192      */
193     virtual Vector<Number> &
194     operator*=(const Number factor) override;
195 
196     /**
197      * Divide the entire vector by a fixed factor.
198      */
199     virtual Vector<Number> &
200     operator/=(const Number factor) override;
201 
202     /**
203      * Add the vector @p V to the present one.
204      */
205     virtual Vector<Number> &
206     operator+=(const VectorSpaceVector<Number> &V) override;
207 
208     /**
209      * Subtract the vector @p V from the present one.
210      */
211     virtual Vector<Number> &
212     operator-=(const VectorSpaceVector<Number> &V) override;
213 
214     /**
215      * Return the scalar product of two vectors.
216      */
217     virtual Number operator*(const VectorSpaceVector<Number> &V) const override;
218 
219     /**
220      * This function is not implemented and will throw an exception.
221      */
222     virtual void
223     import(
224       const ReadWriteVector<Number> &                 V,
225       VectorOperation::values                         operation,
226       std::shared_ptr<const CommunicationPatternBase> communication_pattern =
227         std::shared_ptr<const CommunicationPatternBase>()) override;
228 
229     /**
230      * Add @p a to all components. Note that @p a is a scalar not a vector.
231      */
232     virtual void
233     add(const Number a) override;
234 
235     /**
236      * Simple addition of a multiple of a vector, i.e. <tt>*this += a*V</tt>.
237      */
238     virtual void
239     add(const Number a, const VectorSpaceVector<Number> &V) override;
240 
241     /**
242      * Multiple addition of a multiple of a vector, i.e. <tt>*this +=
243      * a*V+b*W</tt>.
244      */
245     virtual void
246     add(const Number                     a,
247         const VectorSpaceVector<Number> &V,
248         const Number                     b,
249         const VectorSpaceVector<Number> &W) override;
250 
251     /**
252      * Scaling and simple addition of a multiple of a vector, i.e. <tt>*this =
253      * s*(*this)+a*V</tt>.
254      */
255     virtual void
256     sadd(const Number                     s,
257          const Number                     a,
258          const VectorSpaceVector<Number> &V) override;
259 
260     /**
261      * Scale each element of this vector by the corresponding element in the
262      * argument. This function is mostly meant to simulate multiplication (and
263      * immediate re-assignment) by a diagonal scaling matrix.
264      */
265     virtual void
266     scale(const VectorSpaceVector<Number> &scaling_factors) override;
267 
268     /**
269      * Assignment <tt>*this = a*V</tt>.
270      */
271     virtual void
272     equ(const Number a, const VectorSpaceVector<Number> &V) override;
273 
274     /**
275      * Return whether the vector contains only elements with value zero.
276      */
277     virtual bool
278     all_zero() const override;
279 
280     /**
281      * Return the mean value of all the entries of this vector.
282      */
283     virtual value_type
284     mean_value() const override;
285 
286     /**
287      * Return the l<sub>1</sub> norm of the vector (i.e., the sum of the
288      * absolute values of all entries).
289      */
290     virtual typename VectorSpaceVector<Number>::real_type
291     l1_norm() const override;
292 
293     /**
294      * Return the l<sub>2</sub> norm of the vector (i.e., the square root of
295      * the sum of the square of all entries among all processors).
296      */
297     virtual typename VectorSpaceVector<Number>::real_type
298     l2_norm() const override;
299 
300     /**
301      * Return the maximum norm of the vector (i.e., the maximum absolute value
302      * among all entries and among all processors).
303      */
304     virtual typename VectorSpaceVector<Number>::real_type
305     linfty_norm() const override;
306 
307     /**
308      * Perform a combined operation of a vector addition and a subsequent
309      * inner product, returning the value of the inner product. In other
310      * words, the result of this function is the same as if the user called
311      * @code
312      * this->add(a, V);
313      * return_value = *this * W;
314      * @endcode
315      *
316      * The reason this function exists is that this operation involves less
317      * memory transfer than calling the two functions separately. This method
318      * only needs to load three vectors, @p this, @p V, @p W, whereas calling
319      * separate methods means to load the calling vector @p this twice. Since
320      * most vector operations are memory transfer limited, this reduces the time
321      * by 25\% (or 50\% if @p W equals @p this).
322      *
323      * For complex-valued vectors, the scalar product in the second step is
324      * implemented as
325      * $\left<v,w\right>=\sum_i v_i \bar{w_i}$.
326      */
327     virtual Number
328     add_and_dot(const Number                     a,
329                 const VectorSpaceVector<Number> &V,
330                 const VectorSpaceVector<Number> &W) override;
331 
332     /**
333      * Return the global size of the vector, equal to the sum of the number of
334      * locally owned indices among all processors.
335      */
336     virtual size_type
337     size() const override;
338 
339     /**
340      * Return an index set that describes which elements of this vector are
341      * owned by the current processor. As a consequence, the index sets
342      * returned on different processors if this is a distributed vector will
343      * form disjoint sets that add up to the complete index set. Obviously, if
344      * a vector is created on only one processor, then the result would
345      * satisfy
346      * @code
347      *  vec.locally_owned_elements() == complete_index_set(vec.size())
348      * @endcode
349      */
350     virtual dealii::IndexSet
351     locally_owned_elements() const override;
352 
353     /**
354      * Print the vector to the output stream @p out.
355      */
356     virtual void
357     print(std::ostream &     out,
358           const unsigned int precision  = 3,
359           const bool         scientific = true,
360           const bool         across     = true) const override;
361 
362     /**
363      * Print the vector to the output stream @p out in a format that can be
364      * read by numpy::readtxt(). Note that the IndexSet is not printed but only
365      * the values stored in the Vector. To load the vector in python just do
366      * <code>
367      * vector = numpy.loadtxt('my_vector.txt')
368      * </code>
369      */
370     void
371     print_as_numpy_array(std::ostream &     out,
372                          const unsigned int precision = 9) const;
373 
374     /**
375      * Write the vector en bloc to a file. This is done in a binary mode, so
376      * the output is neither readable by humans nor (probably) by other
377      * computers using a different operating system or number format.
378      */
379     void
380     block_write(std::ostream &out) const;
381 
382     /**
383      * Read a vector en block from a file. This is done using the inverse
384      * operations to the above function, so it is reasonably fast because the
385      * bitstream is not interpreted.
386      *
387      * The vector is resized if necessary.
388      *
389      * A primitive form of error checking is performed which will recognize
390      * the bluntest attempts to interpret some data as a vector stored bitwise
391      * to a file, but not more.
392      */
393     void
394     block_read(std::istream &in);
395 
396     /**
397      * Return the memory consumption of this class in bytes.
398      */
399     virtual std::size_t
400     memory_consumption() const override;
401 
402     /**
403      * Attempt to perform an operation between two incompatible vector types.
404      *
405      * @ingroup Exceptions
406      */
407     DeclException0(ExcVectorTypeNotCompatible);
408 
409   private:
410     /**
411      * Serialize the data of this object using boost. This function is
412      * necessary to use boost::archive::text_iarchive and
413      * boost::archive::text_oarchive.
414      */
415     template <typename Archive>
416     void
417     serialize(Archive &ar, const unsigned int version);
418 
419     friend class boost::serialization::access;
420 
421     // Make all other ReadWriteVector types friends.
422     template <typename Number2>
423     friend class Vector;
424   };
425 
426   /*@}*/
427   /*--------------------------- Inline functions ----------------------------*/
428 
429   template <typename Number>
Vector(const Vector<Number> & V)430   inline Vector<Number>::Vector(const Vector<Number> &V)
431     : ReadWriteVector<Number>(V)
432   {}
433 
434 
435 
436   template <typename Number>
Vector(const size_type n)437   inline Vector<Number>::Vector(const size_type n)
438     : ReadWriteVector<Number>(n)
439   {}
440 
441 
442 
443   template <typename Number>
444   template <typename InputIterator>
Vector(const InputIterator first,const InputIterator last)445   inline Vector<Number>::Vector(const InputIterator first,
446                                 const InputIterator last)
447   {
448     this->reinit(complete_index_set(std::distance(first, last)), true);
449     std::copy(first, last, this->begin());
450   }
451 
452 
453 
454   template <typename Number>
455   inline typename Vector<Number>::size_type
size()456   Vector<Number>::size() const
457   {
458     return ReadWriteVector<Number>::size();
459   }
460 
461 
462 
463   template <typename Number>
464   inline dealii::IndexSet
locally_owned_elements()465   Vector<Number>::locally_owned_elements() const
466   {
467     return IndexSet(ReadWriteVector<Number>::get_stored_elements());
468   }
469 
470 
471 
472   template <typename Number>
473   inline void
print(std::ostream & out,const unsigned int precision,const bool scientific,const bool)474   Vector<Number>::print(std::ostream &     out,
475                         const unsigned int precision,
476                         const bool         scientific,
477                         const bool) const
478   {
479     ReadWriteVector<Number>::print(out, precision, scientific);
480   }
481 
482 
483 
484   template <typename Number>
485   template <typename Archive>
486   inline void
serialize(Archive & ar,const unsigned int)487   Vector<Number>::serialize(Archive &ar, const unsigned int)
488   {
489     size_type current_size = this->size();
490     ar &static_cast<Subscriptor &>(*this);
491     ar & this->stored_elements;
492     // If necessary, resize the vector during a read operation
493     if (this->size() != current_size)
494       this->reinit(this->size());
495     ar &boost::serialization::make_array(this->values.get(), this->size());
496   }
497 
498 
499 
500   template <typename Number>
501   inline std::size_t
memory_consumption()502   Vector<Number>::memory_consumption() const
503   {
504     return ReadWriteVector<Number>::memory_consumption();
505   }
506 } // end of namespace LinearAlgebra
507 
508 
509 /**
510  * Declare dealii::LinearAlgebra::Vector as serial vector.
511  */
512 template <typename Number>
513 struct is_serial_vector<LinearAlgebra::Vector<Number>> : std::true_type
514 {};
515 
516 #ifndef DOXYGEN
517 /*----------------------- Inline functions ----------------------------------*/
518 
519 namespace LinearAlgebra
520 {
521   template <typename Number>
522   inline bool
523   Vector<Number>::has_ghost_elements() const
524   {
525     return false;
526   }
527 } // namespace LinearAlgebra
528 
529 #endif
530 
531 
532 DEAL_II_NAMESPACE_CLOSE
533 
534 #ifdef DEAL_II_MSVC
535 #  include <deal.II/lac/la_vector.templates.h>
536 #endif
537 
538 #endif
539