suanPan
Loading...
Searching...
No Matches
tensor.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2025 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
29#ifndef TENSOR_H
30#define TENSOR_H
31
32#include <Toolbox/utility.h>
33
34template<typename T> class Quaternion;
35
36namespace tensor {
37 mat isotropic_stiffness(double, double);
38 mat orthotropic_stiffness(const vec&, const vec&);
39
43
44 static const vec unit_tensor2{1., 1., 1., 0., 0., 0.};
45
46 namespace stress {
47 // applies to 3D tensor only, either principal or not
48 double invariant1(const vec&);
49 // applies to 3D tensor only, either principal or not
50 double invariant2(const vec&);
51 // applies to 3D tensor only, either principal or not
52 double invariant3(const vec&);
53
54 // compute lode angle based on input stress
55 double lode(vec);
56 // compute derivative of lode angle based on input stress
57 vec lode_der(vec);
58
59 static const vec norm_weight{1., 1., 1., 2., 2., 2.};
60 } // namespace stress
61 namespace strain {
62 // applies to 3D tensor only, either principal or not
63 double invariant1(const vec&);
64 // applies to 3D tensor only, either principal or not
65 double invariant2(const vec&);
66 // applies to 3D tensor only, either principal or not
67 double invariant3(const vec&);
68
69 // compute lode angle based on input deviatoric strain
70 double lode(vec);
71
72 static const vec norm_weight{1., 1., 1., .5, .5, .5};
73 } // namespace strain
74 double trace2(const vec&);
75 double trace3(const vec&);
76 double mean3(const vec&);
77 vec dev(const vec&);
78 vec dev(vec&&);
79
80 mat dev(const mat&);
81 mat dev(mat&&);
82
83 namespace strain {
84 mat to_green(mat&&);
85 mat to_green(const mat&);
86 mat to_tensor(const vec&);
87 vec to_voigt(const mat&);
88 double norm(const vec&);
89 double double_contraction(const vec&);
90 double double_contraction(const vec&, const vec&);
91 double double_contraction(vec&&, vec&&);
92 } // namespace strain
93 namespace stress {
94 mat to_tensor(const vec&);
95 vec to_voigt(const mat&);
96 double norm(const vec&);
97 double double_contraction(const vec&);
98 double double_contraction(const vec&, const vec&);
99 double double_contraction(vec&&, vec&&);
100 } // namespace stress
101
102 namespace base {
103 class Base3D {
104 const vec3 g1, g2, g3;
105 mat33 g;
106
107 public:
108 Base3D(const vec3&, const vec3&, const vec3&);
109 [[nodiscard]] std::tuple<vec3, vec3, vec3> to_inverse() const;
110 };
111
112 vec3 unit_norm(const vec3&, const vec3&);
113 } // namespace base
114
115 mat diff_unit(const vec&);
116
117 mat diff_triad(const vec3&, const vec3&, const vec3&);
118} // namespace tensor
119
120namespace transform {
121 void tsai_wu_projection(const vec&, mat&, mat&);
122 void hoffman_projection(const vec&, mat&, mat&);
123 mat hill_projection(double, double, double, double, double, double);
124
125 double atan2(const vec&);
128
129 mat66 eigen_to_tensor_base(const mat&);
130 vec eigen_to_tensile_stress(const vec&, const mat&);
131 std::pair<mat, mat> eigen_to_tensile_derivative(const vec&, const mat&);
132
133 template<typename T> Mat<T> skew_symm(const Mat<T>& R) {
134 suanpan_assert([&] { if(R.n_elem != 3) throw std::invalid_argument("need 3 element vector"); });
135
136 Mat<T> S(3, 3, fill::zeros);
137
138 S(0, 1) = -(S(1, 0) = R(2));
139 S(2, 0) = -(S(0, 2) = R(1));
140 S(1, 2) = -(S(2, 1) = R(0));
141
142 return S;
143 }
144
145 template<typename T> concept HasEval = requires(const T& x) { { x.eval() } -> std::convertible_to<mat>; };
146
147 template<HasEval T> mat skew_symm(const T& R) { return skew_symm(R.eval()); }
148
149 template<typename T> Mat<T> rodrigues(const Mat<T>& R) { return arma::expmat(transform::skew_symm(R)); }
150
151 template<typename T> Quaternion<T> to_quaternion(const Mat<T>& R) {
152 if(3 == R.n_elem) {
153 const auto angle = arma::norm(R);
154
155 if(suanpan::approx_equal(angle, 0.)) return {0., 0., 0., 0.};
156
157 return {std::cos(.5 * angle), std::sin(.5 * angle) / angle * R};
158 }
159
160 if(9 == R.n_elem) {
161 const auto tr_r = arma::trace(R);
162 const auto max_r = arma::max(R.diag());
163 if(tr_r >= max_r) {
164 const auto q0 = .5 * std::sqrt(tr_r + 1.);
165 const auto q1 = .25 / q0 * (R(2, 1) - R(1, 2));
166 const auto q2 = .25 / q0 * (R(0, 2) - R(2, 0));
167 const auto q3 = .25 / q0 * (R(1, 0) - R(0, 1));
168 return {q0, q1, q2, q3};
169 }
170
171 for(auto I = 0; I < 3; ++I)
172 if(suanpan::approx_equal(R(I, I), max_r)) {
173 const auto J = (I + 1) % 3;
174 const auto K = (J + 1) % 3;
175 vec q(3, fill::none);
176 q(I) = std::sqrt(.5 * max_r + .25 * (1. - tr_r));
177 const double q0 = .25 / q(I) * (R(K, J) - R(J, K));
178 q(J) = .25 / q(I) * (R(J, I) + R(I, J));
179 q(K) = .25 / q(I) * (R(K, I) + R(I, K));
180
181 return {q0, std::move(q)};
182 }
183 }
184
185 throw std::invalid_argument("need either rotation vector or matrix");
186 }
187
188 template<typename T> Col<T> to_pseudo(const Mat<T>& R) {
189 const Mat<T> S = arma::real(arma::logmat(R));
190
191 return {S(2, 1), S(0, 2), S(1, 0)};
192 }
193
194 namespace strain {
195 double angle(const vec&);
196 mat trans(double);
197 vec principal(const vec&);
198 vec rotate(const vec&, double);
199 } // namespace strain
200 namespace stress {
201 double angle(const vec&);
202 mat trans(double);
203 vec principal(const vec&);
204 vec rotate(const vec&, double);
205 } // namespace stress
206 namespace beam {
207 mat global_to_local(double, double, double);
208 mat global_to_local(const vec&, double);
209 } // namespace beam
210 namespace triangle {
211 vec to_area_coordinate(const vec&, const mat&);
212 }
213} // namespace transform
214
215namespace suanpan {
216 template<typename T> T ramp(const T in) { return in > T(0) ? in : T(0); }
217} // namespace suanpan
218
219#endif
220
An Quaternion class.
Definition Quaternion.hpp:34
Definition tensor.h:103
std::tuple< vec3, vec3, vec3 > to_inverse() const
Definition tensor.cpp:288
Definition tensor.h:145
Definition SparseMatMAGMA.hpp:43
T ramp(const T in)
Definition tensor.h:216
bool approx_equal(T x, T y, int ulp=2)
Definition utility.h:67
vec3 unit_norm(const vec3 &, const vec3 &)
Definition tensor.cpp:294
mat to_green(mat &&)
Definition tensor.cpp:297
mat to_tensor(const vec &)
Definition tensor.cpp:321
double invariant3(const vec &)
compute the third invariant of the given 3D strain tensor, could be either normal or deviatoric strai...
Definition tensor.cpp:121
double norm(const vec &)
Definition tensor.cpp:375
double invariant2(const vec &)
compute the second invariant of the given 3D strain tensor, could be either normal or deviatoric stra...
Definition tensor.cpp:109
double invariant1(const vec &)
compute the first invariant of the given 3D strain tensor, could be either normal or deviatoric strai...
Definition tensor.cpp:98
double double_contraction(const vec &)
Definition tensor.cpp:381
vec to_voigt(const mat &)
Definition tensor.cpp:346
double lode(vec)
Definition tensor.cpp:163
vec to_voigt(const mat &)
Definition tensor.cpp:412
double invariant2(const vec &)
compute the second invariant of the given 3D stress tensor, could be either normal or deviatoric stre...
Definition tensor.cpp:144
vec lode_der(vec)
Definition tensor.cpp:181
double lode(vec)
Definition tensor.cpp:172
double invariant3(const vec &)
compute the third invariant of the given 3D stress tensor, could be either normal or deviatoric stres...
Definition tensor.cpp:156
double invariant1(const vec &)
compute the first invariant of the given 3D stress tensor, could be either normal or deviatoric stres...
Definition tensor.cpp:133
double norm(const vec &)
Definition tensor.cpp:441
mat to_tensor(const vec &)
Definition tensor.cpp:387
double double_contraction(const vec &)
Definition tensor.cpp:447
Definition tensor.h:36
double trace3(const vec &)
Only accepts 3D tensor!
Definition tensor.cpp:205
mat diff_unit(const vec &)
Definition tensor.cpp:236
mat unit_deviatoric_tensor4v2()
Definition tensor.cpp:76
mat unit_deviatoric_tensor4()
Definition tensor.cpp:65
double mean3(const vec &)
Definition tensor.cpp:211
mat diff_triad(const vec3 &, const vec3 &, const vec3 &)
Definition tensor.cpp:241
vec dev(const vec &)
Definition tensor.cpp:213
mat unit_symmetric_tensor4()
Definition tensor.cpp:84
mat isotropic_stiffness(double, double)
Definition tensor.cpp:20
mat orthotropic_stiffness(const vec &, const vec &)
Definition tensor.cpp:35
double trace2(const vec &)
Only accepts 2D tensor!
Definition tensor.cpp:194
mat global_to_local(double, double, double)
Definition tensor.cpp:751
vec principal(const vec &)
Definition tensor.cpp:703
mat trans(double)
Definition tensor.cpp:689
double angle(const vec &)
Definition tensor.cpp:683
vec rotate(const vec &, double)
Definition tensor.cpp:715
vec principal(const vec &)
Definition tensor.cpp:737
mat trans(double)
Definition tensor.cpp:723
double angle(const vec &)
Definition tensor.cpp:721
vec rotate(const vec &, double)
Definition tensor.cpp:749
vec to_area_coordinate(const vec &, const mat &)
Definition tensor.cpp:668
Definition tensor.h:120
mat compute_jacobian_nominal_to_principal(const mat &)
Definition tensor.cpp:547
Mat< T > skew_symm(const Mat< T > &R)
Definition tensor.h:133
mat hill_projection(double, double, double, double, double, double)
Definition tensor.cpp:524
Col< T > to_pseudo(const Mat< T > &R)
Definition tensor.h:188
vec eigen_to_tensile_stress(const vec &, const mat &)
Definition tensor.cpp:632
mat66 eigen_to_tensor_base(const mat &)
Definition tensor.cpp:615
double atan2(const vec &)
Definition tensor.cpp:545
mat compute_jacobian_principal_to_nominal(const mat &)
Definition tensor.cpp:581
void hoffman_projection(const vec &, mat &, mat &)
Generate two projection matrix based on the given yield stress according to the Hoffman yielding crit...
Definition tensor.cpp:507
Quaternion< T > to_quaternion(const Mat< T > &R)
Definition tensor.h:151
std::pair< mat, mat > eigen_to_tensile_derivative(const vec &, const mat &)
Definition tensor.cpp:654
Mat< T > rodrigues(const Mat< T > &R)
Definition tensor.h:149
void tsai_wu_projection(const vec &, mat &, mat &)
Generate two projection matrix based on the given yield stress according to the Tsai-Wu yielding crit...
Definition tensor.cpp:484
void suanpan_assert(const std::function< void()> &F)
Definition suanPan.h:363