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