34 return find(
get_prim().get_unit_cell_coord(tcoord, tol));
47 tcoord.
cart() += (*primclex).get_prim().basis[bijk[0]].cart();
55 tcoord.
cart() += (*primclex).get_prim().basis[
get_b(l)].cart();
89 m_nlist = notstd::make_cloneable<SuperNeighborList>(
194 fg_index, trans_index);
213 fs::ifstream file(background);
214 background_struc.
read(file);
233 if(verbose) std::cout <<
"begin enumerate_perturb_configurations" << std::endl;
238 if(verbose) std::cout <<
"Generate background structure" << std::endl;
250 background_tree.min_num_components = 2;
253 background_tree.max_length.clear();
254 auto update_max_length = [&](
int branch,
double max_length) {
255 while(branch > background_tree.max_length.size() - 1) {
256 background_tree.max_length.push_back(0.0);
258 background_tree.max_length[branch] = max_length;
261 for(
auto it = json[
"orbit_branch_specs"].cbegin(); it != json[
"orbit_branch_specs"].cend(); ++it) {
262 update_max_length(std::stoi(it.name()), it->find(
"max_length")->get<
double>());
264 background_tree.max_num_sites = background_tree.max_length.size() - 1;
268 if(verbose) std::cout <<
"Generate background orbitree" << std::endl;
269 background_tree.generate_orbitree(background_scel);
271 if(verbose) std::cout <<
"background_config: " << background_config.
name() << std::endl;
277 if(verbose) std::cout <<
"Enumerate perturb configurations" << std::endl;
280 jsonsrc[
"supercell_name"] =
get_name();
281 jsonsrc[
"configid"] = background_config.
get_id();
286 for(
Index nb = 0; nb < perturb_config_index.
size(); nb++) {
287 std::cout <<
" Branch: " << nb << std::endl;
289 for(
Index no = 0; no < perturb_config_index[nb].
size(); no++) {
290 std::cout <<
" Orbit: " << no << std::endl;
291 background_tree.prototype(nb, no).print_decorated_sites(std::cout, 8,
'\n');
293 for(
Index nd = 0; nd < perturb_config_index[nb][no].
size(); nd++) {
294 std::cout <<
" config_index: " << perturb_config_index[nb][no][nd] << std::endl;
301 if(verbose) std::cout <<
"Print info" << std::endl;
305 fs::create_directory(
"training_data");
307 catch(
const fs::filesystem_error &ex) {
308 std::cerr <<
"Error in Supercell::enumerate_perturb_configurations()." << std::endl;
309 std::cerr << ex.what() << std::endl;
315 catch(
const fs::filesystem_error &ex) {
316 std::cerr <<
"Error in Supercell::enumerate_perturb_configurations()." << std::endl;
317 std::cerr << ex.what() << std::endl;
321 std::string pathstr = background_config.
get_path().filename().string() +
".perturb";
322 const fs::path config_path = background_config.
get_path().remove_filename() /= pathstr;
326 fs::create_directory(config_path);
333 if(fs::exists(config_path /
"CSPECS"))
334 fs::remove(config_path /
"CSPECS");
335 fs::copy(
fs::path(CSPECS), config_path /
"CSPECS");
340 if(fs::exists(config_path /
"CLUST"))
341 fs::remove(config_path /
"CLUST");
343 background_tree.write_proto_clust((config_path /
"CLUST").
string());
349 if(fs::exists(config_path /
"FCLUST"))
350 fs::remove(config_path /
"FCLUST");
352 background_tree.write_full_clust((config_path /
"FCLUST").
string());
358 if(fs::exists(config_path /
"PERTURB.json"))
359 fs::remove(config_path /
"PERTURB.json");
361 fs::ofstream file(config_path /
"PERTURB.json");
363 print_PERTURB_json(file, background_config, perturb_config_index, perturb_config_symop_index,
false);
367 catch(
const fs::filesystem_error &ex) {
368 std::cerr <<
"Error in Supercell::enumerate_perturb_configurations()." << std::endl;
369 std::cerr << ex.what() << std::endl;
373 if(verbose) std::cout <<
"finish enumerate_perturb_configurations" << std::endl;
437 config_index.resize(background_tree.
size());
438 config_symop_index.resize(background_tree.
size());
443 for(
Index nb = 0; nb < background_tree.
size(); nb++) {
446 config_index[nb].resize(background_tree[nb].size());
447 config_symop_index[nb].resize(background_tree[nb].size());
450 for(
Index no = 0; no < background_tree[nb].
size(); no++) {
457 decor_map = background_tree[nb][no].
prototype.get_full_decor_map();
461 linear_indices.
clear();
463 for(
Index i = 0; i < background_tree[nb][no].
prototype.size(); i++) {
474 for(
Index i = 0; i < decor_map.
size(); i++) {
477 for(
Index j = 0; j < decor_map[i].
size(); j++) {
478 config.
set_occ(linear_indices[j], decor_map[i][j]);
483 jsonsrc[
"perturbation"].
put_obj();
484 jsonsrc[
"perturbation"][
"branch"] = nb;
485 jsonsrc[
"perturbation"][
"orbit"] = no;
486 jsonsrc[
"perturbation"][
"decor"] = decor_map[i];
493 config_index[nb][no].push_back(index);
494 config_symop_index[nb][no].push_back(permute_it);
501 for(
Index i = 0; i < orig_occ.
size(); i++) {
502 config.
set_occ(linear_indices[i], orig_occ[i]);
610 std::pair<Supercell::config_const_iterator, bool>
618 std::pair<Supercell::config_const_iterator, bool>
621 std::pair<Supercell::config_const_iterator, bool> res;
641 throw std::runtime_error(
"Error adding Configuration to Supercell: Supercell mismatch");
658 std::cerr <<
"Error in Supercell::read_configuration." << std::endl;
659 std::cerr <<
" config_list.size() != 0, only use this once" << std::endl;
674 std::stringstream ss;
696 real_super_lattice(RHS.real_super_lattice),
697 recip_prim_lattice(RHS.recip_prim_lattice),
698 m_prim_grid((*
primclex).get_prim().lattice(), real_super_lattice, (*
primclex).get_prim().basis.size()),
699 recip_grid(recip_prim_lattice, (*
primclex).get_prim().lattice().get_reciprocal()),
701 m_nlist(RHS.m_nlist),
702 m_canonical(nullptr),
703 config_list(RHS.config_list),
704 transf_mat(RHS.transf_mat),
705 scaling(RHS.scaling),
713 real_super_lattice((*
primclex).get_prim().lattice().lat_column_mat() * transf_mat_init.cast<double>()),
714 recip_prim_lattice(real_super_lattice.get_reciprocal()),
715 m_prim_grid((*
primclex).get_prim().lattice(), real_super_lattice, (*
primclex).get_prim().basis.size()),
716 recip_grid(recip_prim_lattice, (*
primclex).get_prim().lattice().get_reciprocal()),
717 m_canonical(nullptr),
718 transf_mat(transf_mat_init) {
728 real_super_lattice(superlattice),
729 recip_prim_lattice(real_super_lattice.get_reciprocal()),
730 m_prim_grid((*
primclex).get_prim().lattice(), real_super_lattice, (*
primclex).get_prim().basis.size()),
731 recip_grid(recip_prim_lattice, (*
primclex).get_prim().lattice().get_reciprocal()),
732 m_canonical(nullptr),
733 transf_mat(
primclex->calc_transf_mat(superlattice)) {
779 bool print_config_name)
const {
783 json[
"supercell_name"] =
get_name();
784 if(print_config_name) {
785 json[
"config"] = background_config.
name();
788 json[
"configid"] = background_config.
get_id();
792 for(
Index nb = 0; nb < perturb_config_index.size(); nb++) {
793 for(
Index no = 0; no < perturb_config_index[nb].size(); no++) {
794 for(
Index nd = 0; nd < perturb_config_index[nb][no].size(); nd++) {
798 jsonobj[
"orbitbranch"] = nb;
799 jsonobj[
"orbit"] = no;
801 if(print_config_name) {
802 jsonobj[
"config"] =
get_config(perturb_config_index[nb][no][nd]).
name();
805 jsonobj[
"configid"] = perturb_config_index[nb][no][nd];
807 jsonobj[
"symop"] = perturb_config_symop_index[nb][no][nd];
809 json[
"perturbations"].
push_back(jsonobj);
831 std::cerr <<
"WARNING: In Supercell::generate_permutations(), but permutations data already exists.\n"
832 <<
" It will be overwritten.\n";
959 std::cerr <<
"ERROR in Supercell::configuration" << std::endl;
960 std::cerr <<
"The provided structure is not a supercell of the PRIM. Tranformation matrix was:" << std::endl;
961 std::cerr << transmat << std::endl;
965 std::cerr <<
"WARNING in Supercell::config(): This routine has not been tested on relaxed structures using 'tol'" << std::endl;
969 const Structure &prim = (*primclex).get_prim();
986 Index linear_index, b;
993 b =
get_b(linear_index);
996 if(config.
occ(linear_index) != -1) {
997 std::cerr <<
"Error in Supercell::config." << std::endl;
998 std::cerr <<
" Adding a second atom on site: linear index: " << linear_index <<
" bijk: " <<
uccoord(linear_index) << std::endl;
1004 std::cerr <<
"Error in Supercell::config." << std::endl;
1005 std::cerr <<
" The molecule: " << superstruc.
basis[i].occ_name() <<
" is not allowed on basis site " << b <<
" of the Supercell prim." << std::endl;
1008 config.
set_occ(linear_index, val);
1012 for(
Index i = 0; i < config.
size(); i++) {
1013 if(config.
occ(i) == -1) {
1020 std::cerr <<
"Error in Supercell::config." << std::endl;
1021 std::cerr <<
" Missing atom. Vacancies are not allowed on the site: " <<
uccoord(i) << std::endl;
1074 superstruc.
basis[i].set_occ_value(config.
occ(i));
1092 std::cerr <<
"ERROR in Supercell::superstructure" << std::endl;
1093 std::cerr <<
"Requested superstructure of configuration with index " << config_index <<
" but there are only " <<
config_list.size() <<
" configurations" << std::endl;
1111 occupation[i] = index;
1124 for(
int i = 0; i <
volume(); i++) {
1126 temp_real_point.
within();
1127 real_coords.row(i) = temp_real_point.
const_cart().transpose();
1142 for(
int i = 0; i <
volume(); i++) {
1148 kpoint_coords.row(i) = temp_kpoint.
const_cart().transpose();
1150 return kpoint_coords;
1156 Array<bool> is_commensurate(recip_coordinates.rows(),
true);
1157 for(
int i = 0; i < recip_frac_coords.rows(); i++) {
1158 for(
int j = 0; j < recip_frac_coords.cols(); j++) {
1159 if(std::abs(
round(recip_frac_coords(i, j)) - recip_frac_coords(i, j)) >
tol) {
1160 is_commensurate[i] =
false;
1165 return is_commensurate;
1178 if((real_coordinates.cols() != 3) || recip_coordinates.cols() != 3) {
1179 std::cerr <<
"ERROR in generate_fourier_matrix, your matrices are incorrectly initialized" << std::endl;
1180 std::cerr <<
"QUITTING" << std::endl;
1185 std::cerr <<
"WARNING in Supercell::generate_fourier_matrix. You already have a k-mesh in this Supercell"
1186 <<
" It will be overwritten" << std::endl;
1190 Eigen::MatrixXcd _fourier_matrix(real_coordinates.rows(),
m_k_mesh.rows());
1191 std::complex<double> pre_factor(0, -1);
1192 _fourier_matrix = pre_factor * real_coordinates *
m_k_mesh.transpose();
1197 Array<bool> is_commensurate(recip_coordinates.rows(),
true);
1201 if(!is_commensurate[i]) {
1212 std::complex<double> pre_factor(0, -1);
1214 _phase_factor = pre_factor * shift_vectors *
m_k_mesh.transpose();
1220 if(!is_commensurate[i]) {
1248 throw std::runtime_error(
1249 "Error using Supercell::operator<(const Supercell& B): "
1250 "Only Supercell with the same PrimClex may be compared this way.");
1260 throw std::runtime_error(
1261 "Error using Supercell::operator==(const Supercell& B): "
1262 "Only Supercell with the same PrimClex may be compared this way.");
1277 std::string name_str;
1281 std::stringstream tname;
1283 tname << H(0, 0)*H(1, 1)*H(2, 2) <<
"_" << H(0, 0) <<
"_" << H(1, 1) <<
"_" << H(2, 2) <<
"_" << H(1, 2) <<
"_" << H(0, 2) <<
"_" << H(0, 1);
1284 name_str.append(tname.str());
const Configuration & get_config(Index i) const
const Array< Permutation > & translation_permute() const
Supercell(const Supercell &RHS)
SymOp from_canonical() const
Coordinate coord(const UnitCellCoord &bijk) const
void set_site_internals()
Associate each site with its basis index by setting its internal flags (asym_ind -> -1) ...
void _add_canon_config(const Configuration &config)
std::string get_name() const
Return supercell name.
ConfigIterator< const Configuration, const PrimClex > config_const_iterator
Eigen::MatrixXcd m_fourier_matrix
bool is_canonical(double tol=TOL) const
Check if Lattice is in the canonical form.
ReturnArray< int > max_allowed_occupation() const
void generate_factor_group() const
std::string m_name
unique name of the supercell based on hermite normal form (see _generate_name() ) ...
bool contains(const T &test_elem) const
PermuteIterator permute_const_iterator
std::map< const Configuration *, Index, ConfigMapCompare > m_config_map
std::pair< config_const_iterator, bool > insert_config(const Configuration &config)
Insert a configuration that may be non-canonical.
const int & occ(Index site_l) const
Occupant variable on site l.
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
SymGroupRep const & permutation_symrep() const
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.
Eigen::Matrix3i transf_mat
std::string generate_name(const Eigen::Matrix3i &transf_mat)
void push_back(const T &toPush)
const Structure & get_prim() const
fs::path get_path() const
Return casm project directory path.
Structure specifies the lattice and atomic basis of a crystal.
Object copy_apply(const Transform &f, Object obj, Args &&...args)
Configuration canonical_form() const
Returns the canonical form Configuration in the same Supercell.
Configuration configuration(const BasicStructure< Site > &structure_to_config, double tol=TOL)
SymGroupRepID permutation_symrep_ID() const
void _generate_name() const
BasicStructure create_superstruc(const Lattice &scel_lat, double map_tol=TOL) const
Shortcut routine to create a supercell structure and fill it with sites.
const jsonParser & source() const
notstd::cloneable_ptr< SuperNeighborList > m_nlist
const Lattice & get_real_super_lattice() const
SymOp to_canonical() const
Supercell & canonical_form() const
void generate_permutations() const
const Lattice & lattice() const
Supercell * m_canonical
Store a pointer to the canonical equivalent Supercell.
Represents a supercell of the primitive parent crystal structure.
const vector_type & const_cart() const
user override to force const Access the Cartesian coordinate vector
config_const_iterator config_cend() const
Lattice recip_prim_lattice
void generate_fourier_matrix()
Structure Factor.
bool contains_config(const Configuration &config) const
PrimClex & get_primclex() const
Index find(const Coordinate &_coord) const
void read_config_list(const jsonParser &json)
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
jsonParser & write_config_list(jsonParser &json)
Call Configuration::write out every configuration in supercell.
fs::path get_path() const
Return path to supercell directory.
void reset()
clears symmetry, site internals, and other attributes
The SuperNeighborList gives the linear indices of neighboring sites and unitcells in a particular Sup...
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
std::string get_id() const
void generate_phase_factor(const Eigen::MatrixXd &shift_vectors, const Array< bool > &is_commensurate, const bool &override)
const Eigen::Matrix3d & inv_lat_column_mat() const
Inverse of Lattice::lat_column_mat() It is the transformation matrix 'C2F', such that f = C2F * c whe...
permute_const_iterator permute_begin() const
double crystallography_tol() const
Lattice real_super_lattice
void print_PERTURB_json(std::ofstream &file, const Configuration &background_config, const Array< Array< Array< Index > > > &perturb_config_index, const Array< Array< Array< permute_const_iterator > > > &perturb_config_symop_index, bool print_config_name) const
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Represents cartesian and fractional coordinates.
ConfigIterator< Configuration, PrimClex > config_iterator
SymGroupRepID make_permutation_representation(const SymGroup &group, SymGroupRepID basis_permute_rep) const
const SuperNeighborList & nlist() const
Returns the SuperNeighborList.
EigenIndex Index
For long integer indexing:
Index volume() const
Return number of primitive cells that fit inside of *this.
Array< bool > is_commensurate_kpoint(const Eigen::MatrixXd &recip_coordinates, double tol=TOL)
void set_occupation(const Array< int > &newoccupation)
Set occupant variables.
Array< CoordType > basis
Lattice vectors that specifies periodicity of the crystal.
bool add_canon_config(const Configuration &config, Index &index)
Structure superstructure() const
Index m_id
index into PrimClex::supercell_list
bool add_config(const Configuration &config)
fs::path get_path() const
SymOp to_canonical(double tol=TOL) const
Returns the operation that applied to *this returns the canonical form.
permute_const_iterator translate_begin() const
Begin iterator over pure translational permutations.
const SymGroup & factor_group() const
PrimClex is the top-level data structure for a CASM project.
UnitCellCoord uccoord(Index i) const
bool is_supercell_of(const Structure &structure) const
bool is_supercell_of(const Lattice &tile, Eigen::Matrix3d &multimat, double _tol=TOL) const
Matrix that relates two lattices (e.g., strain or slat)
Eigen::MatrixXd real_coordinates() const
Structure create_superstruc(const Lattice &scel_lat, double map_tol=TOL) const
Shortcut routine to create a supercell structure and fill it with sites.
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...
Index get_linear_index(const Site &site, double tol=TOL) const
config_const_iterator config_cbegin() const
std::string name() const
SCELV_A_B_C_D_E_F/i.
PermuteIterator begin_next_fg_op() const
PrimNeighborList & nlist() const
Access to the primitive neighbor list.
void swap_elem(Index i, Index j)
virtual void read(std::istream &stream)
Print intpolated images in seperate directries.
Index find(const UnitCellCoord &bijk) const
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
std::pair< Eigen::MatrixXi, Eigen::MatrixXi > hermite_normal_form(const Eigen::MatrixXi &M)
Return the hermite normal form, M == H*V.
void enumerate_perturb_configurations(const std::string &background, fs::path CSPECS, double tol=TOL, bool verbose=false, bool print=false)
Array & append(const Array &new_tail)
SymOpOutputIterator find_invariant_subgroup(SymOpIterator begin, SymOpIterator end, SymOpOutputIterator result, double pg_tol=TOL) const
Output the SymOp that leave this lattice invariant.
PermuteIterator to_canonical() const
Returns the operation that applied to *this returns the canonical form.
Permutation const * get_permutation(Index i) const
permute_const_iterator translate_end() const
End iterator over pure translational permutations.
jsonParser & put_obj()
Puts new empty JSON object.
size_type size() const
size of the neighborhood of unit cells
const ClustType & prototype(Index np, Index no) const
Access prototype of orbit (np, no)
Lattice get_reciprocal() const
Return reciprocal lattice.
bool is_canonical() const
const Supercell & get_supercell(Index i) const
const Access supercell by index
Eigen::MatrixXd recip_coordinates() const
config_iterator config_end()
void set_source(const jsonParser &source)
jsonParser & push_back(const T &value)
Puts new valued element at end of array of any type T for which 'jsonParser& to_json( const T &value...
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
config_iterator config_begin()
void set_occ(Index site_l, int val)
Set occupant variable on site l.
const Array< Permutation > & translation_permutations() const
const access to m_trans_permutations. Generates permutations if they don't already exist...
void set_lattice(const Lattice &new_lat)
const Permutation & factor_group_permute(Index i) const
void populate_structure_factor()
Eigen::MatrixXcd m_phase_factor
Index amount_selected() const
Count how many configs are selected in *this.
void set_selected(bool _selected)
bool _eq(const Supercell &B) const
Coordinate coord(Index l, CELL_TYPE lat_mode) const
std::pair< config_const_iterator, bool > insert_canon_config(const Configuration &config)
Insert a configuration that is known to be canonical.
bool operator<(const Supercell &B) const
Supercell & get_supercell() const
Get the Supercell for this Configuration.
const Eigen::Matrix3i & get_transf_mat() const
Index get_b(Index i) const
Index m_nlist_size_at_construction
ReturnArray< int > vacant() const
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
const Permutation & translation_permutation(Index i) const
SymGroupRepID m_perm_symrep_ID
static jsonParser object()
Returns an empty json object.
permute_const_iterator permute_end() const
SymOp from_canonical(double tol=TOL) const
Returns the operation that applied to the canonical form returns *this.
static jsonParser array()
Returns an empty json array.
Object & apply(const Transform &f, Object &obj, Args &&...args)
permute_const_iterator permute_it(Index fg_index, Index trans_index) const
Index size(Index np) const
Number of orbits in OrbitBranch 'np'.
A Configuration represents the values of all degrees of freedom in a Supercell.
const Structure & get_prim() const
const Access to primitive Structure
void print_bijk(std::ostream &stream)