14 #include "casm/external/Eigen/src/Core/Map.h"
15 #include "casm/external/Eigen/src/Core/PermutationMatrix.h"
16 #include "casm/external/Eigen/src/Core/util/Constants.h"
17 #include "casm/external/Eigen/src/Core/util/Meta.h"
24 static bool lex_lt(Eigen::Matrix<long, 3, 3>
const &A,
25 Eigen::Matrix<long, 3, 3>
const &B) {
26 return std::lexicographical_compare(A.data(), A.data() + 9, B.data(),
32 namespace StrucMapping {
39 return pow(3. * abs(atomic_vol) / (4. * M_PI), -2. / 3.) *
53 return pow(3. * abs(atomic_vol) / (4. * M_PI), -2. / 3.) *
69 const std::vector<Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic,
70 Index>> &permutation_group,
74 Eigen::MatrixXd::Zero(disp_matrix.rows(), disp_matrix.cols());
76 auto transformed_disp =
factor_group[i].matrix * disp_matrix;
78 transformed_disp * permutation_group[i];
79 symmetry_preserving_displacement += transformed_and_permuted_disp;
81 symmetry_preserving_displacement =
83 auto new_report = basic_mapping_node;
93 template <
typename OutputIterator>
98 bool const &symmetrize_atomic_cost,
111 for (Eigen::Vector3d
const &translation :
131 calculator.
finalize(node, child_struc, symmetrize_atomic_cost);
133 if (node.
cost < max_cost) {
143 template <
typename OutputIterator>
147 bool const &symmetrize_atomic_cost,
168 Index old_j, new_j, deleted_j;
173 t1.is_partitioned =
false;
199 n2.
irow = std::vector<Index>(++n1.
irow.begin(), n1.
irow.end());
204 for (old_j = 0, new_j = 0; old_j < m; ++old_j, ++new_j) {
205 if (old_j == deleted_j) {
216 for (
Index i = 1; i < m; ++i)
227 if (n1.
icol[deleted_j] >= cN) {
228 for (old_j = n1.
icol.size() - 1; old_j >= 0 && n1.
icol[old_j] >= cN;
238 _calculator.
finalize(*p1, child_struc, symmetrize_atomic_cost);
252 : parent(parent_prim, parent_scel),
255 child(
Lattice((parent_scel.lat_column_mat() *
256 child_scel.inv_lat_column_mat()) *
257 child_prim.lat_column_mat(),
284 isometry((_lat_map.deformation_gradient() * stretch).transpose()),
285 parent(parent_prim,
Lattice(_lat_map.parent_matrix(), parent_prim.tol())),
287 child_prim.lat_column_mat(),
289 Lattice(_lat_map.parent_matrix(), parent_prim.tol())),
290 cost(_lat_map.strain_cost()) {}
390 return std::lexicographical_compare(
401 double _lattice_weight ,
double _max_volume_change ,
404 double _cost_tol ,
double _min_va_frac ,
405 double _max_va_frac )
406 : m_calc_ptr(calculator.
clone()),
407 m_max_volume_change(_max_volume_change),
409 m_cost_tol(
max(1e-10, _cost_tol)),
411 m_lattice_transformation_range(1),
413 m_symmetrize_lattice_cost(false),
414 m_symmetrize_atomic_cost(false) {
435 Index min_vol(0), max_vol(0);
444 double N_sites_c = double(
_n_species(child_struc));
446 if (
calculator().fixed_species().size() > 0) {
449 for (std::string
const &sp : c_info.
names) {
450 if (sp == tcompon) ncompon++;
452 min_vol = ncompon / int(
calculator().fixed_species().begin()->second);
462 double max_va_frac_limit = double(max_n_va) / N_sites_p;
471 double min_n_sites = floor(N_sites_c / (1. - t_min_va_frac) -
TOL);
475 double max_n_sites = ceil(N_sites_c / (1. - t_max_va_frac) +
TOL);
479 min_vol = ceil((min_n_sites - 0.5) / N_sites_p);
483 max_vol = floor((max_n_sites + 0.5) / N_sites_p);
487 if (min_vol != max_vol) {
491 double Nvol = (std::abs(child_struc.
lat_column_mat.determinant() /
492 parent().lat_column_mat.determinant()));
504 Index smallest_possible_vol = ceil((N_sites_c - 0.5) / N_sites_p);
505 min_vol = max<Index>(min_vol, smallest_possible_vol);
506 max_vol = max<Index>(max_vol, smallest_possible_vol);
509 return std::pair<Index, Index>(min_vol, max_vol);
522 double max_lattice_cost,
double min_lattice_cost,
526 min_vol = vol_range.first;
527 max_vol = vol_range.second;
538 std::set<MappingNode> mapping_seed;
539 for (
Index i_vol = min_vol; i_vol <= max_vol; i_vol++) {
540 std::vector<Lattice> lat_vec;
545 lat_vec.push_back(lat);
550 k, max_lattice_cost,
max(min_lattice_cost,
cost_tol()),
553 mapping_seed.insert(std::make_move_iterator(t_seed.begin()),
554 std::make_move_iterator(t_seed.end()));
575 double max_cost ,
double min_cost ,
576 bool keep_invalid )
const {
589 bool c_lat_is_supercell_of_parent;
592 if (!c_lat_is_supercell_of_parent) {
608 derot_c_lat, c_lat,
calculator().point_group().begin(),
617 child_struc, lattice_node, k, max_cost, min_cost, keep_invalid);
624 double max_cost ,
double min_cost ,
625 bool keep_invalid ,
SymOpVector const &child_factor_group)
const {
628 child_struc, vols.first, vols.second, k, max_cost, min_cost, keep_invalid,
636 Index k ,
double max_cost ,
637 double min_cost ,
bool keep_invalid ,
639 int seed_k = 10 + 5 * k;
641 child_struc, seed_k, min_vol, max_vol,
647 keep_invalid,
false, no_partition);
656 Index k ,
double max_cost ,
657 double min_cost ,
bool keep_invalid ,
660 child_struc, {imposed_lat},
667 keep_invalid,
false, no_partition);
675 Index k ,
double max_cost ,
676 double min_cost ,
bool keep_invalid )
const {
677 std::set<MappingNode> mapping_seed;
681 keep_invalid,
false, no_partition);
689 throw std::runtime_error(
"Cannot enumerate lattice of volume " +
691 ", which is out of bounds.\n");
714 for (
auto it = enumerator.
begin(); it != enumerator.
end(); ++it) {
719 lat_vec.push_back(canon_lat);
756 double max_cost ,
double min_cost ,
757 bool keep_invalid ,
bool keep_tail ,
758 bool no_partition )
const {
761 std::set<std::pair<Index, Index>> vol_mismatch;
769 auto it = queue.begin();
770 while (it != queue.end()) {
774 if (it->cost <= (max_cost + this->cost_tol())) {
777 if (!vol_mismatch.count(current->vol_pair())) {
780 if (current->atomic_node.empty()) {
789 std::inserter(queue, current))) {
792 vol_mismatch.insert(current->vol_pair());
794 }
else if (current->is_viable) {
801 if (current->is_valid && current->cost > min_cost && nfound < k) {
810 max_cost = current->cost;
818 if (nfound < k || current->cost <= min_cost) {
819 if (!(no_partition || current->is_partitioned)) {
822 std::inserter(queue, current));
827 if (current->is_valid || keep_invalid) erase =
false;
842 if (erase) queue.erase(current);
854 std::vector<Lattice>
const &_parent_scels,
855 std::vector<Lattice>
const &_child_scels,
Index k,
856 double max_lattice_cost ,
857 double min_lattice_cost ,
861 std::set<MappingNode> result;
864 max_lattice_cost = min_lattice_cost;
866 for (
Lattice const &c_lat : _child_scels) {
869 c_lat_factor_group.reserve(pg_indices.size());
870 for (
Index i : pg_indices) {
871 c_lat_factor_group.push_back(child_factor_group[i]);
874 for (
Lattice const &p_lat : _parent_scels) {
887 if (lattice_map.
strain_cost() > min_lattice_cost) {
891 max_lattice_cost =
max(min_lattice_cost, lattice_map.
strain_cost());
898 result.emplace(
LatticeNode(lattice_map, p_prim_lat, c_prim_lat),
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
double volume() const
Return signed volume of this lattice.
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...
static Lattice cubic(double tol=TOL)
Construct simple cubic primitive cell of unit volume.
double strain_cost() const
LatticeMap const & next_mapping_better_than(double max_cost) const
Data structure for holding supercell enumeration properties.
Representation of a crystal of molecular and/or atomic occupants, and any additional properties....
void deform_coords(Eigen::Ref< const Eigen::Matrix3d > const &_F)
Apply homogeneous deformation gradient tensor _F to lat_column_mat, mol_info, and atom_info.
void rotate_coords(Eigen::Ref< const Eigen::Matrix3d > const &_R)
Apply homogeneous rotation matrix _R to lat_column_mat, mol_info, and atom_info.
Eigen::Matrix3d lat_column_mat
static double isotropic_strain_cost(Eigen::Matrix3d const &_deformation_gradient)
virtual void finalize(MappingNode &_node, SimpleStructure const &child_struc, bool const &symmetrize_atomic_cost=false) const =0
Calculates final mapping score and sets _node.is_valid.
Index max_n_va() const
Return maximum possible number of vacancies in underlying primitive structure.
virtual std::vector< Eigen::Vector3d > translations(MappingNode const &_node, SimpleStructure const &child_struc) const =0
construct list of prospective mapping translations
virtual bool populate_cost_mat(MappingNode &_node, SimpleStructure const &child_struc) const =0
SimpleStructure const & parent() const
SimpleStructure::Info const & struc_info(SimpleStructure const &_struc) const
SymOpVector const & point_group() const
List of point group operations that map parent onto itself (neglecting internal translation)
StrucMapping::FixedSpecies const & fixed_species() const
bool lattices_constrained() const
returns true if the search of parent superlattices is constrained to a pre-specified list
double max_va_frac() const
Returns the maximum fraction of sites allowed to be vacant in the mapping relation Vacancy fraction i...
std::set< MappingNode > _seed_from_vol_range(SimpleStructure const &child_struc, Index k, Index min_vol, Index max_vol, double max_strain_cost, double min_strain_cost, SymOpVector const &child_factor_group={SymOp::identity()}) const
construct partial mapping nodes (with uninitialized atomic_node) based on current settings considers ...
bool symmetrize_atomic_cost() const
void set_max_va_frac(double _max_va)
Sets the maximum fraction of sites allowed to be vacant in the mapping relation Vacancy fraction is u...
std::set< MappingNode > map_ideal_struc(const SimpleStructure &child_struc, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false) const
k-best mappings of ideal child structure onto parent structure Assumes that child_struc and parent_st...
Index lattice_transformation_range() const
Max element considered for integer unimodular matrix transformations (which define orientation relati...
std::set< MappingNode > map_deformed_struc_impose_lattice(const SimpleStructure &child_struc, const Lattice &imposed_lat, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false, SymOpVector const &child_factor_group={SymOp::identity()}) const
k-best mappings of arbitrary child structure onto parent structure imposes simplifying assumption tha...
bool symmetrize_lattice_cost() const
bool _filter_lat(Lattice const &_parent_lat, Lattice const &_child_lat) const
StrucMapCalculatorInterface const & calculator() const
std::pair< Index, Index > _vol_range(const SimpleStructure &child_struc) const
int options() const
returns bit flag of selected options for this StrucMapper
LatMapType m_allowed_superlat_map
LatMapType m_superlat_map
Maps the supercell volume to a vector of Lattices with that volume.
std::set< MappingNode > _seed_k_best_from_super_lats(SimpleStructure const &child_struc, std::vector< Lattice > const &_parent_scels, std::vector< Lattice > const &_child_scels, Index k, double max_strain_cost, double min_strain_cost, SymOpVector const &child_factor_group={SymOp::identity()}) const
generate list of partial mapping seeds (i.e., LatticeNode only) from a list of supercells of the pare...
std::set< MappingNode > map_deformed_struc_impose_lattice_vols(const SimpleStructure &child_struc, Index min_vol, Index max_vol, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false, SymOpVector const &child_factor_group={SymOp::identity()}) const
k-best mappings of arbitrary child structure onto parent structure imposes simplifying assumption tha...
double xtal_tol() const
Tolerance for initializing lattices. For now it is initialized to CASM::TOL.
Index _n_species(SimpleStructure const &sstruc) const
returns number of species in a SimpleStructure given the current calculator settings....
void set_lattice_weight(double _lw)
std::set< MappingNode > map_deformed_struc(const SimpleStructure &child_struc, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false, SymOpVector const &child_factor_group={SymOp::identity()}) const
k-best mappings of arbitrary child structure onto parent structure, without simplifying assumptions I...
double min_va_frac() const
Returns the minimum fraction of sites allowed to be vacant in the mapping relation Vacancy fraction i...
void set_min_va_frac(double _min_va)
Sets the minimum fraction of sites allowed to be vacant in the mapping relation Vacancy fraction is u...
StrucMapper(StrucMapCalculatorInterface const &_calculator, double _lattice_weight=0.5, double _max_volume_change=0.5, int _options=0, double _cost_tol=TOL, double _min_va_frac=0., double _max_va_frac=1.)
Construct and initialize a StrucMapper.
double m_max_volume_change
SimpleStructure const & parent() const
returns reference to parent structure
std::set< MappingNode > map_deformed_struc_impose_lattice_node(const SimpleStructure &child_struc, const LatticeNode &imposed_node, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false) const
k-best mappings of arbitrary child structure onto parent structure imposes simplifying assumption tha...
double lattice_weight() const
double cost_tol() const
Tolerance for determining if two mapping-cost values are identical.
Index k_best_maps_better_than(SimpleStructure const &child_struc, std::set< MappingNode > &queue, Index k=1, double max_cost=StrucMapping::big_inf(), double min_cost=-TOL, bool keep_invalid=false, bool keep_tail=false, bool no_partiton=false) const
low-level function. Takes a queue of mappings and use it to seed a search for k-best total mappings....
std::vector< Lattice > _lattices_of_vol(Index prim_vol) const
Eigen::MatrixXd m_strain_gram_mat
A fake container of supercell matrices.
const Eigen::Matrix3l & transformation_matrix_to_super() const
const Lattice & superlattice() const
std::string to_string(ENUM val)
Return string representation of enum class.
const_iterator end() const
A const iterator to the past-the-last volume.
const_iterator begin() const
A const iterator to the beginning volume, specify here how the iterator should jump through the enume...
double volume(const Lattice &lat)
Returns the volume of a Lattice.
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::Matrix3d polar_decomposition(Eigen::Matrix3d const &mat)
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
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.
Eigen::Matrix3d right_stretch_tensor(const Eigen::Ref< const Eigen::Matrix3d > &deformation_tensor)
Calculates and returns the value of U where F = R*U.
static bool lex_lt(Eigen::Matrix< long, 3, 3 > const &A, Eigen::Matrix< long, 3, 3 > const &B)
static void partition_node(MappingNode const &_node, StrucMapCalculatorInterface const &_calculator, SimpleStructure child_struc, bool const &symmetrize_atomic_cost, OutputIterator it)
static bool initial_atomic_maps(SimpleStructure child_struc, MappingNode const &seed, StrucMapCalculatorInterface const &calculator, double max_cost, bool const &symmetrize_atomic_cost, OutputIterator it)
double big_inf()
Very large value used to denote invalid or impossible mapping.
double atomic_cost_child(const MappingNode &mapped_result, Index Nsites)
Calculate the basis cost function of a MappingNode as the normalized mean-square displacement of its ...
double atomic_cost_parent(const MappingNode &mapped_result, Index Nsites)
Calculate the basis cost function of a MappingNode as the normalized mean-square displacement of its ...
double atomic_cost(const MappingNode &mapped_config, Index Nsites)
Calculate the basis cost function of a MappingNode as the average of atomic_cost_child and atomic_cos...
Lattice equivalent(Lattice const &in_lat, SymOpVector const &point_grp, double compare_tol)
bool check(const Lattice &lat)
bool identical(LatticeNode const &A, LatticeNode const &B, double cost_tol)
returns true if cost values and parent/child supercell transformations are same for A and B
std::vector< Index > invariant_subgroup_indices(const Lattice &lat, SymOpVector const &super_grp)
Construct indices of the subgroup that leaves a lattice unchanged.
bool less(LatticeNode const &A, LatticeNode const &B, double cost_tol)
Compare two LatticeMap objects, based on their mapping cost first, followed by PrimGrid transformatio...
std::pair< OpIterator, Eigen::Matrix3d > is_equivalent_superlattice(const Object &scel, const Object &unit, OpIterator begin, OpIterator end, double tol)
std::vector< SymOp > SymOpVector
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
void swap(ConfigDoF &A, ConfigDoF &B)
double hungarian_method(const Eigen::MatrixXd &cost_matrix, std::vector< Index > &optimal_assignments, const double _tol)
bool float_lexicographical_compare(const Eigen::Ref< const Eigen::MatrixXd > &A, const Eigen::Ref< const Eigen::MatrixXd > &B, double tol)
Floating point lexicographical comparison with tol.
T min(const T &A, const T &B)
bool valid_index(Index i)
INDEX_TYPE Index
For long integer indexing:
T max(const T &A, const T &B)
std::unique_ptr< T > clone(const T &obj)
Structure to encode the solution of a constrained atomic assignmnet problem This describes the permut...
std::vector< Index > irow
'real' indices of rows in the reduced 'cost_mat' When a site assignment {i,j} is added to forced_on,...
Eigen::Vector3d translation
Mapping translation from child to parent Defined such that translation=parent_coord....
bool empty() const
True if cost matrix and assignment vector are uninitialized.
bool operator<(AssignmentNode const &other) const
Compares time_reversal and translation for time_reversal, false is less than true for translation,...
std::vector< Index > assignment
Solution of the assignment problem for the reduced 'cost_mat' An assignment {k,l} in the reduced prob...
Eigen::MatrixXd cost_mat
Cost matrix for an assignment problem, which may be a reduced assignment problem if forced_on....
std::vector< Index > icol
'real' indices of columns in the reduced 'cost_mat' When a site assignment {i,j} is added to forced_o...
std::set< std::pair< Index, Index > > forced_on
parent->child site assignments that have been forced on at this node for element 'el' such that force...
bool time_reversal
time_reversal relationship between child and parent
Class describing the lattice-mapping portion of a particular mapping A general map for child_struc on...
LatticeNode(Lattice const &parent_prim, Lattice const &parent_scel, Lattice const &child_prim, Lattice const &child_scel, Index child_N_atom, double _cost=StrucMapping::big_inf())
Construct with ideal parent_scel and deformed child_scel, which are related by a deformation tensor.
double cost
strain_cost of the LatticeNode
Superlattice parent
PrimGrid for supercell of parent structure The parent structure defines the ideal strain state,...
Superlattice child
PrimGrid for supercell of child structure The child lattice is recorded in its idealized state (de-ro...
Eigen::Matrix3d stretch
stretch tensor that takes child superlattice from its de-rotated, deformed state to its ideal,...
Eigen::Matrix3d isometry
cartesian rotation/reflection/rotoreflection that rotates the child superlattice to its de-rotated,...
void calc()
non-const calc method solves the assignment problem via hungarian_method sets is_viable -> false if n...
bool operator<(MappingNode const &other) const
static MappingNode invalid()
Static constructor to build an invalid MappingNode, can be used as return value when no valid mapping...
AssignmentNode atomic_node
std::vector< Index > atom_permutation
Eigen::Matrix3d const & stretch() const
convenience method to access MappingNode::lattice_node.stretch
bool is_partitioned
true if node has been partitioned into sub-nodes for generalized k-best assignment problem – default ...
Eigen::MatrixXd atom_displacement
3xN matrix of displacements for all sites in parent supercell (Va are included, but set to Zero)
bool is_viable
true if assignment problem is not yet known to be insoluable – default true
double cost
total, finalized cost, populated by a StrucMapCalculator. Not guaranteed to be a linear function of l...
bool is_valid
true if assignment has been checked for physical validity and passes – default false
Eigen::Matrix3d const & isometry() const
convenience method to access MappingNode::lattice_node.isometry
Struct to encode all information about the crystal basis Info may describe the basis in a atomic cont...
std::vector< std::string > names
names[i] is name of species that occupies sites 'i'
Index size() const
Number of sites is defined as names.size()