CASM  1.1.0
A Clusters Approach to Statistical Mechanics
UnitCellCoord.hh
Go to the documentation of this file.
1 #ifndef UNITCELLCOORD_HH
2 #define UNITCELLCOORD_HH
3 
4 #include <iostream>
5 #include <stdexcept>
6 
8 #include "casm/global/eigen.hh"
10 
11 namespace CASM {
12 namespace xtal {
13 class Coordinate;
14 class Site;
15 class BasicStructure;
16 class Lattice;
17 class UnitCellCoord;
18 class Superlattice;
19 } // namespace xtal
20 
21 namespace xtal {
22 
34 class UnitCell : public Eigen::Vector3l {
35  public:
36  UnitCell(void) : Eigen::Vector3l() {}
37 
39  template <typename OtherDerived>
40  UnitCell(const Eigen::MatrixBase<OtherDerived> &integral_coordinate)
41  : Eigen::Vector3l(integral_coordinate) {}
42 
43  UnitCell(Index a, Index b, Index c) : UnitCell(Eigen::Vector3l(a, b, c)) {}
44 
46  static UnitCell from_coordinate(Coordinate const &lattice_point);
47 
50  static UnitCell from_cartesian(const Eigen::Vector3d &cartesian_coord,
51  const Lattice &tiling_unit);
52 
55  Coordinate coordinate(const Lattice &tiling_unit) const;
56 
58  UnitCell reset_tiling_unit(const Lattice &current_tiling_unit,
59  const Lattice &new_tiling_unit) const;
60 
61  // This method allows you to assign Eigen expressions to MyVectorType
62  template <typename OtherDerived>
63  UnitCell &operator=(const Eigen::MatrixBase<OtherDerived> &other) {
64  this->Eigen::Vector3l::operator=(other);
65  return *this;
66  }
67 
69  bool operator<(const UnitCell &B) const {
70  const auto &A = *this;
71  for (Index i = 0; i < 3; i++) {
72  if (A(i) < B(i)) {
73  return true;
74  }
75  if (A(i) > B(i)) {
76  return false;
77  }
78  }
79  return false;
80  }
81 
82  private:
86  throw std::runtime_error(
87  "Could not round values to integers within a reasonable tolerance");
88  }
89 };
90 
96 template <typename Base>
97 struct Translatable : public Base {
98  typedef typename Base::MostDerived MostDerived;
99  using Base::derived;
100 
101  MostDerived &operator-=(UnitCell frac) { return derived() += -frac; }
102 
104  MostDerived tmp{derived()};
105  return tmp += frac;
106  }
107 
109  MostDerived tmp{derived()};
110  return tmp += -frac;
111  }
112 };
113 
114 /* -- UnitCellCoord Declarations ------------------------------------- */
115 
121  : public Comparisons<Translatable<CRTPBase<UnitCellCoord>>> {
122  public:
124 
126  : m_unitcell(_unitcell), m_sublat(_sublat) {
127  if (!valid_index(_sublat)) {
128  throw std::runtime_error(
129  "Error in UnitCellCoord. Construction requires a positive sublattice "
130  "index.");
131  }
132  }
133 
134  UnitCellCoord(Index _sublat, Index i, Index j, Index k)
135  : UnitCellCoord(_sublat, UnitCell(i, j, k)) {}
136 
137  explicit UnitCellCoord() : UnitCellCoord(0, 0, 0, 0) {}
138 
139  static UnitCellCoord from_coordinate(const PrimType &,
140  const Coordinate &coord, double tol);
141 
142  UnitCellCoord(const UnitCellCoord &B) = default;
143 
144  UnitCellCoord &operator=(const UnitCellCoord &B) = default;
145 
146  UnitCellCoord(UnitCellCoord &&B) = default;
147 
149 
150  const UnitCell &unitcell() const { return m_unitcell; }
151 
152  Index sublattice() const { return m_sublat; }
153 
155  Coordinate coordinate(const PrimType &prim) const;
156 
158  Site site(const PrimType &prim) const;
159 
162  const Site &sublattice_site(const PrimType &prim) const;
163 
164  Index operator[](Index i) const;
165 
167 
168  bool operator<(const UnitCellCoord &B) const;
169 
170  private:
173 
175 
176  Index &_sublattice() { return m_sublat; }
177 
178  bool eq_impl(const UnitCellCoord &B) const;
179 
182  bool _is_compatible_with_prim(const PrimType &prim) const;
183 
184  // TODO: Should this be made into an actual exception class?
186 
189 };
190 
191 inline std::ostream &operator<<(std::ostream &sout, const UnitCellCoord &site) {
192  return sout << site.sublattice() << ", " << site.unitcell().transpose();
193 }
194 
196  if (i == 0) {
197  return m_sublat;
198  }
199  return unitcell()[i - 1];
200 }
201 
203  m_unitcell += frac;
204  return *this;
205 }
206 
208 inline bool UnitCellCoord::operator<(const UnitCellCoord &B) const {
209  const auto &A = *this;
210  for (Index i = 0; i < 3; i++) {
211  if (A.unitcell()(i) < B.unitcell()(i)) {
212  return true;
213  }
214  if (A.unitcell()(i) > B.unitcell()(i)) {
215  return false;
216  }
217  }
218  if (A.sublattice() < B.sublattice()) {
219  return true;
220  }
221 
222  return false;
223 }
224 
225 inline bool UnitCellCoord::eq_impl(const UnitCellCoord &B) const {
226  const auto &A = *this;
227  return A.unitcell()(0) == B.unitcell()(0) &&
228  A.unitcell()(1) == B.unitcell()(1) &&
229  A.unitcell()(2) == B.unitcell()(2) && A.sublattice() == B.sublattice();
230 }
231 
237  const Superlattice &superlattice);
239  const Lattice &tiling_unit,
240  const Lattice &superlattice);
241 
242 } // namespace xtal
243 } // namespace CASM
244 
245 /* #include "casm/crystallography/Coordinate.hh" */
246 namespace CASM {
247 namespace xtal {}
248 } // namespace CASM
249 
250 namespace std {
251 template <>
252 struct hash<CASM::xtal::UnitCell> {
253  std::size_t operator()(const CASM::xtal::UnitCell &value) const;
254 };
255 
256 template <>
257 struct hash<CASM::xtal::UnitCellCoord> {
258  std::size_t operator()(const CASM::xtal::UnitCellCoord &value) const;
259 };
260 } // namespace std
261 #endif
BasicStructure specifies the lattice and atomic basis of a crystal.
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
Unit Cell Coordinates.
Site site(const PrimType &prim) const
Get a copy of corresponding site.
UnitCellCoord(Index _sublat, Index i, Index j, Index k)
UnitCellCoord & operator=(const UnitCellCoord &B)=default
UnitCellCoord(UnitCellCoord &&B)=default
UnitCellCoord & operator=(UnitCellCoord &&B)=default
const UnitCell & unitcell() const
UnitCellCoord(const UnitCellCoord &B)=default
const Site & sublattice_site(const PrimType &prim) const
Get reference to corresponding sublattice site in the unit structure.
Coordinate coordinate(const PrimType &prim) const
Get corresponding coordinate.
static UnitCellCoord from_coordinate(const PrimType &, const Coordinate &coord, double tol)
static void _throw_incompatible_primitive_cell()
bool _is_compatible_with_prim(const PrimType &prim) const
UnitCellCoord(Index _sublat, const UnitCell &_unitcell)
bool operator<(const UnitCellCoord &B) const
Compare UnitCellCoord.
Index operator[](Index i) const
bool eq_impl(const UnitCellCoord &B) const
UnitCellCoord & operator+=(UnitCell frac)
Unit Cell Indices.
static UnitCell from_cartesian(const Eigen::Vector3d &cartesian_coord, const Lattice &tiling_unit)
Coordinate coordinate(const Lattice &tiling_unit) const
UnitCell(Index a, Index b, Index c)
static UnitCell from_coordinate(Coordinate const &lattice_point)
Convert lattice point to a unitcell.
UnitCell reset_tiling_unit(const Lattice &current_tiling_unit, const Lattice &new_tiling_unit) const
Finds a new UnitCell with values relative to the given tiling unit.
static void _throw_large_rounding_error()
bool operator<(const UnitCell &B) const
Compare UnitCell.
UnitCell(const Eigen::MatrixBase< OtherDerived > &integral_coordinate)
Construct from integral fractional values, relative to the tiling unit.
UnitCell & operator=(const Eigen::MatrixBase< OtherDerived > &other)
Base class for CRTP pattern.
Definition: CRTPBase.hh:8
std::ostream & operator<<(std::ostream &stream, const Site &site)
Definition: Site.cc:417
Coordinate make_superlattice_coordinate(const UnitCell &ijk, const Superlattice &superlattice)
Main CASM namespace.
Definition: APICommand.hh:8
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Matrix< long int, 3, 1 > Vector3l
Definition: eigen.hh:13
Definition: stream_io.hh:24
CRTP class to implement '-=', '+', and '-' in terms of '+='.
MostDerived operator+(UnitCell frac) const
MostDerived & operator-=(UnitCell frac)
Base::MostDerived MostDerived
MostDerived operator-(UnitCell frac) const
Implements other comparisons in terms of '<'.
Definition: Comparisons.hh:25