CASM  1.1.0
A Clusters Approach to Statistical Mechanics
SymOp.cc
Go to the documentation of this file.
1 #include "casm/symmetry/SymOp.hh"
2 
3 #include "casm/casm_io/Log.hh"
6 #include "casm/misc/CASM_math.hh"
9 
10 namespace CASM {
11 
12 const double &SymOp::map_error() const { return m_map_error; }
13 
14 //*******************************************************************************************
15 
16 void SymOp::set_map_error(const double &value) {
17  m_map_error = value;
18  return;
19 }
20 
21 //*******************************************************************************************
22 
23 void SymOp::set_index(const MasterSymGroup &new_group, Index new_index) {
24  if ((valid_index(new_index) && new_index < new_group.size()) &&
25  (this == &(new_group[new_index]) ||
26  almost_equal(matrix(), new_group[new_index].matrix()))) {
27  m_master_group = &new_group;
28  m_op_index = new_index;
30  } else {
31  m_master_group = &new_group;
32  // m_master_group = NULL;
33  m_op_index = -1;
35  }
36 }
37 
38 //*******************************************************************************************
39 
40 SymOp SymOp::operator*(const SymOp &RHS) const {
41  SymOp t_op(
42  matrix() * RHS.matrix(), tau() + matrix() * RHS.tau(),
43  time_reversal() !=
44  RHS.time_reversal(), // time reversal set by XOR operation
45  sqrt(map_error() * map_error() + RHS.map_error() * RHS.map_error()), -1,
46  nullptr);
47 
49  t_op.set_index(master_group(),
50  master_group().ind_prod(index(), RHS.index()));
51  } else if (RHS.m_master_group && !m_master_group && is_identity()) {
52  t_op.set_index(RHS.master_group(), RHS.index());
53  } else if (m_master_group && !RHS.m_master_group && RHS.is_identity()) {
54  t_op.set_index(master_group(), index());
55  }
56  // The following blocks caused problems at some point (mainly for
57  // non-primitive structures) else if(is_identity() && RHS.is_identity()) {
58  // t_op.m_op_index = 0;
59  //}
60  // else{
61  // std::cout << "This symmetry is " << symmetry << " with head " <<
62  // m_master_group << " and RHS symmetry is " << RHS.symmetry << " with head "
63  // << RHS.m_master_group << "\n";
64  //}
65 
66  return t_op;
67 }
68 
69 //*******************************************************************************************
70 
71 SymOp &SymOp::operator+=(const Eigen::Ref<const SymOp::vector_type> &RHS) {
72  m_tau += RHS - matrix() * RHS;
73  return (*this);
74 }
75 
76 //*******************************************************************************************
77 
78 SymOp &SymOp::operator-=(const Eigen::Ref<const SymOp::vector_type> &RHS) {
79  m_tau -= RHS - matrix() * RHS;
80  return (*this);
81 }
82 
83 //*******************************************************************************************
84 // SymOp matrix is unitary, so inverse is equivalent to transpose.
85 // To do inverse of translation, you must perform
86 // inverse matrix operaton on translation and subtract
88  SymOp t_op(matrix().transpose(), -(matrix().transpose() * tau()),
89  time_reversal(), map_error(), -1, nullptr);
90  if (m_master_group) {
92  } else if (is_identity()) {
93  t_op.m_op_index = 0;
94  t_op._set_integral_tau();
95  }
96 
97  return t_op;
98 }
99 
100 //*******************************************************************************************
101 
103  return SymOp(matrix(), vector_type::Zero(), time_reversal(), map_error(),
104  index(), m_master_group);
105 }
106 
107 //*******************************************************************************************
108 
109 bool SymOp::operator==(const SymOp &RHS) const {
110  return almost_equal(matrix(), RHS.matrix()) &&
111  almost_equal(tau(), RHS.tau()) &&
112  time_reversal() == RHS.time_reversal();
113 };
114 
115 //*******************************************************************************************
116 
118  (*this) = op * (*this) * (op.inverse());
119  return *this;
120 }
121 
122 //*******************************************************************************************
123 
125  std::ostream &stream,
126  const Eigen::Ref<const SymOp::matrix_type> &c2f_mat) const {
127  print(stream, c2f_mat);
128 }
129 
130 //*******************************************************************************************
131 
132 void SymOp::print(std::ostream &stream,
133  const Eigen::Ref<const SymOp::matrix_type> &c2f_mat) const {
134  int tprec = stream.precision();
135  std::ios::fmtflags tflags = stream.flags();
136 
137  stream.precision(3);
138 
139  stream.flags(std::ios::left);
140  stream
141  << std::setw(53) << "Symmetry Operation Matrix"
142  << "Shift \n"; // SOM has 25 chars, width of those 3 columns are 14 each,
143  // so 42 width. Shift width is 22, so spacing of 9-11
144  // extra characters, so add 5 more to get in the middle
145 
146  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
147  stream.precision(9);
148  matrix_type tmat(c2f_mat * matrix() * c2f_mat.inverse());
149  vector_type ttau(c2f_mat * tau());
150  for (int i = 0; i < 3; i++) {
151  // Print each row of the symmetry matrix separately
152  for (int j = 0; j < 3; j++) {
153  stream << std::setw(14) << tmat(i, j);
154  }
155 
156  stream << std::setw(22) << ttau(i) << "\n";
157  }
158 
159  stream << "Time Reversal: " << (time_reversal() ? "yes" : "no") << "\n";
160  stream.precision(tprec);
161  stream.flags(tflags);
162  return;
163 }
164 
165 //*******************************************************************************************
166 
167 const SymOp::matrix_type &get_matrix(const SymOp &op) { return op.matrix(); }
168 
169 const SymOp::vector_type &get_translation(const SymOp &op) { return op.tau(); }
170 
171 bool get_time_reversal(const SymOp &op) { return op.time_reversal(); }
172 
174  if (has_valid_master() && valid_index(index())) {
175  m_integral_tau = tau() - master_group()[index()].tau();
176  m_valid_integral_tau = true;
177  } else if (is_identity()) {
178  m_integral_tau = tau();
179  m_valid_integral_tau = true;
180  } else {
181  m_valid_integral_tau = false;
182  }
183 }
184 
196 void print_matrix_tau_col(Log &log, const SymOp &op, Index prec) {
197  Index w1 = 3;
198  w1 = print_matrix_width(log, op.matrix(), w1);
199  Eigen::IOFormat fmt1(prec, w1);
200 
201  Index w2 = 3;
202  w2 = print_matrix_width(log, op.tau(), w2);
203  Eigen::IOFormat fmt2(prec, w2);
204 
205  std::string header = std::string(2 + w1 * 3 - 6, ' ') + "Matrix | " +
206  std::string(w2 - 3, ' ') + "Tau";
207  log << log.indent_str() << header << std::endl;
208  log << log.indent_str() << op.matrix().row(0).format(fmt1) << " | "
209  << op.tau().row(0).format(fmt2) << std::endl;
210  log << log.indent_str() << op.matrix().row(1).format(fmt1) << " | "
211  << op.tau().row(1).format(fmt2) << std::endl;
212  log << log.indent_str() << op.matrix().row(2).format(fmt1) << " | "
213  << op.tau().row(2).format(fmt2) << std::endl;
214 }
215 
216 } // namespace CASM
Definition: Log.hh:48
std::string indent_str() const
Definition: Log.hh:273
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
void print(std::ostream &stream, const Eigen::Ref< const matrix_type > &c2fmat=matrix_type::Identity()) const
Definition: SymOp.cc:132
SymOp no_trans() const
Get copy of the SymOp without translation.
Definition: SymOp.cc:102
Eigen::Matrix3d matrix_type
Definition: SymOp.hh:30
SymOp & operator+=(const Eigen::Ref< const vector_type > &RHS)
Definition: SymOp.cc:71
SymOp operator*(const SymOp &RHS) const
Definition: SymOp.cc:40
const matrix_type & matrix() const
Const access of entire cartesian symmetry matrix.
Definition: SymOp.hh:60
Eigen::Vector3d vector_type
Definition: SymOp.hh:31
void set_index(const MasterSymGroup &new_group, Index new_index)
Definition: SymOp.cc:23
void print_short(std::ostream &stream, const Eigen::Ref< const matrix_type > &c2fmat=matrix_type::Identity()) const
Definition: SymOp.cc:124
bool is_identity() const
returns true if matrix part of operation is identity
Definition: SymOp.hh:78
bool operator==(const SymOp &RHS) const
Definition: SymOp.cc:109
void set_map_error(const double &value)
Definition: SymOp.cc:16
SymOp inverse() const
get the inverse of this SymOp
Definition: SymOp.cc:87
bool time_reversal() const
Const access of the time-reversal flag (true if operation reverses time)
Definition: SymOp.hh:66
vector_type m_integral_tau
Definition: SymOp.hh:185
const double & map_error() const
Allows access to the map_error.
Definition: SymOp.cc:12
void _set_integral_tau() override
Set the difference between the translation of this compared to.
Definition: SymOp.cc:173
SymOp & operator-=(const Eigen::Ref< const vector_type > &RHS)
Definition: SymOp.cc:78
const vector_type & tau() const
Const access of the cartesian translation vector, 'tau'.
Definition: SymOp.hh:63
vector_type m_tau
Definition: SymOp.hh:176
SymOp & apply_sym(const SymOp &op)
Definition: SymOp.cc:117
double m_map_error
Definition: SymOp.hh:192
bool m_valid_integral_tau
Definition: SymOp.hh:187
MasterSymGroup const * m_master_group
Pointer to the MasterSymGroup where prototype of this SymOp lives.
const MasterSymGroup & master_group() const
const access of head group
Index ind_prod(const SymOpRepresentation &RHS) const
bool has_valid_master() const
check if this representation is registered with a MasterSymGroup
Index m_op_index
Index into MasterSymGroup that specifies the operation.
const SymOp::matrix_type & get_matrix(const SymOp &op)
Definition: SymOp.cc:167
bool get_time_reversal(const SymOp &op)
Definition: SymOp.cc:171
const SymOp::vector_type & get_translation(const SymOp &op)
Definition: SymOp.cc:169
void print_matrix_tau_col(Log &log, const SymOp &op, Index prec)
Print formatted SymOp matrix and tau.
Definition: SymOp.cc:196
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
Log & log()
Definition: Log.hh:424
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Index print_matrix_width(std::ostream &s, const Derived &m, Index width)