1 #ifndef OMEGA_H_MATRIX_HPP
2 #define OMEGA_H_MATRIX_HPP
4 #include <Omega_h_array.hpp>
5 #include <Omega_h_vector.hpp>
11 #ifdef OMEGA_H_USE_KOKKOS
13 template <Int m, Int n>
14 class Matrix :
public Few<Vector<m>, n> {
16 OMEGA_H_INLINE Matrix() {}
20 inline Matrix(std::initializer_list<Vector<m>> l) : Few<Vector<m>, n>(l) {}
21 inline Matrix(std::initializer_list<Real> l);
22 OMEGA_H_INLINE Matrix(Matrix<m, n>
const& rhs) : Few<Vector<m>, n>(rhs) {}
23 OMEGA_H_INLINE Real& operator()(Int i, Int j) {
24 return Few<Vector<m>, n>::operator[](j)[i];
26 OMEGA_H_INLINE Real
const& operator()(Int i, Int j)
const {
27 return Few<Vector<m>, n>::operator[](j)[i];
33 template <Int m, Int n>
41 inline Matrix(std::initializer_list<Real> l);
46 OMEGA_H_INLINE Real& operator()(Int i, Int j) OMEGA_H_NOEXCEPT {
49 OMEGA_H_INLINE Real
const& operator()(Int i, Int j)
const OMEGA_H_NOEXCEPT {
59 template <Int m, Int n>
63 template <Int m, Int n>
64 OMEGA_H_INLINE Real
const* scalar_ptr(Matrix<m, n>
const& a) {
68 template <Int m, Int n>
69 inline Matrix<m, n>::Matrix(std::initializer_list<Real> l) {
72 (*this)[k % n][k / n] = v;
77 template <Int m, Int n>
78 OMEGA_H_INLINE Vector<m> operator*(
79 Matrix<m, n> a, Vector<n> b)OMEGA_H_NOEXCEPT {
80 Vector<m> c = a[0] * b[0];
81 for (Int j = 1; j < n; ++j) c = c + a[j] * b[j];
85 template <Int m, Int n, Int p>
86 OMEGA_H_INLINE Matrix<m, n> operator*(Matrix<m, p> a, Matrix<p, n> b) {
88 for (Int j = 0; j < n; ++j) c[j] = a * b[j];
92 template <Int m, Int n>
93 OMEGA_H_INLINE Matrix<n, m> transpose(Matrix<m, n> a) {
95 for (Int i = 0; i < m; ++i)
96 for (Int j = 0; j < n; ++j) b[i][j] = a[j][i];
100 template <Int max_m, Int max_n>
101 OMEGA_H_INLINE Matrix<max_m, max_n> identity_matrix(Int m, Int n) {
102 Matrix<max_m, max_n> a;
103 for (Int j = 0; j < n; ++j)
104 for (Int i = 0; i < m; ++i) a[j][i] = (i == j);
108 template <Int max_m, Int max_n>
109 OMEGA_H_INLINE Matrix<max_m, max_n> identity_matrix() {
110 return identity_matrix<max_m, max_n>(max_m, max_n);
114 OMEGA_H_INLINE Tensor<dim> identity_tensor() {
115 return identity_matrix<dim, dim>();
118 OMEGA_H_INLINE Matrix<1, 1> matrix_1x1(Real a) {
124 OMEGA_H_INLINE Tensor<1> tensor_1(Real a) {
return matrix_1x1(a); }
126 OMEGA_H_INLINE Matrix<2, 2> matrix_2x2(Real a, Real b, Real c, Real d) {
128 o[0] = vector_2(a, c);
129 o[1] = vector_2(b, d);
133 OMEGA_H_INLINE Tensor<2> tensor_2(Real a, Real b, Real c, Real d) {
134 return matrix_2x2(a, b, c, d);
137 OMEGA_H_INLINE Matrix<3, 3> matrix_3x3(
138 Real a, Real b, Real c, Real d, Real e, Real f, Real g, Real h, Real i) {
140 o[0] = vector_3(a, d, g);
141 o[1] = vector_3(b, e, h);
142 o[2] = vector_3(c, f, i);
146 OMEGA_H_INLINE Tensor<3> tensor_3(
147 Real a, Real b, Real c, Real d, Real e, Real f, Real g, Real h, Real i) {
148 return matrix_3x3(a, b, c, d, e, f, g, h, i);
151 template <Int m, Int n>
152 OMEGA_H_INLINE Matrix<m, n> operator*(Matrix<m, n> a, Real b) {
154 for (Int j = 0; j < n; ++j) c[j] = a[j] * b;
158 template <Int m, Int n>
159 OMEGA_H_INLINE Matrix<m, n>& operator*=(Matrix<m, n>& a, Real b) {
164 template <Int m, Int n>
165 OMEGA_H_INLINE Matrix<m, n> operator*(Real a, Matrix<m, n> b) {
169 template <Int m, Int n>
170 OMEGA_H_INLINE Matrix<m, n> operator/(Matrix<m, n> a, Real b) {
172 for (Int j = 0; j < n; ++j) c[j] = a[j] / b;
176 template <Int m, Int n>
177 OMEGA_H_INLINE Matrix<m, n>& operator/=(Matrix<m, n>& a, Real b) {
182 template <Int m, Int n>
183 OMEGA_H_INLINE Matrix<m, n> operator+(Matrix<m, n> a, Matrix<m, n> b) {
185 for (Int j = 0; j < n; ++j) c[j] = a[j] + b[j];
189 template <Int m, Int n>
190 OMEGA_H_INLINE Matrix<m, n>& operator+=(Matrix<m, n>& a, Matrix<m, n> b) {
195 template <Int m, Int n>
196 OMEGA_H_INLINE Matrix<m, n> operator-(Matrix<m, n> a, Matrix<m, n> b) {
198 for (Int j = 0; j < n; ++j) c[j] = a[j] - b[j];
202 template <Int m, Int n>
203 OMEGA_H_INLINE Matrix<m, n>& operator-=(Matrix<m, n>& a, Matrix<m, n> b) {
208 template <Int m, Int n>
209 OMEGA_H_INLINE Matrix<m, n> operator-(Matrix<m, n> a) {
211 for (Int j = 0; j < n; ++j) c[j] = -a[j];
215 template <Int m, Int n>
216 OMEGA_H_INLINE Real max_norm(Matrix<m, n> a) {
218 for (Int j = 0; j < n; ++j)
219 for (Int i = 0; i < m; ++i) x = max2(x, std::abs(a[j][i]));
223 template <Int m, Int n>
224 OMEGA_H_INLINE
bool are_close(
225 Matrix<m, n> a, Matrix<m, n> b, Real tol = EPSILON, Real floor = EPSILON) {
226 for (Int j = 0; j < n; ++j)
227 if (!are_close(a[j], b[j], tol, floor))
return false;
231 template <Int m, Int n>
232 OMEGA_H_INLINE Matrix<m, n> outer_product(Vector<m> a, Vector<n> b) {
234 for (Int j = 0; j < n; ++j)
235 for (Int i = 0; i < m; ++i) c[j][i] = a[i] * b[j];
240 OMEGA_H_INLINE Real trace(Tensor<m> a) {
242 for (Int i = 1; i < m; ++i) t += a[i][i];
247 OMEGA_H_INLINE Vector<m> diagonal(Tensor<m> a) {
249 for (Int i = 0; i < m; ++i) v[i] = a[i][i];
253 template <Int m, Int n>
254 OMEGA_H_INLINE Matrix<m, n> zero_matrix() {
256 for (Int j = 0; j < n; ++j) a[j] = zero_vector<m>();
260 OMEGA_H_INLINE Real determinant(Tensor<1> m) {
return m[0][0]; }
262 OMEGA_H_INLINE Real determinant(Tensor<2> m) {
267 return a * d - b * c;
270 OMEGA_H_INLINE Real determinant(Tensor<3> m) {
280 return (a * e * i) + (b * f * g) + (c * d * h) - (c * e * g) - (b * d * i) -
284 template <Int max_m, Int max_n>
285 OMEGA_H_INLINE Real inner_product(
286 Int m, Int n, Matrix<max_m, max_n> a, Matrix<max_m, max_n> b) {
288 for (Int j = 0; j < n; ++j) {
289 for (Int i = 0; i < m; ++i) {
290 out += a[j][i] * b[j][i];
296 template <Int m, Int n>
297 OMEGA_H_INLINE Real inner_product(Matrix<m, n> a, Matrix<m, n> b) {
298 return inner_product(m, n, a, b);
301 template <Int max_m, Int max_n>
302 OMEGA_H_INLINE Real norm(
303 Int
const m, Int
const n, Matrix<max_m, max_n>
const & a) {
304 return std::sqrt(inner_product(m, n, a, a));
307 template <Int m, Int n>
308 OMEGA_H_INLINE Real norm(Matrix<m, n>
const & a) {
309 return norm(m, n, a);
312 OMEGA_H_INLINE Tensor<3> cross(Vector<3>
const & a) {
313 return matrix_3x3(0, -a[2], a[1], a[2], 0, -a[0], -a[1], a[0], 0);
316 OMEGA_H_INLINE Vector<3> uncross(Tensor<3>
const & c) {
318 vector_3(c[1][2] - c[2][1], c[2][0] - c[0][2], c[0][1] - c[1][0]);
321 OMEGA_H_INLINE Tensor<1> invert(Tensor<1>
const & m) {
322 return matrix_1x1(1.0 / m[0][0]);
325 OMEGA_H_INLINE Tensor<2> invert(Tensor<2>
const & m) {
330 return matrix_2x2(d, -b, -c, a) / determinant(m);
333 OMEGA_H_INLINE Tensor<3> invert(Tensor<3>
const & a) {
335 b[0] = cross(a[1], a[2]);
336 b[1] = cross(a[2], a[0]);
337 b[2] = cross(a[0], a[1]);
338 return transpose(b) / determinant(a);
341 template <Int m, Int n>
342 OMEGA_H_INLINE
typename std::enable_if<(n == m), Matrix<n, m>>::type
343 pseudo_invert(Matrix<m, n>
const & a) {
347 template <Int m, Int n>
348 OMEGA_H_INLINE
typename std::enable_if<(n < m), Matrix<n, m>>::type
349 pseudo_invert(Matrix<m, n>
const &a) {
350 auto at = transpose(a);
351 return invert(at * a) * at;
354 template <Int m, Int n>
355 OMEGA_H_INLINE
typename std::enable_if<(n > m), Matrix<n, m>>::type
356 pseudo_invert(Matrix<m, n>
const &a) {
357 auto at = transpose(a);
358 return at * invert(a * at);
362 OMEGA_H_INLINE Tensor<m> diagonal(Vector<m> v) {
364 for (Int i = 0; i < m; ++i)
365 for (Int j = i + 1; j < m; ++j) a[i][j] = a[j][i] = 0.0;
366 for (Int i = 0; i < m; ++i) a[i][i] = v[i];
370 OMEGA_H_INLINE constexpr Int symm_ncomps(Int dim) {
371 return ((dim + 1) * dim) / 2;
374 OMEGA_H_INLINE Vector<1> symm2vector(Tensor<1> symm) {
375 return vector_1(symm[0][0]);
378 OMEGA_H_INLINE Tensor<1> vector2symm(Vector<1> v) {
return matrix_1x1(v[0]); }
380 OMEGA_H_INLINE Vector<3> symm2vector(Tensor<2> symm) {
388 OMEGA_H_INLINE Tensor<2> vector2symm(Vector<3> v) {
393 symm[0][1] = symm[1][0];
397 OMEGA_H_INLINE Vector<6> symm2vector(Tensor<3> symm) {
408 OMEGA_H_INLINE Tensor<3> vector2symm(Vector<6> v) {
416 symm[0][1] = symm[1][0];
417 symm[1][2] = symm[2][1];
418 symm[0][2] = symm[2][0];
424 OMEGA_H_INLINE Tensor<1> vector2symm_inria(Vector<1> v) {
425 return matrix_1x1(v[0]);
428 OMEGA_H_INLINE Tensor<2> vector2symm_inria(Vector<3> v) {
433 symm[1][0] = symm[0][1];
437 OMEGA_H_INLINE Tensor<3> vector2symm_inria(Vector<6> v) {
445 symm[1][0] = symm[0][1];
446 symm[2][0] = symm[0][2];
447 symm[2][1] = symm[1][2];
451 OMEGA_H_INLINE Vector<1> symm2vector_inria(Tensor<1> symm) {
452 return vector_1(symm[0][0]);
455 OMEGA_H_INLINE Vector<3> symm2vector_inria(Tensor<2> symm) {
463 OMEGA_H_INLINE Vector<6> symm2vector_inria(Tensor<3> symm) {
474 OMEGA_H_INLINE constexpr Int matrix_ncomps(Int m, Int n) {
return m * n; }
476 template <Int m, Int n>
477 OMEGA_H_INLINE Vector<matrix_ncomps(m, n)> matrix2vector(Matrix<m, n> a) {
478 Vector<matrix_ncomps(m, n)> v;
479 for (Int i = 0; i < m; ++i) {
480 for (Int j = 0; j < n; ++j) {
481 v[i * n + j] = a(i, j);
487 template <Int m, Int n>
488 OMEGA_H_INLINE Matrix<m, n> vector2matrix(Vector<matrix_ncomps(m, n)> v) {
490 for (Int i = 0; i < m; ++i) {
491 for (Int j = 0; j < n; ++j) {
492 a(i, j) = v[i * n + j];
499 OMEGA_H_DEVICE
void set_symm(Write<Real>
const& a, Int i, Tensor<n> symm) {
500 set_vector(a, i, symm2vector(symm));
503 template <Int n,
typename Arr>
504 OMEGA_H_DEVICE Tensor<n> get_symm(Arr
const& a, Int i) {
505 return vector2symm(get_vector<symm_ncomps(n)>(a, i));
508 template <Int m, Int n>
509 OMEGA_H_DEVICE
void set_matrix(
510 Write<Real>
const& matrices, Int i, Matrix<m, n> matrix) {
511 set_vector(matrices, i, matrix2vector(matrix));
514 template <Int m, Int n,
typename Arr>
515 OMEGA_H_DEVICE Matrix<m, n> get_matrix(Arr
const& matrices, Int
const i) {
516 return vector2matrix<m, n>(get_vector<matrix_ncomps(m, n)>(matrices, i));
520 OMEGA_H_INLINE Tensor<3> rotate(Real
const angle, Vector<3>
const axis) {
521 return std::cos(angle) * identity_matrix<3, 3>() +
522 std::sin(angle) * cross(axis) +
523 (1 - std::cos(angle)) * outer_product(axis, axis);
526 OMEGA_H_INLINE Tensor<2> rotate(Real
const angle) {
528 std::cos(angle), -std::sin(angle), std::sin(angle), std::cos(angle));
531 OMEGA_H_INLINE Real rotation_angle(Tensor<2>
const r) {
532 auto const cos_theta = 0.5 * trace(r);
533 auto const sin_theta = 0.5 * (r(1, 0) - r(0, 1));
534 return std::atan2(sin_theta, cos_theta);
537 OMEGA_H_INLINE Real rotation_angle(Tensor<3>
const r) {
538 auto const cos_theta = 0.5 * (trace(r) - 1.0);
539 return std::acos(cos_theta);
542 OMEGA_H_INLINE Tensor<1> form_ortho_basis(Vector<1>
const v) {
543 return tensor_1(v[0]);
546 OMEGA_H_INLINE Tensor<2> form_ortho_basis(Vector<2>
const v) {
556 OMEGA_H_INLINE Tensor<3> form_ortho_basis(Vector<3>
const v) {
559 auto sign = std::copysign(1.0, v(2));
560 const auto a = -1.0 / (sign + v(2));
561 const auto b = v(0) * v(1) * a;
562 A[1] = vector_3(1.0 + sign * v(0) * v(0) * a, sign * b, -sign * v(0));
563 A[2] = vector_3(b, sign + v(1) * v(1) * a, -v(1));
568 OMEGA_H_INLINE Tensor<dim> deviator(Tensor<dim>
const a) {
569 return (a - ((1.0 / dim) * trace(a) * identity_matrix<dim, dim>()));
572 template <
int new_dim,
int old_dim>
573 OMEGA_H_INLINE Tensor<new_dim> resize(Tensor<old_dim>
const m) {
574 constexpr
int min_dim = Omega_h::min2(new_dim, old_dim);
576 for (
int i = 0; i < min_dim; ++i)
577 for (
int j = 0; j < min_dim; ++j) m2(i, j) = m(i, j);
578 for (
int i = 0; i < new_dim; ++i)
579 for (
int j = min_dim; j < new_dim; ++j) m2(i, j) = m2(j, i) = 0.0;
584 Reals repeat_symm(LO
const n, Tensor<dim>
const symm);
585 extern template Reals repeat_symm(LO
const n, Tensor<3>
const symm);
586 extern template Reals repeat_symm(LO
const n, Tensor<2>
const symm);
587 extern template Reals repeat_symm(LO
const n, Tensor<1>
const symm);
589 Reals resize_symms(Reals old_symms, Int old_dim, Int new_dim);
592 Reals repeat_matrix(LO
const n, Tensor<dim> m);
594 extern template Reals repeat_matrix(LO
const n, Tensor<3>
const m);
595 extern template Reals repeat_matrix(LO
const n, Tensor<2>
const m);
596 extern template Reals repeat_matrix(LO
const n, Tensor<1>
const m);
598 Reals matrices_times_vectors(Reals ms, Reals vs, Int dim);
599 Reals matrices_times_matrices(Reals ms, Reals vs, Int dim);
601 Reals symms_inria2osh(Int dim, Reals symms);
602 Reals symms_osh2inria(Int dim, Reals symms);
604 Reals matrices_to_symms(Reals
const matrices, Int
const dim);
Definition: Omega_h_few.hpp:61
Definition: Omega_h_matrix.hpp:34
Definition: amr_mpi_test.cpp:6