CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
NeighborList.cc
Go to the documentation of this file.
2 #include "casm/misc/CASM_math.hh"
5 
6 namespace CASM {
7 
10  return m_W;
11  }
12 
15 
16  // save the old range
17  Scalar prev_range = m_range;
18 
19  auto result = m_neighborhood.insert(uccoord.unitcell());
20 
21  // if a new UnitCell
22  if(result.second) {
23  // ensure all intermediate UnitCell are included
24  _expand(prev_range);
25  }
26  }
27 
29  void PrimNeighborList::_expand(Scalar prev_range) {
30 
31  // if some are new, we need to make sure we including all intermediate UnitCell in our neighborhood
32  // get the score of the last element in the set
33  m_range = _dist(*m_neighborhood.rbegin());
34 
35  // count over possible UnitCell, adding to neighborhood if prev_range < dist <= m_range
36  // we're using a std::set for m_neighborhood, so it gets sorted
37 
38  // We want the bounding box that contains the ellipsoid defined by
39  // m_range = (i,j,k).transpose() * W * (i,j,k)
40  // = F.t * U.t * U * F
41  // = F.t * (M.inv).t * (M.inv) * F
42  // 1 = F.t * (sqrt(m_range)*M.inv).t * (sqrt(m_range)*M.inv) * F
43  // has maximum bb_end
44  // bb_end(i) = M.row(i).norm() (from considerations of an affine transformation M of unit sphere)
45  // where M = sqrt(m_range)*U.inv
46  // and minimum
47  // bb_begin = -bb_end
48 
49  Eigen::MatrixXd M = sqrt(1.0 * m_range) * m_Uinv;
50 
51  auto d = [&](int i) {
52  return std::lround(std::ceil(M.row(i).norm()));
53  };
54 
55  VectorXType bb_end(3);
56  bb_end << d(0), d(1), d(2);
57  VectorXType bb_begin = -bb_end;
58  VectorXType bb_incr = VectorXType::Constant(3, 1);
59 
60  typedef Counter< VectorXType,
61  Scalar,
62  Index,
64 
65  VectorXCounter counter(bb_begin, bb_end, bb_incr);
66 
67  Scalar dist;
68  for(; counter.valid(); ++counter) {
69  dist = _dist(counter.current());
70  if(prev_range < dist && dist <= m_range) {
71  m_neighborhood.insert(counter.current());
72  }
73  }
74  }
75 
78  return m_neighborhood.size();
79  }
80 
83  return m_neighborhood.cbegin();
84  }
85 
88  return m_neighborhood.cend();
89  }
90 
93  return m_neighborhood.cbegin();
94  }
95 
98  return m_neighborhood.cend();
99  }
100 
103  return m_sublat_indices;
104  }
105 
108  return A.transpose() * m_W * A;
109  }
110 
113  VectorXType vec(4);
114  vec(0) = _dist(A);
115  vec.segment(1, 3) = A;
116  return vec;
117  }
118 
120  bool PrimNeighborList::_compare_unitcell(const UnitCell &A, const UnitCell &B) const {
121  return _compare_vec(_add_dist(A), _add_dist(B));
122  }
123 
126  return std::lexicographical_compare(A.data(), A.data() + A.size(), B.data(), B.data() + B.size());
127  }
128 
143 
144  Eigen::Matrix3d W = lat_column_mat.transpose() * lat_column_mat;
145 
147  for(int i = 0; i < 3; ++i) {
148  for(int j = 0; j < 3; ++j) {
149  if(!almost_zero(W(i, j), tol) && std::abs(W(i, j)) < std::abs(min)) {
150  min = W(i, j);
151  }
152  }
153  }
154  W /= min;
155 
156  // make positive definite
157  Eigen::LLT<Eigen::MatrixXd> llt(W);
158  if(llt.info() != Eigen::Success) {
159  W = -W;
160  }
161 
162  double n = 1.0;
163  while(!is_integer(n * W, tol) &&
164  ((n + 1.0)*W).cwiseAbs().maxCoeff() < max_element_value) {
165  n += 1.0;
166  }
167  return lround(n * W);
168  }
169 
171  std::unique_ptr<PrimNeighborList> PrimNeighborList::clone() const {
172  return std::unique_ptr<PrimNeighborList>(new PrimNeighborList(*this));
173  }
174 
175 
190  const PrimNeighborList &prim_nlist) :
191  m_prim_grid_size(prim_grid.size()),
192  m_site(prim_grid.size()),
193  m_unitcell(prim_grid.size()) {
194 
195  // use the PrimNeighborList to generate the UnitCell and Site indices for
196  // the neighbors of each UnitCell in the supercell
197 
198  UnitCellCoord bijk;
199 
200  // for each unit cell in the supercell
201  for(Index i = 0; i < m_prim_grid_size; ++i) {
202 
203  // for each neighbor unitcell
204  for(auto it = prim_nlist.begin(); it != prim_nlist.end(); ++it) {
205 
206  // get the neighbor unitcell's index
207  size_type unitcell_index = prim_grid.find(prim_grid.unitcell(i) + *it);
208 
209  // store the unitcell index
210  m_unitcell[i].push_back(unitcell_index);
211 
212  // calculate and store the site indices for all sites in the neighbor unitcell that are requested
213  // - Depends on Configuration sites being stored in blocks by sublattice and unitcell indices
214  // determined by the PrimGrid ordering
215  for(auto b_it = prim_nlist.sublat_indices().begin(); b_it != prim_nlist.sublat_indices().end(); ++b_it) {
216  m_site[i].push_back((*b_it)*m_prim_grid_size + unitcell_index);
217  }
218 
219  }
220  }
221  }
222 
224  const std::vector<SuperNeighborList::size_type> &SuperNeighborList::sites(size_type unitcell_index) const {
225  return m_site[unitcell_index];
226  }
227 
229  const std::vector<SuperNeighborList::size_type> &SuperNeighborList::unitcells(size_type unitcell_index) const {
230  return m_unitcell[unitcell_index];
231  }
232 
237 
238  // there is an overlap if any of the neighboring unitcell indices is repeated
239  // so sort and check if any two neighboring indices are the same
240 
241  std::vector<size_type> nlist = m_unitcell[0];
242  std::sort(nlist.begin(), nlist.end());
243  return std::adjacent_find(nlist.begin(), nlist.end()) != nlist.end();
244  }
245 
247  std::unique_ptr<SuperNeighborList> SuperNeighborList::clone() const {
248  return std::unique_ptr<SuperNeighborList>(new SuperNeighborList(*this));
249  }
250 
251 }
Eigen::MatrixXd MatrixXd
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:41
const SublatIndices & sublat_indices() const
pair of const_iterators over a range of indices of sublattices to include
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef Index Scalar
Definition: NeighborList.hh:30
size_type m_prim_grid_size
store prim grid size for site index -> unitcell index conversion unitcell_index = site_index % m_prim...
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:71
Scalar _dist(const UnitCell &A) const
Calculate A.transpose()*M*A.
std::unique_ptr< PrimNeighborList > clone() const
Clone.
std::unique_ptr< SuperNeighborList > clone() const
Clone.
Unit Cell Coordinates.
const_iterator cend() const
const_iterator over the neighborhood of unit cells
Definition: NeighborList.cc:97
Scalar m_range
the neighborhood, m_neighborhood, contains all UnitCell with r <= m_range
const_iterator cbegin() const
const_iterator over the neighborhood of unit cells
Definition: NeighborList.cc:92
Main CASM namespace.
Definition: complete.cpp:8
std::vector< std::vector< size_type > > m_unitcell
m_unitcell[unitcell_index][neighbor unitcell index]
NeighborSet::size_type size_type
Definition: NeighborList.hh:34
NeighborSet::const_iterator const_iterator
Definition: NeighborList.hh:35
void expand(UnitCellCoord uccoord)
Expand the neighbor list to include the given UnitCellCoord.
Definition: NeighborList.cc:14
Unit Cell Indices.
bool _compare_unitcell(const UnitCell &A, const UnitCell &B) const
Convert [i,j,k] -> [r,i,j,k] and then lexicographically compare.
Index find(const Coordinate &_coord) const
Definition: PrimGrid.cc:144
SuperNeighborList(const PrimGrid &prim_grid, const PrimNeighborList &prim_nlist)
Constructor.
Helper Functor for Counter container access using operator()
Definition: CASM_TMP.hh:180
Matrix3Type m_W
Weighting matrix.
double tol
void _expand(Scalar prev_range)
Ensure that all intermediate UnitCell are included in our neighborhood.
Definition: NeighborList.cc:29
static bool _compare_vec(const VectorXType &A, const VectorXType &B)
Lexicographical comparison.
Eigen::Matrix< long, Eigen::Dynamic, 1 > VectorXType
Definition: NeighborList.hh:32
NeighborSet m_neighborhood
the neighborhood of [i, j, k]
std::vector< std::vector< size_type > > m_site
m_site[unitcell_index][neighbor site index]
const std::vector< size_type > & unitcells(size_type unitcell_index) const
const Access the list of unitcells neighboring a particular unit cell
EigenIndex Index
For long integer indexing:
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.
UnitCell & unitcell()
VectorXType _add_dist(const UnitCell &A) const
Return [r, i, j, k], where r = _dist(A)
T max(const T &A, const T &B)
Definition: CASM_math.hh:32
T min(const T &A, const T &B)
Definition: CASM_math.hh:25
static Matrix3Type make_weight_matrix(const Eigen::Matrix3d lat_column_mat, Index max_element_value, double tol)
Returns a NeighborList weighting matrix appropriate for a particular lattice.
bool is_integer(const Eigen::MatrixBase< Derived > &M, double tol)
Check if Eigen::Matrix is integer.
Eigen::Matrix3d Matrix3d
size_type size() const
size of the neighborhood of unit cells
Definition: NeighborList.cc:77
The PrimNeighborList gives the coordinates of UnitCell that are neighbors of the origin UnitCell...
Definition: NeighborList.hh:24
std::set< int > SublatIndices
Definition: NeighborList.hh:36
SublatIndices m_sublat_indices
the indices of sublattices that should be included
PrimNeighborList(const Matrix3Type &W, SublatIterator begin, SublatIterator end)
Constructor, specifying the weighting matrix to use and the indices of sublattices to include...
size_type unitcell_index(size_type site_index) const
get unit cell index from site index
bool overlaps() const
Returns true if periodic images of the neighbor list overlap.
const_iterator begin() const
const_iterator over the neighborhood of unit cells
Definition: NeighborList.cc:82
const std::vector< size_type > & sites(size_type unitcell_index) const
const Access the list of sites neighboring a particular unit cell
Eigen::MatrixXd m_Uinv
Cholesky decomposition: W = U.transpose()*U, useful for getting bounding box.
UnitCell unitcell(Index i) const
Definition: PrimGrid.cc:229
Matrix3Type weight_matrix() const
Return the weighting matrix W used to define the canonical order.
Definition: NeighborList.cc:9
Eigen::Matrix3l Matrix3Type
Definition: NeighborList.hh:31
const_iterator end() const
const_iterator over the neighborhood of unit cells
Definition: NeighborList.cc:87