8 template <
typename CoordType>
10 m_lat_ptr(&init_home),
13 m_clust_group(
LOCAL) {
20 template <
typename CoordType>
22 if(m_lat_ptr == &new_home)
24 m_lat_ptr = &new_home;
25 for(
Index i = 0; i < size(); i++)
26 at(i).set_lattice(new_home, mode);
32 template <
typename CoordType>
35 for(
Index i = 0; i < (*this).size(); i++) {
36 basis_ind = ref_struc.
find(at(i));
38 std::cerr <<
"ERROR in GenericCluster<CoordType>::set_occupant_basis. Could not "
39 <<
"find a basis site in ref_struc that corresponds to site " << i
40 <<
"QUITTING" << std::endl;
41 std::cerr <<
"DEBUGGING info: " << std::endl;
47 (*this).at(i).update_data_members(ref_struc.
basis[basis_ind]);
54 template <
typename CoordType>
56 if(iperm.
size() != size()) {
57 std::cerr <<
"WARNING: Attempted to permute points of cluster of size " << size() <<
" using a permutation of " << iperm.
size() <<
" indicies.\n";
67 template <
typename CoordType>
73 template <
typename CoordType>
75 for(
Index i = 0; i < size(); i++)
84 template <
typename CoordType>
86 for(
Index i = 0; i < size(); i++)
99 template <
typename _CoordType>
102 _clust_group().clear();
104 perm_array_ptr->clear();
106 for(
Index ng = 0; ng < super_group.
size(); ng++) {
111 find(tclust, iperm, tol);
123 template <
typename _CoordType>
125 std::vector<Permutation> tperms;
126 tperms.reserve(clust_group().size());
128 for(
Index i = 0; i < clust_group().size(); i++) {
129 for(
Index j = 0; j < size(); j++)
130 iperm[j] =
find(clust_group()[i] * at(j),
tol);
138 template <
typename CoordType>
143 if(pivot_ind >= size()) {
144 std::cerr <<
"WARNING: Attempted to map cluster within unit cell with invalid pivot." << std::endl;
149 at(pivot_ind).within(tcoord);
150 for(
Index i = 0; i < size(); i++) {
160 template <
typename CoordType>
165 if(pivot_ind >= size()) {
166 std::cerr <<
"WARNING: Attempted to map cluster within unit cell with invalid pivot." << std::endl;
171 at(pivot_ind).within(trans);
172 for(
Index i = 0; i < size(); i++) {
182 template <
typename CoordType>
189 for(
Index i = 0; i < size(); i++)
200 template <
typename CoordType>
205 for(i = 0; i < size(); i++) {
206 for(j = i + 1; j < size(); j++) {
207 tcoord = at(j) - at(i);
209 if(tnV > max_nV || tnV < 0)
219 template <
typename CoordType>
225 for(
Index i = 1; i < size(); i++) {
228 tcoord.
cart() /= size();
234 template <
typename CoordType>
237 for(i = 0; i < test_cluster.
size(); i++) {
238 for(j = 0; j < size(); j++) {
239 if(test_cluster[i] == at(j))
250 template <
typename CoordType>
252 for(
Index i = 0; i < size(); i++) {
253 if(at(i).compare(test_site, tol))
261 template <
typename CoordType>
265 for(j = 0; j < size(); j++) {
266 if(test_elem.almost_equal(at(j), tol))
275 template <
typename CoordType>
280 for(i = 0; i < test_cluster.
size(); i++) {
281 for(j = 0; j < size(); j++) {
298 template <
typename CoordType>
302 if(!(home() == pivot.
home())) {
303 std::cerr <<
"WARNING in Cluster::map_onto_subcluser!!\n"
304 <<
"You are trying to map a pivot onto a cluster with\n"
305 <<
"a different lattice! \n";
314 for(i = 0; i < tsize; i++) {
328 if(
find(pivot, tarray, tol)) {
329 Index t_ind, n_switch(0);
330 for(j = 0; j < tperm.
size(); j++) {
331 t_ind = tarray.
find(j);
332 if(t_ind < tarray.
size()) {
337 tperm[tarray.
size() + n_switch] = j;
354 template <
typename CoordType>
358 if(!(home() == pivot.
home())) {
359 std::cerr <<
"WARNING in Cluster::map_onto_subcluser!!\n"
360 <<
"You are trying to map a pivot onto a cluster with\n"
361 <<
"a different lattice! \n";
370 for(i = 0; i < tsize; i++) {
383 if(!
find(pivot, tarray, tol))
continue;
384 if(tmaps != num_maps) {
388 Index t_ind, n_switch(0);
389 for(j = 0; j < tperm.
size(); j++) {
390 t_ind = tarray.
find(j);
391 if(t_ind < tarray.
size()) {
396 tperm[tarray.
size() + n_switch] = j;
410 template <
typename CoordType>
412 for(
Index ns = 0; ns < size(); ns++) {
413 at(ns).set_basis_ind(-1);
414 for(
Index nb = 0; nb < basis.
size(); nb++) {
415 if(at(ns).compare(basis[nb], shift)) {
416 at(ns).set_basis_ind(nb);
421 std::cerr <<
"WARNING in GenericCluster::collect_basis_info" << std::endl;
422 std::cerr <<
"Could not get basis info for " << at(ns) << std::endl;
430 template <
typename CoordType>
432 for(
Index ns = 0; ns < size(); ns++) {
433 at(ns).set_basis_ind(-1);
434 for(
Index nb = 0; nb < basis.
size(); nb++) {
435 if(at(ns).compare(basis[nb])) {
436 at(ns).set_basis_ind(nb);
441 std::cerr <<
"WARNING in GenericCluster::collect_basis_info" << std::endl;
442 std::cerr <<
"Could not get basis info for " << at(ns) << std::endl;
456 template <
typename CoordType>
460 CoordType t_coord(*m_lat_ptr);
468 std::cout <<
"INSIDE CLUSTER READ \n";
469 std::cout <<
"char(35) is " << char(35) <<
"\n";
472 while((ch !=
char(35))) {
474 std::cout <<
"looking for # ch is " << ch <<
"\n";
476 stream.ignore(1000,
'\n');
480 stream.getline(tchar, 1000,
':');
484 std::cout <<
"np is " << np <<
"\n";
488 while((ch !=
'M') && (ch !=
'm')) {
489 stream.ignore(1000,
'\n');
494 std::cout <<
"GOING TO TRY TO READ MAX MIN LENGTHS\n";
497 stream.getline(tchar, 1000,
':');
498 stream >> m_max_length;
499 stream.getline(tchar, 1000,
':');
500 stream >> m_min_length;
503 std::cout <<
"m_max_length is " << m_max_length <<
"\n";
504 std::cout <<
"m_min_length is " << m_min_length <<
"\n";
510 for(
Index i = 0; i < np; i ++) {
511 t_coord.read(stream);
522 template <
typename CoordType>
528 m_lat_ptr = &back().home();
530 else if(&(back().home()) != m_lat_ptr)
531 back().set_lattice(*m_lat_ptr,
CART);
539 template <
typename CoordType>
551 template <
typename CoordType>
553 for(
Index i = 0; i < size(); i++)
560 template <
typename CoordType>
562 for(
Index i = 0; i < size(); i++)
569 template <
typename CoordType>
571 if(size() != RHS.
size())
return false;
575 for(i = 0; i < size(); i++) {
576 for(j = 0; j < RHS.
size(); j++) {
577 if((at(i) == RHS[j]) && (!check_ind[j])) {
590 template <
typename CoordType>
592 if(size() != test_clust.
size())
return false;
596 for(
Index i = 0; i < tclust.
size(); i++) {
598 if(tclust == test_clust) {
607 template <
typename CoordType>
609 if(size() != test_clust.
size())
return false;
613 for(
Index i = 0; i < tclust.
size(); i++) {
615 if(tclust == test_clust) {
628 template <
typename CoordType>
630 if(size() != test_clust.
size())
return false;
631 if(size() == 0)
return true;
637 Coordinate tshift(*m_lat_ptr), trans(*m_lat_ptr);
638 for(
Index i = 0; i < size(); i++) {
639 tshift = test_clust[0] - at(i);
640 if(tshift.is_lattice_shift(tol)) {
653 template <
typename CoordType>
655 if(size() != test_clust.
size())
return false;
656 trans.
frac() = Eigen::Vector3d::Zero();
657 if(size() == 0)
return true;
660 return (*
this) == test_clust;
664 for(
Index i = 0; i < size(); i++) {
665 tshift = test_clust[0] - at(i);
674 trans.
frac() = Eigen::Vector3d::Zero();
680 template <
typename CoordType>
686 m_max_length = m_min_length = 0;
688 else if(size() > 1) {
690 m_max_length = m_min_length = at(0).dist(at(1));
692 for(
Index i = 0; i < size(); i++) {
693 for(
Index j = i + 1; j < size(); j++) {
694 tlength = at(i).dist(at(j));
695 if(tlength < m_min_length)
696 m_min_length = tlength;
697 if(tlength > m_max_length)
698 m_max_length = tlength;
716 template <
typename CoordType>
725 for(
Index i = 0; i < size(); i++) {
726 for(
Index k = 0; k < phenom_clust.
size(); k++) {
727 dist = phenom_clust[k].dist(at(i));
728 if(dist > m_max_length)
730 if(dist < m_min_length)
737 for(
Index i = 0; i < size(); i++) {
738 for(
Index k = i + 1; k < size(); k++) {
739 dist = at(k).dist(at(i));
740 if(dist > m_max_length)
742 if(dist < m_min_length)
755 template <
typename CoordType>
761 stream <<
"#Points: " << size() << std::endl
762 <<
"MaxLength: " << m_max_length <<
" MinLength: " << m_min_length << std::endl;
763 for(
Index np = 0; np < size(); np++) {
764 stream.setf(std::ios::showpoint, std::ios_base::fixed);
767 at(np).print(stream);
775 template <
typename CoordType>
781 stream <<
"#Points: " << size() << std::endl
782 <<
"MaxLength: " << m_max_length <<
" MinLength: " << m_min_length << std::endl;
783 for(
Index np = 0; np < size(); np++) {
784 stream.setf(std::ios::showpoint, std::ios_base::fixed);
787 (at(np) + shift).print(stream);
796 template <
typename CoordType>
801 for(
Index np = 0; np < size(); np++) {
802 for(
int i = 0; i < space; i++) {
805 stream.setf(std::ios::showpoint, std::ios_base::fixed);
808 at(np).print(stream);
816 template <
typename CoordType>
821 for(
Index np = 0; np < size(); np++) {
822 for(
int i = 0; i < space; i++) {
825 stream.setf(std::ios::showpoint, std::ios_base::fixed);
828 at(np).print(stream);
829 stream <<
" " << at(np).basis_ind() <<
" ";
837 template <
typename CoordType>
842 for(
Index np = 0; np < size(); np++) {
843 for(
int i = 0; i < space; i++) {
846 stream.setf(std::ios::showpoint, std::ios_base::fixed);
849 at(np).print_occ(stream);
860 template <
typename CoordType>
861 std::ostream &operator<< (std::ostream &stream, const GenericCluster<CoordType> &cluster) {
862 cluster.print(stream,
'\n');
868 template <
typename CoordType>
874 template <
typename CoordType>
881 template <
typename CoordType>
887 template <
typename CoordType>
889 if(LHS.
size() != RHS.
size())
return false;
893 for(i = 0; i < LHS.
size(); i++) {
894 for(j = 0; j < RHS.
size(); j++) {
895 if((LHS[i].
almost_equal(RHS[j], tol)) && (!check_ind[j])) {
void print_basis_info(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
static SymOp translation(const Eigen::Ref< const vector_type > &_tau)
static method to create operation that describes pure translation
bool contains(const T &test_elem) const
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
bool is_lattice_shift(double tol=TOL) const
Checks to see if coordinate is at a lattice translation with respect to the origin.
void push_back(const T &toPush)
void push_back(const CoordType &new_coord)
const Array< Index > & perm_array() const
BasicStructure specifies the lattice and atomic basis of a crystal.
*bool image_check(const Lattice &cell, int nV=0) const
Checks to see if cluster is "compact" relative to (Lattice cell) in other words, period images of the...
bool contains_periodic(const CoordType &test_coord, double tol) const
Like Array::contains(), but takes periodicity mode into account.
void collect_basis_info(const Array< CoordType > &basis)
Figure out which basis atoms in basis correspond to the points in cluster (*this) ...
void print_sites(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
GenericCluster< CoordType > operator+(const GenericCluster< CoordType > &LHS, const Coordinate &RHS)
create translated cluster
GenericCluster & operator-=(const Coordinate &RHS)
GenericCluster< CoordType > operator-(const GenericCluster< CoordType > &LHS, const Coordinate &RHS)
create translated cluster
Index find(const CoordType2 &test_site, double tol=TOL) const
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
GenericCluster(const Lattice &init_home)
void set_lattice(const Lattice &new_home, COORD_TYPE mode)
GenericCluster & permute(const Array< Index > &perm)
permute sites of the cluster, and everything that depends on the site order
int voronoi_number() const
void print_shifted(std::ostream &stream, const Coordinate &shift, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
COORD_MODE specifies the current coordinate mode (Fractional or Cartesian)
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
void calc_properties()
gets max_length and min_length
Represents cartesian and fractional coordinates.
GenericCluster & apply_sym_no_trans(const SymOp &op)
apply symmetry to all points of the cluster without translation
EigenIndex Index
For long integer indexing:
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
std::vector< Permutation > clust_group_permutations(double tol) const
Finds the Permutation corresponding to each element of clust_group.
Coordinate geometric_center() const
Returns the geometric center of "mass" of a cluster (treats all sites as having equal mass) ...
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
GenericCluster & operator+=(const Coordinate &RHS)
in=place translation of a cluster
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...
void update_data_members(const BasicStructure< CoordType > &ref_struc)
Index find(const T &test_elem) const
void all_within()
Map every point of cluster inside unit cell.
bool is_equivalent(const GenericCluster &test_clust) const
are two clusters identical, to within permutation and translation
const Lattice & home() const
void reserve(Index new_max)
GenericCluster & apply_sym(const SymOp &op)
apply symmetry to all points of the cluster
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
void generate_clust_group(const SymGroup &super_group, std::vector< Permutation > *perm_array_ptr=nullptr, double tol=TOL)
Finds the sub_group of super_group that is the point group of the cluster.
void read(std::istream &stream, int num_sites, COORD_TYPE mode, bool SD_is_on)
bool map_onto_subcluster(const GenericCluster &pivot, double tol=TOL)
void print_decorated_sites(std::ostream &stream, int space, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
void merge(const GenericCluster &RHS)
adds unique points of 'RHS' to (*this)
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
void within(Index pivot_ind=0)
Translate entire cluster so that point at(pivot_ind) is inside unit cell.
Index find(const CoordType &test_elem, double tol) const
is test_cluster a subcluster of (*this), and how do the indices map points of test_cluster ...
bool operator==(const GenericCluster &RHS) const
are two clusters identical, to within a permutation
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
bool map_onto(const GenericCluster &test_clust, double tol)
if is_equivalent(test_clust) is true, return true and map (*this) onto test_clust ...
void print(std::ostream &stream, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
Array & permute(const Array< Index > &perm_array)
bool contains(const GenericCluster &test_cluster) const
is test_cluster a subcluster of (*this)
bool valid_index(Index i)
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())