1 // -*- C++ -*-
2 // Vec.h: Vectors in three-dimensional space, i.e. three doubles.
3 //
4 // Copyright (C) 2001-2011 Jakob Schiotz and Center for Individual
5 // Nanoparticle Functionality, Department of Physics, Technical
6 // University of Denmark.  Email: schiotz@fysik.dtu.dk
7 //
8 // This file is part of Asap version 3.
9 // Asap is released under the GNU Lesser Public License (LGPL) version 3.
10 // However, the parts of Asap distributed within the OpenKIM project
11 // (including this file) are also released under the Common Development
12 // and Distribution License (CDDL) version 1.0.
13 //
14 // This program is free software: you can redistribute it and/or
15 // modify it under the terms of the GNU Lesser General Public License
16 // version 3 as published by the Free Software Foundation.  Permission
17 // to use other versions of the GNU Lesser General Public License may
18 // granted by Jakob Schiotz or the head of department of the
19 // Department of Physics, Technical University of Denmark, as
20 // described in section 14 of the GNU General Public License.
21 //
22 // This program is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // and the GNU Lesser Public License along with this program.  If not,
29 // see <http://www.gnu.org/licenses/>.
30 
31 #ifndef _VEC_H
32 #define _VEC_H
33 
34 #include "Asap.h"
35 #include <iostream>
36 using std::istream;
37 using std::ostream;
38 
39 namespace ASAPSPACE {
40 
41 /// A 3-vector useful for postions etc.
42 
43 /// The only data is the three positions (and there are no virtual
44 /// functions), so the memory layout of an array of Vecs will be x0,
45 /// y0, z0, x1, y1, z1, x2, ...
46 ///
47 /// Almost all operations are inline for speed.
48 
49 class Vec
50 {
51 public:
52   /// Dummy constructor needed by STL containers.
Vec()53   Vec() {};
54   /// Construct a 3-vector from three doubles.
55   Vec(double x0, double x1, double x2);
56   /// Dot product
57   double operator*(const Vec& v) const;
58   /// Multiplication with scalar
59   Vec operator*(const double& s) const;
60   friend Vec operator*(const double &s, const Vec v);
61   /// Division with scalar
62   Vec operator/(const double& s) const;
63   /// Add two Vecs
64   Vec operator+(const Vec& v) const;
65   /// Subtract two Vecs
66   Vec operator-(const Vec& v) const;
67   /// Unary minus
68   Vec operator-() const;
69   /// Add a Vec to this one.
70   Vec& operator+=(const Vec& v);
71   /// Subtract a vec from this one.
72   Vec& operator-=(const Vec& v);
73   /// Multiply this vec with a scalar
74   Vec& operator*=(double s);
75   /// Divide this Vec with a scalar.
76   Vec& operator/=(double s);
77   /// Vec equality (bitwise!)
78   bool operator==(const Vec &v) const;
79   /// Vec inequality (bitwise!)
80   bool operator!=(const Vec &v) const;
81   /// const indexing
82   double operator[](int n) const;
83   /// Non-const indexing
84   double& operator[](int n);
85   /// Cross product of two Vecs.
86   friend Vec Cross(const Vec& v1, const Vec& v2);
87   /// The length of a Vec
88   friend double Length2(const Vec& v);
89   /// Increment y with a times x.
90   friend void Vaxpy(double a, const Vec& x, Vec& y);
91   /// Print a Vec
92   friend ostream& operator<<(ostream& out, const Vec& v);
93   /// Read a Vec
94   friend istream& operator>>(istream& in, Vec& v);
95 public:
96   ///< The actual data.
97   // Using an array would hinder vectorization by the Intel compiler.
98   double x, y, z;
99 };
100 
Vec(double x0,double x1,double x2)101 inline Vec::Vec(double x0, double x1, double x2)
102 {
103   x = x0;
104   y = x1;
105   z = x2;
106 }
107 
108 inline double Vec::operator*(const Vec& v) const
109 {
110   return x * v.x + y * v.y + z * v.z;
111 }
112 
113 inline Vec Vec::operator*(const double& s) const
114 {
115   return Vec(s * x, s * y, s * z);
116 }
117 
118 inline Vec operator*(const double &s, const Vec v)
119 {
120   return Vec(s * v.x, s * v.y, s * v.z);
121 }
122 
123 inline Vec Vec::operator/(const double& s) const
124 {
125   return Vec(x / s, y / s, z / s);
126 }
127 
128 inline Vec Vec::operator+(const Vec& v) const
129 {
130   return Vec(x + v.x, y + v.y, z + v.z);
131 }
132 
133 inline Vec Vec::operator-(const Vec& v) const
134 {
135   return Vec(x - v.x, y - v.y, z - v.z);
136 }
137 
138 inline Vec Vec::operator-() const
139 {
140   return Vec(-x, -y, -z);
141 }
142 
143 inline Vec& Vec::operator+=(const Vec& v)
144 {
145   x += v.x; y += v.y; z += v.z;
146   return *this;
147 }
148 
149 inline Vec& Vec::operator-=(const Vec& v)
150 {
151   x -= v.x; y -= v.y; z -= v.z;
152   return *this;
153 }
154 
155 inline Vec& Vec::operator*=(double s)
156 {
157   x *= s; y *= s; z *= s;
158   return *this;
159 }
160 
161 inline Vec& Vec::operator/=(double s)
162 {
163   x /= s; y /= s; z /= s;
164   return *this;
165 }
166 
167 inline bool Vec::operator==(const Vec &v) const
168 {
169   return (x == v.x) && (y == v.y) && (z == v.z);
170 }
171 
172 inline bool Vec::operator!=(const Vec &v) const
173 {
174   return !(*this == v);
175 }
176 
177 inline double Vec::operator[](int n) const
178 {
179   return (&x)[n];
180 }
181 
182 inline double& Vec::operator[](int n)
183 {
184   return (&x)[n];
185 }
186 
Cross(const Vec & v1,const Vec & v2)187 inline Vec Cross(const Vec& v1, const Vec& v2)
188 {
189   return Vec(v1.y * v2.z - v1.z * v2.y,
190              v1.z * v2.x - v1.x * v2.z,
191              v1.x * v2.y - v1.y * v2.x);
192 }
193 
Vaxpy(double a,const Vec & x,Vec & y)194 inline void Vaxpy(double a, const Vec& x, Vec& y)
195 {
196   y.x += a * x.x;
197   y.y += a * x.y;
198   y.z += a * x.z;
199 }
200 
Length2(const Vec & v)201 inline double Length2(const Vec& v)
202 {
203   return v.x * v.x + v.y * v.y + v.z * v.z;
204 }
205 
206 } // end namespace
207 
208 #endif // _VEC_H
209 
210