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