CASM  1.1.0
A Clusters Approach to Statistical Mechanics
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 
15 namespace ConfigDoFIsEquivalent {
16 
23 class Base {
24  public:
25  virtual ~Base() {}
26 
30  bool is_less() const { return m_less; }
31 
33  bool operator()(Configuration const &other) const {
34  return (*this)(other.configdof());
35  }
36 
38  virtual bool operator()(ConfigDoF const &other) const = 0;
39 
41  virtual bool operator()(PermuteIterator const &A) const = 0;
42 
44  virtual bool operator()(PermuteIterator const &A,
45  PermuteIterator const &B) const = 0;
46 
48  virtual bool operator()(PermuteIterator const &A,
49  ConfigDoF const &other) const = 0;
50 
52  virtual bool operator()(PermuteIterator const &A, PermuteIterator const &B,
53  ConfigDoF const &other) const = 0;
54 
55  std::unique_ptr<Base> clone() const {
56  return std::unique_ptr<Base>(this->_clone());
57  }
58 
59  protected:
60  mutable bool m_less;
61 
62  private:
63  virtual Base *_clone() const = 0;
64 };
65 
70 class Occupation : public Base {
71  public:
72  Occupation(ConfigDoF const &_configdof) : m_configdof_ptr(&_configdof) {}
73 
75  bool operator()(ConfigDoF const &other) const override {
76  return _for_each([&](Index i) { return this->configdof().occ(i); },
77  [&](Index i) { return other.occ(i); });
78  }
79 
81  bool operator()(PermuteIterator const &A) const override {
82  return _for_each(
83  [&](Index i) { return this->configdof().occ(i); },
84  [&](Index i) { return this->configdof().occ(A.permute_ind(i)); });
85  }
86 
88  bool operator()(PermuteIterator const &A,
89  PermuteIterator const &B) const override {
90  return _for_each(
91  [&](Index i) { return this->configdof().occ(A.permute_ind(i)); },
92  [&](Index i) { return this->configdof().occ(B.permute_ind(i)); });
93  }
94 
96  bool operator()(PermuteIterator const &A,
97  ConfigDoF const &other) const override {
98  return _for_each([&](Index i) { return this->configdof().occ(i); },
99  [&](Index i) { return other.occ(A.permute_ind(i)); });
100  }
101 
103  bool operator()(PermuteIterator const &A, PermuteIterator const &B,
104  ConfigDoF const &other) const override {
105  return _for_each(
106  [&](Index i) { return this->configdof().occ(A.permute_ind(i)); },
107  [&](Index i) { return other.occ(B.permute_ind(i)); });
108  }
109 
110  protected:
111  ConfigDoF const &configdof() const { return *m_configdof_ptr; }
112 
113  template <typename F, typename G>
114  bool _for_each(F f, G g) const {
115  Index i;
116  for (i = 0; i < configdof().size(); i++) {
117  if (!_check(f(i), g(i))) {
118  return false;
119  }
120  }
121  // std::cout << "Equal!\n";
122  return true;
123  }
124 
125  private:
126  Occupation *_clone() const override { return new Occupation(*this); }
127 
128  template <typename T>
129  bool _check(const T &A, const T &B) const {
130  if (A == B) {
131  return true;
132  }
133  m_less = (A < B);
134  return false;
135  }
136 
138 };
139 
155 class AnisoOccupation : public Base {
156  public:
157  AnisoOccupation(ConfigDoF const &_configdof)
158  : m_configdof_ptr(&_configdof),
159  m_tmp_valid(true),
160  m_fg_index_A(0),
162  m_fg_index_B(0),
164 
166  bool operator()(ConfigDoF const &other) const override {
167  return _for_each([&](Index i) { return this->configdof().occ(i); },
168  [&](Index i) { return other.occ(i); });
169  }
170 
172  bool operator()(PermuteIterator const &B) const override {
173  _update_B(B, configdof());
174  m_tmp_valid = true;
175 
176  return _for_each(
177  [&](Index i) { return this->configdof().occ(i); },
178  [&](Index i) { return this->m_new_occ_B[B.permute_ind(i)]; });
179  }
180 
183  PermuteIterator const &B) const override {
184  _update_A(A, configdof());
185  _update_B(B, configdof());
186  m_tmp_valid = true;
187 
188  return _for_each(
189  [&](Index i) { return this->m_new_occ_A[A.permute_ind(i)]; },
190  [&](Index i) { return this->m_new_occ_B[B.permute_ind(i)]; });
191  }
192 
195  ConfigDoF const &other) const override {
196  _update_B(B, other);
197  m_tmp_valid = false;
198 
199  return _for_each(
200  [&](Index i) { return this->m_configdof_ptr->occ(i); },
201  [&](Index i) { return this->m_new_occ_B[B.permute_ind(i)]; });
202  }
203 
205  bool operator()(PermuteIterator const &A, PermuteIterator const &B,
206  ConfigDoF const &other) const override {
207  _update_A(A, configdof());
208  _update_B(B, other);
209  m_tmp_valid = false;
210 
211  return _for_each(
212  [&](Index i) { return this->m_new_occ_A[A.permute_ind(i)]; },
213  [&](Index i) { return this->m_new_occ_B[B.permute_ind(i)]; });
214  }
215 
216  protected:
217  ConfigDoF const &configdof() const { return *m_configdof_ptr; }
218 
219  template <typename F, typename G>
220  bool _for_each(F f, G g) const {
221  Index i;
222  for (i = 0; i < configdof().size(); i++) {
223  if (!_check(f(i), g(i))) {
224  return false;
225  }
226  }
227  // std::cout << "Equal!\n";
228  return true;
229  }
230 
231  void _update_A(PermuteIterator const &A, ConfigDoF const &before) const {
234  Index l = 0;
235  for (Index b = 0; b < m_configdof_ptr->n_sublat(); ++b) {
236  for (Index n = 0; n < m_configdof_ptr->n_vol(); ++n, ++l) {
237  m_new_occ_A[l] = (*(A.occ_rep(b).permutation()))[before.occ(l)];
238  }
239  }
240  }
241  }
242 
243  void _update_B(PermuteIterator const &B, ConfigDoF const &before) const {
246  Index l = 0;
247  for (Index b = 0; b < m_configdof_ptr->n_sublat(); ++b) {
248  for (Index n = 0; n < m_configdof_ptr->n_vol(); ++n, ++l) {
249  m_new_occ_B[l] = (*(B.occ_rep(b).permutation()))[before.occ(l)];
250  }
251  }
252  }
253  }
254 
255  private:
256  AnisoOccupation *_clone() const override {
257  return new AnisoOccupation(*this);
258  }
259 
260  template <typename T>
261  bool _check(const T &A, const T &B) const {
262  if (A == B) {
263  return true;
264  }
265  m_less = (A < B);
266  return false;
267  }
268 
269  // Points to ConfigDoF this was constructed with
271 
272  // Set to false when comparison is made to "other" ConfigDoF, to force update
273  // of temporary dof during the next comparison
274  mutable bool m_tmp_valid;
275 
276  // Store temporary DoFValues under fg operation only:
277 
279  mutable Eigen::VectorXi m_new_occ_A;
280 
282  mutable Eigen::VectorXi m_new_occ_B;
283 };
284 
290 class Float : public Base {
291  public:
292  Float(double _tol, DoFKey const &_key) : m_tol(_tol), m_key(_key) {}
293 
294  DoFKey const &key() const { return m_key; }
295 
296  protected:
297  template <typename T>
298  bool _check(const T &A, const T &B) const {
299  // std::cout << "A: " << A << "; B: " << B <<"; ";
300  if (A < B - tol()) {
301  m_less = true;
302  // std::cout << "Greater!\n";
303  return false;
304  }
305  if (A > B + tol()) {
306  // std::cout << "Less!\n";
307  m_less = false;
308  return false;
309  }
310  // std::cout << "Equal!\n";
311  return true;
312  }
313 
314  private:
315  double tol() const { return m_tol; }
316 
317  const double m_tol;
318 
319  const DoFKey m_key;
320 };
321 
334 class Local : public Float {
335  public:
336  Local(ConfigDoF const &_configdof, DoFKey const &_key, double _tol)
337  : Float(_tol, _key),
338  m_values_ptr(&(_configdof.local_dof(_key))),
339  m_tmp_valid(true),
341  m_fg_index_A(0),
343  m_fg_index_B(0),
345  m_zeros.setZero();
346  }
347 
348  Local(Configuration const &_config, DoFKey const &_key, double _tol)
349  : Local(_config.configdof(), _key, _tol) {}
350 
352  bool operator()(ConfigDoF const &other) const override {
353  LocalContinuousConfigDoFValues const *other_ptr;
354  if (other.has_local_dof(key())) {
355  other_ptr = &(other.local_dof(key()));
356  } else {
357  other_ptr = &m_zeros;
358  }
359 
360  return _for_each(
361  [&](Index i, Index j) { return this->_values().values()(i, j); },
362  [&](Index i, Index j) { return (*other_ptr).values()(i, j); });
363  }
364 
366  bool operator()(PermuteIterator const &B) const override {
367  _update_B(B, _values());
368  m_tmp_valid = true;
369 
370  return _for_each(
371  [&](Index i, Index j) { return this->_values().values()(i, j); },
372  [&](Index i, Index j) { return this->new_dof_B(i, B.permute_ind(j)); });
373  }
374 
377  PermuteIterator const &B) const override {
378  _update_A(A, _values());
379  _update_B(B, _values());
380  m_tmp_valid = true;
381  return _for_each(
382  [&](Index i, Index j) { return this->new_dof_A(i, A.permute_ind(j)); },
383  [&](Index i, Index j) { return this->new_dof_B(i, B.permute_ind(j)); });
384  }
385 
388  ConfigDoF const &other) const override {
389  LocalContinuousConfigDoFValues const *other_ptr;
390  if (other.has_local_dof(key())) {
391  other_ptr = &(other.local_dof(key()));
392  } else {
393  other_ptr = &m_zeros;
394  }
395 
396  _update_B(B, *other_ptr);
397  m_tmp_valid = false;
398 
399  return _for_each(
400  [&](Index i, Index j) { return this->_values().values()(i, j); },
401  [&](Index i, Index j) { return this->new_dof_B(i, B.permute_ind(j)); });
402  }
403 
405  bool operator()(PermuteIterator const &A, PermuteIterator const &B,
406  ConfigDoF const &other) const override {
407  LocalContinuousConfigDoFValues const *other_ptr;
408  if (other.has_local_dof(key())) {
409  other_ptr = &(other.local_dof(key()));
410  } else {
411  other_ptr = &m_zeros;
412  }
413  _update_A(A, _values());
414  _update_B(B, *other_ptr);
415  m_tmp_valid = false;
416 
417  return _for_each(
418  [&](Index i, Index j) { return this->new_dof_A(i, A.permute_ind(j)); },
419  [&](Index i, Index j) { return this->new_dof_B(i, B.permute_ind(j)); });
420  }
421 
422  private:
424  return *m_values_ptr;
425  }
426 
427  void _update_A(PermuteIterator const &A,
428  LocalContinuousConfigDoFValues const &before) const {
430  for (Index b = 0; b < m_values_ptr->n_sublat(); ++b) {
432  Index rows = A.local_dof_rep(key(), b).MatrixXd()->rows();
433  m_new_dof_A.sublat(b).topRows(rows) =
434  *(A.local_dof_rep(key(), b).MatrixXd()) *
435  before.sublat(b).topRows(rows);
436  }
437  }
438  }
439 
440  void _update_B(PermuteIterator const &B,
441  LocalContinuousConfigDoFValues const &before) const {
443  for (Index b = 0; b < m_values_ptr->n_sublat(); ++b) {
445  Index rows = B.local_dof_rep(key(), b).MatrixXd()->rows();
446 
447  m_new_dof_B.sublat(b).topRows(rows) =
448  *(B.local_dof_rep(key(), b).MatrixXd()) *
449  before.sublat(b).topRows(rows);
450  }
451  }
452  }
453 
454  double new_dof_A(Index i, Index j) const {
455  return m_new_dof_A.values()(i, j);
456  }
457 
458  double new_dof_B(Index i, Index j) const {
459  return m_new_dof_B.values()(i, j);
460  }
461 
462  template <typename F, typename G>
463  bool _for_each(F f, G g) const {
464  Index i, j;
465  for (j = 0; j < _values().values().cols(); j++) {
466  for (i = 0; i < _values().values().rows(); i++) {
467  if (!_check(f(i, j), g(i, j))) {
468  return false;
469  }
470  }
471  }
472  return true;
473  }
474 
475  Base *_clone() const override { return new Local(*this); }
476 
477  // Points to LocalContinuousConfigDoFValues of ConfigDoF this was constructed
478  // with
480 
481  // Set to false when comparison is made to "other" ConfigDoF, to force update
482  // of temporary dof during the next comparison
483  mutable bool m_tmp_valid;
484 
485  // Used when "other" ConfigDoF does not have local DoF==this->key()
487 
488  // Store temporary DoFValues under fg operation only:
489 
492 
495 };
496 
500 class Global : public Float {
501  public:
502  Global(ConfigDoF const &_configdof, DoFKey const &_key, double _tol)
503  : Float(_tol, _key),
504  m_values_ptr(&_configdof.global_dof(_key)),
505  m_tmp_valid(true),
507  m_fg_index_A(0),
509  m_fg_index_B(true),
511  m_zeros.setZero();
512  }
513 
514  Global(Configuration const &_config, DoFKey const &_key, double _tol)
515  : Global(_config.configdof(), _key, _tol) {}
516 
518  bool operator()(ConfigDoF const &other) const override {
519  GlobalContinuousConfigDoFValues const *other_ptr;
520  if (other.has_global_dof(key())) {
521  other_ptr = &(other.global_dof(key()));
522  } else {
523  other_ptr = &m_zeros;
524  }
525 
526  return _for_each([&](Index i) { return this->_values(i); },
527  [&](Index i) { return other_ptr->values()[i]; });
528  }
529 
531  bool operator()(PermuteIterator const &B) const override {
532  _update_B(B, _values());
533  m_tmp_valid = true;
534  return _for_each([&](Index i) { return this->_values(i); },
535  [&](Index i) { return this->_new_dof_B(i); });
536  }
537 
540  PermuteIterator const &B) const override {
541  _update_A(A, _values());
542  _update_B(B, _values());
543  m_tmp_valid = true;
544  return _for_each([&](Index i) { return this->_new_dof_A(i); },
545  [&](Index i) { return this->_new_dof_B(i); });
546  }
547 
550  ConfigDoF const &other) const override {
551  GlobalContinuousConfigDoFValues const *other_ptr;
552  if (other.has_global_dof(key())) {
553  other_ptr = &(other.global_dof(key()));
554  } else {
555  other_ptr = &m_zeros;
556  }
557  _update_B(B, *other_ptr);
558  m_tmp_valid = false;
559  return _for_each([&](Index i) { return this->_values().values()[i]; },
560  [&](Index i) { return this->_new_dof_B(i); });
561  }
562 
564  bool operator()(PermuteIterator const &A, PermuteIterator const &B,
565  ConfigDoF const &other) const override {
566  GlobalContinuousConfigDoFValues const *other_ptr;
567  if (other.has_global_dof(key())) {
568  other_ptr = &(other.global_dof(key()));
569  } else {
570  other_ptr = &m_zeros;
571  }
572  _update_A(A, _values());
573  _update_B(B, *other_ptr);
574  m_tmp_valid = false;
575  return _for_each([&](Index i) { return this->_new_dof_A(i); },
576  [&](Index i) { return _new_dof_B(i); });
577  }
578 
579  private:
580  Base *_clone() const override { return new Global(*this); }
581 
582  void _update_A(PermuteIterator const &A,
583  GlobalContinuousConfigDoFValues const &before) const {
587  before.values());
588  }
589  }
590 
591  void _update_B(PermuteIterator const &B,
592  GlobalContinuousConfigDoFValues const &before) const {
596  before.values());
597  }
598  }
599 
601  return *m_values_ptr;
602  }
603 
604  double _values(Index i) const { return _values().values()[i]; }
605 
606  double _new_dof_A(Index i) const { return m_new_dof_A.values()[i]; }
607 
608  double _new_dof_B(Index i) const { return m_new_dof_B.values()[i]; }
609 
610  template <typename F, typename G>
611  bool _for_each(F f, G g) const {
612  Index i;
613  for (i = 0; i < _values().values().size(); i++) {
614  if (!_check(f(i), g(i))) {
615  return false;
616  }
617  }
618  return true;
619  }
620 
621  // Points to GlobalContinuousConfigDoFValues of ConfigDoF this was constructed
622  // with
624 
625  // Set to false when comparison is made to "other" ConfigDoF, to force update
626  // of temporary dof during the next comparison
627  mutable bool m_tmp_valid;
628 
629  // Used when "other" ConfigDoF does not have local DoF==this->key()
631 
632  // Store temporary DoFValues under fg operation only:
633 
636 
639 };
640 
641 } // namespace ConfigDoFIsEquivalent
642 
646 // template<typename ConfigDoFIsEquivalentType, typename ...Args>
647 // ConfigDoFIsEquivalent make_dof_is_equivalent(Args &&...args) {
648 // return
649 // ConfigDoFIsEquivalent(notstd::make_unique<ConfigDoFIsEquivalentType>(std::forward<Args>(args)...));
650 //}
651 
653 } // namespace CASM
654 
655 #endif
Index size() const
Number of sites in the ConfigDoF.
Definition: ConfigDoF.cc:11
Index n_vol() const
Integer volume of ConfigDoF.
Definition: ConfigDoF.cc:14
bool has_local_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:143
Index n_sublat() const
Number of sublattices in ConfigDoF.
Definition: ConfigDoF.cc:17
bool has_global_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:88
GlobalContinuousConfigDoFValues const & global_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:69
int & occ(Index i)
Reference occupation value on site i.
Definition: ConfigDoF.cc:34
LocalContinuousConfigDoFValues const & local_dof(DoFKey const &_key) const
Definition: ConfigDoF.cc:124
bool operator()(ConfigDoF const &other) const override
Return config == other, store config < other.
void _update_B(PermuteIterator const &B, ConfigDoF const &before) const
bool operator()(PermuteIterator const &B) const override
Return config == B*config, store config < B*config.
bool operator()(PermuteIterator const &A, PermuteIterator const &B, ConfigDoF const &other) const override
Return A*config == B*other, store A*config < B*other.
bool operator()(PermuteIterator const &A, PermuteIterator const &B) const override
Return A*config == B*config, store A*config < B*config.
void _update_A(PermuteIterator const &A, ConfigDoF const &before) const
bool operator()(PermuteIterator const &B, ConfigDoF const &other) const override
Return config == B*other, store config < B*other.
Base class for functors that compare ConfigDoF.
bool operator()(Configuration const &other) const
Return config == other.
std::unique_ptr< Base > clone() const
virtual bool operator()(PermuteIterator const &A, PermuteIterator const &B, ConfigDoF const &other) const =0
Return A*config == B*other.
virtual bool operator()(PermuteIterator const &A) const =0
Return config == A*config.
virtual bool operator()(PermuteIterator const &A, PermuteIterator const &B) const =0
Return A*config == B*config.
virtual Base * _clone() const =0
bool is_less() const
Returns less than comparison.
virtual bool operator()(ConfigDoF const &other) const =0
Return config == other.
virtual bool operator()(PermuteIterator const &A, ConfigDoF const &other) const =0
Return config == A*other.
Abstract base class specialization of Base for floating point DoF types.
Float(double _tol, DoFKey const &_key)
bool _check(const T &A, const T &B) const
GlobalContinuousConfigDoFValues m_new_dof_A
bool operator()(PermuteIterator const &A, PermuteIterator const &B, ConfigDoF const &other) const override
Return A*config == B*other, store A*config < B*other.
bool operator()(PermuteIterator const &B, ConfigDoF const &other) const override
Return config == B*other, store config < B*other.
GlobalContinuousConfigDoFValues const & _values() const
bool operator()(PermuteIterator const &B) const override
Return config == B*config, store config < B*config.
GlobalContinuousConfigDoFValues const * m_values_ptr
Global(Configuration const &_config, DoFKey const &_key, double _tol)
GlobalContinuousConfigDoFValues m_new_dof_B
GlobalContinuousConfigDoFValues m_zeros
bool operator()(PermuteIterator const &A, PermuteIterator const &B) const override
Return A*config == B*config, store A*config < B*config.
void _update_A(PermuteIterator const &A, GlobalContinuousConfigDoFValues const &before) const
void _update_B(PermuteIterator const &B, GlobalContinuousConfigDoFValues const &before) const
bool operator()(ConfigDoF const &other) const override
Return config == other, store config < other.
Global(ConfigDoF const &_configdof, DoFKey const &_key, double _tol)
bool operator()(PermuteIterator const &A, PermuteIterator const &B) const override
Return A*config == B*config, store A*config < B*config.
bool operator()(PermuteIterator const &B) const override
Return config == B*config, store config < B*config.
LocalContinuousConfigDoFValues const & _values() const
bool operator()(PermuteIterator const &A, PermuteIterator const &B, ConfigDoF const &other) const override
Return A*config == B*other, store A*config < B*other.
double new_dof_B(Index i, Index j) const
bool operator()(PermuteIterator const &B, ConfigDoF const &other) const override
Return config == B*other, store config < B*other.
double new_dof_A(Index i, Index j) const
LocalContinuousConfigDoFValues m_new_dof_A
LocalContinuousConfigDoFValues m_zeros
LocalContinuousConfigDoFValues const * m_values_ptr
LocalContinuousConfigDoFValues m_new_dof_B
Local(ConfigDoF const &_configdof, DoFKey const &_key, double _tol)
bool operator()(ConfigDoF const &other) const override
Return config == other, store config < other.
void _update_A(PermuteIterator const &A, LocalContinuousConfigDoFValues const &before) const
Local(Configuration const &_config, DoFKey const &_key, double _tol)
void _update_B(PermuteIterator const &B, LocalContinuousConfigDoFValues const &before) const
bool operator()(PermuteIterator const &A, ConfigDoF const &other) const override
Return config == A*other, store config < A*other.
bool operator()(PermuteIterator const &A, PermuteIterator const &B, ConfigDoF const &other) const override
Return A*config == B*other, store A*config < B*other.
bool _check(const T &A, const T &B) const
bool operator()(PermuteIterator const &A) const override
Return config == A*config, store config < A*config.
bool operator()(PermuteIterator const &A, PermuteIterator const &B) const override
Return A*config == B*config, store A*config < B*config.
bool operator()(ConfigDoF const &other) const override
Return config == other, store config < other.
const ConfigDoF & configdof() const
const Access the DoF
Eigen::VectorXd const & values() const
Const access global DoF values.
void setZero()
Set DoF values to zero.
void set_values(Eigen::Ref< const Eigen::MatrixXd > const &_values)
Set global DoF values.
SublatReference sublat(Index b)
Access matrix block of values for all sites on one sublattice.
Eigen::MatrixXd const & values() const
Const access DoF values (prim DoF basis, matrix representing all sites)
void setZero()
Set DoF values to zero.
SymOpRepresentation const & global_dof_rep(DoFKey const &_key) const
Index factor_group_index() const
Return the supercell factor group index.
SymOpRepresentation const & local_dof_rep(DoFKey const &_key, Index b) const
SymOpRepresentation const & occ_rep(Index b) const
Index permute_ind(Index i) const
virtual Permutation const * permutation() const
virtual Eigen::MatrixXd const * MatrixXd() const
DoF_impl::OccupationDoFTraits occupation()
Main CASM namespace.
Definition: APICommand.hh:8
Eigen::MatrixXd MatrixXd
std::string DoFKey
Definition: DoFDecl.hh:7
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39