Chi-Tech
chi_meshmatrix3x3.h
Go to the documentation of this file.
1#ifndef _chi_meshmatrix3x3_h
2#define _chi_meshmatrix3x3_h
3
4#include <cmath>
5#include <sstream>
6#include "chi_meshvector.h"
7
9{
10 double vals[9];
11
12 /**Creates a zeros matrix of size 3x3.*/
14 {
15 vals[0] = 0.0; vals[1] = 0.0; vals[2] = 0.0;
16 vals[3] = 0.0; vals[4] = 0.0; vals[5] = 0.0;
17 vals[6] = 0.0; vals[7] = 0.0; vals[8] = 0.0;
18 }
19
20 /**Produces a rotation matrix with a reference vector rotated from the
21 * cartesian basis vectors \f$\hat{i}\f$, \f$\hat{j}\f$ and \f$\hat{k}\f$.
22 *
23 * By default a rotation matrix that creates no rotation is
24 * the identity matrix. Such a matrix can be defined from basis vectors
25 * following the notion that the "up-vector" is \f$\hat{k}\f$,
26 * this is also called the normal vector \f$\hat{n}\f$.
27 * The tangent vector is \f$\hat{i}\f$, denoted with \f$\hat{t}\f$.
28 * And the bi-norm vector is \f$\hat{j}\f$, denoted with \f$\hat{b}\f$.
29 *
30 * By specifying only the normal vector we can compute a simple pitch based
31 * rotation matrix. The supplied vector is therefore the new normal-vector,
32 * the tangent vector is computed as \f$ \hat{t} = \hat{n} \times \hat{k} \f$,
33 * and the bi-norm vector is computed as
34 * \f$ \hat{b} = \hat{n} \times \hat{t} \f$*/
36 {
38
39 chi_mesh::Vector3 n = vec;
40 chi_mesh::Vector3 khat(0.0, 0.0, 1.0);
41
42 if (n.Dot(khat) > 0.9999999)
43 R.SetDiagonalVec(1.0,1.0,1.0);
44 else if (n.Dot(khat) < -0.9999999)
45 R.SetDiagonalVec(1.0,1.0,-1.0);
46 else
47 {
48 auto tangent = n.Cross(khat ).Normalized();
49 auto binorm = n.Cross(tangent).Normalized();
50
51 R.SetColJVec(0,tangent);
52 R.SetColJVec(1,binorm);
53 R.SetColJVec(2,n);
54 }
55 return R;
56 }
57
58 /**Copy constructor*/
60 {
61 for (int k=0;k<9;k++)
62 this->vals[k] = inM.vals[k];
63 return *this;
64 }
65
66 /**Matrix addition operator.*/
68 {
69 Matrix3x3 oM;
70 for (int k=0;k<9;k++)
71 oM.vals[k] = this->vals[k] + inM.vals[k];
72 return oM;
73 }
74
75 /**Matrix subtraction operator.*/
77 {
78 Matrix3x3 oM;
79 for (int k=0;k<9;k++)
80 oM.vals[k] = this->vals[k] - inM.vals[k];
81 return oM;
82 }
83
84 /**Matrix multiply with scalar.*/
85 Matrix3x3 operator*(const double value)
86 {
87 Matrix3x3 oM;
88 for (int k=0; k<9; k++)
89 {
90 oM.vals[k] = this->vals[k]*value;
91 }
92 return oM;
93 }
94
95 /**Matrix multiply with vector.*/
96 Vector3 operator*(const Vector3& vec) const
97 {
98 double i_vec[] = {vec.x,vec.y,vec.z};
99 double o_vec[] = {0.0,0.0,0.0};
100
101 for (int i=0;i<3;i++)
102 {
103 for (int j=0;j<3;j++)
104 {
105 o_vec[i] += this->GetIJ(i,j)*i_vec[j];
106 }
107 }
108 Vector3 oV(o_vec[0], o_vec[1], o_vec[2]);
109 return oV;
110 }
111
112 /**Set value at row i and column j.*/
113 void SetIJ(int i, int j, double value)
114 {
115 int k = j + 3*i;
116 vals[k] = value;
117 }
118
119 /**Add value to value at row i and column j.*/
120 void AddIJ(int i, int j, double value)
121 {
122 int k = j + 3*i;
123 vals[k] += value;
124 }
125
126 /**Obtain a copy of the value at row i and column j.*/
127 double GetIJ(int i, int j) const
128 {
129 int k = j + 3*i;
130 return vals[k];
131 }
132
133 /**Set row i using a vector.*/
134 void SetRowIVec(int i, Vector3 vec)
135 {
136 vals[0 + 3*i] = vec.x;
137 vals[1 + 3*i] = vec.y;
138 vals[2 + 3*i] = vec.z;
139 }
140
141 /**Set column j using a vector.*/
142 void SetColJVec(int j, Vector3 vec)
143 {
144 vals[j + 3*0] = vec.x;
145 vals[j + 3*1] = vec.y;
146 vals[j + 3*2] = vec.z;
147 }
148
149 /**Sets the diagonal of the matrix.*/
150 void SetDiagonalVec(double a00,double a11, double a22)
151 {
152 vals[0 + 3*0] = a00;
153 vals[1 + 3*1] = a11;
154 vals[2 + 3*2] = a22;
155 }
156
157 /**Get the determinant using specified row [default:0].*/
158 double Det(int row=0)
159 {
160 double det=0.0;
161
162 int sign = -1;
163 for (int j=0; j<3; j++)
164 {
165 int k = j + 3*row;
166 sign *= -1;
167
168 det += sign*GetIJ(row,j)*MinorIJ(row,j);
169 }
170
171 return det;
172 }
173
174 /**Get the minor value associated with row ir and column jr.*/
175 double MinorIJ(int ir, int jr)
176 {
177 double a[] = {0.0,0.0,0.0,0.0};
178
179 int k = -1;
180 for (int i=0; i<3; i++)
181 {
182 if (i==ir) continue;
183
184 for (int j=0; j<3; j++)
185 {
186 if (j==jr) continue;
187
188 k++;
189 int kr = j + 3*i;
190 a[k] = vals[kr];
191 }
192 }
193
194 return a[0]*a[3]-a[2]*a[1];
195 }
196
197 /**Compute the matrix transpose.*/
199 {
200 Matrix3x3 oM;
201 for (int i=0; i<3; i++)
202 {
203 for (int j=0; j<3; j++)
204 {
205 int kO = j + 3*i;
206 int kI = i + 3*j;
207
208 oM.vals[kO] = vals[kI];
209 }
210 }
211 return oM;
212 }
213
214 /**Compute the matrix transpose.*/
216 {
217 Matrix3x3 oM;
218 Matrix3x3 oMT;
219
220 //================================= Compute matrix of minors
221 for (int i=0; i<3; i++)
222 {
223 for (int j=0; j<3; j++)
224 {
225 oM.SetIJ(i,j,MinorIJ(i,j));
226 }
227 }
228
229 //================================= Compute matrix of cofactors
230 int sign = -1;
231 for (int i=0; i<3; i++)
232 {
233 for (int j=0; j<3; j++)
234 {
235 sign*=-1;
236 oM.SetIJ(i,j,oM.GetIJ(i,j)*sign);
237 }
238 }
239
240 //================================= Compute the transpose
241 oMT = oM.Transpose();
242
243 //================================= Get determinant
244 double det = Det();
245
246 return oMT*(1.0/det);
247 }
248
249 /**Outputs the matrix to a stream.*/
250 friend std::ostream & operator<< (std::ostream& out, Matrix3x3& inM)
251 {
252 out << "[";
253 for (int i=0;i<3;i++)
254 {
255 for (int j=0;j<3;j++)
256 {
257 out << inM.GetIJ(i,j) << " ";
258 }
259 if (i!=2)
260 out << "\n";
261 else
262 out << "]\n";
263 }
264
265 return out;
266 }
267
268 std::string PrintS()
269 {
270 std::stringstream out;
271 out << "[";
272 for (int i=0;i<3;i++)
273 {
274 for (int j=0;j<3;j++)
275 {
276 out << GetIJ(i,j) << " ";
277 }
278 if (i!=2)
279 out << "\n ";
280 else
281 out << "]";
282 }
283
284 return out.str();
285 }
286
287};
288
289#endif
void SetColJVec(int j, Vector3 vec)
void SetDiagonalVec(double a00, double a11, double a22)
Matrix3x3 operator*(const double value)
double MinorIJ(int ir, int jr)
friend std::ostream & operator<<(std::ostream &out, Matrix3x3 &inM)
static Matrix3x3 MakeRotationMatrixFromVector(const Vector3 &vec)
void SetIJ(int i, int j, double value)
void AddIJ(int i, int j, double value)
void SetRowIVec(int i, Vector3 vec)
Matrix3x3 & operator=(const Matrix3x3 &inM)
double GetIJ(int i, int j) const
Vector3 operator*(const Vector3 &vec) const
Matrix3x3 operator+(const Matrix3x3 &inM)
Matrix3x3 operator-(const Matrix3x3 &inM)
double Det(int row=0)
double x
Element-0.
Vector3 Cross(const Vector3 &that) const
Vector3 Normalized() const
Vector3 Dot(const chi_mesh::TensorRank2Dim3 &that) const
double y
Element-1.
double z
Element-2.