Vector.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 // A header file that is used to define the oomph-lib Vector class
27 
28 // Include guards to prevent multiple inclusions of the header
29 #ifndef OOMPH_VECTOR_HEADER
30 #define OOMPH_VECTOR_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 // Standard library includes
38 #include <vector>
39 #include <sstream>
40 #include <cmath>
41 
42 // Oomph-lib error handler
43 #include "oomph_definitions.h"
44 
45 
46 namespace oomph
47 {
48  //===========================================================================
49  /// A slight extension to the standard template vector class so that
50  /// we can include "graceful" array range checks if the RANGE_CHECKING
51  /// flag is set. The generalisation to general allocators is NOT handled here,
52  /// mainly because we never use it, but also because the intel and gnu
53  /// compilers have different names for the internal classes, which makes
54  /// writing code that works for both a pain!
55  //===========================================================================
56  template<class _Tp>
57  class Vector : public std::vector<_Tp>
58  {
59  public:
60  /// Typedef to make the constructors look a bit cleaner
61  typedef _Tp value_type;
62 
63  /// Typedef to make the constructors look a bit cleaner
65 
66  /// Typedef to make the constructors look a bit cleaner
67  typedef const value_type& const_reference;
68 
69  /// Typedef to make the constructors look a bit cleaner
70  typedef size_t size_type;
71 
72 // Only include this code, if we are range checking
73 #ifdef RANGE_CHECKING
74  private:
75  // Function to return a reference to a vector entry,
76  // including array range checking
78  {
79  // If there is an out of range error, die, but issue a warning message
80  if (__n >= this->size())
81  {
82  // Construct an error message, as a string stream
83  std::ostringstream error_message;
84  if (this->size() == 0)
85  {
86  error_message
87  << "Range Error: Vector is empty but you requested entry " << __n;
88  }
89  else
90  {
91  error_message << "Range Error: " << __n << " is not in the range (0,"
92  << this->size() - 1 << ")";
93  }
94 
95  // Throw an Oomph-lib error
96  throw OomphLibError(error_message.str(),
97  OOMPH_CURRENT_FUNCTION,
98  OOMPH_EXCEPTION_LOCATION);
99 
100  // This is a dummy return to keep the Intel compiler happy
101  return std::vector<_Tp>::operator[](__n);
102  }
103  else
104  {
105  return std::vector<_Tp>::operator[](__n);
106  }
107  }
108 
109  // Function to return a constant reference to a vector entry
110  // including error range checking
112  {
113  // If there is an out of range error, die, but issue a warning message
114  if (__n >= this->size())
115  {
116  // Construct an error message, as a string stream
117  std::ostringstream error_message;
118  error_message << "Range Error: " << __n << " is not in the range (0,"
119  << this->size() - 1 << ")";
120 
121  // Throw an Oomph-lib error
122  throw OomphLibError(error_message.str(),
123  OOMPH_CURRENT_FUNCTION,
124  OOMPH_EXCEPTION_LOCATION);
125 
126  // This is a dummy return to keep the Intel compiler happy
127  return std::vector<_Tp>::operator[](__n);
128  }
129  else
130  {
131  return std::vector<_Tp>::operator[](__n);
132  }
133  }
134 
135 #endif
136 
137  public:
138  // Standard Constuctors (some have been omitted from the stl classes)
139 
140  /// Construct an empty vector
141  Vector() : std::vector<_Tp>() {}
142 
143  /// A constructor that creates a vector of size __n.
144  /// Note the use of explicit for "strong" type checking
145  explicit Vector(size_type __n) : std::vector<_Tp>(__n) {}
146 
147  /// A constructor that creates a vector of size __n and
148  /// initialises every entry to __value
149  Vector(size_type __n, const _Tp& __value) : std::vector<_Tp>(__n, __value)
150  {
151  }
152 
153  /// A constructor that creates a vector with entries set by the
154  /// values in the input initialiser_list
155  /// Example:
156  /// Vector<int> arr{0, 20, 100, 150);
157  /// Vector<int> arr = {0, 20, 100, 150);
158  Vector(std::initializer_list<_Tp> init) : std::vector<_Tp>(init) {}
159 
160  /// Copy constructor
161  Vector(const Vector<_Tp>& __x) : std::vector<_Tp>(__x) {}
162 
163  // No explicit destructor is required because the base class destructor
164  // handles all memory issues ~Vector() {}
165 
166  /// Iterate over all values and set to the desired value
167  void initialise(const _Tp& __value)
168  {
169  for (typename std::vector<_Tp>::iterator it = std::vector<_Tp>::begin();
170  it != std::vector<_Tp>::end();
171  it++)
172  {
173  *it = __value;
174  }
175  }
176 
177 #ifdef RANGE_CHECKING
178  /// Overload the bracket access operator to include array-range checking
179  /// if the RANGE_CHECKING flag is set
181  {
182  return error_checked_access(__n);
183  }
184 
185  /// Overloaded, range-checking, bracket access operator (const version)
187  {
188  return error_checked_access(__n);
189  }
190 #endif
191  };
192 
193  //==================================================================
194  /// A Vector of bools cannot be created because the is no
195  /// compiler-independent implementation of the bit manipulators.
196  /// Making all the constructors private should lead to compile-time
197  /// errors.
198  //=================================================================
199  template<>
200  class Vector<bool> : private std::vector<bool>
201  {
202  public:
203  /// Typedef to make the constructors look a bit cleaner
204  typedef bool value_type;
205 
206  /// Typedef to make the constructors look a bit cleaner
208 
209  /// Typedef to make the constructors look a bit cleaner
210  typedef const value_type& const_reference;
211 
212  /// Typedef to make the constructors look a bit cleaner
213  typedef size_t size_type;
214 
215 
216  /// Dummy constructor to avoid compiler from warning about
217  /// only-private constructors
218  Vector(const double& dont_call_this_constructor)
219  {
220  // Throw an Oomph-lib error
221  throw OomphLibError("Please use vector<bool> instead of Vector<bool>",
222  OOMPH_CURRENT_FUNCTION,
223  OOMPH_EXCEPTION_LOCATION);
224  }
225 
226  private:
227  // Standard Constuctors (some have been omitted from the stl classes)
228 
229  /// Construct an empty vector
230  Vector() : std::vector<bool>() {}
231 
232  /// A constructor that creates a vector of size __n.
233  /// Note the use of explicit for "strong" type checking
234  explicit Vector(size_type __n) : std::vector<bool>(__n) {}
235 
236  /// A constructor that creates a vector of size __n and
237  /// initialises every entry to __value
238  Vector(size_type __n, const bool& __value) : std::vector<bool>(__n, __value)
239  {
240  }
241 
242  /// A constructor that creates a vector with entries set by the
243  /// values in the input initialiser_list.
244  /// Example:
245  /// Vector<int> arr{true, false, false, true);
246  /// Vector<int> arr = {true, false, false, true);
247  Vector(std::initializer_list<bool> init) : std::vector<bool>(init) {}
248 
249  /// Copy constructor
250  Vector(const Vector<bool>& __x) : std::vector<bool>(__x) {}
251 
252  /// Iterate over all values and set to the desired value
253  void initialise(const bool& __value)
254  {
255  for (std::vector<bool>::iterator it = std::vector<bool>::begin();
256  it != std::vector<bool>::end();
257  it++)
258  {
259  *it = __value;
260  }
261  }
262  };
263 
264 
265  //=================================================================
266  /// Namespace for helper functions for Vector<double>
267  //=================================================================
268  namespace VectorHelpers
269  {
270  /// Check the lengths if two Vectors are the same length
271  inline void check_lengths_match(const Vector<double>& a,
272  const Vector<double>& b)
273  {
274 #ifdef PARANOID
275  if (a.size() != b.size())
276  {
277  std::ostringstream err;
278  err << "Vectors must be the same length."
279  << "len(a) = " << a.size() << ", "
280  << "len(b) = " << b.size() << ".";
281 
282  throw OomphLibError(
283  err.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
284  }
285 #endif
286  }
287 
288 
289  /// Probably not always best/fastest because not optimised for
290  /// dimension but useful...
291  inline double dot(const Vector<double>& a, const Vector<double>& b)
292  {
293  check_lengths_match(a, b);
294  double temp = 0;
295  for (unsigned i = 0, ni = a.size(); i < ni; i++)
296  {
297  temp += a[i] * b[i];
298  }
299  return temp;
300  }
301 
302  /// Get the magnitude of a vector.
303  inline double magnitude(const Vector<double>& a)
304  {
305  return (std::sqrt(dot(a, a)));
306  }
307 
308  /// Get the angle between two vector.
309  inline double angle(const Vector<double>& a, const Vector<double>& b)
310  {
311  // Notice that we use one square root operation by avoiding the
312  // call to magnitude(...)
313  return std::acos(dot(a, b) / std::sqrt(dot(a, a) * dot(b, b)));
314  }
315 
316 
317  /// Cross product using "proper" output (move semantics means this is
318  /// ok nowadays).
319  inline void cross(const Vector<double>& A,
320  const Vector<double>& B,
321  Vector<double>& C)
322  {
323 #ifdef PARANOID
324  if ((A.size() != 3) || (B.size() != 3) || (C.size() != 3))
325  {
326  std::ostringstream err;
327  err << "Cross product only defined for vectors of length 3.\n"
328  << "len(a) = " << A.size() << ", "
329  << "len(b) = " << B.size() << ", "
330  << "len(c) = " << C.size() << ".";
331 
332  throw OomphLibError(
333  err.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
334  }
335 #endif
336 
337  C[0] = A[1] * B[2] - A[2] * B[1];
338  C[1] = A[2] * B[0] - A[0] * B[2];
339  C[2] = A[0] * B[1] - A[1] * B[0];
340  }
341 
342  /// Cross product using "proper" output (move semantics means this is
343  /// ok This calls the other cross(...) function.
345  const Vector<double>& B)
346  {
347  Vector<double> output(3, 0.0);
348  cross(A, B, output);
349 
350  return output;
351  }
352 
353  } // namespace VectorHelpers
354 
355 
356 } // namespace oomph
357 
358 
359 #endif
cstr elem_len * i
Definition: cfortran.h:603
An OomphLibError object which should be thrown when an run-time error is encountered....
A Vector of bools cannot be created because the is no compiler-independent implementation of the bit ...
Definition: Vector.h:201
size_t size_type
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:213
Vector(std::initializer_list< bool > init)
A constructor that creates a vector with entries set by the values in the input initialiser_list....
Definition: Vector.h:247
Vector(const double &dont_call_this_constructor)
Dummy constructor to avoid compiler from warning about only-private constructors.
Definition: Vector.h:218
void initialise(const bool &__value)
Iterate over all values and set to the desired value.
Definition: Vector.h:253
Vector()
Construct an empty vector.
Definition: Vector.h:230
Vector(size_type __n, const bool &__value)
A constructor that creates a vector of size __n and initialises every entry to __value.
Definition: Vector.h:238
const value_type & const_reference
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:210
Vector(size_type __n)
A constructor that creates a vector of size __n. Note the use of explicit for "strong" type checking.
Definition: Vector.h:234
Vector(const Vector< bool > &__x)
Copy constructor.
Definition: Vector.h:250
bool value_type
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:204
value_type & reference
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:207
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
Vector()
Construct an empty vector.
Definition: Vector.h:141
Vector(size_type __n, const _Tp &__value)
A constructor that creates a vector of size __n and initialises every entry to __value.
Definition: Vector.h:149
Vector(std::initializer_list< _Tp > init)
A constructor that creates a vector with entries set by the values in the input initialiser_list Exam...
Definition: Vector.h:158
Vector(const Vector< _Tp > &__x)
Copy constructor.
Definition: Vector.h:161
reference operator[](size_type __n)
Overload the bracket access operator to include array-range checking if the RANGE_CHECKING flag is se...
Definition: Vector.h:180
_Tp value_type
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:61
value_type & reference
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:64
size_t size_type
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:70
const_reference error_checked_access(size_type __n) const
Definition: Vector.h:111
const_reference operator[](size_type __n) const
Overloaded, range-checking, bracket access operator (const version)
Definition: Vector.h:186
Vector(size_type __n)
A constructor that creates a vector of size __n. Note the use of explicit for "strong" type checking.
Definition: Vector.h:145
reference error_checked_access(size_type __n)
Definition: Vector.h:77
const value_type & const_reference
Typedef to make the constructors look a bit cleaner.
Definition: Vector.h:67
void initialise(const _Tp &__value)
Iterate over all values and set to the desired value.
Definition: Vector.h:167
void output()
Doc the command line arguments.
double dot(const Vector< double > &a, const Vector< double > &b)
Probably not always best/fastest because not optimised for dimension but useful...
Definition: Vector.h:291
void cross(const Vector< double > &A, const Vector< double > &B, Vector< double > &C)
Cross product using "proper" output (move semantics means this is ok nowadays).
Definition: Vector.h:319
double angle(const Vector< double > &a, const Vector< double > &b)
Get the angle between two vector.
Definition: Vector.h:309
void check_lengths_match(const Vector< double > &a, const Vector< double > &b)
Check the lengths if two Vectors are the same length.
Definition: Vector.h:271
double magnitude(const Vector< double > &a)
Get the magnitude of a vector.
Definition: Vector.h:303
//////////////////////////////////////////////////////////////////// ////////////////////////////////...