CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Coordinate.cc
Go to the documentation of this file.
2 
3 #include "casm/misc/CASM_math.hh"
5 #include "casm/symmetry/SymOp.hh"
7 
8 namespace CASM {
9 
10  Coordinate::Coordinate(const Eigen::Vector3d &init_vec,
11  const Lattice &init_home,
12  COORD_TYPE mode)
13  : m_home(&init_home),
14  m_basis_ind(-1) {
15  if(mode == FRAC)
16  _set_frac(init_vec);
17  if(mode == CART)
18  _set_cart(init_vec);
19  }
20 
21  //********************************************************************
22 
23  Coordinate::Coordinate(double _x, double _y, double _z, const Lattice &init_home, COORD_TYPE mode)
24  : m_home(&init_home),
25  m_basis_ind(-1) {
26  if(mode == FRAC) {
27  m_frac_coord << _x, _y, _z;
28  _update_cart();
29  }
30  if(mode == CART) {
31  m_cart_coord << _x, _y, _z;
32  _update_frac();
33  }
34  }
35 
36  //********************************************************************
37 
39  cart() += RHS.cart();
40  return *this;
41  }
42 
43  //********************************************************************
44 
46  cart() -= RHS.cart();
47  return *this;
48 
49  }
50 
51  //********************************************************************
52 
54  return Coordinate(-frac(), home(), FRAC);
55  }
56 
57  //********************************************************************
58 
59  bool Coordinate::operator==(const Coordinate &RHS) const {
61  }
62 
63 
64  //********************************************************************
65 
66  bool Coordinate::almost_equal(const Coordinate &RHS, double tol) const {
67  return dist(RHS) < tol;
68  }
69 
70 
71  //********************************************************************
72 
73  bool Coordinate::compare(const Coordinate &RHS, double compare_tol) const {
74  return (compare_type(RHS)) && (min_dist(RHS) < compare_tol);
75 
76  }
77 
78  //********************************************************************
79 
80  bool Coordinate::compare(const Coordinate &RHS, Coordinate &translation, double compare_tol) const {
81  return (compare_type(RHS)) && (min_dist(RHS + translation) < compare_tol);
82  }
83 
84  //********************************************************************
85 
86  bool Coordinate::compare_type(const Coordinate &RHS)const {
87  return true;
88  }
89 
90  //********************************************************************
91 
92  void Coordinate::read(std::istream &stream, COORD_TYPE mode) {
93  if(mode == FRAC) {
94  stream >> m_frac_coord;
95  _update_cart();
96  }
97  else if(mode == CART) {
98  stream >> m_cart_coord;
99  _update_frac();
100  }
101 
102  return;
103  }
104 
105  //********************************************************************
106 
107  void Coordinate::print(std::ostream &stream, char term, int prec, int pad) const {
108  print(stream, COORD_MODE::CHECK(), term, prec, pad);
109  }
110 
111  //********************************************************************
112  void Coordinate::print(std::ostream &stream, COORD_TYPE mode, char term, int prec, int pad) const {
113 
114  stream.precision(prec);
115  stream.width(prec + pad);
116  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
117 
118  if(mode == CART)
119  stream << const_cart().transpose();
120  else if(mode == FRAC)
121  stream << const_frac().transpose();
122  if(term) stream << term;
123  return;
124  }
125 
126  //********************************************************************
127 
129  void Coordinate::print_axis(std::ostream &stream, COORD_TYPE mode, char term, int prec, int pad) const {
130 
131  stream.precision(prec);
132  stream.width(prec + pad);
133  stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
134 
135  if(mode == CART)
136  stream << const_cart().normalized().transpose();
137  else if(mode == FRAC)
138  stream << const_frac().normalized().transpose();
139  if(term) stream << term;
140  return;
141  }
142 
143  //********************************************************************
144  // Finds distance between two coordinates
145 
146  double Coordinate::dist(const Coordinate &neighbor) const {
147  return (cart() - neighbor.cart()).norm();
148  }
149 
150  //********************************************************************
151  // Finds minimum distance from any periodic image of a coordinate to any
152  // periodic image of a neighboring coordinate
153  //********************************************************************
154 
155  double Coordinate::min_dist(const Coordinate &neighbor) const {
156  vector_type tfrac(frac() - neighbor.frac());
157  tfrac -= lround(tfrac).cast<double>();
158 
159  return (home().lat_column_mat() * tfrac).norm();
160  }
161 
162  //********************************************************************
163  // Finds minimum distance from any periodic image of a coordinate to any
164  // periodic image of a neighboring coordinate. Also passes the
165  // calculated translation in the argument.
166  //********************************************************************
167 
168 
169  double Coordinate::min_dist(const Coordinate &neighbor, Coordinate &translation) const {
170  translation = (*this) - neighbor;
171  translation.frac() -= lround(translation.const_frac()).cast<double>();
172  return translation.const_cart().norm();
173  }
174  //********************************************************************
175  // Finds minimum distance from any periodic image of a coordinate to any
176  // periodic image of a neighboring coordinate
177  //********************************************************************
178 
179  double Coordinate::robust_min_dist(const Coordinate &neighbor) const {
180  Coordinate translation(home());
181  return robust_min_dist(neighbor, translation);
182  }
183 
184  //********************************************************************
185  // Finds minimum distance from any periodic image of a coordinate to any
186  // periodic image of a neighboring coordinate. Also passes the
187  // calculated translation in the argument.
188  //********************************************************************
189 
190  double Coordinate::robust_min_dist(const Coordinate &neighbor, Coordinate &translation) const {
191  double fast_result = min_dist(neighbor, translation);
192 
193  if(fast_result < (home().inner_voronoi_radius() + TOL))
194  return fast_result;
195 
196  translation.voronoi_within();
197  return translation.const_cart().norm();
198  }
199 
200  //********************************************************************
201  // Finds minimum distance from any periodic image of a coordinate to any
202  // periodic image of a neighboring coordinate
203  //********************************************************************
204 
205  double Coordinate::min_dist2(const Coordinate &neighbor, const Eigen::Ref<const Eigen::Matrix3d> &metric) const {
206  vector_type tfrac(frac() - neighbor.frac());
207  tfrac -= lround(tfrac).cast<double>();
208 
209  return (home().lat_column_mat() * tfrac).dot(metric * (home().lat_column_mat() * tfrac));
210  }
211 
212  //********************************************************************
213  // Applies symmetry to a coordinate.
214  //********************************************************************
215 
217  cart() = op.matrix() * const_cart() + op.tau();
218 
219  return *this;
220  }
221 
222  //********************************************************************
223  // Applies symmetry to a coordinate, but doesn't apply translation
224  //********************************************************************
225 
227  cart() = op.matrix() * const_cart();
228  return *this;
229  }
230 
231  //********************************************************************
232  // Change the home lattice of the coordinate, selecting one representation (either CART or FRAC)
233  // that remains invariant
234  //
235  // invariant_mode == CART: Cartesian coordinates stay the same, and fractional coordinates are updated
236  // Ex: (my_coord.set_lattice(superlattice, CART); // this is how superlattices get filled.
237  //
238  // invariant_mode == FRAC: Fractional coordinates stay the same, and Cartesian coordinates are updated
239  // Ex: you can apply a strain by changing the lattice and keepin FRAC invariant
240  // (my_coord.set_lattice(strained_lattice, FRAC);
241  // Ex: you can apply a rotation by changing the lattice and keeping FRAC invariant
242  // (my_coord.set_lattice(rotated_lattice, FRAC);
243  //********************************************************************
244 
245  void Coordinate::set_lattice(const Lattice &new_lat, COORD_TYPE invariant_mode) {
246  m_home = &new_lat;
247 
248  if(invariant_mode == CART)
249  _update_frac();
250  else if(invariant_mode == FRAC)
251  _update_cart();
252 
253  return;
254  }
255 
256  //********************************************************************
257  // Within: if a point is outiside the cell defined by Lattice home
258  // then map that point back into the cell via translation by lattice vectors
259  //********************************************************************
260 
262  if(PERIODICITY_MODE::IS_LOCAL()) return true;
263 
264  bool was_within = true;
265  double tshift;
266  for(int i = 0; i < 3; i++) {
267  tshift = floor(m_frac_coord[i] + 1E-6);
268  if(!almost_zero(tshift, TOL)) {
269  was_within = false;
270  m_frac_coord[i] -= tshift;
271  }
272  }
273  if(!was_within)
274  _update_cart();
275  return was_within;
276  }
277 
278  //********************************************************************
279 
280  bool Coordinate::within(Coordinate &translation) {
281  translation.m_home = m_home;
282  if(PERIODICITY_MODE::IS_LOCAL()) return true;
283 
284  bool was_within = true;
285 
286  for(int i = 0; i < 3; i++) {
287  translation.m_frac_coord[i] = -floor(m_frac_coord[i] + 1E-6);
288  if(!almost_zero(translation.m_frac_coord[i], TOL)) {
289  was_within = false;
290  }
291  }
292  translation._update_cart();
293 
294  if(!was_within)
295  (*this) += translation;
296  return was_within;
297  }
298 
299  //********************************************************************
300 
301  bool Coordinate::is_within() const {
302 
303  double tshift;
304  for(int i = 0; i < 3; i++) {
305  tshift = floor(m_frac_coord[i] + 1E-6);
306  if(std::abs(tshift) > TOL) {
307  return false;
308  }
309  }
310  return true;
311  }
312 
313  //********************************************************************
314  // Checks to see if coordinate is within voronoi cell of its home lattice.
315  //********************************************************************
316 
318  return voronoi_number(home());
319  }
320 
321  //********************************************************************
322  // Checks to see if coordinate is within voronoi cell of specified lattice
323  //********************************************************************
324 
325  int Coordinate::voronoi_number(const Lattice &cell) const {
326  return cell.voronoi_number(const_cart());
327  }
328 
329  //********************************************************************
330  // Applies Lattice translations until coordinate is within voronoi cell of its home lattice.
331  //********************************************************************
332 
334  bool was_within(true);
335  Eigen::Vector3d lattice_trans;
336  while(home().max_voronoi_measure(cart(), lattice_trans) > (1. + TOL)) {
337  was_within = false;
338  cart() -= lattice_trans;
339  }
340 
341  return was_within;
342  }
343 
344  //********************************************************************
345  // Applies Lattice translations until coordinate is within voronoi cell of its home lattice.
346  //********************************************************************
347 
349  translation.m_home = m_home;
350  translation.cart() = vector_type::Zero();
351 
352  Eigen::Vector3d lattice_trans;
353  bool was_within(true);
354  while(home().max_voronoi_measure(cart(), lattice_trans) > (1. + TOL)) {
355  was_within = false;
356  cart() -= lattice_trans;
357  translation.cart() -= lattice_trans;
358  }
359 
360  return was_within;
361  }
362 
363  //********************************************************************
364  // Checks to see if coordinate describes shift by a general lattice vector l*V1+m*V2+n*V3, where l, m, n are integer
365  //********************************************************************
366 
367  bool Coordinate::is_lattice_shift(double tol) const {
368 
369  //If mode is local, return true only if coordinate describes origin
371  return std::abs(m_frac_coord[0]) < tol && std::abs(m_frac_coord[1]) < tol && std::abs(m_frac_coord[2]) < tol;
372 
373  return (std::abs(m_frac_coord[0] - round(m_frac_coord[0])) < tol
374  && std::abs(m_frac_coord[1] - round(m_frac_coord[1])) < tol
375  && std::abs(m_frac_coord[2] - round(m_frac_coord[2])) < tol);
376  }
377 
378 
379  //********************************************************************
380  // Read/write coordinate to json
381  //********************************************************************
382 
384  json.put_obj();
385 
386  // mutable Vector3< double > coord[2];
387  to_json_array(m_frac_coord, json["FRAC"]);
388  to_json_array(m_frac_coord, json["CART"]);
389 
390  // mutable int basis_ind;
391  json["basis_ind"] = basis_ind();
392 
393  return json;
394  }
395 
396  //********************************************************************
397 
398  void Coordinate::from_json(const jsonParser &json) {
399  // mutable Vector3< double > coord[2];
400  m_frac_coord[0] = json["FRAC"][0].get<double>();
401  m_frac_coord[1] = json["FRAC"][1].get<double>();
402  m_frac_coord[2] = json["FRAC"][2].get<double>();
403 
404  m_cart_coord[0] = json["CART"][0].get<double>();
405  m_cart_coord[1] = json["CART"][1].get<double>();
406  m_cart_coord[2] = json["CART"][2].get<double>();
407 
408 
409  // mutable int basis_ind;
410  CASM::from_json(m_basis_ind, json["basis_ind"]);
411  }
412 
413  //********************************************************************
414 
415  jsonParser &to_json(const Coordinate &coord, jsonParser &json) {
416  return coord.to_json(json);
417  }
418 
419  //********************************************************************
420 
421  void from_json(Coordinate &coord, const jsonParser &json) {
422  coord.from_json(json);
423  }
424 
425  //********************************************************************
426  // Applies symmetry to a coordinate.
427  //
428  // Overloads the * operator to apply symmetry to a coordinate
429  // using its Cartesian representation
430  //********************************************************************
431 
432  Coordinate operator*(const SymOp &LHS, const Coordinate &RHS) {
433  Coordinate tcoord(RHS);
434  return tcoord.apply_sym(LHS);
435  }
436 
437  //********************************************************************
438  // Allows direct printing of Coordinate with the << operator.
439  //********************************************************************
440 
441  std::ostream &operator << (std::ostream &stream, const Coordinate &coord) {
442  coord.print(stream);
443  return stream;
444  }
445 
446 }
447 
Coordinate & operator-=(const Coordinate &RHS)
Negative translation of this coordinate by RHS.cart()
Definition: Coordinate.cc:45
Eigen::MatrixXd pad(const Eigen::MatrixXd &M, int n)
Construct a matrix consisting of blocks M and Identity(n,n)
Definition: PCA.hh:88
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:41
jsonParser & to_json(jsonParser &json) const
Definition: Coordinate.cc:383
bool voronoi_within()
Map coordinate into the voronoi cell using a lattice translation.
Definition: Coordinate.cc:333
void from_json(ClexDescription &desc, const jsonParser &json)
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Definition: Coordinate.hh:593
bool is_lattice_shift(double tol=TOL) const
Checks to see if coordinate is at a lattice translation with respect to the origin.
Definition: Coordinate.cc:367
Coordinate operator-() const
unary minus of this coordinate
Definition: Coordinate.cc:53
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
double dist(const Coordinate &neighbor) const
distance (in Angstr) of neighbor from *this
Definition: Coordinate.cc:146
Main CASM namespace.
Definition: complete.cpp:8
Coordinate & apply_sym(const SymOp &op)
Transform coordinate by symmetry operation (including translation)
Definition: Coordinate.cc:216
const double TOL
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:104
void from_json(const jsonParser &json)
Definition: Coordinate.cc:398
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
Definition: Coordinate.hh:92
T get(Args...args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:729
const vector_type & const_frac() const
user override to force const Access the fractional coordinate vector
Definition: Coordinate.hh:66
vector_type m_frac_coord
Definition: Coordinate.hh:290
double tol
int voronoi_number() const
Definition: Coordinate.cc:317
const matrix_type & matrix() const
Const access of entire cartesian symmetry matrix.
Definition: SymOp.hh:57
bool operator==(const Coordinate &RHS) const
Definition: Coordinate.cc:59
double min_dist(const Coordinate &neighbor) const
Returns distance (in Angstr) to nearest periodic image of neighbor.
Definition: Coordinate.cc:155
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
void _set_frac(const Eigen::Ref< const vector_type > &f)
Definition: Coordinate.hh:260
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
Definition: BasisSet.cc:1154
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
Coordinate & apply_sym_no_trans(const SymOp &op)
Transform coordinate by symmetry operation (without translation)
Definition: Coordinate.cc:226
T norm(const Tensor< T > &ttens)
Definition: Tensor.hh:968
void print(std::ostream &stream, COORD_TYPE mode, char term=0, int prec=7, int pad=5) const
Definition: Coordinate.cc:112
Eigen::Vector3d vector_type
Definition: Coordinate.hh:36
Coordinate & operator+=(const Coordinate &RHS)
Positive translation of this coordinate by RHS.cart()
Definition: Coordinate.cc:38
double robust_min_dist(const Coordinate &neighbor) const
Returns distance (in Angstr) to nearest periodic image of neighbor.
Definition: Coordinate.cc:179
Eigen::CwiseUnaryOp< decltype(std::ptr_fun(boost::math::lround< typename Derived::Scalar >)), const Derived > lround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXl.
bool is_within() const
Checks to see if coordinate is in the unit cell, but does not translate it.
Definition: Coordinate.cc:301
void read(std::istream &stream, COORD_TYPE mode)
Definition: Coordinate.cc:92
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:245
T dot(const Tensor< T > &LHS, const Tensor< T > &RHS)
Definition: Tensor.hh:961
void _set_cart(const Eigen::Ref< const vector_type > &c)
Definition: Coordinate.hh:272
CASM::jsonParser & to_json_array(const Eigen::MatrixBase< Derived > &value, CASM::jsonParser &json)
Write Eigen Matrix with 1 row or 1 column to JSON array.
Definition: container.hh:191
bool compare_type(const Coordinate &RHS) const
Return true – Exists to allow duck-typing with Site.
Definition: Coordinate.cc:86
bool compare(const Coordinate &RHS, double tol=TOL) const
Returns true if this->min_dist(RHS)
Definition: Coordinate.cc:73
jsonParser & put_obj()
Puts new empty JSON object.
Definition: jsonParser.hh:276
Index basis_ind() const
Access basis Index.
Definition: Coordinate.hh:190
bool almost_equal(const Coordinate &RHS, double tol) const
Definition: Coordinate.cc:66
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:581
const vector_type & tau() const
Const access of the cartesian translation vector, 'tau'.
Definition: SymOp.hh:63
void print_axis(std::ostream &stream, COORD_TYPE mode, char term=0, int prec=7, int pad=5) const
Print normalized vector.
Definition: Coordinate.cc:129
const Lattice & home() const
Access the home lattice of the coordinate.
Definition: Coordinate.hh:195
Lattice const * m_home
Definition: Coordinate.hh:288
vector_type m_cart_coord
Definition: Coordinate.hh:290
double min_dist2(const Coordinate &neighbor, const Eigen::Ref< const Eigen::Matrix3d > &metric) const
Finds same shift as min_dist but returns shift(CART).transpose()*metric*shift(CART) ...
Definition: Coordinate.cc:205
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
int voronoi_number(const Eigen::Vector3d &pos) const
Definition: Lattice.cc:541
Coordinate(const Lattice &_home)
Minimal constructor only takes a lattice.
Definition: Coordinate.hh:46
int round(double val)
Definition: CASM_math.cc:6
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())