19 if(!fs::exists(filepath)) {
20 std::cerr <<
"Error in Structure::Structure(const fs::path &filepath)." << std::endl;
21 std::cerr <<
" File does not exist at: " << filepath << std::endl;
24 fs::ifstream infile(filepath);
126 std::vector<Specie> struc_specie;
131 for(i = 0; i < struc_molecule.size(); i++) {
133 for(j = 0; j < struc_molecule[i].size(); j++) {
134 if(!
contains(struc_specie, struc_molecule[i][j].specie)) {
135 struc_specie.push_back(struc_molecule[i][j].specie);
148 std::vector<Molecule> struc_molecule;
154 for(j = 0; j <
basis[i].site_occupant().
size(); j++) {
157 struc_molecule.push_back(
basis[i].site_occupant()[j]);
162 return struc_molecule;
172 std::vector<std::string> struc_mol_name;
173 for(
int i = 0; i < struc_mol.size(); i++) {
174 struc_mol_name.push_back(struc_mol[i].name);
177 return struc_mol_name;
187 Eigen::VectorXi num_each_specie = Eigen::VectorXi::Zero(struc_specie.size());
193 for(j = 0; j <
basis[i].occ().
size(); j++) {
199 return num_each_specie;
209 Eigen::VectorXi num_each_molecule = Eigen::VectorXi(struc_molecule.size());
218 return num_each_molecule;
279 for(i = 0; i < prim_grid.size(); i++) {
304 for(
Index j = 0; j < prim_grid.size(); j++) {
314 std::cerr <<
"WARNING: You have a very large factor group of a non-primitive structure. Certain symmetry features will be unavailable.\n";
352 stream <<
" Printing symmetry operations that leave each site unchanged:\n \n";
353 for(
Index i = 0; i < asym_unit.
size(); i++) {
354 for(
Index j = 0; j < asym_unit[i].
size(); j++) {
356 asym_unit.
at(i).at(j).at(0).print(stream);
357 stream <<
" Total Symmetry Operations: " << asym_unit[i][j].clust_group().
size() <<
"\n";
359 for(
Index nc = 0; nc < asym_unit[i][j].clust_group().
size(); nc++) {
362 stream << std::setw(4) << nc + 1 <<
": ";
368 stream.flags(std::ios::left);
369 stream <<
"\n" << std::setw(3) << nc + 1 <<
": ";
370 stream.unsetf(std::ios::left);
372 asym_unit[i][j].clust_group()[nc].
print(stream, Eigen::Matrix3d::Identity());
374 asym_unit[i][j].clust_group()[nc].
print(stream,
lattice().inv_lat_column_mat());
377 stream <<
"\n --------------------------------------------------------------------- \n\n";
389 basis[nb].set_basis_ind(nb);
411 if(out_trees.
size() != 0) {
412 std::cerr <<
"WARNING in Structure::generate_flowertrees_safe" << std::endl;
413 std::cerr <<
"The provided array of SiteOrbitree wasn't empty! Hope nothing important was there..." << std::endl;
424 for(
Index s = 1; s < in_tree.
size(); s++) {
434 in_tree[s].extract_orbits_including(tsiteclust, out_trees[b].back(), tol);
436 out_trees[b].get_index();
437 out_trees[b].collect_basis_info(*
this);
447 Index na, np, nb, ne;
462 for(na = 0; na < asym_unit.
size(); na++) {
463 asym_unit.
prototype(na).clust_group().character_table();
465 nb = out_tree.
size();
470 for(np = 0; np < in_tree.
size(); np++) {
471 if(num_sites != in_tree[np].num_sites()) {
475 in_tree[np].extract_orbits_including(asym_unit.
prototype(na), out_tree.
back(),
tol);
479 for(ne = 1; ne < asym_unit[na].equivalence_map.
size(); ne++) {
481 out_tree.
back().apply_sym(asym_unit[na].equivalence_map[ne][0]);
516 for(na = 0; na < asym_unit.
size(); na++) {
523 for(np = 0; np < in_tree.
size(); np++) {
524 if(num_sites != in_tree[np].num_sites()) {
529 in_tree[np].extract_orbits_including(asym_unit.
prototype(na), out_tree.
back(),
tol);
563 if(out_trees.
size() != 0) {
564 std::cerr <<
"WARNING in Structure::generate_flowertrees_safe" << std::endl;
565 std::cerr <<
"The provided array of SiteOrbitree wasn't empty! Hope nothing important was there..." << std::endl;
570 Index max_clust_size = in_tree.
size() - 1;
574 for(
Index i = 1; i < (max_clust_size + 1); i++) {
588 for(
Index j = 0; j < bouquets.
size(); j++) {
613 std::cerr <<
"*******************************************\n"
614 <<
"ERROR in Structure::map_superstruc_to_prim:\n"
615 <<
"The structure \n";
617 std::cerr <<
"is not a supercell of the given prim!\n";
619 std::cerr <<
"*******************************************\n";
629 for(
Index pg = 0; pg < prim_grid.size(); pg++) {
631 shifted_site = prim.
basis[pb];
632 shifted_site += prim_grid.coord(pg,
PRIM);
634 shifted_site.within();
641 shifted_site.set_basis_ind(-1);
642 prim_to_scel =
find(shifted_site);
645 std::cerr <<
"*******************************************\n"
646 <<
"ERROR in Structure::map_superstruc_to_prim:\n"
647 <<
"Cannot associate site \n"
648 << shifted_site <<
"\n"
649 <<
"with a site in the supercell basis. \n"
650 <<
"*******************************************\n";
651 std::cerr <<
"The basis_ind is "
652 << shifted_site.basis_ind() <<
"\n ";
665 bool is_equiv(
lattice() == new_lat);
700 std::cerr <<
"ERROR in Structure::stack_on" << std::endl;
701 std::cerr <<
"Lattice mismatch! Your structures are oriented differently in space. ab planes of structures must be parallel before stacking.\
702 Redefine your structure or use Structure::align_with to fix issue." << std::endl;
703 std::cerr <<
"Your vectors were:\n" << understruc.
lattice()[0].cross(understruc.
lattice()[1]) <<
"\n" << overstruc.
lattice()[0].cross(overstruc.
lattice()[1]) << std::endl;
714 std::cerr <<
"WARNING in Structure::stack_on" << std::endl;
715 std::cerr <<
"You've chosen to ignore if ab planes of your structures are not parallel and/or c axes point the right way.\
716 This will almost surely result in a malformed structure. Do not take the output for granted." << std::endl;
738 heterostruc.set_lattice(heterolat,
CART);
745 heterostruc.basis.push_back(tsite);
749 for(
Index i = 0; i < heterostruc.basis.size(); i++) {
750 heterostruc.basis[i].within();
753 heterostruc.update();
772 Eigen::Vector3d zreflect;
773 zreflect << 1, 1, -1;
810 for(
Index i = 0; i < siamese[2].
size(); i++) {
811 for(
Index j = 0; j < siamese[2][i].
size(); j++) {
812 Site avgsite(siamese[2][i][j][1]);
813 avgsite.
cart() = (siamese[2][i][j][0].const_cart() + siamese[2][i][j][1].const_cart()) * 0.5;
817 std::cout <<
"###############" << std::endl;
818 std::cout << siamese[2][i][j][0].basis_ind() <<
" " << siamese[2][i][j][0] << std::endl;
819 std::cout << siamese[2][i][j][1].basis_ind() <<
" " << siamese[2][i][j][1] << std::endl;
820 std::cout <<
"-------" << std::endl;
821 std::cout <<
basis[siamese[2][i][j][0].basis_ind()].basis_ind() <<
" " <<
basis[siamese[2][i][j][0].basis_ind()] << std::endl;
822 std::cout <<
basis[siamese[2][i][j][1].basis_ind()].basis_ind() <<
" " <<
basis[siamese[2][i][j][1].basis_ind()] << std::endl;
823 std::cout <<
"###############" << std::endl;
826 basis[siamese[2][i][j][0].basis_ind()].set_basis_ind(-99);
827 basis[siamese[2][i][j][1].basis_ind()].set_basis_ind(-99);
832 std::cout <<
"BASIS IND:" << std::endl;
835 for(
int i = bsize - 1; i >= 0; i--) {
836 std::cout <<
basis[i].basis_ind() <<
" " <<
basis[i] << std::endl;
863 if(
basis[j].occ_name() >
basis[j + 1].occ_name()) {
891 std::cerr <<
"ERROR in Structure::stamp_with (are you using Structure::bedazzle?)" << std::endl;
892 std::cerr <<
"The lattice of your cluster is not related to the lattice of the structure you want to stamp!" << std::endl;
903 std::cerr <<
"ERROR in Structure::stamp_with" << std::endl;
904 std::cerr <<
"Your superstructure isn't big enough to fit your cluster!" << std::endl;
905 std::cerr <<
"Culprit:" << std::endl;
906 stamp.
print(std::cerr);
914 Index sanity_count = 0;
915 for(
Index i = 0; i < stamp.
size(); i++) {
919 stampedstruc.
basis[j] = stamp[i];
924 if(sanity_count != stamp.
size()) {
925 std::cerr <<
"ERROR in Structure::stamp_with (are you using Structure::bedazzle?)" << std::endl;
926 std::cerr << stamp.
size() - sanity_count <<
" sites in the cluster (size " << stamp.
size() <<
" did not map onto your structure.\
927 If you got this far your lattices passed the test, but it seems your bases are unrelated. My guesses:" << std::endl;
928 std::cerr <<
"You're trying to map a relaxed site onto an ideal one." << std::endl;
929 std::cerr <<
"You have a vacancy in the structure you're stamping that's not in the basis." << std::endl;
933 stampedstruc.
reset();
947 for(
Index i = 0; i < stamps.
size(); i++) {
951 return all_decorations;
966 if(!bouquet.
size()) {
967 std::cerr <<
"WARNING in Structure::get_NN_table" << std::endl;
968 std::cerr <<
"The provided SiteOrbitree is about to be rewritten!" << std::endl;
987 for(
Index i = 0; i < bouquet.
size(); i++) {
989 for(
Index j = 0; j < bouquet[i].
size(); j++) {
990 NN[i][0].
push_back(bouquet[i][j].size());
991 NN[i][1].
push_back(bouquet[i][j].max_length());
1030 for(
Index rf = 0; rf < relaxed_factors.
size(); rf++) {
1035 std::cout << std::endl;
1040 double smallest = 1000000;
1042 for(
Index ob = 0; ob < operbasis.
size(); ob++) {
1043 double dist = operbasis[ob].min_dist(
basis[b], tshift);
1044 if(dist < smallest) {
1049 bshift.
cart() *= (1.0 / relaxed_factors.
size());
1050 avg_basis[b] += bshift;
1092 std::cerr << cshift.
const_frac() << std::endl;
1093 std::cerr <<
"WARNING: You're shifting in the c direction! This will mess with your vacuum and/or structure!!" << std::endl;
1094 std::cerr <<
"See Structure::add_vacuum_shift" << std::endl;
1097 Eigen::Vector3d vacuum_vec;
1099 vacuum_vec.normalize();
1104 new_surface_struc = *
this;
1118 Eigen::Vector3d shift(0, 0, 0);
1141 for(
int m = 0; m < Nofimag + 1; m++) {
1146 std::string header =
"POSCAR 0";
1147 std::stringstream convert;
1149 tstruc.
title = header + convert.str();
1155 temp.
frac() = (
basis[i] - end_struc.
basis[i]).const_frac() * m / (Nofimag + 1);
1192 std::cerr <<
"The size of the occ index and basis index do not match!\nEXITING\n";
1196 basis[i].set_occ_value(occ_index[i]);
1266 return structure.
to_json(json);
1299 std::vector< std::vector<Index> > converter(struc.
basis.
size());
1302 converter[i].resize(struc.
basis[i].site_occupant().
size());
1304 for(
Index j = 0; j < struc.
basis[i].site_occupant().
size(); j++) {
1305 converter[i][j] =
find_index(mol_list, struc.
basis[i].site_occupant()[j]);
1317 std::vector< std::vector<Index> > converter(struc.
basis.
size());
1320 converter[i].resize(struc.
basis[i].site_occupant().
size());
1322 for(
Index j = 0; j < struc.
basis[i].site_occupant().
size(); j++) {
1323 converter[i][j] =
find_index(mol_name_list, struc.
basis[i].site_occupant()[j].name);
1337 std::vector< std::vector<Index> > converter_inv(struc.
basis.
size());
1340 converter_inv[i].resize(mol_name_list.size());
1342 std::vector<std::string> site_occ_name_list;
1343 for(
Index j = 0; j < struc.
basis[i].site_occupant().
size(); j++) {
1344 site_occ_name_list.push_back(struc.
basis[i].site_occupant()[j].name);
1347 for(
Index j = 0; j < mol_name_list.size(); j++) {
1348 converter_inv[i][j] =
find_index(site_occ_name_list, mol_name_list[j]);
1352 return converter_inv;
void from_json(const jsonParser &json)
SymGroupRepID basis_permutation_symrep_ID() const
double angle(const Eigen::Ref< const Eigen::Vector3d > &a, const Eigen::Ref< const Eigen::Vector3d > &b)
Get angle, in radians, between two vectors on range [0,pi].
MasterSymGroup m_factor_group
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
jsonParser & to_json(jsonParser &json) const
void from_json(ClexDescription &desc, const jsonParser &json)
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Type-safe ID object for communicating and accessing Symmetry representation info. ...
void generate_flowertrees_safe(const SiteOrbitree &in_tree, Array< SiteOrbitree > &out_trees, double tol=TOL)
Gets clusters of every size radiating from one site and saves them to a flowertree. A garland for each site is constructed.
void generate_point_group(SymGroup &point_group, double pg_tol=TOL) const
Populate.
bool empty() const
Returns true if SymGroupRepID has not been initialized with valid group_index or rep_index.
bool compare(const T &A, const T &B, double tol)
Floating point comparison with tol, return A < B.
const SymGroup & point_group() const
void push_back(const T &toPush)
const SymGroup & point_group() const
Structure & operator+=(const Coordinate &shift)
Translates all atoms in cell.
Structure specifies the lattice and atomic basis of a crystal.
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
SymGroupRepID generate_basis_permutation_representation(bool verbose=false) const
Obtain the basis permutation representation of factor_group, returns its rep_id, and sets internal ba...
void generate_factor_group_slow(double map_tol=TOL) const
Obtain factor group by testing all operations of the lattice point_group and keep.
void copy_attributes_from(const Structure &RHS)
copy all non-derived members
void generate_flowertrees(const SiteOrbitree &in_tree, Array< SiteOrbitree > &out_trees, double tol=TOL)
BasicStructure specifies the lattice and atomic basis of a crystal.
std::vector< Molecule > get_struc_molecule() const
Returns an Array of each possible Molecule in this Structure.
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
GenericOrbitBranch< SiteCluster > SiteOrbitBranch
Structure stack_on(const Structure &understruc, bool override=0) const
void fg_converge(double large_tol)
generate factor groups for a range of tol values, prints results to screen (for now) ...
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
void generate_factor_group_slow(SymGroup &factor_group, double map_tol) const
const Lattice & lattice() const
*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...
void push_back(const GenericOrbit< ClustType > &new_orbit)
void push_back(const Site &new_site)
void push_back(const SymOp &op)
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
void symmetrize(const SymGroup &relaxed_factors)
void generate_factor_group(SymGroup &factor_group, double map_tol) const
apply a symmetry operation to the current structure (may change lattice vectors and order of basis at...
void sort_basis()
Rearrange basis by grouping atoms by type.
void generate_factor_group(double map_tol=TOL) const
void get_index() const
Populates 'index', 'index_to_row' and 'index_to_column' Arrays.
const vector_type & const_frac() const
user override to force const Access the fractional coordinate vector
SymGroupRepID basis_perm_rep_ID
This holds the representation id of the permutation representation.
std::vector< std::string > get_struc_molecule_name() const
Returns an Array of each possible Molecule in this Structure.
SymGroupRep const * basis_permutation_symrep() const
bool SD_flag
Specifies whether selectice dynamics is on or of for DFT calculations.
Index find(const CoordType2 &test_site, double tol=TOL) const
void reset()
clears symmetry, site internals, and other attributes
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
void set_lattice(const Lattice &new_home, COORD_TYPE mode)
void print(std::ostream &stream) const
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
const MasterSymGroup & factor_group() const
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
void print(std::ostream &stream, COORD_TYPE mode=FRAC)
Represents cartesian and fractional coordinates.
void add_vacuum_shift(Structure &new_surface_struc, double vacuum_thickness, Eigen::Vector3d shift, COORD_TYPE mode) const
Add vacuum and shift c vector. The vacuum is always added parallel to c, and the shift vector should ...
void collect_basis_info(const Structure &struc)
EigenIndex Index
For long integer indexing:
Structure & operator-=(const Coordinate &shift)
void fill_supercell(const Structure &prim, double map_tol=TOL)
fill an empty structure with the basis of its corresponding primitive cell - performs optimized facto...
void from_json(const jsonParser &json)
void add_vacuum(Structure &new_surface_struc, double vacuum_thickness) const
Adds vacuum layer on top of ab plane.
Array< Site > basis
Lattice vectors that specifies periodicity of the crystal.
void generate_basis_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol)
Structure stamp_with(SiteCluster stamp, bool lat_override=0, bool im_override=0) const
void fg_converge(double small_tol, double large_tol, double increment)
void invalidate_multi_tables() const
void set_lattice(const Lattice &lattice, COORD_TYPE mode)
void generate_asym_bouquet(const SiteOrbitree &in_tree, SiteOrbitree &out_tree, Index num_sites, double tol)
std::string title
User-specified name of this Structure.
bool is_supercell_of(const Lattice &tile, Eigen::Matrix3d &multimat, double _tol=TOL) const
Matrix that relates two lattices (e.g., strain or slat)
Structure create_superstruc(const Lattice &scel_lat, double map_tol=TOL) const
Shortcut routine to create a supercell structure and fill it with sites.
std::vector< std::vector< Index > > get_index_converter(const Structure &struc, std::vector< Molecule > mol_list)
Helper Functions.
Structure get_reflection() const
Return reflection of structure.
GenericOrbit< ClustType > & at(Index ind)
void intpol(Structure end_struc, int Nofimag, PERIODICITY_TYPE mode, Array< Structure > &images)
void swap_elem(Index i, Index j)
virtual void read(std::istream &stream)
Print intpolated images in seperate directries.
Index find_no_trans(const SymOp &test_op) const
Check to see if a SymOp is contained in in SymGroup and return its index.
void print_full_clust(std::ostream &out) const
void from_json(const jsonParser &json)
void copy_attributes_from(const BasicStructure &RHS)
std::vector< Specie > get_struc_specie() const
Returns an Array of each possible Specie in this Structure.
Array< Array< Array< double > > > get_NN_table(const double &maxr, SiteOrbitree &bouquet, double tol)
ClustType & prototype(Index no)
Method to access prototypes.
Array< Structure > bedazzle(Array< SiteCluster > stamps, bool lat_override=0, bool im_override=0) const
Structure & operator=(const Structure &RHS)
const Lattice & home() const
void generate_orbitree(const Structure &prim, bool verbose=false)
void set_occs(Array< int > occ_index)
Setting the current occupants of the structure to those specified by an array of integers.
Eigen::VectorXi get_num_each_molecule() const
std::vector< std::vector< Index > > get_index_converter_inverse(const Structure &struc, std::vector< std::string > mol_name_list)
void reserve(Index new_max)
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
void map_superstruc_to_prim(Structure &prim)
Figures out which prim basis each superstructure basis corresponds to.
Array< double > max_length
void set_lattice(const Lattice &new_lat)
SymGroupRep is an alternative representation of a SymGroup for something other than real space...
SymGroupRepID generate_basis_permutation_representation(const MasterSymGroup &factor_group, bool verbose) const
void within()
Translate all basis sites so that they are inside the unit cell.
Index size(Index no) const
How many equivalent clusters are int orbit 'no'.
void print_site_symmetry(std::ostream &stream, COORD_TYPE mode, int shorttag, double tol)
For each symmetrically distinct site, print the symmetry operations that map it onto itself...
void generate_asymmetric_unit(const Array< typename ClustType::WhichCoordType > &basis, const SymGroup &factor_group, double tol)
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.
Basic std::vector like container (deprecated)
void clump_atoms(double maxdist, double tol)
If atoms are too close together, average their distance and make them one.
void print(std::ostream &stream, char delim= '\n', COORD_TYPE mode=COORD_DEFAULT) const
Index size(Index np) const
Number of orbits in OrbitBranch 'np'.
jsonParser & to_json(jsonParser &json) const
Eigen::VectorXi get_num_each_specie() const
SymGroupRep const & representation(SymGroupRepID i) const
Const access of alternate Representations of a SymGroup.
virtual BasicStructure & operator=(const BasicStructure &RHS)