CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
StrainConverter.cc
Go to the documentation of this file.
5 
6 namespace CASM {
7 
8  //Calculates the metric tensor of the the deformation gradient as
9  //F^{T}F
11  return F.transpose() * F;
12  }
13  //*******************************************************************************************
14  //calculates and returns the value of U where F = R*U
15  Matrix3d StrainConverter::right_stretch_tensor(Matrix3d &C, Eigen::Vector3d &eigenvalues,
16  Matrix3d &eigenvectors, const Matrix3d &F) {
17  C = metric_tensor(F);
18  Eigen::SelfAdjointEigenSolver <Matrix3d> eigen_solver(C);
19  Matrix3d U = eigen_solver.operatorSqrt();
20  eigenvalues = eigen_solver.eigenvalues();
21  eigenvectors = eigen_solver.eigenvectors();
22  return U;
23  }
24 
25  //*******************************************************************************************
26  //overloaded version of the above
28  Matrix3d C, eigenvectors;
29  Eigen::Vector3d eigenvalues;
30  return right_stretch_tensor(C, eigenvalues, eigenvectors, F);
31  }
32 
33  //*******************************************************************************************
36  return 0.5 * (F.transpose() * F - Eigen::MatrixXd::Identity(3, 3));
37  }
38 
39  //*******************************************************************************************
42  Eigen::SelfAdjointEigenSolver<Matrix3d> es(2 * E + Eigen::MatrixXd::Identity(3, 3));
43  return es.eigenvectors() * es.eigenvalues().array().sqrt().matrix().asDiagonal() * es.eigenvectors().inverse();
44  }
45 
46  //*******************************************************************************************
49  return (right_stretch_tensor(F) - Eigen::MatrixXd::Identity(3, 3));
50  }
51 
52  //*******************************************************************************************
55  return B + Eigen::MatrixXd::Identity(3, 3);
56  }
57 
58  //*******************************************************************************************
61  Eigen::SelfAdjointEigenSolver<Matrix3d> es(F.transpose()*F);
62  return es.eigenvectors() * es.eigenvalues().array().log().matrix().asDiagonal() * es.eigenvectors().inverse() / 2.0;
63 
64  //Matrix3d S = es.eigenvectors()*es.eigenvalues().array().log().asDiagonal()*es.eigenvectors().inverse()/2.0;
65  //S(0, 0) = log(S(0, 0)) / 2.0;
66  //S(1, 1) = log(S(1, 1)) / 2.0;
67  //S(2, 2) = log(S(2, 2)) / 2.0;
68  //return es.eigenvectors() * S * es.eigenvectors().inverse();
69  }
70 
71  //*******************************************************************************************
74  Eigen::SelfAdjointEigenSolver<Matrix3d> es(H);
75  return es.eigenvectors() * es.eigenvalues().array().exp().matrix().asDiagonal() * es.eigenvectors().inverse();
76  }
77 
78  //*******************************************************************************************
81  return 0.5 * (Eigen::MatrixXd::Identity(3, 3) - (F * F.transpose()).inverse());
82  }
83 
84  //*******************************************************************************************
87  Eigen::SelfAdjointEigenSolver<Matrix3d> es((Eigen::MatrixXd::Identity(3, 3) - 2 * A).inverse());
88  return es.eigenvectors() * es.eigenvalues().array().sqrt().matrix().asDiagonal() * es.eigenvectors().inverse();
89  }
90 
91  //*******************************************************************************************
94  return F;
95  }
96 
97  //*******************************************************************************************
98  //Calculates the strain metric based on what mode is passed
99  //in. Allowed modes are listed in STRAIN_METRIC
102  if(MODE == GREEN_LAGRANGE) {
103  return green_lagrange(F);
104  }
106  else if(MODE == BIOT) {
107  return biot(F);
108  }
110  else if(MODE == HENCKY) {
111  return hencky(F);
112  }
114  else if(MODE == EULER_ALMANSI) {
115  return euler_almansi(F);
116  }
118  else if(MODE == DISP_GRAD) {
119  return disp_grad(F);
120  }
121  else {
122  std::cerr << "CRITICAL ERROR: In StrainConverter::strain_metric. Unrecognized strain metric" << std::endl;
123  std::cerr << " Your only options are GREEN_LAGRANGE, BIOT, HENCKY, EULER_ALMANSI, and DISP_GRAD" << std::endl;
124  std::cerr << " Exiting..." << std::endl;
125  exit(1);
126  }
127  }
128 
129  //*******************************************************************************************
130  //Calculates the strain metric based on what mode is passed
131  //in. Allowed modes are listed in STRAIN_METRIC
133  assert(curr_metric_func && "StrainConverter object improperly initialized!");
134  return (*curr_metric_func)(F);
135  }
136 
137  //*******************************************************************************************
138  //Calculates the strain metric based on what mode is passed
139  //in. Allowed modes are listed in STRAIN_METRIC
141  assert(curr_inv_metric_func && "StrainConverter object improperly initialized!");
142  return (*curr_inv_metric_func)(E);
143  }
144 
145  //*******************************************************************************************
146  //Returns the symmetrically unique elements of E (assuming your
147  //strain metric is symmetric) ordered in a manner decided by
148  //m_order_strain
150  VectorXd _unrolled_E(m_order_strain.size());
151  for(Index i = 0; i < m_order_strain.size(); i++) {
152  _unrolled_E(i) = m_weight_strain[i] * E(m_order_strain[i][0], m_order_strain[i][1]);
153  }
154  return _unrolled_E;
155  }
156 
157  //*******************************************************************************************
158  //Returns the symmetrically unique elements of E (assuming your
159  //strain metric is symmetric) ordered in a manner decided by
160  //m_order_strain
161  Matrix3d StrainConverter::rollup_E(const VectorXd &_unrolled_E) const {
162  Matrix3d _rolled_E;
163  for(Index i = 0; i < m_order_strain.size(); i++) {
164  _rolled_E(m_order_strain[i][0], m_order_strain[i][1]) = _unrolled_E(i) / m_weight_strain[i];
165  _rolled_E(m_order_strain[i][1], m_order_strain[i][0]) = _unrolled_E(i) / m_weight_strain[i];
166  }
167  return _rolled_E;
168  }
169 
170  //*******************************************************************************************
172  return unroll_E(strain_metric(F));
173  }
174 
175  //*******************************************************************************************
177  return strain_metric_to_F(rollup_E(E));
178  }
179 
180  //*******************************************************************************************
181  //Calculates a linear combination of the components of unroll_E
182  //using the sop_transf_mat
183  VectorXd StrainConverter::sop(Matrix3d &E, Matrix3d &C, Matrix3d &U, Eigen::Vector3d &eigenvalues,
184  Matrix3d &eigenvectors, const Matrix3d &F, STRAIN_METRIC MODE) const {
185  U = right_stretch_tensor(C, eigenvalues, eigenvectors, F);
186  E = strain_metric(F, MODE);
187  VectorXd _unroll_E = unroll_E(E);
188  VectorXd _sop = m_sop_transf_mat * _unroll_E;
189  return _sop;
190  }
191 
192  //*******************************************************************************************
193 
194  VectorXd StrainConverter::sop(Matrix3d &E, Matrix3d &C, Matrix3d &U, Eigen::Vector3d &eigenvalues,
195  Matrix3d &eigenvectors, const Matrix3d &F) const {
196  return sop(E, C, U, eigenvalues, eigenvectors, F, STRAIN_METRIC_MODE);
197  }
198 
199  //************************************* SET routines ****************************************
200 
201  void StrainConverter::set_mode(const std::string &mode_name) {
202 
204  if(mode_name == "STRAIN_GL" || mode_name == "GL") {
209  }
211  else if(mode_name == "STRAIN_B" || mode_name == "B") {
216  }
218  else if(mode_name == "STRAIN_H" || mode_name == "H") {
223  }
225  else if(mode_name == "STRAIN_EA" || mode_name == "EA") {
230  }
232  else if(mode_name == "STRAIN_F" || mode_name == "F") {
237  }
238  else {
239  std::cerr << "CRITICAL ERROR: In StrainConverter::set_mode(). Unrecognized strain metric '" << mode_name << "'" << std::endl;
240  std::cerr << " Your only options are STRAIN_GL, STRAIN_B, STRAIN_H, STRAIN_EA, and STRAIN_F" << std::endl;
241  std::cerr << " Exiting..." << std::endl;
242  exit(1);
243  }
244  }
245 
246  //*******************************************************************************************
247 
248  std::vector<Eigen::MatrixXd> StrainConverter::irreducible_sop_wedges(const SymGroup &pg, std::vector<Index> &multiplicities) {
249  if(m_symrep_ID.empty()) {
251  }
252 
254 
255  return srep.irreducible_wedges(pg, multiplicities);
256  }
257 
258  //*******************************************************************************************
259 
260  std::vector<Eigen::MatrixXd> StrainConverter::irreducible_wedges(const SymGroup &pg, std::vector<Index> &multiplicities) {
261  std::vector<Eigen::MatrixXd> wedges = irreducible_sop_wedges(pg, multiplicities);
262  for(auto &w : wedges) {
263  w = m_sop_transf_mat * w; // Eigen handles aliasing
264  }
265  return wedges;
266  }
267 
268  //*******************************************************************************************
269 
271  Eigen::VectorXd tvec(Eigen::VectorXd::Zero(m_order_strain.size()));
272  Eigen::Matrix3d tmat;
273  SymGroupRep strain_rep(pg);
274 
275  for(Index g = 0; g < pg.size(); g++) {
276  Eigen::MatrixXd trep(tvec.size(), tvec.size());
277  for(Index i = 0; i < tvec.size(); i++) {
278  tvec[i] = 1;
279  tmat = rollup_E(tvec);
280  tvec[i] = 0;
281  tmat = pg[g].matrix() * tmat * pg[g].matrix().transpose();
282  trep.col(i) = unroll_E(tmat);
283  }
284  strain_rep.set_rep(pg[g], SymMatrixXd(trep));
285  }
286  Eigen::VectorXd breathing = unroll_E(Eigen::Matrix3d::Identity());
287  breathing.normalize();
288 
289  Eigen::MatrixXd bigmat(tvec.size(), tvec.size() + 1);
290  bigmat.col(0) = breathing;
291  bigmat.rightCols(tvec.size()) = strain_rep.get_irrep_trans_mat(pg).transpose();
292  //m_sop_transf_mat=strain_rep.get_irrep_trans_mat(pg).transpose();
293  Eigen::HouseholderQR<Eigen::MatrixXd> QR(bigmat);
294  m_sop_transf_mat = QR.householderQ();
295  m_symrep_ID = (strain_rep.coord_transformed_copy(m_sop_transf_mat.transpose())).add_copy_to_master();
296  }
297 
298  //*******************************************************************************************
299  //Conventional strain order parameters:
300  // e1 = (E11+E22+E33) / sqrt(3)
301  // e2 = (E11-E22) / sqrt(2)
302  // e3 = (2E33-E11+E22) / sqrt(6)
303  // e4 = E12
304  // e5 = E23
305  // e6 = E13
307  m_sop_transf_mat.resize(6, 6);
308  m_sop_transf_mat << 1.0 / sqrt(3.0), 1.0 / sqrt(3.0), 1.0 / sqrt(3.0), 0, 0, 0,
309  1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0, 0, 0, 0,
310  -1.0 / sqrt(6.0), -1.0 / sqrt(6.0), 2.0 / sqrt(6.0), 0, 0, 0,
311  0, 0, 0, 0, 0, 1,
312  0, 0, 0, 0, 1, 0,
313  0, 0, 0, 1, 0, 0;
314  }
315 
316  //*******************************************************************************************
317  //Conventional order_strain:
318  // unroll_E = (E11 E22 E33 E23 E13 E12)
320  m_order_strain.resize(6, Array<int>(2, 0));
321 
322  m_order_strain[0][0] = 0;
323  m_order_strain[0][1] = 0;
324  m_order_strain[1][0] = 1;
325  m_order_strain[1][1] = 1;
326  m_order_strain[2][0] = 2;
327  m_order_strain[2][1] = 2;
328  m_order_strain[3][0] = 1;
329  m_order_strain[3][1] = 2;
330  m_order_strain[4][0] = 0;
331  m_order_strain[4][1] = 2;
332  m_order_strain[5][0] = 0;
333  m_order_strain[5][1] = 1;
334 
335  m_weight_strain.resize(3, 1.0);
336  m_weight_strain.append(Array<double>(3, sqrt(2.0)));
337 
338  }
339 
340 
341  //*******************************************************************************************
342  //Conventional order_strain:
343  // unroll_E = (E11 E12 E13 E21 E22 E23 E31 E32 E33)
345  m_order_strain.resize(9, Array<int>(2, 0));
346  m_weight_strain.resize(9, 1.0);
347 
348  Index l = 0;
349  for(Index i = 0; i < 3; i++) {
350  for(Index j = 0; j < 3; j++) {
351  m_order_strain[l][0] = i;
352  m_order_strain[l][1] = j;
353  l++;
354  }
355  }
356  }
357 
358 }
359 
Eigen::MatrixXd MatrixXd
void set_mode(const std::string &mode_name)
static Matrix3d hencky(const Matrix3d &F)
HENCKY = log(C)/2.
static Matrix3d biot(const Matrix3d &F)
BIOT = (U-I)
std::vector< Eigen::MatrixXd > irreducible_wedges(const SymGroup &head_group, std::vector< Index > &multiplicities) const
Definition: SymGroupRep.cc:442
static Matrix3d green_lagrange(const Matrix3d &F)
GREEN_LAGRANGE = (C-I)/2.
MetricFuncPtr curr_inv_metric_func
Index size() const
Definition: Array.hh:145
const MasterSymGroup & master_group() const
Definition: SymGroup.hh:56
bool empty() const
Returns true if SymGroupRepID has not been initialized with valid group_index or rep_index.
static Matrix3d disp_grad_to_F(const Matrix3d &F)
static Matrix3d strain_metric(const Matrix3d &F, STRAIN_METRIC MODE)
static Matrix3d hencky_to_F(const Matrix3d &H)
HENCKY = log(C)/2.
void resize(Index new_N)
Definition: Array.hh:468
Matrix3d rollup_E(const VectorXd &_unrolled_E) const
Matrix3d unrolled_strain_metric_to_F(const VectorXd &E) const
VectorXd unroll_E(const Matrix3d &E) const
Unrolls the green-lagrange metric ( or any symmetric metric)
Main CASM namespace.
Definition: complete.cpp:8
Matrix3d strain_metric_to_F(const Matrix3d &E) const
Array< Array< int > > m_order_strain
static Matrix3d euler_almansi_to_F(const Matrix3d &A)
EULER_ALMANSI = (I-(F F^{T})^(-1))/2.
Eigen::MatrixXd get_irrep_trans_mat(const SymGroup &head_group) const
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:33
static Matrix3d euler_almansi(const Matrix3d &F)
EULER_ALMANSI = (I-(F F^{T})^(-1))/2.
static Matrix3d disp_grad(const Matrix3d &F)
DISP_GRAD = F.
EigenIndex Index
For long integer indexing:
Eigen::Matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > inverse(const Eigen::MatrixBase< Derived > &M)
Return the integer inverse matrix of an invertible integer matrix.
STRAIN_METRIC STRAIN_METRIC_MODE
Eigen::VectorXd VectorXd
void set_symmetrized_sop(const SymGroup &pg)
Array< double > m_weight_strain
VectorXd sop(Matrix3d &E, Matrix3d &C, Matrix3d &U, Eigen::Vector3d &eigenvalues, Matrix3d &eigenvectors, const Matrix3d &F) const
Array & append(const Array &new_tail)
Definition: Array.hh:897
Generalized symmetry matrix representation for arbitrary dimension Can be used to describe applicatio...
Definition: SymMatrixXd.hh:22
Eigen::Matrix3d Matrix3d
std::vector< Eigen::MatrixXd > irreducible_wedges(const SymGroup &pg, std::vector< Index > &multiplicities)
void set_conventional_order_unsymmetric()
SymGroupRep coord_transformed_copy(const Eigen::MatrixXd &trans_mat) const
Definition: SymGroupRep.cc:280
static Matrix3d metric_tensor(const Matrix3d &F)
SymGroupRep is an alternative representation of a SymGroup for something other than real space...
Definition: SymGroupRep.hh:30
static Matrix3d green_lagrange_to_F(const Matrix3d &E)
GREEN_LAGRANGE = 1/2 * (F^{T} F - I)
static Matrix3d biot_to_F(const Matrix3d &B)
BIOT = (U-I)
VectorXd unrolled_strain_metric(const Matrix3d &F) const
static Matrix3d right_stretch_tensor(Matrix3d &C, Eigen::Vector3d &eigenvalues, Matrix3d &eigenvectors, const Matrix3d &F)
std::vector< Eigen::MatrixXd > irreducible_sop_wedges(const SymGroup &pg, std::vector< Index > &multiplicities)
MetricFuncPtr curr_metric_func
SymGroupRep const & representation(SymGroupRepID i) const
Const access of alternate Representations of a SymGroup.
Definition: SymGroup.cc:375
void set_rep(const SymOpRepresentation &base_rep, const SymOpRepresentation &new_rep) const
Definition: SymGroupRep.cc:82