CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
ConfigDoFIsEquivalent.hh
Go to the documentation of this file.
1 #ifndef CASM_ConfigDoFIsEquivalent
2 #define CASM_ConfigDoFIsEquivalent
3 
4 #include "casm/casm_io/Log.hh"
5 #include "casm/clex/ConfigDoF.hh"
7 
8 namespace CASM {
9 
14  namespace DoFIsEquivalent {
16 
24 
25  public:
26 
27  ConfigDoFIsEquivalentBase(const ConfigDoF &_configdof) :
28  m_configdof(&_configdof) {}
29 
30  const ConfigDoF &configdof() const {
31  return *m_configdof;
32  }
33 
34  Index size() const {
35  return configdof().size();
36  }
37 
41  bool is_less() const {
42  return m_less;
43  }
44 
46  bool operator()(const Configuration &other) const {
47  return (*this)(other.configdof());
48  }
49 
51  virtual bool operator()(const ConfigDoF &other) const = 0;
52 
54  virtual bool operator()(const PermuteIterator &A) const = 0;
55 
57  virtual bool operator()(const PermuteIterator &A, const PermuteIterator &B) const = 0;
58 
59  std::unique_ptr<ConfigDoFIsEquivalentBase> clone() const {
60  return std::unique_ptr<ConfigDoFIsEquivalentBase>(this->_clone());
61  }
62 
63  protected:
64 
65  mutable bool m_less;
66 
67  private:
68 
69  virtual ConfigDoFIsEquivalentBase *_clone() const = 0;
70 
72 
73  };
74 
81 
82  public:
83  IntegralIsEquivalent(const ConfigDoF &_configdof) :
84  ConfigDoFIsEquivalentBase(_configdof) {}
85 
86  protected:
87  template<typename T>
88  bool _check(const T &A, const T &B) const {
89  if(A == B) {
90  return true;
91  }
92  m_less = (A < B);
93  return false;
94  }
95  };
96 
103 
104  public:
105  FloatIsEquivalent(const ConfigDoF &_configdof, double _tol) :
106  ConfigDoFIsEquivalentBase(_configdof), m_tol(_tol) {}
107 
108  protected:
109  template<typename T>
110  bool _check(const T &A, const T &B) const {
111  if(A < B - tol()) {
112  m_less = true;
113  return false;
114  }
115  if(A > B + tol()) {
116  m_less = false;
117  return false;
118  }
119  return true;
120  }
121 
122  private:
123 
124  double tol() const {
125  return m_tol;
126  }
127 
128  double m_tol;
129  };
130 
131 
134 
135  public:
136 
137  Occupation(const ConfigDoF &_configdof) :
138  IntegralIsEquivalent(_configdof) {}
139 
140  Occupation(const Configuration &_config) :
141  Occupation(_config.configdof()) {}
142 
144  bool operator()(const ConfigDoF &other) const override {
145  return _for_each(
146  [&](Index i) {
147  return this->configdof().occ(i);
148  },
149  [&](Index i) {
150  return other.occ(i);
151  });
152  }
153 
155  bool operator()(const PermuteIterator &A) const override {
156  return _for_each(
157  [&](Index i) {
158  return this->configdof().occ(i);
159  },
160  [&](Index i) {
161  return this->configdof().occ(A.permute_ind(i));
162  });
163  }
164 
166  bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override {
167  return _for_each(
168  [&](Index i) {
169  return this->configdof().occ(A.permute_ind(i));
170  },
171  [&](Index i) {
172  return this->configdof().occ(B.permute_ind(i));
173  });
174  }
175 
176  std::unique_ptr<Occupation> clone() const {
177  return std::unique_ptr<Occupation>(this->_clone());
178  }
179 
180  private:
181 
182  template<typename F, typename G>
183  bool _for_each(F f, G g) const {
184  Index i;
185  for(i = 0; i < size(); i++) {
186  if(!_check(f(i), g(i))) {
187  return false;
188  }
189  }
190  return true;
191  }
192 
193  Occupation *_clone() const override {
194  return new Occupation(*this);
195  }
196  };
197 
198 
201 
202  public:
203 
204  Displacement(const ConfigDoF &_configdof, double _tol) :
205  FloatIsEquivalent(_configdof, _tol),
206  m_fg_index_A(-1),
207  m_fg_index_B(-1) {}
208 
209  Displacement(const Configuration &_config, double _tol) :
210  Displacement(_config.configdof(), _tol) {}
211 
213  bool operator()(const ConfigDoF &other) const override {
214  return _for_each(
215  [&](Index i, Index j) {
216  return this->configdof().disp(i)[j];
217  },
218  [&](Index i, Index j) {
219  return other.disp(i)[j];
220  });
221  }
222 
224  bool operator()(const PermuteIterator &A) const override {
225  _update_A(A);
226  return _for_each(
227  [&](Index i, Index j) {
228  return this->configdof().disp(i)[j];
229  },
230  [&](Index i, Index j) {
231  return this->new_disp_A(j, A.permute_ind(i));
232  });
233  }
234 
236  bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override {
237  _update_A(A);
238  _update_B(B);
239  return _for_each(
240  [&](Index i, Index j) {
241  return this->new_disp_A(j, A.permute_ind(i));
242  },
243  [&](Index i, Index j) {
244  return this->new_disp_B(j, B.permute_ind(i));
245  });
246  }
247 
248  std::unique_ptr<Displacement> clone() const {
249  return std::unique_ptr<Displacement>(this->_clone());
250  }
251 
252  private:
253 
254  void _update_A(const PermuteIterator &A) const {
255  if(A.factor_group_index() != m_fg_index_A) {
258  }
259  }
260 
261  void _update_B(const PermuteIterator &B) const {
262  if(B.factor_group_index() != m_fg_index_B) {
265  }
266  }
267 
268  double new_disp_A(Index i, Index j) const {
269  return m_new_disp_A(i, j);
270  }
271 
272  double new_disp_B(Index i, Index j) const {
273  return m_new_disp_B(i, j);
274  }
275 
276  template<typename F, typename G>
277  bool _for_each(F f, G g) const {
278  Index i, j;
279  for(i = 0; i < size(); i++) {
280  for(j = 0; j < 3; j++) {
281  if(!_check(f(i, j), g(i, j))) {
282  return false;
283  }
284  }
285  }
286  return true;
287  }
288 
289  Displacement *_clone() const override {
290  return new Displacement(*this);
291  }
292 
295 
298  };
299 
300 
304  class Strain : public FloatIsEquivalent {
305 
306  public:
307 
308  Strain(const ConfigDoF &_configdof, double _tol) :
309  FloatIsEquivalent(_configdof, _tol),
310  m_def_tensor(_configdof.deformation().transpose() * _configdof.deformation()),
311  m_fg_index_A(-1),
312  m_fg_index_B(-1) {}
313 
314  Strain(const Configuration &_config, double _tol) :
315  Strain(_config.configdof(), _tol) {}
316 
318  bool operator()(const ConfigDoF &other) const override {
319  Eigen::MatrixXd other_def_tensor = other.deformation().transpose() * other.deformation();
320  return _for_each(
321  [&](Index i, Index j) {
322  return this->_def_tensor(i, j);
323  },
324  [&](Index i, Index j) {
325  return other_def_tensor(i, j);
326  });
327  }
328 
330  bool operator()(const PermuteIterator &A) const override {
331  _update_A(A);
332  return _for_each(
333  [&](Index i, Index j) {
334  return this->_def_tensor(i, j);
335  },
336  [&](Index i, Index j) {
337  return this->_def_tensor_A(i, j);
338  });
339  }
340 
342  bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override {
343  _update_A(A);
344  _update_B(B);
345  return _for_each(
346  [&](Index i, Index j) {
347  return this->_def_tensor_A(i, j);
348  },
349  [&](Index i, Index j) {
350  return this->_def_tensor_B(i, j);
351  });
352  }
353 
354  std::unique_ptr<Strain> clone() const {
355  return std::unique_ptr<Strain>(this->_clone());
356  }
357 
358  private:
359 
360  Strain *_clone() const override {
361  return new Strain(*this);
362  }
363 
364  void _update_A(const PermuteIterator &A) const {
365  if(A.factor_group_index() != m_fg_index_A) {
367  m_def_tensor_A = A.sym_op().matrix() * m_def_tensor * A.sym_op().matrix().transpose();
368  }
369  }
370 
371  void _update_B(const PermuteIterator &B) const {
372  if(B.factor_group_index() != m_fg_index_B) {
374  m_def_tensor_B = B.sym_op().matrix() * m_def_tensor * B.sym_op().matrix().transpose();
375  }
376  }
377 
378  double _def_tensor(Index i, Index j) const {
379  return m_def_tensor(i, j);
380  }
381 
382  double _def_tensor_A(Index i, Index j) const {
383  return m_def_tensor_A(i, j);
384  }
385 
386  double _def_tensor_B(Index i, Index j) const {
387  return m_def_tensor_B(i, j);
388  }
389 
390  template<typename F, typename G>
391  bool _for_each(F f, G g) const {
392  Index i, j;
393  for(i = 0; i < 3; i++) {
394  for(j = 0; j < 3; j++) {
395  if(!_check(f(i, j), g(i, j))) {
396  return false;
397  }
398  }
399  }
400  return true;
401  }
402 
405 
408 
411  };
412 
413  }// end namespace DoF
414 
415 
421 
422  public:
423 
434  template<typename ConfigDoFIsEquivalentType>
435  ConfigDoFIsEquivalent(std::unique_ptr<ConfigDoFIsEquivalentType> f) :
436  m_f(f) {}
437 
441  bool is_less() const {
442  return m_f->is_less();
443  }
444 
446  bool operator()(const Configuration &other) const {
447  return (*this)(other.configdof());
448  }
449 
451  bool operator()(const ConfigDoF &other) const {
452  return (*m_f)(other);
453  }
454 
456  bool operator()(const PermuteIterator &A) const {
457  return (*m_f)(A);
458  }
459 
461  bool operator()(const PermuteIterator &A, const PermuteIterator &B) const {
462  return (*m_f)(A, B);
463  }
464 
465  private:
467 
468  };
469 
473  template<typename ConfigDoFIsEquivalentType, typename ...Args>
475  return ConfigDoFIsEquivalent(notstd::make_unique<ConfigDoFIsEquivalentType>(std::forward<Args>(args)...));
476  }
477 
479 }
480 
481 #endif
FloatIsEquivalent(const ConfigDoF &_configdof, double _tol)
Eigen::MatrixXd MatrixXd
void _update_B(const PermuteIterator &B) const
Abstract base class specialization of ConfigDoFIsEquivalentBase for integral DoF types.
void _update_A(const PermuteIterator &A) const
bool _check(const T &A, const T &B) const
bool operator()(const ConfigDoF &other) const override
Return config == other, store config < other.
bool is_less() const
Returns less than comparison.
Base class for functors that compare ConfigDoF.
int & occ(Index i)
Definition: ConfigDoF.hh:61
bool operator()(const ConfigDoF &other) const
Return config == other.
bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override
Return A*config == B*config, store A*config < B*config.
bool is_less() const
Returns less than comparison.
double _def_tensor_A(Index i, Index j) const
Index permute_ind(Index i) const
Displacement(const Configuration &_config, double _tol)
bool operator()(const ConfigDoF &other) const override
Return config == other, store config < other.
const ConfigDoF & configdof() const
const Access the DoF
double _def_tensor(Index i, Index j) const
Main CASM namespace.
Definition: complete.cpp:8
Strain * _clone() const override
double _def_tensor_B(Index i, Index j) const
Index size() const
*** ACCESSORS ***
Definition: ConfigDoF.hh:53
bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override
Return A*config == B*config, store A*config < B*config.
const Eigen::Matrix3d & deformation() const
Definition: ConfigDoF.hh:85
double new_disp_B(Index i, Index j) const
void _update_B(const PermuteIterator &B) const
Eigen::MatrixXd m_def_tensor
config().deformation().transpose()*config().deformation()
bool operator()(const PermuteIterator &A) const
Return config == A*config.
Occupation(const ConfigDoF &_configdof)
bool operator()(const PermuteIterator &A) const override
Return config == A*config, store config < A*config.
const matrix_type & matrix() const
Const access of entire cartesian symmetry matrix.
Definition: SymOp.hh:57
bool operator()(const PermuteIterator &A, const PermuteIterator &B) const
Return A*config == B*config.
notstd::cloneable_ptr< DoFIsEquivalent::ConfigDoFIsEquivalentBase > m_f
Displacement(const ConfigDoF &_configdof, double _tol)
bool operator()(const PermuteIterator &A, const PermuteIterator &B) const override
Return A*config == B*config, store A*config < B*config.
EigenIndex Index
For long integer indexing:
std::unique_ptr< ConfigDoFIsEquivalentBase > clone() const
bool operator()(const ConfigDoF &other) const override
Return config == other, store config < other.
A container class for the different degrees of freedom a Configuration might have.
Definition: ConfigDoF.hh:27
Occupation * _clone() const override
std::unique_ptr< Occupation > clone() const
Displacement * _clone() const override
Abstract base class specialization of ConfigDoFIsEquivalentBase for floating point DoF types...
virtual ConfigDoFIsEquivalentBase * _clone() const =0
double new_disp_A(Index i, Index j) const
bool operator()(const PermuteIterator &A) const override
Return config == A*config, store config < A*config.
Wrapper class for generic equality comparison of ConfigDoF.
std::unique_ptr< Strain > clone() const
Occupation(const Configuration &_config)
std::unique_ptr< Displacement > clone() const
bool operator()(const Configuration &other) const
Return config == other.
void _update_A(const PermuteIterator &A) const
const displacement_matrix_t & displacement() const
Definition: ConfigDoF.hh:81
ConfigDoFIsEquivalent(std::unique_ptr< ConfigDoFIsEquivalentType > f)
Construct a ConfigDoFCompare object for a particular DoF type.
bool operator()(const PermuteIterator &A) const override
Return config == A*config, store config < A*config.
Strain(const ConfigDoF &_configdof, double _tol)
bool operator()(const Configuration &other) const
Return config == other.
displacement_t disp(Index i)
Definition: ConfigDoF.hh:73
Strain(const Configuration &_config, double _tol)
ConfigDoFIsEquivalent make_dof_is_equivalent(Args &&...args)
Index factor_group_index() const
Return the index into m_factor_group_permute of the factor group op being pointed at...
bool _check(const T &A, const T &B) const
A Configuration represents the values of all degrees of freedom in a Supercell.