CASM  1.1.0
A Clusters Approach to Statistical Mechanics
DoF.hh
Go to the documentation of this file.
1 #ifndef DOF_HH
2 #define DOF_HH
3 
4 #include <boost/algorithm/string.hpp>
5 #include <functional>
6 #include <set>
7 #include <string>
8 #include <vector>
9 
14 #include "casm/global/eigen.hh"
15 #include "casm/misc/CASM_math.hh"
16 #include "casm/misc/algorithm.hh"
19 
20 namespace CASM {
21 
22 class AnisoValTraits;
23 
24 class SymGroup;
25 
26 template <typename OccType>
27 class OccupantDoF;
28 
29 class ContinuousDoF;
30 class DoFSet;
31 
32 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33 namespace DoF {
35 
39 
40 // For now this isn't used, but may be in the future if we need a dynamic
41 // clexulator class for prototyping
42 class RemoteHandle {
43  public:
44  // \brief Construct with basic identification info
45  RemoteHandle(std::string const &_type_name, std::string const &_var_name,
46  Index _dof_ID)
47  : m_type_name(_type_name), m_var_name(_var_name), m_dof_ID(_dof_ID) {}
48 
49  // \brief Initialize pointer to double
50  RemoteHandle &operator=(double const &d) {
51  m_d_ptr = &d;
52  m_i_ptr = nullptr;
53  return *this;
54  }
55 
56  // \brief Initialize pointer to int
57  RemoteHandle &operator=(int const &i) {
58  m_d_ptr = nullptr;
59  m_i_ptr = &i;
60  return *this;
61  }
62 
63  // \brief prevent construction by non-addressable integer
64  RemoteHandle &operator=(double &&d) = delete;
65 
66  // \brief prevent construction by non-addressable double
67  RemoteHandle &operator=(int &&i) = delete;
68 
69  // \brief Less-than comparison to allow use of STL algorithms
70  bool operator<(RemoteHandle const &_rhs) const {
71  return m_dof_ID < _rhs.m_dof_ID ||
72  (m_dof_ID == _rhs.m_dof_ID && (m_type_name < _rhs.m_type_name ||
73  (m_type_name == _rhs.m_type_name &&
74  m_var_name < _rhs.m_var_name)));
75  }
76 
77  // \brief Equality comparison, irrespective of internal pointers (compares
78  // name and ID only)
79  bool operator==(RemoteHandle const &_rhs) const {
80  return m_dof_ID == _rhs.m_dof_ID && m_type_name == _rhs.m_type_name &&
81  m_var_name == _rhs.m_var_name;
82  }
83 
84  // \brief const access of integer pointer
85  const int *i_ptr() const { return m_i_ptr; }
86 
87  // \brief const access of double pointer
88  const double *d_ptr() const { return m_d_ptr; }
89 
90  private:
91  double const *m_d_ptr;
92  int const *m_i_ptr;
93 
94  std::string m_type_name;
95  std::string m_var_name;
97 };
98 
99 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100 
102 
119 class Base {
120  public:
122 
124  : m_traits(BasicTraits::null()),
125  m_var_name("NULL"),
126  m_dof_ID(-1),
127  m_ID_lock(false) {}
128 
129  Base(BasicTraits const &traits, std::string const &_var_name, Index _ID);
130 
131  BasicTraits const &traits() const { return m_traits; }
132 
134  std::string type_name() const { return m_traits.name(); }
135 
137  std::string var_name() const { return m_var_name; }
138 
140  Index ID() const { return m_dof_ID; }
141 
144  return RemoteHandle(type_name(), var_name(), ID());
145  }
146 
148  bool is_locked() const { return m_ID_lock; }
149 
151  void set_ID(Index new_ID) {
152  if (m_ID_lock) return;
153  // std::cout << "DoF " << this << " ID updated from " << ID() << " to " <<
154  // new_ID << '\n';
155  m_dof_ID = new_ID;
156  }
157 
159  void lock_ID() { m_ID_lock = true; }
160 
162  void unlock_ID() { m_ID_lock = false; }
163 
164  private:
166  std::string m_var_name;
167 
173 
175  bool m_ID_lock;
176 };
177 } // namespace DoF
178 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179 
180 class DiscreteDoF : public DoF::Base {
181  public:
182  using Base = DoF::Base;
185  : Base(),
186  m_current_state(0),
187  m_remote_state(nullptr),
188  m_symrep_ID(SymGroupRepID::identity(0)) {}
189 
190  DiscreteDoF(BasicTraits const &_traits, std::string const &_var_name,
191  Index _dof_ID = -1, int _current_state = 0,
193  : Base(_traits, _var_name, _dof_ID),
194  m_current_state(_current_state),
195  m_remote_state(nullptr),
196  m_symrep_ID(_id) {}
197 
198  virtual ~DiscreteDoF() {}
199 
200  SymGroupRepID symrep_ID() const { return m_symrep_ID; }
201 
203 
204  bool is_specified() const { return valid_index(m_current_state); }
205 
206  void invalidate() { m_current_state = -1; }
207 
208  int value() const { return m_current_state; }
209 
210  int remote_value() const {
211  assert(m_remote_state &&
212  "In DiscreteDoF::remote_value() m_remote_state is nullptr.\n");
213  return *m_remote_state;
214  }
215 
216  int const *remote_ptr() const { return m_remote_state; }
217 
218  void register_remote(RemoteHandle const &handle) const {
219  assert(handle.i_ptr() &&
220  "In DiscreteDoF::register_remote(), attempting to register to "
221  "nullptr!");
223  }
224 
225  std::unique_ptr<DiscreteDoF> clone() const {
226  return std::unique_ptr<DiscreteDoF>(this->_clone());
227  }
228 
229  virtual Index size() const = 0;
230 
231  virtual void set_value(int new_state) {
232  m_current_state = new_state;
233  return;
234  }
235 
236  virtual bool operator==(DiscreteDoF const &RHS) const {
237  if (value() != RHS.value()) return false;
238 
239  if (size() != RHS.size()) return false;
240 
241  return true;
242  }
243 
244  void print(std::ostream &out) const { out << value(); }
245 
246  protected:
249 
251  mutable int const *m_remote_state;
252 
255 
256  private:
257  virtual DiscreteDoF *_clone() const = 0;
258 };
259 
260 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261 
262 template <typename T>
263 class OccupantDoF : public DiscreteDoF {
264  public:
265  OccupantDoF(BasicTraits const &_traits, std::string const &_var_name,
266  SymGroupRepID symrep_ID, std::vector<T> const &_domain,
267  int _current_state = 0)
268  : DiscreteDoF(_traits, _var_name, -1, _current_state, symrep_ID),
269  m_domain(_domain) {}
270 
271  const T &occ() const { return m_domain[m_current_state]; }
272 
274  void set_value(int occ_index) override {
275  if (Index(occ_index) >= m_domain.size()) {
276  throw std::runtime_error(
277  "In OccupantDoF::set_value(): Bad Assignment, occ_index>=size.\n");
278  }
279  m_current_state = occ_index;
280  return;
281  }
282 
284  void set_current_state(T const &new_state) {
285  Index new_index = find_index(m_domain.begin(), m_domain.end(), new_state);
286  if (new_index >= m_domain.size()) {
287  throw std::runtime_error(
288  "In OccupantDoF::set_current_state(): Bad Assignment, new_state not "
289  "found in domain.\n");
290  }
291  m_current_state = new_index;
292  return;
293  }
294 
297  bool compare(OccupantDoF const &RHS, bool compare_value) const {
298  if (compare_value && (value() != RHS.value())) return false;
299 
300  if (size() != RHS.size()) return false;
301 
302  for (Index i = 0; i < size(); i++) {
303  if (!((*this)[i] == RHS[i])) return false;
304  }
305 
306  return true;
307  }
308 
310  bool operator==(OccupantDoF const &RHS) const { return compare(RHS, true); }
311 
312  void set_domain(std::vector<T> new_dom) {
313  m_domain = std::move(new_dom);
314  if (m_domain.size() == 1)
315  m_current_state = 0;
316  else
317  m_current_state = -1;
319  }
320 
321  const std::vector<T> &domain() const { return m_domain; }
322 
323  T &operator[](Index i) { return m_domain[i]; }
324 
325  const T &operator[](Index i) const { return m_domain[i]; }
326 
327  Index size() const override { return m_domain.size(); }
328 
329  void print(std::ostream &out) const {
330  for (Index i = 0; i < size(); i++) {
331  if (i == 0)
332  out << m_domain[i].name();
333  else
334  out << ' ' << m_domain[i].name();
335  }
336  }
337 
338  std::unique_ptr<OccupantDoF> clone() const {
339  return std::unique_ptr<OccupantDoF>(
340  static_cast<OccupantDoF *>(this->_clone()));
341  }
342 
343  private:
344  DiscreteDoF *_clone() const override { return new OccupantDoF(*this); }
345  /**** Inherited from DiscreteDoF ****
346  // index into domain of the current state, -1 if unspecified
347  // int m_current_state;
348 
349  // Allows DoF to point to a remote value for faster/easier evaluation
350  // const int *m_remote_state;
351  **/
352 
354  std::vector<T> m_domain;
355 };
356 
357 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358 
359 class ContinuousDoF : public DoF::Base {
360  public:
361  using Base = DoF::Base;
363 
364  ContinuousDoF(BasicTraits const &_traits, std::string const &_var_name,
365  Index _ID)
366  : Base(_traits, _var_name, _ID),
367  current_val(NAN),
368  m_remote_ptr(nullptr) {}
369 
370  ContinuousDoF(BasicTraits const &_traits) : ContinuousDoF(_traits, "", -1) {}
371 
372  double value() const { return current_val; }
373 
374  bool compare(ContinuousDoF const &RHS, bool compare_value = false) const {
375  if (compare_value && !almost_equal(value(), RHS.value())) return false;
376 
377  return (type_name() == RHS.type_name() && var_name() == RHS.var_name() &&
378  (ID() == RHS.ID()));
379  }
380 
381  bool operator==(ContinuousDoF const &RHS) const {
382  return ((type_name() == RHS.type_name()) && var_name() == RHS.var_name() &&
383  (ID() == RHS.ID()) && almost_equal(value(), RHS.value()));
384  }
385 
386  double remote_value() const {
387  assert(m_remote_ptr &&
388  "In ContinuousDoF::remote_value() m_remote_val is nullptr.\n");
389  return *m_remote_ptr;
390  }
391 
392  double const *remote_ptr() const { return m_remote_ptr; }
393 
394  void register_remote(RemoteHandle const &handle) const {
395  assert(handle.d_ptr() &&
396  "In ContinuousDoF::register_remote(), attempting to register to "
397  "nullptr!");
399  }
400 
401  std::unique_ptr<ContinuousDoF> clone() const {
402  return notstd::make_unique<ContinuousDoF>(*this);
403  }
404 
405  private:
406  double current_val;
407 
409  mutable double const *m_remote_ptr;
410 };
411 
412 inline bool compare_no_value(ContinuousDoF const &A, ContinuousDoF const &B) {
413  return A.compare(B);
414 }
415 } // namespace CASM
416 #endif
Specifies traits of (possibly) anisotropic crystal properties.
std::string const & name() const
Const access of name.
ContinuousDoF(BasicTraits const &_traits)
Definition: DoF.hh:370
bool operator==(ContinuousDoF const &RHS) const
Definition: DoF.hh:381
double current_val
Definition: DoF.hh:406
double const * m_remote_ptr
Allows DoF to point to a remote value for faster/easier evaluation.
Definition: DoF.hh:409
double const * remote_ptr() const
Definition: DoF.hh:392
std::unique_ptr< ContinuousDoF > clone() const
Definition: DoF.hh:401
double remote_value() const
Definition: DoF.hh:386
ContinuousDoF(BasicTraits const &_traits, std::string const &_var_name, Index _ID)
Definition: DoF.hh:364
double value() const
Definition: DoF.hh:372
void register_remote(RemoteHandle const &handle) const
Definition: DoF.hh:394
bool compare(ContinuousDoF const &RHS, bool compare_value=false) const
Definition: DoF.hh:374
void register_remote(RemoteHandle const &handle) const
Definition: DoF.hh:218
int remote_value() const
Definition: DoF.hh:210
virtual bool operator==(DiscreteDoF const &RHS) const
Definition: DoF.hh:236
void set_symrep_ID(SymGroupRepID _id)
Definition: DoF.hh:202
SymGroupRepID m_symrep_ID
ID for the permutation representation for occupants.
Definition: DoF.hh:254
virtual Index size() const =0
virtual DiscreteDoF * _clone() const =0
void print(std::ostream &out) const
Definition: DoF.hh:244
SymGroupRepID symrep_ID() const
Definition: DoF.hh:200
int value() const
Definition: DoF.hh:208
void invalidate()
Definition: DoF.hh:206
virtual void set_value(int new_state)
Definition: DoF.hh:231
bool is_specified() const
Definition: DoF.hh:204
int const * m_remote_state
Allows DoF to point to a remote value for faster/easier evaluation.
Definition: DoF.hh:251
std::unique_ptr< DiscreteDoF > clone() const
Definition: DoF.hh:225
virtual ~DiscreteDoF()
Definition: DoF.hh:198
int m_current_state
index into domain of the current state, -1 if unspecified
Definition: DoF.hh:248
int const * remote_ptr() const
Definition: DoF.hh:216
DiscreteDoF(BasicTraits const &_traits, std::string const &_var_name, Index _dof_ID=-1, int _current_state=0, SymGroupRepID _id=SymGroupRepID::identity(0))
Definition: DoF.hh:190
A class that represents an individual Degree of Freedom.
Definition: DoF.hh:119
RemoteHandle handle() const
Create a RemoteHandle that refers to this DoF.
Definition: DoF.hh:143
void unlock_ID()
mutator to unlock integer ID
Definition: DoF.hh:162
Index ID() const
Const access of integer ID.
Definition: DoF.hh:140
DoF::RemoteHandle RemoteHandle
Definition: DoF.hh:121
Index m_dof_ID
Definition: DoF.hh:172
BasicTraits const & traits() const
Definition: DoF.hh:131
std::string m_var_name
Definition: DoF.hh:166
std::string var_name() const
Const access of variable name.
Definition: DoF.hh:137
void lock_ID()
mutator to lock integer ID
Definition: DoF.hh:159
bool is_locked() const
true if ID is locked
Definition: DoF.hh:148
std::string type_name() const
Const access of DoF type name.
Definition: DoF.hh:134
bool m_ID_lock
Locks the ID so that it can't be updated. Is used for global DoF's.
Definition: DoF.hh:175
BasicTraits m_traits
Definition: DoF.hh:165
void set_ID(Index new_ID)
mutator to set integer ID if it is unlocked
Definition: DoF.hh:151
bool operator<(RemoteHandle const &_rhs) const
Definition: DoF.hh:70
int const * m_i_ptr
Definition: DoF.hh:92
std::string m_var_name
Definition: DoF.hh:95
std::string m_type_name
Definition: DoF.hh:94
const double * d_ptr() const
Definition: DoF.hh:88
RemoteHandle & operator=(double &&d)=delete
const int * i_ptr() const
Definition: DoF.hh:85
RemoteHandle & operator=(int const &i)
Definition: DoF.hh:57
RemoteHandle & operator=(double const &d)
Definition: DoF.hh:50
RemoteHandle & operator=(int &&i)=delete
RemoteHandle(std::string const &_type_name, std::string const &_var_name, Index _dof_ID)
Definition: DoF.hh:45
bool operator==(RemoteHandle const &_rhs) const
Definition: DoF.hh:79
double const * m_d_ptr
Definition: DoF.hh:91
T & operator[](Index i)
Definition: DoF.hh:323
void set_current_state(T const &new_state)
Set occupant by value.
Definition: DoF.hh:284
const T & operator[](Index i) const
Definition: DoF.hh:325
void print(std::ostream &out) const
Definition: DoF.hh:329
bool operator==(OccupantDoF const &RHS) const
Equivalent to (*this).compare(RHS,true)
Definition: DoF.hh:310
void set_domain(std::vector< T > new_dom)
Definition: DoF.hh:312
bool compare(OccupantDoF const &RHS, bool compare_value) const
Returns true if (*this) is equivalent to RHS,.
Definition: DoF.hh:297
OccupantDoF(BasicTraits const &_traits, std::string const &_var_name, SymGroupRepID symrep_ID, std::vector< T > const &_domain, int _current_state=0)
Definition: DoF.hh:265
const std::vector< T > & domain() const
Definition: DoF.hh:321
const T & occ() const
Definition: DoF.hh:271
Index size() const override
Definition: DoF.hh:327
std::unique_ptr< OccupantDoF > clone() const
Definition: DoF.hh:338
void set_value(int occ_index) override
Set occupant by index.
Definition: DoF.hh:274
DiscreteDoF * _clone() const override
Definition: DoF.hh:344
std::vector< T > m_domain
Allowed values, assume class T has method 'T.name()()'.
Definition: DoF.hh:354
Type-safe ID object for communicating and accessing Symmetry representation info.
static SymGroupRepID identity(Index dim)
Static function to construct an ID for identity representations.
AnisoValTraits BasicTraits
Definition: DoF.hh:34
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
Definition: algorithm.hh:24
bool compare_no_value(ContinuousDoF const &A, ContinuousDoF const &B)
Definition: DoF.hh:412
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39