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_vector_space_vector_h 17 #define dealii_vector_space_vector_h 18 19 #include <deal.II/base/config.h> 20 21 #include <deal.II/base/numbers.h> 22 23 #include <deal.II/lac/vector_operation.h> 24 25 #include <memory> 26 27 28 DEAL_II_NAMESPACE_OPEN 29 30 // Forward declarations 31 #ifndef DOXYGEN 32 class IndexSet; 33 namespace LinearAlgebra 34 { 35 class CommunicationPatternBase; 36 template <typename Number> 37 class ReadWriteVector; 38 } // namespace LinearAlgebra 39 #endif 40 41 namespace LinearAlgebra 42 { 43 /*! @addtogroup Vectors 44 *@{ 45 */ 46 47 /** 48 * VectorSpaceVector is an abstract class that is used to define the 49 * interface that vector classes need to implement when they want to 50 * implement global operations. This class is complementary of 51 * ReadWriteVector which allows the access of individual elements but does 52 * not allow global operations. 53 */ 54 template <typename Number> 55 class VectorSpaceVector 56 { 57 public: 58 using value_type = Number; 59 using size_type = types::global_dof_index; 60 using real_type = typename numbers::NumberTraits<Number>::real_type; 61 62 /** 63 * Change the dimension to that of the vector V. The elements of V are not 64 * copied. 65 */ 66 virtual void 67 reinit(const VectorSpaceVector<Number> &V, 68 const bool omit_zeroing_entries = false) = 0; 69 70 /** 71 * Sets all elements of the vector to the scalar @p s. This operation is 72 * only allowed if @p s is equal to zero. 73 */ 74 virtual VectorSpaceVector<Number> & 75 operator=(const Number s) = 0; 76 77 /** 78 * Multiply the entire vector by a fixed factor. 79 */ 80 virtual VectorSpaceVector<Number> & 81 operator*=(const Number factor) = 0; 82 83 /** 84 * Divide the entire vector by a fixed factor. 85 */ 86 virtual VectorSpaceVector<Number> & 87 operator/=(const Number factor) = 0; 88 89 /** 90 * Add the vector @p V to the present one. 91 */ 92 virtual VectorSpaceVector<Number> & 93 operator+=(const VectorSpaceVector<Number> &V) = 0; 94 95 /** 96 * Subtract the vector @p V from the present one. 97 */ 98 virtual VectorSpaceVector<Number> & 99 operator-=(const VectorSpaceVector<Number> &V) = 0; 100 101 /** 102 * Import all the elements present in the vector's IndexSet from the input 103 * vector @p V. VectorOperation::values @p operation is used to decide if 104 * the elements in @p V should be added to the current vector or replace the 105 * current elements. The last parameter can be used if the same 106 * communication pattern is used multiple times. This can be used to improve 107 * performance. 108 */ 109 virtual void 110 import( 111 const ReadWriteVector<Number> & V, 112 VectorOperation::values operation, 113 std::shared_ptr<const CommunicationPatternBase> communication_pattern = 114 std::shared_ptr<const CommunicationPatternBase>()) = 0; 115 116 /** 117 * Return the scalar product of two vectors. 118 */ 119 virtual Number operator*(const VectorSpaceVector<Number> &V) const = 0; 120 121 /** 122 * Add @p a to all components. Note that @p a is a scalar not a vector. 123 */ 124 virtual void 125 add(const Number a) = 0; 126 127 /** 128 * Simple addition of a multiple of a vector, i.e. <tt>*this += a*V</tt>. 129 */ 130 virtual void 131 add(const Number a, const VectorSpaceVector<Number> &V) = 0; 132 133 /** 134 * Multiple addition of scaled vectors, i.e. <tt>*this += a*V+b*W</tt>. 135 */ 136 virtual void 137 add(const Number a, 138 const VectorSpaceVector<Number> &V, 139 const Number b, 140 const VectorSpaceVector<Number> &W) = 0; 141 142 /** 143 * Scaling and simple addition of a multiple of a vector, i.e. <tt>*this = 144 * s*(*this)+a*V</tt>. 145 */ 146 virtual void 147 sadd(const Number s, 148 const Number a, 149 const VectorSpaceVector<Number> &V) = 0; 150 151 /** 152 * Scale each element of this vector by the corresponding element in the 153 * argument. This function is mostly meant to simulate multiplication (and 154 * immediate re-assignment) by a diagonal scaling matrix. 155 */ 156 virtual void 157 scale(const VectorSpaceVector<Number> &scaling_factors) = 0; 158 159 /** 160 * Assignment <tt>*this = a*V</tt>. 161 */ 162 virtual void 163 equ(const Number a, const VectorSpaceVector<Number> &V) = 0; 164 165 /** 166 * Return whether the vector contains only elements with value zero. 167 */ 168 virtual bool 169 all_zero() const = 0; 170 171 /** 172 * Return the mean value of all the entries of this vector. 173 */ 174 virtual value_type 175 mean_value() const = 0; 176 177 /** 178 * Return the l<sub>1</sub> norm of the vector (i.e., the sum of the 179 * absolute values of all entries among all processors). 180 */ 181 virtual real_type 182 l1_norm() const = 0; 183 184 /** 185 * Return the l<sub>2</sub> norm of the vector (i.e., the square root of 186 * the sum of the square of all entries among all processors). 187 */ 188 virtual real_type 189 l2_norm() const = 0; 190 191 /** 192 * Return the maximum norm of the vector (i.e., the maximum absolute value 193 * among all entries and among all processors). 194 */ 195 virtual real_type 196 linfty_norm() const = 0; 197 198 /** 199 * Perform a combined operation of a vector addition and a subsequent 200 * inner product, returning the value of the inner product. In other 201 * words, the result of this function is the same as if the user called 202 * @code 203 * this->add(a, V); 204 * return_value = *this * W; 205 * @endcode 206 * 207 * The reason this function exists is that this operation involves less 208 * memory transfer than calling the two functions separately. This method 209 * only needs to load three vectors, @p this, @p V, @p W, whereas calling 210 * separate methods means to load the calling vector @p this twice. Since 211 * most vector operations are memory transfer limited, this reduces the 212 * time by 25\% (or 50\% if @p W equals @p this). 213 * 214 * For complex-valued vectors, the scalar product in the second step is 215 * implemented as 216 * $\left<v,w\right>=\sum_i v_i \bar{w_i}$. 217 */ 218 virtual Number 219 add_and_dot(const Number a, 220 const VectorSpaceVector<Number> &V, 221 const VectorSpaceVector<Number> &W) = 0; 222 223 /** 224 * This function does nothing and only exists for backward compatibility. 225 */ compress(VectorOperation::values)226 virtual void compress(VectorOperation::values) 227 {} 228 229 /** 230 * Return the global size of the vector, equal to the sum of the number of 231 * locally owned indices among all processors. 232 */ 233 virtual size_type 234 size() const = 0; 235 236 /** 237 * Return an index set that describes which elements of this vector are 238 * owned by the current processor. As a consequence, the index sets 239 * returned on different processors if this is a distributed vector will 240 * form disjoint sets that add up to the complete index set. Obviously, if 241 * a vector is created on only one processor, then the result would 242 * satisfy 243 * @code 244 * vec.locally_owned_elements() == complete_index_set(vec.size()) 245 * @endcode 246 */ 247 virtual dealii::IndexSet 248 locally_owned_elements() const = 0; 249 250 /** 251 * Print the vector to the output stream @p out. 252 */ 253 virtual void 254 print(std::ostream & out, 255 const unsigned int precision = 3, 256 const bool scientific = true, 257 const bool across = true) const = 0; 258 259 /** 260 * Return the memory consumption of this class in bytes. 261 */ 262 virtual std::size_t 263 memory_consumption() const = 0; 264 265 /** 266 * Destructor. Declared as virtual so that inheriting classes (which may 267 * manage their own memory) are destroyed correctly. 268 */ 269 virtual ~VectorSpaceVector() = default; 270 }; 271 /*@}*/ 272 } // namespace LinearAlgebra 273 274 // ---------------------------- Free functions -------------------------- 275 276 namespace LinearAlgebra 277 { 278 /** 279 * Shift all entries of the vector by a constant factor so that the mean 280 * value of the vector becomes zero. 281 */ 282 template <typename Number> 283 void set_zero_mean_value(VectorSpaceVector<Number> & vector)284 set_zero_mean_value(VectorSpaceVector<Number> &vector) 285 { 286 vector.add(-vector.mean_value()); 287 } 288 } // namespace LinearAlgebra 289 290 DEAL_II_NAMESPACE_CLOSE 291 292 #endif 293