Chi-Tech
chi_meshvector.h
Go to the documentation of this file.
1#ifndef CHI_MESH_VECTOR3_H
2#define CHI_MESH_VECTOR3_H
3#include<iostream>
4#include<cmath>
5#include <sstream>
6
7namespace chi_mesh
8{
9 struct TensorRank2Dim3;
10}
11
12//namespace chi_mesh
13//{
14//=============================================== General 3D vector structure
15/**General 3 element vector structure.
16 * \author Jan
17*/
19{
20 double x; ///< Element-0
21 double y; ///< Element-1
22 double z; ///< Element-2
23
24 /**Default constructor. Initialized as all zeros.*/
26 x=0.0; y=0.0; z=0.0;
27 }
28
29 /**Constructor where single element is initialized \f$ x[z]=a \f$.*/
30 explicit Vector3(double a){
31 x=a; y=0.0; z=0.0;
32 }
33
34 /**Constructor where \f$ x=a\f$ and \f$ y=b \f$. */
35 explicit Vector3(double a, double b){
36 x=a; y=b; z=0.0;
37 }
38
39 /**Constructor where \f$ \vec{x}=[a,b,c] \f$.*/
40 explicit Vector3(double a, double b, double c){
41 x=a; y=b; z=c;
42 }
43
44 /**Constructor where \f$ \vec{x}=\{a,b,c\} \f$.*/
45 Vector3(std::initializer_list<double> list)
46 {
47 if (not empty(list))
48 {
49 std::vector<double> vec = list;
50 for (size_t i=0; ( (i<3) and ( i<vec.size() ) ); ++i)
51 {
52 if (i==0) x = vec[i];
53 if (i==1) y = vec[i];
54 if (i==2) z = vec[i];
55 }
56 }
57 }
58
59 /**Constructor where \f$ \vec{x}=\{a,b,c\} \f$.*/
60 explicit Vector3(const std::vector<double>& list)
61 {
62 if (not empty(list))
63 {
64 std::vector<double> vec = list;
65 for (size_t i=0; ( (i<3) and ( i<vec.size() ) ); ++i)
66 {
67 if (i==0) x = vec[i];
68 if (i==1) y = vec[i];
69 if (i==2) z = vec[i];
70 }
71 }
72 }
73
74 /**Copy constructor.*/
75 Vector3(const Vector3& that)
76 {
77 this->x = that.x;
78 this->y = that.y;
79 this->z = that.z;
80 }
81
82 /**Assignment operator.*/
84 {
85 this->x = that.x;
86 this->y = that.y;
87 this->z = that.z;
88
89 return *this;
90 }
91
92 Vector3& operator=(std::initializer_list<double> list)
93 {
94 if (not empty(list))
95 {
96 std::vector<double> vec = list;
97 for (size_t i=0; ( (i<3) and ( i<vec.size() ) ); ++i)
98 {
99 this->operator()(i) = vec[i];
100 }
101 }
102
103 return *this;
104 }
105
106 Vector3& operator=(const std::vector<double>& list)
107 {
108 if (not empty(list))
109 {
110 std::vector<double> vec = list;
111 for (size_t i=0; ( (i<3) and ( i<vec.size() ) ); ++i)
112 {
113 this->operator()(i) = vec[i];
114 }
115 }
116
117 return *this;
118 }
119
120 //============================================= Addition
121 /**Component-wise addition of two vectors.
122 * \f$ \vec{w} = \vec{x} + \vec{y} \f$*/
123 Vector3 operator+(const Vector3& that) const
124 {
125 Vector3 newVector;
126 newVector.x = this->x + that.x;
127 newVector.y = this->y + that.y;
128 newVector.z = this->z + that.z;
129
130 return newVector;
131 }
132
133 /**In-place component-wise addition of two vectors.
134 * \f$ \vec{x} = \vec{x} + \vec{y} \f$*/
136 {
137 this->x += that.x;
138 this->y += that.y;
139 this->z += that.z;
140
141 return *this;
142 }
143
144 /**Component-wise shift by scalar-value.
145 * \f$ \vec{w} = \vec{x} + \alpha \f$*/
146 Vector3 Shifted(const double value) const
147 {
148 Vector3 newVector;
149 newVector.x = this->x + value;
150 newVector.y = this->y + value;
151 newVector.z = this->z + value;
152
153 return newVector;
154 }
155
156 /**In-place component-wise shift by scalar-value.
157 * \f$ \vec{x} = \vec{x} + \alpha \f$*/
158 Vector3& Shift(const double value)
159 {
160 this->x += value;
161 this->y += value;
162 this->z += value;
163
164 return *this;
165 }
166
167 //============================================= Subtraction
168 /**Component-wise subtraction.
169 * \f$ \vec{w} = \vec{x} - \vec{y} \f$*/
170 Vector3 operator-(const Vector3& that) const
171 {
172 Vector3 newVector;
173 newVector.x = this->x - that.x;
174 newVector.y = this->y - that.y;
175 newVector.z = this->z - that.z;
176
177 return newVector;
178 }
179
180 /**In-place component-wise subtraction.
181 * \f$ \vec{x} = \vec{x} - \vec{y} \f$*/
183 {
184 this->x -= that.x;
185 this->y -= that.y;
186 this->z -= that.z;
187
188 return *this;
189 }
190
191 //============================================= Multiplication
192 /**Vector component-wise multiplication by scalar.
193 * \f$ \vec{w} = \vec{x} \alpha \f$*/
194 Vector3 operator*(const double value) const
195 {
196 Vector3 newVector;
197 newVector.x = this->x*value;
198 newVector.y = this->y*value;
199 newVector.z = this->z*value;
200
201 return newVector;
202 }
203
204 /**Vector in-place component-wise multiplication by scalar.
205 * \f$ \vec{x} = \vec{x} \alpha \f$*/
206 Vector3& operator*=(const double value)
207 {
208 this->x*=value;
209 this->y*=value;
210 this->z*=value;
211
212 return *this;
213 }
214
215 /**Vector component-wise multiplication.
216 * \f$ w_i = x_i y_i \f$*/
217 Vector3 operator*(const Vector3& that) const
218 {
219 Vector3 newVector;
220 newVector.x = this->x*that.x;
221 newVector.y = this->y*that.y;
222 newVector.z = this->z*that.z;
223
224 return newVector;
225 }
226
227 /**Vector in-place component-wise multiplication.
228 * \f$ x_i = x_i y_i \f$*/
230 {
231 this->x*=that.x;
232 this->y*=that.y;
233 this->z*=that.z;
234
235 return *this;
236 }
237
238 //============================================= Division
239 /**Vector component-wise division by scalar.
240 * \f$ w_i = \frac{x_i}{\alpha} \f$*/
241 Vector3 operator/(const double value) const
242 {
243 Vector3 newVector;
244 newVector.x = this->x/value;
245 newVector.y = this->y/value;
246 newVector.z = this->z/value;
247
248 return newVector;
249 }
250
251 /**Vector in-place component-wise division by scalar.
252 * \f$ x_i = \frac{x_i}{\alpha} \f$*/
253 Vector3& operator/=(const double value)
254 {
255 this->x/=value;
256 this->y/=value;
257 this->z/=value;
258
259 return *this;
260 }
261
262 /**Vector component-wise division.
263 * \f$ w_i = \frac{x_i}{y_i} \f$*/
264 Vector3 operator/(const Vector3& that) const
265 {
266 Vector3 newVector;
267 newVector.x = this->x/that.x;
268 newVector.y = this->y/that.y;
269 newVector.z = this->z/that.z;
270
271 return newVector;
272 }
273
274 /**Vector in-place component-wise division.
275 * \f$ x_i = \frac{x_i}{y_i} \f$*/
277 {
278 this->x/=that.x;
279 this->y/=that.y;
280 this->z/=that.z;
281
282 return *this;
283 }
284
285 //============================================= Element access
286 /**Returns a copy of the value at the given index.*/
287 double operator[](const size_t i) const
288 {
289 if (i==0) return this->x;
290 else if (i==1) return this->y;
291 else if (i==2) return this->z;
292
293 return 0.0;
294 }
295
296 /**Returns a reference of the value at the given index.*/
297 double& operator()(const size_t i)
298 {
299 if (i==0) return this->x;
300 else if (i==1) return this->y;
301 else if (i==2) return this->z;
302
303 return this->x;
304 }
305
306 //============================================= Tensor product
307 //Defined in chi_mesh_utilities.cc
308 chi_mesh::TensorRank2Dim3 OTimes(const Vector3& that) const;
309
310 //============================================= Tensor dot product
311 //Defined in chi_mesh_utilities.cc
312 Vector3 Dot(const chi_mesh::TensorRank2Dim3& that) const;
313
314 //============================================= Operations
315 /**Vector cross-product.
316 * \f$ \vec{w} = \vec{x} \times \vec{y} \f$*/
317 Vector3 Cross(const Vector3& that) const
318 {
319 Vector3 newVector;
320 newVector.x = this->y*that.z - this->z*that.y;
321 newVector.y = this->z*that.x - this->x*that.z;
322 newVector.z = this->x*that.y - this->y*that.x;
323
324 return newVector;
325 }
326
327 /**Vector dot-product.
328 * \f$ \vec{w} = \vec{x} \bullet \vec{y} \f$ */
329 double Dot(const Vector3& that) const
330 {
331 double value = 0.0;
332 value += this->x*that.x;
333 value += this->y*that.y;
334 value += this->z*that.z;
335
336 return value;
337 }
338
339 /**Computes the L2-norm of the vector. Otherwise known as the length of
340 * a 3D vector.*/
341 double Norm() const
342 {
343 double value = 0.0;
344 value += this->x*this->x;
345 value += this->y*this->y;
346 value += this->z*this->z;
347
348 value = sqrt(value);
349
350 return value;
351 }
352
353 /**Computes the square of the L2-norm of the vector. This eliminates the
354 * usage of the square root and is therefore less expensive that a proper
355 * L2-norm. Useful if only comparing distances.*/
356 double NormSquare() const
357 {
358 double value = 0.0;
359 value += this->x*this->x;
360 value += this->y*this->y;
361 value += this->z*this->z;
362
363 return value;
364 }
365
366 /**Normalizes the vector in-place.
367 * \f$ \vec{x} = \frac{\vec{x}}{||x||_2} \f$*/
369 {
370 double norm = this->Norm();
371
372 x /= norm;
373 y /= norm;
374 z /= norm;
375 }
376
377 /**Returns a normalized version of the vector.
378 * \f$ \vec{w} = \frac{\vec{x}}{||x||_2} \f$*/
380 {
381 double norm = this->Norm();
382
383 Vector3 newVector;
384 newVector.x = this->x/norm;
385 newVector.y = this->y/norm;
386 newVector.z = this->z/norm;
387
388 return newVector;
389 }
390
391 /**Returns a vector v^* where each element is inverted provided
392 * that it is greater than the given tolerance, otherwise the offending entry
393 * is set to 0.0.
394 * \f$ w_i = \frac{1.0}{x_i} \f$*/
395 Vector3 InverseZeroIfSmaller(const double tol) const
396 {
397 Vector3 newVector;
398 newVector.x = (std::fabs(this->x)>tol)? 1.0/this->x : 0.0;
399 newVector.y = (std::fabs(this->y)>tol)? 1.0/this->y : 0.0;
400 newVector.z = (std::fabs(this->z)>tol)? 1.0/this->z : 0.0;
401
402 return newVector;
403 }
404
405 /**Returns a vector v^* where each element is inverted provided
406 * that it is greater than the given tolerance, otherwise the offending entry
407 * is set to 1.0.
408 * \f$ w_i = \frac{1.0}{x_i} \f$*/
409 Vector3 InverseOneIfSmaller(const double tol) const
410 {
411 Vector3 newVector;
412 newVector.x = (std::fabs(this->x)>tol)? 1.0/this->x : 1.0;
413 newVector.y = (std::fabs(this->y)>tol)? 1.0/this->y : 1.0;
414 newVector.z = (std::fabs(this->z)>tol)? 1.0/this->z : 1.0;
415
416 return newVector;
417 }
418
419 /**Returns a vector v^* where each element is inverted without any
420 * check for division by zero.
421 * \f$ w_i = \frac{1.0}{x_i} \f$*/
423 {
424 Vector3 newVector;
425 double dx_inv = 1.0/this->x;
426 double dy_inv = 1.0/this->y;
427 double dz_inv = 1.0/this->z;
428
429 return newVector;
430 }
431
432 /**Prints the vector to std::cout.*/
433 void Print() const
434 {
435 std::cout<<this->x << " ";
436 std::cout<<this->y << " ";
437 std::cout<<this->z;
438 }
439
440 friend std::ostream & operator<< (std::ostream& out, Vector3& v)
441 {
442 out << "[" << v.x << " " << v.y << " " << v.z << "]";
443
444 return out;
445 }
446
447 /**Deprecated. Prints the vector to a string and then returns the string.*/
448 std::string PrintS() const //TODO: Deprecated
449 {
450 std::stringstream out;
451 out << "[" << x << " " << y << " " << z << "]";
452
453 return out.str();
454 }
455
456 /**Prints the vector to a string and then returns the string.*/
457 std::string PrintStr() const
458 {
459 std::stringstream out;
460 out << "[" << x << " " << y << " " << z << "]";
461
462 return out.str();
463 }
464
465 static size_t Size()
466 {
467 return 3;
468 }
469};
470
471//The following functions are defined in chi_mesh_utilities.cc
472//Left multiplcation by scalar
473chi_mesh::Vector3 operator*(double value,const chi_mesh::Vector3& that);
474
475//}//namespace chi_mesh
476
477#endif //CHI_MESH_VECTOR3_H
chi_mesh::Vector3 operator*(double value, const chi_mesh::Vector3 &that)
Vector3(double a, double b, double c)
Vector3 Inverse() const
Vector3 operator/(const Vector3 &that) const
Vector3(std::initializer_list< double > list)
std::string PrintS() const
Vector3 & operator/=(const Vector3 &that)
Vector3 & operator=(std::initializer_list< double > list)
double NormSquare() const
Vector3 & operator*=(const double value)
static size_t Size()
Vector3 & operator+=(const Vector3 &that)
std::string PrintStr() const
Vector3(const Vector3 &that)
void Print() const
double x
Element-0.
Vector3 Shifted(const double value) const
double & operator()(const size_t i)
double operator[](const size_t i) const
Vector3 Cross(const Vector3 &that) const
Vector3 & Shift(const double value)
Vector3 operator/(const double value) const
Vector3 & operator/=(const double value)
Vector3 Normalized() const
Vector3 operator-(const Vector3 &that) const
Vector3 Dot(const chi_mesh::TensorRank2Dim3 &that) const
Vector3(const std::vector< double > &list)
chi_mesh::TensorRank2Dim3 OTimes(const Vector3 &that) const
Vector3 & operator=(const std::vector< double > &list)
double y
Element-1.
friend std::ostream & operator<<(std::ostream &out, Vector3 &v)
Vector3 InverseOneIfSmaller(const double tol) const
double z
Element-2.
Vector3 operator*(const Vector3 &that) const
double Norm() const
Vector3 & operator*=(const Vector3 &that)
Vector3(double a, double b)
Vector3 operator+(const Vector3 &that) const
double Dot(const Vector3 &that) const
Vector3 & operator-=(const Vector3 &that)
Vector3 InverseZeroIfSmaller(const double tol) const
Vector3 operator*(const double value) const
Vector3 & operator=(const Vector3 &that)