CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Coordinate.cc
Go to the documentation of this file.
2 
6 
7 namespace CASM {
8 namespace xtal {
9 
11  const Eigen::Ref<const Coordinate::vector_type> &init_vec,
12  const Lattice &init_home, COORD_TYPE mode)
13  : m_home(&init_home) {
14  if (mode == FRAC) _set_frac(init_vec);
15  if (mode == CART) _set_cart(init_vec);
16  assert(m_home && "home lattice pointer was set to null!");
17 }
18 
19 //********************************************************************
20 
21 Coordinate::Coordinate(double _x, double _y, double _z,
22  const Lattice &init_home, COORD_TYPE mode)
23  : m_home(&init_home) {
24  if (mode == FRAC) {
25  m_frac_coord << _x, _y, _z;
26  _update_cart();
27  }
28  if (mode == CART) {
29  m_cart_coord << _x, _y, _z;
30  _update_frac();
31  }
32  assert(m_home && "home lattice pointer was set to null!");
33 }
34 
35 //********************************************************************
36 
38  cart() += RHS.cart();
39  return *this;
40 }
41 
42 //********************************************************************
43 
45  assert(this->m_home && "Home lattice is null");
46  assert(RHS.m_home && "RHS home lattice is null");
47 
48  cart() -= RHS.cart();
49  return *this;
50 }
51 
52 //********************************************************************
53 
55  return Coordinate(-frac(), home(), FRAC);
56 }
57 
58 //********************************************************************
59 
60 bool Coordinate::operator==(const Coordinate &RHS) const {
62 }
63 
64 //********************************************************************
65 
66 bool Coordinate::almost_equal(const Coordinate &RHS) const {
67  return dist(RHS) < lattice().tol();
68 }
69 
70 //********************************************************************
71 
72 bool Coordinate::compare(const Coordinate &RHS) const {
73  return (compare_type(RHS)) && (min_dist(RHS) < lattice().tol());
74 }
75 
76 //********************************************************************
77 
78 bool Coordinate::compare(const Coordinate &RHS, Coordinate &translation) const {
79  return (compare_type(RHS)) && (min_dist(RHS + translation) < lattice().tol());
80 }
81 
82 //********************************************************************
83 
84 bool Coordinate::compare_type(const Coordinate &RHS) const { return true; }
85 
86 //********************************************************************
87 
88 void Coordinate::read(std::istream &stream, COORD_TYPE mode) {
89  if (mode == FRAC) {
90  stream >> m_frac_coord;
91  _update_cart();
92  } else if (mode == CART) {
93  stream >> m_cart_coord;
94  _update_frac();
95  }
96 
97  return;
98 }
99 
100 //********************************************************************
101 
102 void Coordinate::print(std::ostream &stream, char term,
103  Eigen::IOFormat format) const {
104  print(stream, COORD_MODE::CHECK(), term, format);
105 }
106 
107 //********************************************************************
108 
109 void _formatted_print(std::ostream &stream, Eigen::Vector3d vec,
110  COORD_TYPE mode, char term, Eigen::IOFormat format) {
111  // stream.precision(prec);
112  // stream.width(prec + pad);
113  // stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
114 
115  stream << vec.transpose().format(format);
116  if (term) stream << term;
117  return;
118 }
119 
120 //********************************************************************
121 void Coordinate::print(std::ostream &stream, COORD_TYPE mode, char term,
122  Eigen::IOFormat format) const {
123  Eigen::Vector3d vec;
124 
125  if (mode == CART)
126  vec = const_cart();
127  else if (mode == FRAC)
128  vec = const_frac();
129  _formatted_print(stream, vec, mode, term, format);
130  return;
131 }
132 
133 //********************************************************************
134 
135 void Coordinate::print_axis(std::ostream &stream, COORD_TYPE mode, char term,
136  Eigen::IOFormat format) const {
137  Eigen::Vector3d vec;
138  if (mode == CART)
139  vec = const_cart().normalized();
140  else if (mode == FRAC)
141  vec = const_frac().normalized();
142  _formatted_print(stream, vec, mode, term, format);
143  return;
144 }
145 
146 //********************************************************************
147 
148 double Coordinate::dist(const Coordinate &neighbor) const {
149  return (cart() - neighbor.cart()).norm();
150 }
151 
152 double Coordinate::min_dist(const Coordinate &neighbor) const {
153  return this->min_translation(neighbor).const_cart().norm();
154 }
155 
157  assert(this->m_home && "Home lattice is null");
158  assert(neighbor.m_home && "Neighbor home lattice is null");
159  Coordinate translation = (*this) - neighbor;
160 
161  Eigen::Vector3d frac_lattice_translation =
162  lround(translation.const_frac()).cast<double>();
163 
164  translation.frac() -= frac_lattice_translation;
165  return translation;
166 }
167 
168 double Coordinate::robust_min_dist(const Coordinate &neighbor) const {
169  Coordinate translation = this->min_translation(neighbor);
170  double fast_result = translation.const_cart().norm();
171 
172  if (fast_result < (home().inner_voronoi_radius() + TOL)) return fast_result;
173 
174  translation.voronoi_within();
175  return translation.const_cart().norm();
176 }
177 
179  const Coordinate &neighbor,
180  const Eigen::Ref<const Eigen::Matrix3d> &metric) const {
181  vector_type tfrac(frac() - neighbor.frac());
182  tfrac -= lround(tfrac).cast<double>();
183 
184  return (home().lat_column_mat() * tfrac)
185  .dot(metric * (home().lat_column_mat() * tfrac));
186 }
187 
188 //********************************************************************
189 
190 void Coordinate::set_lattice(const Lattice &new_lat,
191  COORD_TYPE invariant_mode) {
192  m_home = &new_lat;
193  assert(m_home && "home lattice pointer was set to null!");
194 
195  if (invariant_mode == CART)
196  _update_frac();
197  else if (invariant_mode == FRAC)
198  _update_cart();
199 
200  return;
201 }
202 
203 //********************************************************************
204 
206  if (PERIODICITY_MODE::IS_LOCAL()) return true;
207 
208  bool was_within = true;
209  double tshift;
210  for (int i = 0; i < 3; i++) {
211  tshift = floor(m_frac_coord[i] + 1E-6);
212  if (!almost_zero(tshift, TOL)) {
213  was_within = false;
214  m_frac_coord[i] -= tshift;
215  }
216  }
217  if (!was_within) _update_cart();
218  return was_within;
219 }
220 
221 //********************************************************************
222 
223 bool Coordinate::within(Coordinate &translation) {
224  translation.m_home = m_home;
225  assert(m_home && "home lattice pointer was set to null!");
226  if (PERIODICITY_MODE::IS_LOCAL()) return true;
227 
228  bool was_within = true;
229 
230  for (int i = 0; i < 3; i++) {
231  translation.m_frac_coord[i] = -floor(m_frac_coord[i] + 1E-6);
232  if (!almost_zero(translation.m_frac_coord[i], TOL)) {
233  was_within = false;
234  }
235  }
236  translation._update_cart();
237 
238  if (!was_within) (*this) += translation;
239  return was_within;
240 }
241 
242 //********************************************************************
243 
244 bool Coordinate::is_within() const {
245  double tshift;
246  for (int i = 0; i < 3; i++) {
247  tshift = floor(m_frac_coord[i] + 1E-6);
248  if (std::abs(tshift) > TOL) {
249  return false;
250  }
251  }
252  return true;
253 }
254 
255 //********************************************************************
256 // Checks to see if coordinate is within voronoi cell of its home lattice.
257 //********************************************************************
258 
260 
261 //********************************************************************
262 // Checks to see if coordinate is within voronoi cell of specified lattice
263 //********************************************************************
264 
265 int Coordinate::voronoi_number(const Lattice &cell) const {
266  return cell.voronoi_number(const_cart());
267 }
268 
269 //********************************************************************
270 // Applies Lattice translations until coordinate is within voronoi cell of its
271 // home lattice.
272 //********************************************************************
273 
275  bool was_within(true);
276  Eigen::Vector3d lattice_trans;
277  while (home().max_voronoi_measure(cart(), lattice_trans) > (1. + TOL)) {
278  was_within = false;
279  cart() -= lattice_trans;
280  }
281 
282  return was_within;
283 }
284 
285 //********************************************************************
286 // Applies Lattice translations until coordinate is within voronoi cell of its
287 // home lattice.
288 //********************************************************************
289 
291  translation.m_home = m_home;
292  assert(m_home && "home lattice pointer was set to null!");
293  translation.cart() = vector_type::Zero();
294 
295  Eigen::Vector3d lattice_trans;
296  bool was_within(true);
297  while (home().max_voronoi_measure(cart(), lattice_trans) > (1. + TOL)) {
298  was_within = false;
299  cart() -= lattice_trans;
300  translation.cart() -= lattice_trans;
301  }
302 
303  return was_within;
304 }
305 
306 //********************************************************************
307 // Checks to see if coordinate describes shift by a general lattice vector
308 // l*V1+m*V2+n*V3, where l, m, n are integer
309 //********************************************************************
310 
311 bool Coordinate::is_lattice_shift(double tol) const {
312  // If mode is local, return true only if coordinate describes origin
314  return std::abs(m_frac_coord[0]) < tol && std::abs(m_frac_coord[1]) < tol &&
315  std::abs(m_frac_coord[2]) < tol;
316 
317  return (std::abs(m_frac_coord[0] - round(m_frac_coord[0])) < tol &&
318  std::abs(m_frac_coord[1] - round(m_frac_coord[1])) < tol &&
319  std::abs(m_frac_coord[2] - round(m_frac_coord[2])) < tol);
320 }
321 
322 //********************************************************************
323 // Applies symmetry to a coordinate.
324 //
325 // Overloads the * operator to apply symmetry to a coordinate
326 // using its Cartesian representation
327 //********************************************************************
328 
329 Coordinate operator*(const SymOp &LHS, const Coordinate &RHS) {
330  Coordinate tcoord(RHS);
331  sym::apply(LHS, tcoord);
332  return tcoord;
333 }
334 
335 //********************************************************************
336 // Allows direct printing of Coordinate with the << operator.
337 //********************************************************************
338 
339 std::ostream &operator<<(std::ostream &stream, const Coordinate &coord) {
340  coord.print(stream);
341  return stream;
342 }
343 
344 } // namespace xtal
345 
346 namespace sym {
348  xtal::Coordinate &mutating_coord) {
349  mutating_coord.cart() =
350  get_matrix(op) * mutating_coord.const_cart() + get_translation(op);
351  return mutating_coord;
352 }
353 
355  apply(op, coord);
356  return coord;
357 }
358 } // namespace sym
359 } // namespace CASM
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
bool almost_equal(const Coordinate &RHS) const
Definition: Coordinate.cc:66
bool is_within() const
Checks to see if coordinate is in the unit cell, but does not translate it.
Definition: Coordinate.cc:244
const Lattice & home() const
Access the home lattice of the coordinate.
Definition: Coordinate.hh:200
void print(std::ostream &stream, COORD_TYPE mode, char term=0, Eigen::IOFormat format=Eigen::IOFormat(7, 12)) const
Definition: Coordinate.cc:121
double min_dist2(const Coordinate &neighbor, const Eigen::Ref< const Eigen::Matrix3d > &metric) const
Definition: Coordinate.cc:178
Coordinate & operator+=(const Coordinate &RHS)
Positive translation of this coordinate by RHS.cart()
Definition: Coordinate.cc:37
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:562
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Change the home lattice of the coordinate, selecting one representation (either CART or FRAC) that re...
Definition: Coordinate.cc:190
Lattice const * m_home
Definition: Coordinate.hh:279
bool is_lattice_shift(double tol=TOL) const
Definition: Coordinate.cc:311
int voronoi_number() const
Definition: Coordinate.cc:259
const Lattice & lattice() const
Access the home lattice of the coordinate.
Definition: Coordinate.hh:206
void print_axis(std::ostream &stream, COORD_TYPE mode, char term=0, Eigen::IOFormat format=Eigen::IOFormat(7, 12)) const
Print normalized vector.
Definition: Coordinate.cc:135
Eigen::Vector3d vector_type
Definition: Coordinate.hh:36
const vector_type & const_frac() const
user override to force const Access the fractional coordinate vector
Definition: Coordinate.hh:68
bool compare(const Coordinate &RHS) const
Returns true if this->min_dist(RHS)<this->lattice().tol()
Definition: Coordinate.cc:72
Coordinate(const Lattice &_home)
Minimal constructor only takes a lattice.
Definition: Coordinate.hh:47
vector_type m_frac_coord
Definition: Coordinate.hh:281
Coordinate min_translation(const Coordinate &neighbor) const
Returns translation coordinate (in Angstr) to nearest periodic image of neighbor.
Definition: Coordinate.cc:156
double robust_min_dist(const Coordinate &neighbor) const
Returns distance (in Angstr) to nearest periodic image of neighbor.
Definition: Coordinate.cc:168
vector_type m_cart_coord
Definition: Coordinate.hh:281
bool compare_type(const Coordinate &RHS) const
Return true – Exists to allow duck-typing with Site.
Definition: Coordinate.cc:84
bool voronoi_within()
Map coordinate into the voronoi cell using a lattice translation.
Definition: Coordinate.cc:274
bool operator==(const Coordinate &RHS) const
Definition: Coordinate.cc:60
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
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:550
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
Definition: Coordinate.hh:90
Coordinate operator-() const
unary minus of this coordinate
Definition: Coordinate.cc:54
double dist(const Coordinate &neighbor) const
distance (in Angstr) of neighbor from *this
Definition: Coordinate.cc:148
int voronoi_number(const Eigen::Vector3d &pos) const
Definition: Lattice.cc:362
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:110
double tol() const
Definition: Lattice.hh:195
Coordinate operator*(const SymOp &LHS, const Coordinate &RHS)
Definition: Coordinate.cc:329
Eigen::CwiseUnaryOp< decltype(Local::lround_l< typename Derived::Scalar >), const Derived > lround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXl.
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
const SymOp::matrix_type & get_matrix(const SymOp &op)
Definition: SymOp.cc:167
const SymOp::vector_type & get_translation(const SymOp &op)
Definition: SymOp.cc:169
T dot(const Tensor< T > &LHS, const Tensor< T > &RHS)
Definition: Tensor.hh:925
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
void _formatted_print(std::ostream &stream, Eigen::Vector3d vec, COORD_TYPE mode, char term, Eigen::IOFormat format)
Definition: Coordinate.cc:109
std::ostream & operator<<(std::ostream &stream, const Site &site)
Definition: Site.cc:417
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
COORD_TYPE
Definition: enum.hh:6
const COORD_TYPE FRAC
Definition: enum.hh:8
const double TOL
Definition: definitions.hh:30
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:104
const COORD_TYPE CART
Definition: enum.hh:9