9 template<
typename ClustType>
33 for(
Index b = 0; b < starttree.
size(); b++) {
39 template<
typename ClustType>
46 template<
typename ClustType>
53 template<
typename ClustType>
60 template<
typename ClustType>
62 return at(np).at(no).prototype;
67 template<
typename ClustType>
69 return at(np).at(no).prototype;
74 template<
typename ClustType>
76 return at(np).at(no).at(ne);
81 template<
typename ClustType>
83 return at(np).at(no).at(ne);
88 template<
typename ClustType>
95 template<
typename ClustType>
97 return orbit(np, no).size();
103 template<
typename ClustType>
106 for(
Index np = 0; np < size(); np++) {
107 for(
Index no = 0; no < at(np).size(); no++) {
108 result += prototype(np, no).clust_basis.size();
116 template<
typename ClustType>
123 template<
typename ClustType>
126 back().set_lattice(lattice,
CART);
133 template<
typename ClustType>
136 for(
Index np = 0; np < size(); np++) {
137 if(at(np).num_sites() == new_orbit.
prototype.size()) {
138 at(np).push_back(new_orbit);
144 back().push_back(new_orbit);
149 template<
typename ClustType>
151 for(
Index nb = 0; nb < size(); nb++)
152 at(nb).set_lattice(new_lat, mode);
156 for(
Index nb = 0; nb < size(); nb++)
157 at(nb).set_lattice(lattice, mode);
164 template<
typename ClustType>
167 for(
Index np = 0; np < size(); np++) {
175 template<
typename ClustType>
182 template<
typename ClustType>
184 generate_clust_bases(std::vector<BasisSet const *>(), max_poly_order);
189 template<
typename ClustType>
191 _populate_site_bases();
194 for(
Index b = 0; b < m_b2asym.size(); b++)
195 sitebases[b] = _asym_unit().equiv(m_b2asym[b][0], m_b2asym[b][1]).clust_basis;
197 for(
Index i = 0; i < size(); i++) {
198 for(
Index j = 0; j < size(i); j++) {
200 for(
Index ns = 0; ns < prototype(i, j).size(); ns++) {
201 local_args.back().push_back(&sitebases[prototype(i, j)[ns].basis_ind()]);
205 prototype(i, j).generate_clust_basis(local_args, global_args);
206 for(
Index k = 0; k < size(i, j); k++) {
207 equiv(i, j, k).clust_basis = prototype(i, j).clust_basis;
208 equiv(i, j, k).clust_basis.apply_sym(orbit(i, j).equivalence_map[k][0]);
214 equiv(i, j, k).clust_basis.set_dof_IDs(equiv(i, j, k).nlist_inds());
222 template<
typename ClustType>
224 _generate_asym_unit(struc);
226 for(
Index np = 0; np < size(); np++)
227 for(
Index no = 0; no < size(np); no++)
228 orbit(np, no).collect_basis_info(struc.
basis);
232 template<
typename ClustType>
238 for(i = 0; i < size(); i++) {
241 if(at(i).num_sites() == test_clust.size()) {
244 for(j = 0; j < at(i).size(); j++) {
245 if(orbit(i, j).contains(test_clust,
tol()))
259 template<
typename ClustType>
264 for(i = 0; i < at(nb).size(); i++) {
265 if(orbit(nb, i).contains(test_clust,
tol()))
274 template<
typename ClustType>
281 for(i = 0; i < size(); i++) {
284 if(at(i).num_sites() == test_orbit.
prototype.size()) {
287 for(j = 0; j < at(i).size(); j++) {
288 if(at(i).orbit(j) == test_orbit)
299 template<
typename ClustType>
301 for(
Index i = 0; i < size(); i++) {
302 if(
find(test_clust, i) < at(i).size())
311 template<
typename ClustType>
315 index_to_row.clear();
316 index_to_column.clear();
317 index.resize(size());
327 for(
Index np = 0; np < size(); np++) {
328 for(
Index no = 0; no < size(np); no++) {
329 orbit(np, no).set_index(count);
330 index[np].push_back(count);
331 index_to_row.push_back(np);
332 index_to_column.push_back(no);
354 template<
typename ClustType>
358 std::cerr <<
"WARNING: In Orbitree::generate_orbitree, prim's factor_group is empty. It must at least have one element (identity).\n";
364 double dist, min_dist;
366 std::string clean(80,
' ');
374 if(verbose) std::cout <<
"* Finding Basis:\n";
377 if(prim.
basis[i].site_occupant().
size() >= min_num_components) {
379 basis.
back().set_lattice(lattice,
CART);
383 double max_radius = max_length.max();
384 dim = lattice.enclose_sphere(max_radius);
386 if(verbose) std::cout <<
"dim is " << dim <<
'\n';
387 if(verbose) std::cout <<
"\n Finding Grid_struc:\n";
389 lat_point.
frac() = grid_count().cast<
double>();
391 for(i = 0; i < basis.
size(); i++) {
392 typename ClustType::WhichCoordType tatom(basis[i] + lat_point);
396 for(j = 0; j < basis.
size(); j++) {
397 dist = tatom.dist(basis[j]);
401 if(min_dist < max_radius) {
408 if(verbose) std::cout <<
"Finished finding grid_struc\n";
411 std::cerr <<
"WARNING: Orbitree is about to be overwritten! Execution will continue normally, but side effects may occur.\n";
414 resize(max_num_sites + 1);
427 if(verbose) std::cout <<
"About to begin construction of non-empty clusters\n";
428 else std::cout << clean <<
'\r' <<
"About to begin construction of non-empty clusters\r" << std::flush;
429 for(np = 1; np <= max_num_sites; np++) {
430 if(verbose) std::cout <<
"Doing np = " << np <<
'\n';
431 else std::cout << clean <<
'\r' <<
"Doing np = " << np <<
'\r' << std::flush;
433 if(size(np - 1) == 0) {
434 std::cerr <<
"CRITICAL ERROR: Orbitree::generate_orbitree is unable to enumerate clusters of size " << np <<
'\n';
440 for(no = 0; no < size(np - 1); no++) {
441 if(verbose) std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
442 else std::cout << clean <<
'\r' <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
" in branch " << np - 1 <<
'\r' << std::flush;
444 ClustType tclust(lattice);
445 for(i = 0; i < orbit(np - 1, no).prototype.size(); i++)
446 tclust.push_back(orbit(np - 1, no).prototype[i]);
448 for(i = 0; i < gridstruc.
size(); i++) {
450 if(tclust.contains(gridstruc[i]))
454 tclust.push_back(gridstruc[i]);
457 tclust.calc_properties();
463 else if(tclust.max_length() < max_length[np] && tclust.min_length() > min_length && !
contains(tclust)) {
473 if(!verbose) std::cout << clean <<
'\r' << std::flush;
496 template<
typename ClustType>
501 double maxClustLength;
509 std::cout <<
"** Finding Basis:\n";
513 if(prim.
basis[i].site_occupant().
size() >= min_num_components) {
515 basis.
back().set_lattice(lattice,
CART);
520 int cellSize = ceil(pow(((maxClust - (basis.
size() * (basis.
size() - 1)) / 2.0) / (basis.
size() * (2 * basis.
size() - 1.0)) + 1.0), 1.0 / 3.0));
523 double max_radius = (cellSize) * min_lat_length;
525 dim = lattice.enclose_sphere(max_radius);
526 gridstruc = lattice.gridstruc_build(max_radius,
double(0), basis, lat_point);
527 double min_radius = max_radius;
528 std::cout << dim <<
" " << cellSize <<
"\n";
534 std::cerr <<
"WARNING: Orbitree is about to be overwritten! Execution will continue normally, but side effects may occur.\n";
537 resize(max_num_sites + 1);
550 std::cout <<
"About to begin construction of non-empty clusters\n";
552 for(np = 1; np <= max_num_sites; np++) {
553 std::cout <<
"Doing np = " << np <<
'\n';
555 if(size(np - 1) == 0) {
556 std::cerr <<
"CRITICAL ERROR: Orbitree::generate_orbitree is unable to enumerate clusters of size " << np <<
'\n';
567 for(no = 0; no < size(np - 1); no++) {
568 std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
570 ClustType tclust(lattice);
571 for(j = 0; j < orbit(np - 1, no).prototype.size(); j++)
572 tclust.push_back(orbit(np - 1, no).prototype[j]);
574 for(; i < gridstruc.
size(); i++) {
576 if(tclust.contains(gridstruc[i]))
579 tclust.push_back(gridstruc[i]);
582 tclust.calc_properties();
584 if(tclust.min_length() > min_length && !
contains(tclust)) {
585 std::cout <<
"Found a new cluster.... adding to Orbitree!\n";
586 std::cout <<
"The minimum length is " << min_length <<
"\n";
589 numClust = numClust + 1;
590 if(maxClustLength < tclust.max_length()) {
591 maxClustLength = tclust.max_length();
597 if(numClust < maxClust) {
599 dim += Eigen::Vector3i::Ones();
601 std::cout <<
"Max Radius" << max_radius <<
"\n";
602 max_radius = (cellSize + ctr) * min_lat_length;
603 std::cout <<
"Max Radius" << max_radius <<
"\n";
604 gridstruc.
append(lattice.gridstruc_build(max_radius, min_radius, basis, lat_point));
605 min_radius = max_radius;
606 std::cout <<
"Built a bigger grid!\n" << gridstruc.
size() <<
"\n";
609 std::cout <<
"Couldnt find enough points " << numClust <<
" " << i <<
" " << maxClust <<
"\n";
611 while(numClust < maxClust);
615 double cutOff = orbit(np, maxClust - 1).max_length();
616 std::cout << cutOff <<
" Cutoff!\n";
617 for(i = maxClust; i < size(np); i++) {
618 if(orbit(np, i).max_length() > cutOff) {
619 std::cout << orbit(np, i).max_length() <<
" " << orbit(np, i).min_length() <<
"Deleted this\n";
628 max_length[np] = maxClustLength;
629 for(no = 0; no < size(np - 1); no++) {
630 std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
632 ClustType tclust(lattice);
633 for(i = 0; i < orbit(np - 1, no).prototype.size(); i++)
634 tclust.push_back(orbit(np - 1, no).prototype[i]);
636 for(i = 0; i < gridstruc.
size(); i++) {
638 if(tclust.contains(gridstruc[i]))
641 tclust.push_back(gridstruc[i]);
644 std::cout <<
"tclust is \n"
649 tclust.calc_properties();
652 std::cout <<
"tclust is \n"
660 else if(tclust.max_length() < max_length[np] && tclust.min_length() > min_length && !
contains(tclust)) {
661 std::cout <<
"Found a new cluster.... adding to Orbitree!\n";
662 std::cout <<
"The minimum length is " << min_length <<
"\n";
666 std::cout <<
"The tclust we pushed back is \n"
683 template<
typename ClustType>
688 double maxClustLength;
697 std::cout <<
"*** Finding Basis:\n";
701 if(prim.
basis[i].site_occupant().
size() >= min_num_components) {
703 basis.
back().set_lattice(lattice,
CART);
710 double max_radius = (cellSize) * min_lat_length;
712 dim = lattice.enclose_sphere(max_radius);
713 gridstruc = lattice.gridstruc_build(max_radius,
double(0), basis, lat_point);
714 double min_radius = max_radius;
715 std::cout << dim <<
" " << cellSize <<
"\n";
720 std::cerr <<
"WARNING: Orbitree is about to be overwritten! Execution will continue normally, but side effects may occur.\n";
723 resize(max_num_sites + 1);
734 std::cout <<
"About to begin construction of non-empty clusters\n";
736 for(np = 1; np <= max_num_sites; np++) {
737 std::cout <<
"Doing np = " << np <<
'\n';
739 if(size(np - 1) == 0) {
740 std::cerr <<
"CRITICAL ERROR: Orbitree::generate_orbitree is unable to enumerate clusters of size " << np <<
'\n';
751 for(no = 0; no < size(np - 1); no++) {
752 std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
754 ClustType tclust(lattice);
755 for(j = 0; j < orbit(np - 1, no).prototype.size(); j++)
756 tclust.push_back(orbit(np - 1, no).prototype[j]);
759 for(; i < gridstruc.
size(); i++) {
761 if(tclust.contains(gridstruc[i]))
764 tclust.push_back(gridstruc[i]);
767 tclust.calc_properties();
769 if(tclust.min_length() > min_length && !
contains(tclust)) {
772 if(maxClustLength < tclust.max_length()) {
773 maxClustLength = tclust.max_length();
783 for(
Index j = 1; j < size(np); j++) {
784 if(orbit(np, j).max_length() == orbit(np, (j - 1)).max_length()) {
788 numClust = numClust + 1;
792 if(numClust < maxNeighbour[0]) {
794 dim += Eigen::Vector3i::Ones();
796 max_radius = (cellSize + ctr) * min_lat_length;
797 gridstruc.
append(lattice.gridstruc_build(max_radius, min_radius, basis, lat_point));
798 min_radius = max_radius;
802 while(numClust < maxNeighbour[0]);
806 neighbour_lengths.
push_back(orbit(np, 0).max_length());
807 for(i = 1; i < size(np); i++) {
808 if(orbit(np, i).max_length() == orbit(np, (i - 1)).max_length()) {
812 neighbour_lengths.
push_back(orbit(np, i).max_length());
814 if(cutOff <= maxNeighbour[0]) {
826 std::cout << neighbour_lengths.
size() <<
"\n";
828 max_length[np] = neighbour_lengths[(maxNeighbour[np - 2] - 1)];
829 std::cout <<
"Looking at np=" << np <<
"\n";
831 for(no = 0; no < size(np - 1); no++) {
832 if(np != 1 && (orbit(np - 1, no).max_length() > max_length[np] && !
almost_zero((orbit(np - 1, no).max_length() - max_length[np])))) {
835 std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
837 ClustType tclust(lattice);
838 for(i = 0; i < orbit(np - 1, no).prototype.size(); i++)
839 tclust.push_back(orbit(np - 1, no).prototype[i]);
842 for(i = 0; i < gridstruc.
size(); i++) {
844 if(tclust.contains(gridstruc[i]))
847 tclust.push_back(gridstruc[i]);
850 tclust.calc_properties();
856 else if((tclust.max_length() < max_length[np] ||
almost_zero(tclust.max_length() - max_length[np])) && tclust.min_length() > min_length && !
contains(tclust)) {
878 template<
typename ClustType>
887 resize(max_num_sites + 1);
891 at(0).back().get_equivalent(symgroup,
tol());
898 for(np = 1; np < in_tree.
size(); np++) {
901 for(no = 0; no < in_tree.
size(np); no++) {
905 decor_map = in_tree.
prototype(np, no).get_full_decor_map();
907 decor_map = in_tree.
prototype(np, no).get_decor_map();
912 for(i = 0; i < decor_map.
size(); i++) {
915 ClustType tclust(in_tree.
prototype(np, no));
917 tclust.decorate(decor_map[i]);
921 at(np).back().get_equivalent(symgroup,
tol());
952 template<
typename ClustType>
977 resize(max_num_sites + 1);
979 Index np, no, nd, ii;
981 std::string clean(80,
' ');
986 for(np = 2; np < in_tree.
size(); np++) {
990 for(no = 0; no < in_tree.
size(np); no++) {
991 std::cout << clean <<
'\r' <<
"Generate HopOrbitree branch: " << np <<
" orbit: " << no <<
"\r" << std::flush;
996 for(nd = 0; nd < full_decor_map.
size(); nd++) {
1001 sclust.
decorate(full_decor_map[nd]);
1006 for(ii = 0; ii < sclust.size(); ii++) {
1007 if(sclust[ii].is_vacant())
1036 for(ii = 0; ii < np; ii++) {
1045 bool perm_ok =
true;
1046 for(ii = 0; ii < np; ii++)
1047 if(perm[ii] == ii) {
1056 if(!ClustType::allowed(sclust, perm))
1061 ClustType tclust(sclust, perm);
1102 std::cout << clean <<
'\r' << std::flush;
1126 template<
typename ClustType>
1132 std::vector<std::string> s_list;
1133 std::vector<Index> n_equiv;
1135 ClustType tclust(lattice);
1139 bool SD_is_on =
false;
1144 std::ifstream file(filename);
1149 this->max_num_sites = 0;
1152 while(!file.eof()) {
1154 std::copy(std::istream_iterator<std::string>(file),
1155 std::istream_iterator<std::string>(),
1156 std::back_inserter(s_list));
1157 if(s_list.size() == 0)
1160 if(s_list[0] ==
"COORD_MODE") {
1163 if(s_list[2][0] ==
'D' || s_list[2][0] ==
'd') {
1168 else if(s_list[2][0] ==
'C' || s_list[2][0] ==
'c') {
1173 std::cerr <<
"Error in GenericOrbitree<ClustType>::generate_orbitree_from_proto_file()." << std::endl
1174 <<
" COORD_MODE not understood: " << s_list << std::endl;
1178 else if(s_list.size() != (index =
find_index(s_list,
"Points:"))) {
1180 Index pts = std::stol(s_list[index + 1]);
1181 if(pts > this->max_num_sites)
1182 this->max_num_sites = pts;
1189 std::copy(std::istream_iterator<std::string>(file),
1190 std::istream_iterator<std::string>(),
1191 std::back_inserter(s_list));
1194 n_equiv.push_back(std::stol(s_list[2]));
1198 tclust.read(file, pts, C.
check(), SD_is_on);
1201 tclust.calc_properties();
1207 resize(max_num_sites + 1);
1210 for(i = 0; i < prototype_list.
size(); i++) {
1214 at(prototype_list[i].size()).back().get_equivalent(sym_group,
tol());
1216 if(n_equiv[i] != at(prototype_list[i].size()).back().size()) {
1217 std::cerr <<
"Error in Orbitree::generate_orbitree_from_proto_file()." << std::endl
1218 <<
" Expected " << n_equiv[i] <<
" equivalents, but only generated " << at(prototype_list[i].size()).back().size() <<
" equivalents." << std::endl
1219 <<
" Prototype: " << std::endl;
1220 prototype_list[i].print_sites(std::cerr, 6,
'\n');
1221 std::cerr <<
"\n" << std::endl;
1223 for(j = 0; j < at(prototype_list[i].size()).back().size(); j++) {
1224 std::cerr <<
" Equivalent " << j << std::endl;
1225 at(prototype_list[i].size()).
back().at(j).print_sites(std::cerr, 6,
'\n');
1245 template<
typename ClustType>
1254 PrimGrid prim_grid(lattice, reduced_cell);
1261 for(i = 0; i < 3; i++)
1262 shift.
frac(i) = shift_count[i];
1264 for(i = 0; i < prim.
basis.
size(); i++) {
1265 if(prim.
basis[i].site_occupant().
size() < min_num_components)
continue;
1267 for(j = 0; j < prim_grid.
size(); j++) {
1270 gridstruc.
back().set_lattice(reduced_cell,
CART);
1271 gridstruc.
back().within();
1272 gridstruc.
back() -= shift;
1273 gridstruc.
back().set_lattice(lattice,
CART);
1278 while(++shift_count);
1283 std::cerr <<
"WARNING: Orbitree is about to be overwritten! Execution will continue normally, but side effects may occur.\n";
1286 resize(max_num_sites + 1);
1298 std::cout <<
"About to begin construction of non-empty clusters\n";
1299 for(np = 1; np <= max_num_sites; np++) {
1300 std::cout <<
"Doing np = " << np <<
'\n';
1302 if(size(np - 1) == 0) {
1303 std::cerr <<
"WARNING: Orbitree::generate_orbitree is unable to enumerate clusters of size " << np - 1 <<
" or larger.\n" ;
1309 for(no = 0; no < size(np - 1); no++) {
1310 std::cout <<
"Adding sites to orbit " << no <<
" of " << size(np - 1) <<
"\n";
1312 ClustType tclust(lattice);
1313 for(i = 0; i < orbit(np - 1, no).prototype.size(); i++)
1314 tclust.push_back(orbit(np - 1, no).prototype[i]);
1317 for(i = 0; i < gridstruc.
size(); i++) {
1319 if(tclust.contains(gridstruc[i]))
1322 tclust.push_back(gridstruc[i]);
1324 if(tclust.image_check(reduced_cell, num_images))
continue;
1326 tclust.calc_properties();
1327 if(!
contains(tclust) && tclust.min_length() > min_length) {
1349 template<
typename ClustType>
1363 for(
Index np = 1; np < size(); np++) {
1364 for(
Index no = 0; no < size(np); no++) {
1366 ClustType tclust(lattice);
1369 max(orbit(np, no).prototype.size(), 1),
1370 inc(orbit(np, no).prototype.size(), 1);
1374 subcluster.push_back(tsubcluster);
1376 if(site_counter() ==
min || site_counter() ==
max)
continue;
1378 for(
Index i = 0; i < site_counter().
size(); i++) {
1379 if(site_counter()[i]) {
1380 tclust.push_back(orbit(np, no).prototype[i]);
1385 subcluster.back().push_back(
find(tclust));
1388 while(++site_counter);
1409 template<
typename ClustType>
1413 int curr_cluster_size = 0;
1417 min_num_components = 0;
1419 stream.ignore(1000,
'\n');
1422 if(ch ==
'R' || ch ==
'r') {
1427 stream.ignore(1000,
'\n');
1428 stream.getline(abc, 200);
1430 while(stream >> cluster_size) {
1431 if(curr_cluster_size == 0) {
1432 max_length.push_back(0.0);
1433 if(cluster_size == 1) {
1439 else if(cluster_size == 2) {
1442 max_length.push_back(0.0);
1447 std::cerr <<
"error in GenericOrbitree<ClustType>::read_CSPECS()" << std::endl
1448 <<
" Your CSPECS file is wrong. The first cluster size is: " << cluster_size << std::endl
1449 <<
" It should be 1 (for local) or 2 (for global)" << std::endl;
1453 curr_cluster_size = cluster_size;
1456 max_length.push_back(specs);
1458 stream.getline(abc, 200);
1462 else if(ch ==
'N' || ch ==
'n') {
1467 stream.ignore(1000,
'\n');
1469 while(stream >> cluster_size) {
1471 num_clusts.push_back(specs);
1472 stream.ignore(1000,
'\n');
1476 std::cerr <<
"ERROR in 2nd line of CSPECS. 2nd line should indicate either Radius or Number.\n";
1484 template<
typename ClustType>
1487 print_proto_clust(stream);
1515 template<
typename ClustType>
1537 m_asym_unit.set_lattice(lattice,
CART);
1552 template<
typename ClustType>
1553 std::ostream &operator<< (std::ostream &stream, const GenericOrbitree<ClustType> &orbitree) {
1554 orbitree.print(stream);
1561 template<
typename ClustType>
1567 out.open(file.c_str());
1569 std::cerr <<
"Can't open" << file <<
".\n";
1573 print_full_clust(out);
1578 template<
typename ClustType>
1584 out.open(file.c_str());
1586 std::cerr <<
"Can't open" << file <<
".\n";
1590 print_proto_clust(out);
1595 template<
typename ClustType>
1602 out.open(file.c_str());
1604 std::cerr <<
"Can't open" << file <<
".\n";
1608 print_full_decorated_clust(out);
1613 template<
typename ClustType>
1618 out.open(file.c_str());
1620 std::cerr <<
"Can't open" << file <<
".\n";
1624 print_proto_decorated_clust(out);
1629 template<
typename ClustType>
1634 if(index.size() != size()) get_index();
1638 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1641 for(
Index i = 0; i < size(); i++) {
1642 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1643 for(
Index j = 0; j < size(i); j++) {
1644 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1645 <<
" Orbit: " << i <<
" " << j
1646 <<
" Points: " << orbit(i, j).prototype.size()
1647 <<
" Mult: " << orbit(i, j).size()
1648 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1649 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1650 <<
'\n' << std::flush;
1652 for(
Index k = 0; k < orbit(i, j).size(); k++) {
1653 out <<
" " << k <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1654 orbit(i, j).at(k).print_sites(out, 18,
'\n');
1656 out <<
'\n' << std::flush;
1658 if(size(i) != 0) out <<
'\n' << std::flush;
1665 template<
typename ClustType>
1670 if(index.size() != size()) get_index();
1674 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1677 for(
Index i = 0; i < size(); i++) {
1678 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1679 for(
Index j = 0; j < size(i); j++) {
1680 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1681 <<
" Orbit: " << i <<
" " << j
1682 <<
" Points: " << orbit(i, j).prototype.size()
1683 <<
" Mult: " << orbit(i, j).size()
1684 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1685 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1686 <<
'\n' << std::flush;
1688 for(
Index k = 0; k < orbit(i, j).size(); k++) {
1689 out <<
" " << k <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1690 orbit(i, j).at(k).print_basis_info(out, 18,
'\n');
1692 out <<
'\n' << std::flush;
1694 if(size(i) != 0) out <<
'\n' << std::flush;
1700 template<
typename ClustType>
1705 if(index.size() != size()) get_index();
1709 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1712 for(
Index i = 0; i < size(); i++) {
1713 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1714 for(
Index j = 0; j < size(i); j++) {
1715 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1716 <<
" Orbit: " << i <<
" " << j
1717 <<
" Points: " << orbit(i, j).prototype.size()
1718 <<
" Mult: " << orbit(i, j).size()
1719 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1720 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1721 <<
'\n' << std::flush;
1723 if(orbit(i, j).size() > 0) {
1724 for(
int k = 0; k < 1; k++) {
1725 out <<
" " <<
"Prototype" <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1726 orbit(i, j).at(k).print_sites(out, 18,
'\n');
1730 out <<
'\n' << std::flush;
1732 if(size(i) != 0) out <<
'\n' << std::flush;
1737 template<
typename ClustType>
1742 if(index.size() != size()) get_index();
1746 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1749 for(
Index no = 0; no < asym_unit().size(); no++) {
1750 out <<
"Asymmetric unit " << no + 1 <<
":\n";
1751 for(
Index ne = 0; ne < asym_unit()[no].size(); ne++) {
1752 Index b = asym_unit()[no][ne][0].basis_ind();
1753 out <<
" Basis site " << b <<
":\n"
1755 asym_unit()[no][ne][0].print(out);
1757 if(asym_unit()[no][ne].clust_basis.size() == 0)
1758 out <<
" [No site basis functions]\n\n";
1759 for(
Index f = 0; f < asym_unit()[no][ne].clust_basis.size(); f++) {
1760 for(
Index s = 0; s < asym_unit()[no][ne][0].site_occupant().size(); s++) {
1763 out <<
" \\phi_" << b <<
'_' << f <<
'[' << asym_unit()[no][ne][0].site_occupant()[s].name <<
"] = "
1764 << asym_unit()[no][ne].clust_basis[f]->eval(
Array<Index>(1, asym_unit()[no][ne][0].site_occupant().ID()),
Array<Index>(1, s));
1765 if(s + 1 == asym_unit()[no][ne][0].site_occupant().size())
1775 for(
Index i = 0; i < size(); i++) {
1776 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1777 for(
Index j = 0; j < size(i); j++) {
1778 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1779 <<
" Orbit: " << i <<
" " << j
1780 <<
" Points: " << orbit(i, j).prototype.size()
1781 <<
" Mult: " << orbit(i, j).size()
1782 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1783 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1784 <<
'\n' << std::flush;
1786 out <<
" " <<
"Prototype" <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1787 prototype(i, j).print_clust_basis(out, nf, 8,
'\n');
1788 nf += prototype(i, j).clust_basis.size();
1789 out <<
"\n\n" << std::flush;
1791 if(size(i) != 0) out <<
'\n' << std::flush;
1797 template<
typename ClustType>
1802 if(index.size() != size()) get_index();
1806 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1809 for(
Index i = 0; i < size(); i++) {
1810 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1811 for(
Index j = 0; j < size(i); j++) {
1812 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1813 <<
" Orbit: " << i <<
" " << j
1814 <<
" Points: " << orbit(i, j).prototype.size()
1815 <<
" Mult: " << orbit(i, j).size()
1816 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1817 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1818 <<
'\n' << std::flush;
1819 for(
Index k = 0; k < orbit(i, j).size(); k++) {
1820 out <<
" " << k <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1821 orbit(i, j).at(k).print_decorated_sites(out, 18,
'\n');
1823 out <<
'\n' << std::flush;
1825 if(size(i) != 0) out <<
'\n' << std::flush;
1831 template<
typename ClustType>
1835 if(index.size() != size()) get_index();
1839 out.flags(std::ios::showpoint | std::ios::fixed | std::ios::left);
1842 for(
Index i = 0; i < size(); i++) {
1843 if(size(i) != 0) out <<
"** Branch " << i <<
" ** \n" << std::flush;
1844 for(
Index j = 0; j < size(i); j++) {
1845 out <<
" ** " << index[i][j] <<
" of " << Norbits <<
" Orbits **"
1846 <<
" Orbit: " << i <<
" " << j
1847 <<
" Points: " << orbit(i, j).prototype.size()
1848 <<
" Mult: " << orbit(i, j).size()
1849 <<
" MinLength: " << orbit(i, j).prototype.min_length()
1850 <<
" MaxLength: " << orbit(i, j).prototype.max_length()
1851 <<
'\n' << std::flush;
1853 if(orbit(i, j).size() > 0) {
1854 for(
int k = 0; k < 1; k++) {
1855 out <<
" " <<
"Prototype" <<
" of " << orbit(i, j).size() <<
" Equivalent Clusters in Orbit " << index[i][j] <<
'\n' << std::flush;
1856 orbit(i, j).at(k).print_decorated_sites(out, 18,
'\n');
1861 out <<
'\n' << std::flush;
1863 if(size(i) != 0) out <<
'\n' << std::flush;
1879 template<
typename ClustType>
template<
class PhenomType>
1881 bool include_phenom_clust_sites) {
1891 PhenomType phenom_clust(tmp_phenom_clust);
1898 Eigen::Vector3i dim;
1899 double dist, max_dist;
1908 for(i = 0; i < prim.
basis.
size(); i++) {
1909 if(prim.
basis[i].site_occupant().
size() >= min_num_components) {
1911 basis.
back().set_lattice(lattice,
CART);
1919 double max_radius = max_length.max();
1922 dim = lattice.enclose_sphere(max_radius);
1929 lat_point.
frac() = grid_count().cast<
double>();
1931 for(i = 0; i < basis.
size(); i++) {
1933 typename ClustType::WhichCoordType tatom(basis[i] + lat_point);
1938 if(!include_phenom_clust_sites) {
1939 bool point_is_in_phenom =
false;
1941 for(
Index j = 0; j < phenom_clust.size(); j++) {
1942 if(phenom_clust[j].Coordinate::operator==(tatom)) {
1943 point_is_in_phenom =
true;
1948 if(point_is_in_phenom)
1955 for(j = 0; j < phenom_clust.size(); j++) {
1956 dist = tatom.dist(phenom_clust[j]);
1962 if(max_dist < max_radius) {
1969 while(++grid_count);
1974 std::cerr <<
"WARNING: Orbitree is about to be overwritten! Execution will continue normally, but side effects may occur.\n" << std::flush;
1977 resize(max_num_sites + 1);
2024 at(0).back().get_equivalent(phenom_clust.clust_group,
tol());
2027 for(np = 1; np <= max_num_sites; np++) {
2030 if(size(np - 1) == 0) {
2031 std::cerr <<
"WARNING: Orbitree::generate_local_orbitree is unable to enumerate clusters of size " << np <<
".\n";
2032 std::cerr <<
" found no clusters of size " << np - 1 <<
".\n" << std::flush;
2041 for(no = 0; no < size(np - 1); no++) {
2045 ClustType tclust(lattice);
2046 for(i = 0; i < orbit(np - 1, no).prototype.size(); i++)
2047 tclust.push_back(orbit(np - 1, no).prototype[i]);
2050 for(i = 0; i < gridstruc.
size(); i++) {
2052 if(tclust.contains(gridstruc[i]))
2056 tclust.push_back(gridstruc[i]);
2059 std::cout <<
"tclust is \n" << tclust <<
"\n" << std::flush;
2067 tclust.calc_properties(phenom_clust);
2077 std::cout <<
"tclust is \n" << tclust <<
"\n" << std::flush;
2083 at(np).back().get_equivalent(phenom_clust.clust_group,
tol());
2085 else if(tclust.max_length() < max_length[np] && tclust.min_length() > min_length && !
contains(tclust)) {
2091 std::cout <<
"The tclust we pushed back is \n" << tclust <<
"\n" << std::flush;
2094 at(np).back().get_equivalent(phenom_clust.clust_group,
tol());
2111 template<
typename ClustType>
2113 for(
Index i = 0; i < size(); i++) {
2114 for(
Index j = 0; j < size(i); j++) {
2115 orbit(i, j).apply_sym(op);
2122 template<
typename ClustType>
2124 std::ofstream file(filename);
2132 template<
typename ClustType>
2134 if(index.size() != size()) get_index();
2135 if(subcluster.size() != size()) get_hierarchy();
2138 << std::setw(8) <<
"label"
2139 << std::setw(8) <<
"weight"
2140 << std::setw(8) <<
"mult"
2141 << std::setw(8) <<
"size"
2142 << std::setw(12) <<
"length"
2143 << std::setw(8) <<
"hierarchy" << std::endl;
2147 for(
Index i = 0; i < size(); i++) {
2148 for(
Index j = 0; j < size(i); j++) {
2150 for(
Index k = 0; k < prototype(i, j).clust_basis.size(); k++, clustcount++) {
2154 << std::setw(8) << clustcount
2155 << std::setw(8) << 0
2156 << std::setw(8) << orbit(i, j).size()
2157 << std::setw(8) << orbit(i, j).prototype.size()
2158 << std::setw(12) << orbit(i, j).prototype.max_length();
2161 out << std::left << std::setw(8) << 0;
2162 for(
Index l = 0; l < subcluster[ index[i][j]].size(); l++) {
2164 << std::setw(8) << subcluster[ index[i][j] ][l];
2166 out <<
'\n' << std::flush;
2227 template<
typename ClustType>
2230 (*this).from_json(json);
2232 bool basis_set_init =
true;
2234 std::cout <<
"In read_orbitree_from_json. Initializing the occupant basis" << std::endl;
2235 if(basis_set_init) {
2238 for(np = 0; np < (*this).size(); np++) {
2239 for(no = 0; no < at(np).size(); no++) {
2241 at(np).at(no).prototype.update_data_members(ref_struc);
2246 for(np = 0; np < (*this).size(); np++) {
2247 for(no = 0; no < at(np).size(); no++) {
2248 at(np).at(no).get_equivalent(sym_group,
tol());
2277 template<
typename ClustType>
2286 for(
int i = 0; i < orbit_specs.
size(); i++) {
2288 std::string in_mode = orbit_specs[i][
"coordinate_mode"].template get<std::string>();
2291 if(in_mode ==
"Cartesian") {
2292 json_coord_mode =
CART;
2294 else if(in_mode ==
"Direct" || in_mode ==
"Fractional") {
2295 json_coord_mode =
FRAC;
2297 else if(in_mode !=
"Integral") {
2298 std::cerr <<
"ERROR in GenericOrbitree<ClustType>::read_custom_clusters_from_json. "
2299 <<
"The specified coord_mode for custom orbit " << i <<
" is invalid." << std::endl;
2300 std::cerr <<
"Prototype: \n" << orbit_specs[i] << std::endl;
2301 std::cerr <<
"coordinate_mode: " << in_mode << std::endl;
2302 std::cerr <<
"Valid options are: 'Cartesian', 'Direct', or 'Fractional'" << std::endl;
2303 throw std::runtime_error(
2304 "ERROR in GenericOrbitree<ClustType>::read_custom_clusters_from_json\n"
2305 " Invalid: \"coordinate_mode\": Expected one of \"Fractional\", \"Direct\", or \"Cartesian\""
2309 const jsonParser &proto_json = orbit_specs[i][
"prototype"];
2310 ClustType temp_clust(lattice);
2311 if(in_mode ==
"Integral") {
2312 for(
int j = 0; j < proto_json.
size(); j++) {
2323 for(
int j = 0; j < coords_as_rows.rows(); j++) {
2325 Coordinate tcoord(coords_as_rows.row(j).transpose(), struc.
lattice(), json_coord_mode);
2328 int site_loc = struc.
find(tcoord);
2330 temp_clust.push_back(struc.
basis[site_loc]);
2332 temp_clust.back().cart() = tcoord.cart();
2336 std::cerr <<
"ERROR in GenericOrbitree<ClustType>::read_custom_clusters_from_json. "
2337 <<
"Coordinate in custom orbit " << i <<
" does not match any site in the prim." << std::endl;
2338 std::cerr <<
"Prototype: \n" << orbit_specs[i] << std::endl;
2339 std::cerr <<
"coordinate_mode: " << in_mode << std::endl;
2340 if(json_coord_mode ==
FRAC)
2341 std::cerr <<
"Could not find: " << tcoord.const_frac() << std::endl;
2343 std::cerr <<
"Could not find: " << tcoord.const_cart() << std::endl;
2344 throw std::runtime_error(
2345 "ERROR in GenericOrbitree<ClustType>::read_custom_clusters_from_json\n"
2346 " Coordinate does not match any site in the prim."
2354 temp_clust.calc_properties();
2359 if(this->size() == 0) {
2364 for(
int i = 0; i < proto_clust.
size(); i++) {
2365 if(proto_clust[i].size() > max_num_sites)
2366 max_num_sites = proto_clust[i].size();
2367 for(
int j = 0; j < proto_clust[i].
size(); j++) {
2368 if(proto_clust[i][j].allowed_occupants().
size() < min_num_components)
2369 min_num_components = proto_clust[i][j].allowed_occupants().
size();
2373 while(size() <= max_num_sites) {
2377 for(
int i = 0; i < proto_clust.
size(); i++) {
2380 std::cerr <<
"Proto_clust: " << std::endl;
2381 proto_clust[i].print(std::cout);
2382 std::cerr <<
"This cluster is already in the Orbitree. Not adding it to the list" << std::endl;
2388 at(proto_clust[i].size()).back().get_equivalent(sym_group,
tol());
2390 bool include_subclusters;
2392 orbit_specs[i].
get_else(include_subclusters,
"include_subclusters",
true);
2393 if(include_subclusters) {
2394 add_subclusters(at(proto_clust[i].size()).back().prototype, struc, verbose);
2406 template<
typename ClustType>
2408 if(verbose) std::cout <<
"In Orbitree::add_subclusters. Working on cluster: " << big_clust << std::endl;
2410 std::cerr <<
"WARNING: In Orbitree::add_subclusters, prim's factor_group is empty. It must at least have one element (identity).\n";
2415 if(!(lattice == prim.
lattice())) {
2416 std::cerr <<
"WARNING in Orbitree::add_subclusters, the lattice in prim and the lattice"
2417 <<
" that was used to construct this cluster are not the same" << std::endl;
2421 if(verbose) std::cout <<
"Size of this is : " << size() << std::endl;
2422 if(verbose) std::cout <<
"Size of cluster is : " << big_clust.size() << std::endl;
2423 if((size() - 1) < big_clust.size()) {
2424 std::cout <<
"Adding more Branches to this orbitree" << std::endl;
2425 for(
Index temp = 0; temp <= (big_clust.size() - size()); temp++)
2427 max_num_sites = big_clust.size();
2431 std::string clean(80,
' ');
2432 Array<int> master_choose(big_clust.size(), 0);
2433 if(verbose) std::cout <<
"Master_Choose : " << master_choose << std::endl;
2435 for(i = 1; i <= big_clust.size(); i++) {
2436 if(verbose) std::cout <<
"Working on a subcluster of size: " << i << std::endl;
2438 for(j = 0; j < i; j++)
2439 choose[choose.
size() - j - 1] = 1;
2440 ClustType test_clust(prim.
lattice());
2442 if(verbose) std::cout <<
"Choose is: " << choose << std::endl;
2444 for(j = 0; j < choose.
size(); j++) {
2446 test_clust.push_back(big_clust.at(j));
2448 test_clust.within();
2449 test_clust.calc_properties();
2452 if(verbose) std::cout <<
"Adding this cluster: " << test_clust << std::endl;
2468 template<
typename ClustType>
2482 resize(json[
"branches"].size());
2483 for(
int i = 0; i < json[
"branches"].
size(); i++) {
2514 std::cerr <<
"WARNING in GenericOrbitree<ClustType>::from_json "
2515 <<
"I HOPE YOU ARE NOT USING THIS AS A STAND ALONE RO"
2516 <<
"UTINE. Use it only as part of "
2517 <<
"GenericOrbitree<ClustType>::read_orbitree_from_json";
2527 template<
typename ClustType>
2531 ClustType tclust(lattice);
2533 tclust.push_back(struc.
basis[i]);
2536 tclust.calc_properties();
2541 m_asym_unit.back().collect_basis_info(struc.
basis);
2542 for(
Index ne = 0; ne < m_asym_unit.back().size(); ne++) {
2543 m_b2asym[_asym_unit().back()[ne][0].basis_ind()][0] = _asym_unit().size() - 1;
2544 m_b2asym[_asym_unit().back()[ne][0].basis_ind()][1] = ne;
2545 m_asym_unit.back()[ne].set_nlist_inds(
Array<Index>(1, _asym_unit().back()[ne][0].basis_ind()));
2553 template<
typename ClustType>
2556 if(bspecs()[
"basis_functions"][
"site_basis_functions"].is_string()) {
2557 std::string func_type = bspecs()[
"basis_functions"][
"site_basis_functions"].template get<std::string>();
2560 switch(std::tolower(func_type[0])) {
2562 for(
Index i = 0; i < _asym_unit().size(); i++) {
2563 Array<double> tprob(m_asym_unit.prototype(i)[0].site_occupant().size(), 1.0 / double(_asym_unit().prototype(i)[0].site_occupant().size()));
2564 m_asym_unit.prototype(i).clust_basis.construct_orthonormal_discrete_functions(_asym_unit().prototype(i)[0].site_occupant(), tprob, _asym_unit().prototype(i)[0].basis_ind(), asym_unit().prototype(i).clust_group());
2565 for(
Index ne = 0; ne < _asym_unit()[i].size(); ne++)
2566 m_asym_unit[i][ne].clust_basis.construct_orthonormal_discrete_functions(_asym_unit()[i][ne][0].site_occupant(), tprob, _asym_unit()[i][ne][0].basis_ind(), asym_unit().prototype(i).clust_group());
2571 for(
Index i = 0; i < _asym_unit().size(); i++) {
2572 Array<double> tprob(_asym_unit().prototype(i)[0].site_occupant().size(), 0.0);
2575 m_asym_unit.prototype(i).clust_basis.construct_orthonormal_discrete_functions(_asym_unit().prototype(i)[0].site_occupant(), tprob, _asym_unit().prototype(i)[0].basis_ind(), asym_unit().prototype(i).clust_group());
2576 for(
Index ne = 0; ne < _asym_unit()[i].size(); ne++)
2577 m_asym_unit[i][ne].clust_basis.construct_orthonormal_discrete_functions(_asym_unit()[i][ne][0].site_occupant(), tprob, _asym_unit()[i][ne][0].basis_ind(), asym_unit().prototype(i).clust_group());
2583 throw std::runtime_error(std::string(
"Parsing BSPECS.json, the specified 'site_basis_function' option -- \"") + func_type +
"\" -- does not exist.\n"
2584 +
"valid options are 'chebychev' or 'occupation'.\n");
2590 typedef std::map<std::string, double> SiteProb;
2591 std::vector<SiteProb> prob_vec(m_b2asym.size());
2593 auto it = bspecs()[
"basis_functions"].find(
"site_basis_functions");
2597 if(it->is_array()) {
2598 end_it = it->cend();
2602 bool sublat_spec =
true;
2604 for(; it != end_it; ++it, num_spec++) {
2607 auto it2 = (*it)[
"composition"].cbegin(), end_it2 = (*it)[
"composition"].cend();
2608 for(; it2 != end_it2; ++it2) {
2609 tprob[it2.name()] = it2->template get<double>();
2612 if(!(it->contains(
"sublat_indices")) || !sublat_spec) {
2615 throw std::runtime_error(std::string(
"Parse error: If multiple 'site_basis_functions' specifications are provided, 'sublat_indices' must be specified for each.\n")
2616 +
" Example: \"site_basis_functions\" : [\n"
2618 +
" \"sublat_indices\" : [0],\n"
2619 +
" \"composition\" : [ \"SpeciesA\" : 0.2, \"SpeciesB\" : 0.8]\n"
2622 +
" \"sublat_indices\" : [1,2],\n"
2623 +
" \"composition\" : [ \"SpeciesA\" : 0.7, \"SpeciesB\" : 0.3]\n"
2627 else if(num_spec == 0)
2628 sublat_spec =
false;
2632 for(
auto &_vec : prob_vec)
2636 it2 = (*it)[
"sublat_indices"].cbegin();
2637 end_it2 = (*it)[
"sublat_indices"].cend();
2638 for(; it2 != end_it2; ++it2) {
2639 Index b_ind = it2->template get<long>();
2640 if(!prob_vec[b_ind].empty())
2641 throw std::runtime_error(
"Duplicate sublat_indices specified in BSPECS.JSON\n");
2643 prob_vec[b_ind] = tprob;
2648 for(
Index i = 0; i < _asym_unit().size(); i++) {
2649 if(_asym_unit().prototype(i)[0].site_occupant().size() < 2)
2651 Array<double> tprob(_asym_unit().prototype(i)[0].site_occupant().size(), 0.0);
2652 if(tprob.
size() == 0)
2654 Index b_ind = _asym_unit().prototype(i)[0].basis_ind();
2656 for(
Index ns = 0; ns < _asym_unit().prototype(i)[0].site_occupant().size(); ns++) {
2657 if(prob_vec[b_ind].
find(_asym_unit().prototype(i)[0].site_occupant()[ns].name) == prob_vec[b_ind].end())
2658 throw std::runtime_error(
"In BSPECS.JSON, basis site " +
std::to_string(b_ind) +
" must have a composition specified for species " + _asym_unit().prototype(i)[0].site_occupant()[ns].name +
"\n");
2660 tprob[ns] = prob_vec[b_ind][_asym_unit().prototype(i)[0].site_occupant()[ns].name];
2665 m_asym_unit.prototype(i).clust_basis.construct_orthonormal_discrete_functions(_asym_unit().prototype(i)[0].site_occupant(), tprob, _asym_unit().prototype(i)[0].basis_ind(), asym_unit().prototype(i).clust_group());
2666 for(
Index ne = 0; ne < _asym_unit()[i].size(); ne++)
2667 m_asym_unit[i][ne].clust_basis.construct_orthonormal_discrete_functions(_asym_unit()[i][ne][0].site_occupant(), tprob, _asym_unit()[i][ne][0].basis_ind(), asym_unit().prototype(i).clust_group());
void print_eci_in(std::ostream &out) const
Array< Array< int > > index
size_type size() const
Returns array size if *this is a JSON array, object size if *this is a JSON object, 1 otherwise.
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Array< Array< int > > subcluster
void generate_decorated_orbitree(const GenericOrbitree< ClustType > &in_tree, const SymGroup &symgroup, PERIODICITY_TYPE ptype, bool full_decor=false)
void apply_sym(const SymOp &op)
void from_json(ClexDescription &desc, const jsonParser &json)
void generate_in_cell(const Structure &prim, const Lattice &cell, int num_images=0)
void write_proto_clust(std::string file) const
A Counter allows looping over many incrementing variables in one loop.
Array< int > index_to_row
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
sets lattice=new_lat and also updates all OrbitBranches, Orbits, and Clusters
double length(Index i) const
Return length of i'th lattice vector.
void push_back(const T &toPush)
Structure specifies the lattice and atomic basis of a crystal.
void generate_orbitree_neighbour(const Structure &prim, const Array< int > maxNeighbour)
void read_CSPECS(std::istream &stream)
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
Lattice get_reduced_cell() const
Find the lattice vectors which give most compact unit cell Compactness is measured by how close lat_c...
ReturnArray< Array< int > > get_full_decor_map() const
void generate_hop_orbitree(const GenericOrbitree< SiteCluster > &in_tree, const Structure &prim)
GenericOrbitree< ClustType > & operator=(const GenericOrbitree< ClustType > &RHS)
std::string to_string(ENUM val)
Return string representation of enum class.
const Lattice & lattice() const
void write_full_clust(std::string file) const
Index find(const ClustType &test_clust) const
If cluster/orbit exists in current orbitree, return its linear index; else, return number of orbits i...
void push_back(const GenericOrbit< ClustType > &new_orbit)
void generate_local_orbitree(const Structure &prim, const PhenomType &tmp_phenom_clust, bool include_phenom_clust_sites)
Constructs a local orbitree about a Phenom Cluster, given a Structure.
T get(Args...args) const
Get data from json, using one of several alternatives.
void get_index() const
Populates 'index', 'index_to_row' and 'index_to_column' Arrays.
void print_proto_clust_funcs(std::ostream &out) const
Array< Array< Index > > m_b2asym
Index basis_set_size() const
Count number of basis functions at each orbit and sum result.
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...
bool read_custom_clusters_from_json(const jsonParser &json, const Structure &struc, const SymGroup &sym_group, bool verbose=false)
Add more orbits to Orbitree based on JSON input.
void print_proto_clust(std::ostream &out) const
const GenericOrbitBranch< ClustType > & _asym_unit() 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...
const MasterSymGroup & factor_group() const
void resize(Index NP)
Initialize NP orbitbranches in the Orbitree. Any existing orbits get deleted.
void write_full_decorated_clust(std::string file) const
Represents cartesian and fractional coordinates.
typename multivector_impl::multivector_tmp< T, N >::type X
void collect_basis_info(const Structure &struc)
void decorate(const Array< int > decor)
EigenIndex Index
For long integer indexing:
GenericOrbitBranch< ClustType > m_asym_unit
void print_full_basis_info(std::ostream &out) const
void _populate_site_bases()
GenericOrbitree(const Lattice &t_lat, double _tol)
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
bool get_else(T &t, const std::string &key, const T &default_value, Args...args) const
Array< int > num_clusts
we don't use num_clusts yet. It might be a better way to specify how many clusters to enumerate ...
void print_proto_decorated_clust(std::ostream &out) const
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
void set(const COORD_TYPE new_mode)
void write_eci_in(std::string filename) const
T max(const T &A, const T &B)
T min(const T &A, const T &B)
Array< int > index_to_column
double tol() const
Access orbitree tolerance.
void generate_orbitree_from_proto_file(std::string filename, const SymGroup &sym_group, PERIODICITY_TYPE ptype)
void print_full_clust(std::ostream &out) const
void _generate_asym_unit(const Structure &prim)
Array & append(const Array &new_tail)
static std::string NAME()
get a string with the name of the active mode
void sort()
Calls 'sort()' on each OrbitBranch to sort Orbits by lengthscale.
void generate_orbitree(const Structure &prim, bool verbose=false)
const ClustType & prototype(Index np, Index no) const
Access prototype of orbit (np, no)
CoordType get_site(const UnitCellCoord &ucc) const
const ClustType & equiv(Index np, Index no, Index ne) const
Access equivalent cluster 'ne' of orbit (np, no)
void read_orbitree_from_json(const std::string &json_file_name, const SymGroup &sym_group, const Structure &ref_struc)
void from_json(const jsonParser &json)
Assumes the pivot lattice is already set.
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Array< double > max_length
void write_proto_decorated_clust(std::string file) const
GenericOrbit< ClustType > & orbit(Index np, Index no)
Access orbits using 2-D indexing.
void print_full_decorated_clust(std::ostream &out) const
Coordinate coord(Index l, CELL_TYPE lat_mode) const
void get_hierarchy() const
void generate_clust_bases(std::vector< BasisSet const * > const &global_args, Index max_poly_order=-1)
get clust_basis for all equivalent clusters
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
bool contains(const ClustType &test_clust)
If cluster exists in current orbitree, return true.
Basic std::vector like container (deprecated)
void print(std::ostream &stream) const
void add_subclusters(const ClustType &big_clust, const Structure &prim, bool verbose=false)
Adding in subclusters of a specific cluster into *this Orbitree.
Index size(Index np) const
Number of orbits in OrbitBranch 'np'.
const jsonParser & bspecs() const
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())