CASM  1.1.0
A Clusters Approach to Statistical Mechanics
LatticeIsEquivalent.cc
Go to the documentation of this file.
2 
6 
7 namespace CASM {
8 namespace xtal {
9 
11 
13 bool LatticeIsEquivalent::operator()(const Lattice &other, double tol) const {
14  tol = tol < 0 ? m_lat.tol() : tol;
15  m_U = other.lat_column_mat().inverse() * m_lat.lat_column_mat();
16  return is_unimodular(m_U, tol);
17 }
18 
21 
22 IsPointGroupOp::IsPointGroupOp(const Lattice &lat) : m_lat(lat) {}
23 
25 bool IsPointGroupOp::operator()(const SymOp &op) const {
26  return (*this)(get_matrix(op));
27 }
28 
30 bool IsPointGroupOp::operator()(const Eigen::Matrix3d &cart_op) const {
31  Eigen::Matrix3d tfrac_op;
32 
33  tfrac_op = lat_column_mat().inverse() * cart_op * lat_column_mat();
34 
35  // Use a soft tolerance of 1% to see if further screening should be performed
36  if (!almost_equal(1.0, std::abs(tfrac_op.determinant()), 0.01) ||
37  !is_integer(tfrac_op, 0.01)) {
38  return false;
39  }
40 
41  return _check(round(tfrac_op));
42 }
43 
45 bool IsPointGroupOp::operator()(const Eigen::Matrix3i &tfrac_op) const {
46  // false if determinant is not 1, because it doesn't preserve volume
47  if (std::abs(tfrac_op.determinant()) != 1) {
48  return false;
49  }
50 
51  return _check(tfrac_op.cast<double>());
52 }
53 
54 double IsPointGroupOp::map_error() const { return m_map_error; }
55 
57 
60 }
61 
63 bool IsPointGroupOp::_check(const Eigen::Matrix3d &tfrac_op) const {
64  // If symmetry is perfect, then -> cart_op * lat_column_mat() ==
65  // lat_column_mat() * frac_op by definition If we assum symmetry is
66  // imperfect, then -> cart_op * lat_column_mat() == F * lat_column_mat() *
67  // frac_op where 'F' is the displacement gradient tensor imposed by frac_op
68  m_cart_op = lat_column_mat() * tfrac_op * inv_lat_column_mat();
69 
70  // tMat uses some matrix math to get F.transpose()*F*lat_column_mat();
71  Eigen::Matrix3d tMat = m_cart_op.transpose() * lat_column_mat() * tfrac_op;
72 
73  // Subtract lat_column_mat() from tMat, leaving us with (F.transpose()*F -
74  // Identity)*lat_column_mat(). This is 2*E*lat_column_mat(), where E is the
75  // green-lagrange strain
76  tMat = (tMat - lat_column_mat()) / 2.0;
77 
78  //... and then multiplying by the transpose...
79  tMat = tMat * tMat.transpose();
80 
81  // The diagonal elements of tMat describe the square of the distance by which
82  // the transformed vectors 'miss' the original vectors
83 
84  if (tMat(0, 0) < 2. * m_lat.tol() && tMat(1, 1) < 2. * m_lat.tol() &&
85  tMat(2, 2) < 2. * m_lat.tol()) {
86  m_map_error = sqrt(tMat.diagonal().maxCoeff());
87  return true;
88  }
89  return false;
90 }
91 
93  return m_lat.lat_column_mat();
94 }
95 
97  return m_lat.inv_lat_column_mat();
98 }
99 
100 bool is_equivalent(const Lattice &ref_lattice, const Lattice &other) {
101  LatticeIsEquivalent is_equiv(ref_lattice);
102  return is_equiv(other);
103 }
104 
105 } // namespace xtal
106 } // namespace CASM
bool _check(const Eigen::Matrix3d &tfrac_op) const
Find the effect of applying symmetry to the lattice vectors.
Eigen::Matrix3d cart_op() const
const Eigen::Matrix3d & lat_column_mat() const
IsPointGroupOp(const Lattice &lat)
bool operator()(const SymOp &cart_op) const
Checks if ref_lat = cart_op*ref_lat*transf_mat(), for any transf_mat()
double map_error() const
Return the mapping error, calculated after performing an equivalence check.
const Eigen::Matrix3d & inv_lat_column_mat() const
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:110
double tol() const
Definition: Lattice.hh:195
const Eigen::Matrix3d & inv_lat_column_mat() const
Inverse of Lattice::lat_column_mat() It is the transformation matrix 'C2F', such that f = C2F * c whe...
Definition: Lattice.hh:117
Eigen::Matrix3d U() const
Returns U found for last check.
LatticeIsEquivalent(const Lattice &_lat)
bool operator()(const Lattice &other, double tol=-1.) const
Checks if lat = other*U, with unimodular U.
bool is_unimodular(const Eigen::MatrixBase< Derived > &M, double tol)
Check if Eigen::Matrix is unimodular.
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
bool is_integer(const Eigen::MatrixBase< Derived > &M, double tol)
Check if Eigen::Matrix is integer.
bool is_equivalent(const Lattice &ref_lattice, const Lattice &other)
Check if ref_lattice = other*U, where U is unimodular.
Eigen::Matrix3d const & get_matrix(MappingNode const &_node)
External accessor for isometry, to provide xtal::SymOp adaptability.
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
Eigen::Matrix3d Matrix3d
static SymOp point_operation(const SymOpMatrixType &mat)
Definition: SymType.hh:43