1 #include <boost/filesystem.hpp>
2 #include <boost/filesystem/fstream.hpp>
3 #include <boost/lexical_cast.hpp>
26 template class SupercellCanonicalForm<CRTPBase<Supercell> >;
27 template class HasPrimClex<
28 DB::Named<Comparisons<SupercellCanonicalForm<CRTPBase<Supercell> > > > >;
31 template class DB::Named<
32 Comparisons<SupercellCanonicalForm<CRTPBase<Supercell> > > >;
37 : m_primclex(RHS.m_primclex),
38 m_shared_prim(RHS.m_shared_prim),
40 m_nlist_size_at_construction(-1) {}
44 : m_primclex(nullptr),
45 m_shared_prim(_shared_prim),
48 transf_mat_init.cast<double>(),
49 crystallography_tol()))),
50 m_nlist_size_at_construction(-1) {}
54 : m_primclex(nullptr),
55 m_shared_prim(_shared_prim),
57 m_nlist_size_at_construction(-1) {
62 <<
"Error in Supercell(PrimClex *_prim, const Lattice &superlattice)"
64 <<
" Bad supercell, the transformation matrix is not integer."
70 err_log() <<
"transformation matrix: \n" << res.second << std::endl;
71 throw std::invalid_argument(
72 "Error constructing Supercell: the transformation matrix is not "
78 const Eigen::Ref<const Eigen::Matrix3l> &transf_mat_init)
83 transf_mat_init.cast<double>(),
84 crystallography_tol()))),
85 m_nlist_size_at_construction(-1) {}
91 m_nlist_size_at_construction(-1) {
96 <<
"Error in Supercell(PrimClex *_prim, const Lattice &superlattice)"
98 <<
" Bad supercell, the transformation matrix is not integer."
100 err_log() <<
"superlattice: \n"
102 err_log() <<
"prim lattice: \n"
104 err_log() <<
"transformation matrix: \n" << res.second << std::endl;
105 throw std::invalid_argument(
106 "Error constructing Supercell: the transformation matrix is not "
138 throw std::runtime_error(
139 "Error in Supercell::set_primclex: primclex should not change");
153 "Error in Supercell::primclex(): does not exist");
215 Eigen::VectorXi max_allowed = Eigen::VectorXi::Zero(n_sublat *
volume());
217 for (
Index b = 0; b < n_sublat; b++) {
218 int sublat_max =
prim().
basis()[b].occupant_dof().size() - 1;
220 Eigen::VectorXi::Constant(
volume(), sublat_max);
253 m_nlist = notstd::make_cloneable<SuperNeighborList>(
269 throw std::runtime_error(
270 "Error using Supercell::operator<(const Supercell& B): "
271 "Only Supercell with shared prim may be compared this way.");
294 throw std::runtime_error(
295 "Error using Supercell::operator==(const Supercell& B): "
296 "Only Supercell with shared prim may be compared this way.");
351 Structure const &prim, std::string supercell_name) {
353 prim.
lattice(), supercell_name);
367 result.set_primclex(&supercell.
primclex());
381 auto it = db.find(
name);
384 if (it != db.end()) {
388 std::vector<std::string> tmp, tokens;
392 boost::split(tmp,
name, boost::is_any_of(
"SCEL_"),
393 boost::token_compress_on);
394 std::copy_if(tmp.begin(), tmp.end(), std::back_inserter(tokens),
395 [](
const std::string &val) { return !val.empty(); });
396 if (tokens.size() != 7) {
397 throw std::invalid_argument(
398 "Error in make_supercell: supercell name format error");
400 }
catch (std::exception &e) {
401 std::string format =
"SCELV_T00_T11_T22_T12_T02_T01";
403 err_log() <<
"expected format: " << format <<
"\n";
404 err_log() <<
"name: |" <<
name <<
"|" << std::endl;
405 err_log() <<
"tokens: " << tokens << std::endl;
406 err_log() <<
"tokens.size(): " << tokens.size() << std::endl;
407 err_log() << e.what() << std::endl;
413 auto cast = [](std::string val) {
return boost::lexical_cast<Index>(val); };
414 T << cast(tokens[1]), cast(tokens[6]), cast(tokens[5]), 0, cast(tokens[2]),
415 cast(tokens[4]), 0, 0, cast(tokens[3]);
416 }
catch (std::exception &e) {
418 err_log() <<
"Could not construct transformation matrix from supercell name"
421 err_log() <<
" tokens: " << tokens << std::endl;
422 err_log() << e.what() << std::endl;
428 return *(scel.
insert().first);
436 std::vector<std::string> tokens;
437 boost::split(tokens,
name, boost::is_any_of(
"."), boost::token_compress_on);
440 if (tokens.size() != 2) {
441 std::string format =
"$CANON_SCEL_NAME.$PRIM_FG_OP";
443 err_log() <<
"expected format: " << format <<
"\n";
445 err_log() <<
"tokens: " << tokens << std::endl;
446 throw std::invalid_argument(
447 "Error in make_shared_supercell: supercell name format error");
451 Index fg_op_index = boost::lexical_cast<Index>(tokens[1]);
458 return std::make_shared<Supercell>(&
primclex, niggli_lat);
466 std::stringstream err_msg;
467 err_msg <<
"Error finding supercell transformation matrix:\n"
468 <<
" Bad supercell, the transformation matrix is not integer.\n\n"
469 <<
"superlattice: \n"
471 <<
"prim lattice: \n"
473 <<
"tolerance: " << tol <<
"\n"
474 <<
"transformation matrix: \n"
475 << res.second <<
"\n";
476 throw std::invalid_argument(err_msg.str());
478 return lround(res.second);
483 std::string name_str;
487 std::stringstream tname;
489 tname << H(0, 0) * H(1, 1) * H(2, 2) <<
"_" << H(0, 0) <<
"_" << H(1, 1)
490 <<
"_" << H(2, 2) <<
"_" << H(1, 2) <<
"_" << H(0, 2) <<
"_" << H(0, 1);
491 name_str.append(tname.str());
522 return bring_within_f;
std::shared_ptr< Structure const > shared_prim
void error(const std::string &what)
PrimClex is the top-level data structure for a CASM project.
Structure specifies the lattice and atomic basis of a crystal.
const SymGroup & point_group() const
const Lattice & lattice() const
const std::vector< xtal::Site > & basis() const
const MasterSymGroup & factor_group() const
Represents a supercell of the primitive parent crystal structure.
Index sublat(Index linear_index) const
Return the sublattice index for a linear index.
Index linear_index(const Coordinate &coord, double tol=TOL) const
Given a Coordinate and tolerance, return linear index into Configuration.
SupercellSymInfo m_sym_info
UnitCellCoord uccoord(Index linear_index) const
Return the integral coordinates corresponding to a linear index.
Eigen::VectorXi max_allowed_occupation() const
returns maximum allowed occupation bitstring – used for initializing enumeration counters
const PrimClex & primclex() const
Use while transitioning Supercell to no longer need a PrimClex const *
double crystallography_tol() const
Coordinate coord(Index linear_index) const
Return the linear index corresponding to integral coordinates.
bool has_primclex() const
Use while transitioning Supercell to no longer need a PrimClex const *
bool operator<(const Supercell &B) const
Supercell(const Supercell &RHS)
const Lattice & lattice() const
The super lattice.
const SuperNeighborList & nlist() const
Returns the SuperNeighborList.
void set_primclex(PrimClex const *primclex_ptr) const
Use while transitioning Supercell to no longer need a PrimClex const *
Eigen::Matrix3l transf_mat() const
std::pair< DB::DatabaseIterator< Supercell >, bool > insert() const
Insert the canonical form of this into the database.
PrimClex const * m_primclex
Index m_nlist_size_at_construction
std::shared_ptr< Structure const > m_shared_prim
notstd::cloneable_ptr< SuperNeighborList > m_nlist
SuperNeighborList, mutable for lazy construction.
Index volume() const
Return number of primitive cells that fit inside of *this.
bool eq_impl(const Supercell &B) const
const SymGroup & factor_group() const
const Structure & prim() const
std::shared_ptr< Structure const > const & shared_prim() const
const SupercellSymInfo & sym_info() const
std::string generate_name_impl() const
Return supercell name.
A class that collects all symmetry information for for performing symmetry transformations on the sit...
const xtal::UnitCellCoordIndexConverter & unitcellcoord_index_converter() const
UnitCellCoordIndexConverter for this superstructure/primstructure pair Used to convert from lattice t...
SymGroup const & factor_group() const
Subgroup of primitive-cell factor group operations that leave supercell lattice invariant.
const xtal::UnitCellIndexConverter & unitcell_index_converter() const
UnitCellIndexConverter for this superlattice/primlattice pair Used to convert from lattice translatio...
const xtal::Lattice & supercell_lattice() const
const reference to supercell lattice
Eigen::Matrix3l transformation_matrix_to_super() const
long-int transformation from primitive lattice vectors to supercell lattice vectors supercell_lattice...
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Represents cartesian and fractional coordinates.
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
const Lattice & superlattice() const
Coordinate coordinate(const PrimType &prim) const
Get corresponding coordinate.
static UnitCellCoord from_coordinate(const PrimType &, const Coordinate &coord, double tol)
Index total_sites() const
Returns the total number of sites within the superlattice.
std::string to_string(ENUM val)
Return string representation of enum class.
std::pair< bool, Eigen::Matrix3d > is_superlattice(const Lattice &scel, const Lattice &unit, double tol)
Check if scel is a superlattice of unitcell unit and some integer transformation matrix T.
Eigen::CwiseUnaryOp< decltype(Local::lround_l< typename Derived::Scalar >), const Derived > lround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXl.
std::pair< Eigen::MatrixXi, Eigen::MatrixXi > hermite_normal_form(const Eigen::MatrixXi &M)
Return the hermite normal form, M == H*V.
Eigen::Matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > inverse(const Eigen::MatrixBase< Derived > &M)
Return the integer inverse matrix of an invertible integer matrix.
DB::Database< T > & db() const
std::shared_ptr< PrimNeighborList > const & shared_nlist() const
Access to the primitive neighbor list as a shared resource.
double crystallography_tol() const
Get the crystallography_tol.
const PrimType & prim() const
const Access to primitive Structure
std::shared_ptr< Supercell > make_shared_supercell(const PrimClex &primclex, std::string name)
std::string generate_name(const Eigen::Matrix3l &transf_mat)
Make hermite normal form name [deprecated].
const Supercell & make_supercell(const PrimClex &primclex, std::string name)
xtal::Superlattice make_superlattice_from_supercell_name(Structure const &prim, std::string supercell_name)
Construct a Superlattice from the supercell name.
std::string canonical_scelname(const Structure &prim, const Lattice &superlat)
Make canonical supercell name name [deprecated].
std::string scelname(const Structure &prim, const Lattice &superlat)
Make supercell name name [deprecated].
std::string make_canonical_supercell_name(Structure const &prim, xtal::Superlattice const &superlattice)
Make the canonical supercell name from a Superlattice.
std::string make_supercell_name(Structure const &prim, xtal::Superlattice const &superlattice)
Make the supercell name from a Superlattice.
Supercell & apply(const SymOp &op, Supercell &scel)
Apply symmetry operation to Supercell.
Eigen::Matrix3l transf_mat(const Lattice &prim_lat, const Lattice &super_lat)
GenericVectorXdScelFormatter lattice()
xtal::Coordinate copy_apply(const xtal::SymOp &op, xtal::Coordinate coord)
Copy and apply SymOp to a Coordinate.
Lattice equivalent(Lattice const &in_lat, SymOpVector const &point_grp, double compare_tol)
Index operation_index(const Lattice &lat, SymOpVector const &g)
bool is_equivalent(const Lattice &ref_lattice, const Lattice &other)
Check if ref_lattice = other*U, where U is unimodular.
IntegralCoordinateWithin_f make_bring_within_f(const Supercell &scel)
Make IntegralCoordinateWithin_f for Supercell [deprecated].
Lattice niggli(const Lattice &in_lat, double compare_tol, bool keep_handedness=false)
MappingNode copy_apply(PermuteIterator const &_it, MappingNode const &_node, bool transform_cost_mat=true)
Reorders the permutation and compounds the spatial isometry (rotation.
GenericDatumFormatter< std::string, DataObject > name()
SupercellSymInfo make_supercell_sym_info(Structure const &prim, Lattice const &super_lattice)
INDEX_TYPE Index
For long integer indexing:
Matrix< long int, 3, 3 > Matrix3l