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-2022 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
46namespace 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
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
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
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 {
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,
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
//////////////////////////////////////////////////////////////////// ////////////////////////////////...