CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Site.cc
Go to the documentation of this file.
2 
3 #include <exception>
4 #include <set>
5 #include <string>
6 #include <vector>
7 
12 
13 namespace {
14 using namespace CASM;
15 bool occupant_dof_are_equal(const std::vector<xtal::Molecule> &LHS,
16  const std::vector<xtal::Molecule> &RHS,
17  double tol) {
18  if (RHS.size() != LHS.size()) return false;
19  Index j;
20  for (Index i = 0; i < LHS.size(); ++i) {
21  for (j = 0; j < RHS.size(); ++j) {
22  if (LHS[i].identical(RHS[j], tol)) {
23  break;
24  }
25  }
26  if (j == RHS.size()) {
27  return false;
28  }
29  }
30  return true;
31 }
32 } // namespace
33 
34 namespace CASM {
35 namespace xtal {
36 
37 // TODO: Can we delete this?
38 Site::Site(const Lattice &init_home)
39  : Coordinate(init_home), m_label(-1), m_type_ID(-1) {}
40 
41 //****************************************************
42 
43 Site::Site(const Coordinate &init_pos, const std::string &occ_name)
44  : Site(init_pos, std::vector<Molecule>{Molecule::make_atom(occ_name)}) {}
45 
47 Site::Site(const Coordinate &init_pos, const std::vector<Molecule> &site_occ,
48  const std::map<std::string, SiteDoFSet> &site_dof)
49  : Coordinate(init_pos),
50  m_label(-1),
51  m_type_ID(-1),
52  m_occupant_dof(site_occ),
53  m_dof_map(site_dof) {}
54 
55 Site::Site(const Coordinate &init_pos, const std::vector<Molecule> &site_occ)
56  : Site(init_pos, site_occ, std::map<std::string, SiteDoFSet>()) {}
57 
60 Site::Site(const Coordinate &init_pos, const std::vector<Molecule> &site_occ,
61  const std::vector<SiteDoFSet> &dofset_vec)
62  : Site(init_pos, site_occ, make_dofset_map(dofset_vec)) {}
63 
65 
66 //****************************************************
67 
68 const std::vector<Molecule> &Site::occupant_dof() const {
69  return m_occupant_dof;
70 }
71 
72 //****************************************************
73 
74 Index Site::dof_size() const { return m_dof_map.size(); }
75 
76 //****************************************************
77 
78 SiteDoFSet const &Site::dof(std::string const &_dof_type) const {
79  auto it = m_dof_map.find(_dof_type);
80  if (it != m_dof_map.end())
81  return (it->second);
82  else
83  throw std::runtime_error(
84  std::string("In Structure::dof(), this structure does not contain any "
85  "global DoF's of type ") +
86  _dof_type);
87 }
88 
89 //****************************************************
90 bool Site::has_dof(std::string const &_dof_type) const {
91  return occupant_dof().size() > 1 ||
92  m_dof_map.find(_dof_type) != m_dof_map.end();
93 }
94 
95 //****************************************************
96 
97 std::vector<std::string> Site::dof_types() const {
98  std::vector<std::string> result;
99  // if(occupant_dof().size() > 1)
100  // result.push_back(occupant_dof().type_name());
101  for (auto it = m_dof_map.begin(); it != m_dof_map.end(); ++it)
102  result.push_back(it->first);
103  return result;
104 }
105 
106 //****************************************************
107 
109  for (auto const &_dof : m_dof_map)
110  if (_dof.second.traits().time_reversal_active()) return true;
111 
112  for (auto const &mol : this->occupant_dof())
113  if (mol.time_reversal_active()) return true;
114  return false;
115 }
116 
117 //****************************************************
118 
119 Index Site::label() const { return m_label; };
120 
121 //****************************************************
122 
123 /* Site &Site::_apply_sym_attributes(const SymOp &op) { */
124 /* for(Index i = 0; i < occupant_dof().size(); i++) */
125 /* m_occupant_dof[i].apply_sym(op); */
126 
127 /* auto it = m_dof_map.begin(); */
128 /* for(; it != m_dof_map.end(); ++it) */
129 /* it->second = sym::copy_apply(op, it->second); */
130 
131 /* m_type_ID = -1; */
132 /* return *this; */
133 /* } */
134 
135 /* Site &Site::apply_sym(const SymOp &op) { */
136 /* Coordinate::apply_sym(op); */
137 /* _apply_sym_attributes(op); */
138 /* return *this; */
139 /* } */
140 
141 //****************************************************
145 //****************************************************
146 
147 Site &Site::operator+=(const Coordinate &translation) {
148  Coordinate::operator+=(translation);
149  return *this;
150 }
151 
152 //****************************************************
156 //****************************************************
157 
158 Site &Site::operator-=(const Coordinate &translation) {
159  Coordinate::operator-=(translation);
160  return *this;
161 }
162 
163 //*******************************************************************************************
167 //*******************************************************************************************
168 
169 bool Site::compare(const Coordinate &test_coord) const {
170  return (min_dist(test_coord) < lattice().tol());
171 }
172 
173 //*******************************************************************************************
177 //*******************************************************************************************
178 
179 bool Site::compare(const Site &test_site) const {
180  return (compare_type(test_site) && min_dist(test_site) < lattice().tol());
181 }
182 
183 //*******************************************************************************************
187 //*******************************************************************************************
188 
189 bool Site::compare_type(const Site &test_site) const {
190  return _type_ID() == test_site._type_ID();
191 }
192 
193 //*******************************************************************************************
194 
195 bool Site::operator==(const Site &test_site) const {
196  return (compare_type(test_site) && Coordinate::operator==(test_site));
197 }
198 
199 //*******************************************************************************************
200 
201 bool Site::almost_equal(const Site &test_site) const {
202  return (compare_type(test_site) && dist(test_site) < lattice().tol());
203 }
204 
205 //****************************************************
206 
207 bool Site::contains(const std::string &name) const {
208  for (Index i = 0; i < occupant_dof().size(); i++)
209  if (occupant_dof()[i].contains(name)) {
210  return true;
211  }
212  return false;
213 }
214 
215 //****************************************************
216 
217 bool Site::contains(const std::string &name, int &index) const {
218  for (Index i = 0; i < occupant_dof().size(); i++)
219  if (occupant_dof()[i].contains(name)) {
220  index = i;
221  return true;
222  }
223  return false;
224 }
225 
226 //****************************************************
227 
228 void Site::set_allowed_occupants(std::vector<Molecule> const &_new_occ_domain) {
229  m_occupant_dof = _new_occ_domain;
230  m_type_ID = -1;
231 }
232 
233 //****************************************************
234 
235 void Site::set_dofs(std::map<std::string, SiteDoFSet> _dofs) {
236  m_dof_map = std::move(_dofs);
237  m_type_ID = -1;
238 }
239 
240 //****************************************************
241 
242 std::vector<std::string> Site::allowed_occupants() const {
243  std::vector<std::string> occ_list;
244  for (Index i = 0; i < occupant_dof().size(); i++) {
245  occ_list.push_back(occupant_dof()[i].name());
246  }
247  return occ_list;
248 }
249 
250 //****************************************************
251 
252 void Site::set_label(Index new_ind) {
253  if (new_ind == m_label) return;
254  m_label = new_ind;
255 
256  m_type_ID = -1;
257  return;
258 }
259 
260 //****************************************************
261 // read site, including all possible occupants
262 void Site::read(std::istream &stream, bool SD_is_on) {
263  set_label(-1);
264 
265  char ch;
266 
267  Eigen::Vector3i SD_flag;
268 
270  if (SD_is_on) {
271  for (int i = 0; i < 3; i++) {
272  stream >> ch;
273  if (ch == 'T') {
274  SD_flag[i] = 1;
275  } else if (ch == 'F') {
276  SD_flag[i] = 0;
277  }
278  }
279  }
280 
281  std::vector<Molecule> tocc;
282 
283  ch = stream.peek();
284  while (ch != '\n' && ch != ':' && !stream.eof()) {
285  while ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') && ch != '\n' &&
286  ch != ':' && !stream.eof()) {
287  stream.ignore();
288  ch = stream.peek();
289  }
290  if (ch != '\n' && ch != ':' && !stream.eof()) {
291  // Need to change this part for real molecules
292  std::string mol_name;
293  stream >> mol_name;
294  tocc.push_back(Molecule::make_atom(mol_name));
295  }
296  ch = stream.peek();
297  }
298 
299  if (ch == ':') {
300  stream.ignore();
301  stream.ignore();
302 
303  std::string mol_name;
304  stream >> mol_name;
305 
306  if (tocc.size()) {
307  m_occupant_dof = tocc;
308  Index index = tocc.size();
309  for (Index i = 0; i < tocc.size(); i++)
310  if (tocc[i].name() == mol_name) {
311  index = i;
312  break;
313  }
314  /* if(index == tocc.size()) { */
315  /* std::stringstream ss; */
316  /* ss << "Error in Site::read(): Occupying molecule not listed in
317  * possible occupants" << std::endl; */
318  /* ss << " occupying molecule name: " << mol_name << " index: " <<
319  * index << std::endl; */
320  /* ss << " possible occupants: "; */
321  /* for(Index i = 0; i < tocc.size(); i++) */
322  /* ss << tocc[i].name() << " "; */
323  /* ss << " " << std::endl; */
324  /* throw std::runtime_error(ss.str()); */
325  /* } */
326  /* else { */
327  /* m_occupant_dof->set_value(index); */
328  /* } */
329 
330  } else {
331  throw std::runtime_error(
332  "Error in Site::read(): Trying to read Site info, but no valid input "
333  "was received.");
334  }
335  m_type_ID = -1;
336  return;
337  }
338 
339  if (tocc.size()) {
340  m_occupant_dof = tocc;
341  } else {
342  throw std::runtime_error(
343  "Error in Site::read(): Trying to read Site info, but no valid input "
344  "was received.");
345  }
346  stream.ignore(1000, '\n'); // ????
347 
348  m_type_ID = -1;
349  return;
350 }
351 
352 //****************************************************
353 // read site, using 'elem' as site occupant domain
354 void Site::read(std::istream &stream, std::string &elem, bool SD_is_on) {
355  char ch;
356 
357  set_label(-1);
358 
359  Eigen::Vector3i SD_flag;
360 
362  if (SD_is_on) {
363  for (int i = 0; i < 3; i++) {
364  stream >> ch;
365  if (ch == 'T') {
366  SD_flag[i] = 1;
367  } else if (ch == 'F') {
368  SD_flag[i] = 0;
369  }
370  }
371  }
372 
373  std::vector<Molecule> tocc;
374 
375  tocc.push_back(Molecule::make_atom(elem));
376 
377  if (tocc.size()) {
378  m_occupant_dof = tocc;
379  } else {
380  throw std::runtime_error(
381  "Error in Site::read(): Trying to read Site info, but no valid input "
382  "was received.");
383  }
384  stream.ignore(1000, '\n');
385 
386  m_type_ID = -1;
387  return;
388 }
389 
390 //****************************************************
394 //****************************************************
395 
396 void Site::print(std::ostream &stream, Eigen::IOFormat format) const {
397  Coordinate::print(stream, 0, format);
398  stream << " ";
399  for (const Molecule &m : this->occupant_dof()) {
400  stream << m.name() << " ";
401  }
402  stream << std::endl;
403 
404  return;
405 }
406 
407 void Site::print_occupant_dof(const std::vector<Molecule> &allowed_occupants,
408  std::ostream &out_stream) {
409  for (const Molecule &m : allowed_occupants) {
410  out_stream << m.name() << ' ';
411  }
412  return;
413 }
414 
415 //****************************************************
416 
417 std::ostream &operator<<(std::ostream &stream, const Site &site) {
418  site.print(stream);
419  return stream;
420 }
421 
422 //*******************************************************************************************
423 
424 bool Site::_compare_type_no_ID(const Site &_other) const {
425  // compare domain but not value
426  if (!(label() == _other.label() &&
427  ::occupant_dof_are_equal(occupant_dof(), _other.occupant_dof(), TOL)))
428  return false;
429 
430  if (m_dof_map.size() != _other.m_dof_map.size()) return false;
431 
432  auto it1 = m_dof_map.begin(), it2 = _other.m_dof_map.begin();
433  for (; it1 != m_dof_map.end(); ++it1, ++it2)
434  if (!SiteDoFSetIsEquivalent_f(it1->second, CASM::TOL)(it2->second)) {
435  return false;
436  }
437 
438  return true;
439 }
440 
441 //*******************************************************************************************
442 
444  if (!valid_index(m_type_ID)) {
445  for (m_type_ID = 0; m_type_ID < _type_prototypes().size(); m_type_ID++) {
447  }
448 
449  _type_prototypes().push_back(*this);
450  }
451  return m_type_ID;
452 }
453 
454 //****************************************************
455 
456 Site operator*(const SymOp &LHS, const Site &RHS) {
457  return sym::copy_apply(LHS, RHS);
458 }
459 
460 //****************************************************
461 
462 Site operator+(const Site &LHS, const Coordinate &RHS) {
463  return Site(LHS) += RHS;
464 }
465 
466 //****************************************************
467 
468 Site operator+(const Coordinate &LHS, const Site &RHS) {
469  return Site(RHS) += LHS;
470 }
471 
472 } // namespace xtal
473 
474 namespace sym {
475 xtal::Site &apply(const xtal::SymOp &op, xtal::Site &mutating_site) {
476  xtal::Site transformed_site = copy_apply(op, mutating_site);
477  std::swap(transformed_site, mutating_site);
478  return mutating_site;
479 }
480 
482  xtal::Coordinate transformed_coord =
483  copy_apply(op, static_cast<xtal::Coordinate &>(site));
484 
485  std::vector<xtal::Molecule> transformed_occupants = site.occupant_dof();
486  for (xtal::Molecule &occ : transformed_occupants) {
487  apply(op, occ);
488  }
489 
490  std::map<std::string, xtal::SiteDoFSet> transformed_dof;
491  for (const auto &name_dof_pr : site.dofs()) {
492  transformed_dof.emplace(name_dof_pr.first,
493  sym::copy_apply(op, name_dof_pr.second));
494  }
495 
496  return xtal::Site(transformed_coord, transformed_occupants, transformed_dof);
497 }
498 } // namespace sym
499 } // namespace CASM
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
void print(std::ostream &stream, COORD_TYPE mode, char term=0, Eigen::IOFormat format=Eigen::IOFormat(7, 12)) const
Definition: Coordinate.cc:121
Coordinate & operator+=(const Coordinate &RHS)
Positive translation of this coordinate by RHS.cart()
Definition: Coordinate.cc:37
const Lattice & lattice() const
Access the home lattice of the coordinate.
Definition: Coordinate.hh:206
Coordinate & operator-=(const Coordinate &RHS)
Negative translation of this coordinate by RHS.cart()
Definition: Coordinate.cc:44
void read(std::istream &stream, COORD_TYPE mode)
Definition: Coordinate.cc:88
double min_dist(const Coordinate &neighbor) const
Returns distance (in Angstr) to nearest periodic image of neighbor.
Definition: Coordinate.cc:152
double dist(const Coordinate &neighbor) const
distance (in Angstr) of neighbor from *this
Definition: Coordinate.cc:148
Class representing a Molecule.
Definition: Molecule.hh:93
bool _compare_type_no_ID(const Site &test_site) const
Definition: Site.cc:424
bool operator==(const Site &test_site) const
Definition: Site.cc:195
bool time_reversal_active() const
Definition: Site.cc:108
Index _type_ID() const
Definition: Site.cc:443
bool compare_type(const Site &test_site) const
Definition: Site.cc:189
std::map< std::string, SiteDoFSet > const & dofs() const
Definition: Site.hh:78
bool compare(const Coordinate &test_coord) const
Definition: Site.cc:169
Index dof_size() const
Definition: Site.cc:74
Site(const Lattice &init_home)
Definition: Site.cc:38
bool has_dof(std::string const &_dof_type) const
Definition: Site.cc:90
void read(std::istream &stream, bool SD_is_on=false)
Definition: Site.cc:262
bool contains(const std::string &name) const
Definition: Site.cc:207
Index m_type_ID
Definition: Site.hh:107
void set_dofs(std::map< std::string, SiteDoFSet > _dofs)
Definition: Site.cc:235
const std::vector< Molecule > & occupant_dof() const
Definition: Site.cc:68
Site & operator-=(const Coordinate &translation)
Definition: Site.cc:158
void print(std::ostream &stream, Eigen::IOFormat format=Eigen::IOFormat(7, 12)) const
Definition: Site.cc:396
SiteDoFSet const & dof(std::string const &_dof_type) const
Definition: Site.cc:78
void set_label(Index _new_label)
Definition: Site.cc:252
Index m_label
Integer label used to differentiate sites of otherwise identical type.
Definition: Site.hh:104
static std::vector< Site > & _type_prototypes()
Definition: Site.hh:98
std::vector< std::string > allowed_occupants() const
Definition: Site.cc:242
void set_allowed_occupants(const std::vector< Molecule > &new_occ_domain)
Definition: Site.cc:228
std::map< std::string, SiteDoFSet > m_dof_map
additional continuous degrees of freedom
Definition: Site.hh:115
Site & operator+=(const Coordinate &translation)
Definition: Site.cc:147
std::vector< std::string > dof_types() const
Definition: Site.cc:97
static void print_occupant_dof(const std::vector< Molecule > &allowed_occupants, std::ostream &out_stream)
Definition: Site.cc:407
std::vector< Molecule > m_occupant_dof
Definition: Site.hh:112
bool almost_equal(const Site &test_site) const
Definition: Site.cc:201
Index label() const
access m_label;
Definition: Site.cc:119
Coordinate operator*(const SymOp &LHS, const Coordinate &RHS)
Definition: Coordinate.cc:329
Coordinate operator+(const Coordinate &LHS, const Coordinate &RHS)
Definition: Coordinate.hh:290
static Molecule make_atom(std::string const &atom_name)
Return an atomic Molecule with specified name.
Definition: Molecule.cc:86
xtal::Coordinate copy_apply(const xtal::SymOp &op, xtal::Coordinate coord)
Copy and apply SymOp to a Coordinate.
Definition: Coordinate.cc:354
xtal::Coordinate & apply(const xtal::SymOp &op, xtal::Coordinate &coord)
apply SymOp to a Coordinate
Definition: Coordinate.cc:347
std::map< std::string, DoFSetType > make_dofset_map(std::vector< DoFSetType > const &dofset_vec)
Definition: DoFSet.hh:130
std::ostream & operator<<(std::ostream &stream, const Site &site)
Definition: Site.cc:417
Main CASM namespace.
Definition: APICommand.hh:8
void swap(ConfigDoF &A, ConfigDoF &B)
Definition: ConfigDoF.cc:260
const double TOL
Definition: definitions.hh:30
GenericDatumFormatter< std::string, DataObject > name()
bool identical(AnisoValTraits const &A, AnisoValTraits const &B)
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Definition: stream_io.hh:24