CASM  1.1.0
A Clusters Approach to Statistical Mechanics
FillSupercell_impl.hh
Go to the documentation of this file.
1 #ifndef CASM_FillSupercell_impl
2 #define CASM_FillSupercell_impl
3 
7 
8 namespace CASM {
9 
26 template <typename ConfigOutputIterator>
27 ConfigOutputIterator make_all_super_configurations(
28  Configuration const &configuration,
29  std::shared_ptr<Supercell const> shared_supercell,
30  ConfigOutputIterator result) {
31  // There may be equivalent configurations (as infinite crystals) that can not
32  // be obtained via Supercell permutations. This method finds all of these by
33  // identifying the unique ways the primitive configuration's lattice can tile
34  // the supercell.
35  //
36  // notes:
37  // - The prim.factor_group() generates an orbit of equivalent primitive
38  // configuration lattices
39  // - The shared_supercell->factor_group() has possibly lower symmetry,
40  // resulting in sub-orbits
41  // of lattices that cannot be obtained via Supercell permutations
42  // - This will find a prim.factor_group() operation to transform the primitive
43  // configuration
44  // lattice into an element from each sub-orbit.
45  // - Then, for each sub-orbit generating lattice, if it can tile
46  // shared_supercell, it is tiled
47  // into shared_supercell to create an initial configuration which is
48  // permuted to generate equivalents.
49 
50  // --- gather input and make useful functions ---
51  auto const &prim = shared_supercell->prim();
52  auto const &supercell_sym_info = shared_supercell->sym_info();
53  Configuration primitive_configuration = configuration.primitive();
54  SymGroup const &super_group = prim.factor_group();
55 
56  // Subgroup of prim factor group that leaves primitive_configuration's lattice
57  // invariant
58  auto prim_config_lattice_invariant_subgroup = sym::invariant_subgroup(
59  super_group, primitive_configuration.ideal_lattice());
60 
61  // Find primitive configuration lattice sub-orbit generating elements for
62  // super_group -> shared_supercell->factor_group() symmetry breaking
63  //
64  // Function returns true if super_group_op.index() is the minimum of all
65  // generated by:
66  // subgroup_op * super_group_op * invariant_subgroup_op
67  //
68  // If true, sym::copy_apply(super_group_op,
69  // primitive_configuration.ideal_lattice()) is a unique
70  // element of a sub-orbit of lattices
71  auto generates_unique_prim_config_lattice_wrt_supercell_factor_group =
72  [&](SymOp const &super_group_op) {
73  for (auto const &invariant_subgroup_op :
74  prim_config_lattice_invariant_subgroup) {
75  for (auto const &subgroup_op : supercell_sym_info.factor_group()) {
76  if ((subgroup_op * super_group_op * invariant_subgroup_op).index() <
77  super_group_op.index()) {
78  return false;
79  }
80  }
81  }
82  return true;
83  };
84 
85  // Function to find first subgroup_op, if it exists, such that
86  // copy_apply(subgroup_op * super_group_op, prim_config_lattice) fills the
87  // supercell
88  //
89  // TODO: is it necessary to check all supercell factor group ops?
90  auto find_supercell_factor_group_op_such_that_product_fills_supercell =
91  [&](SymOp const &super_group_op) {
92  auto const &super_lattice = shared_supercell->lattice();
93  auto const &prim_config_lattice =
94  primitive_configuration.ideal_lattice();
95  double xtal_tol = prim_config_lattice.tol();
96  auto it = supercell_sym_info.factor_group().begin();
97  auto end = supercell_sym_info.factor_group().end();
98  for (; it != end; ++it) {
99  auto test_op = (*it) * super_group_op;
100  auto test_lattice = sym::copy_apply(test_op, prim_config_lattice);
101  if (is_superlattice(super_lattice, test_lattice, xtal_tol).first) {
102  return it;
103  }
104  }
105  return end;
106  };
107 
108  // --- make all super configurations ---
109 
110  for (auto const &super_group_op : super_group) {
111  if (generates_unique_prim_config_lattice_wrt_supercell_factor_group(
112  super_group_op)) {
113  auto it =
114  find_supercell_factor_group_op_such_that_product_fills_supercell(
115  super_group_op);
116  if (it != supercell_sym_info.factor_group().end()) {
117  Configuration initial_configuration = fill_supercell(
118  (*it) * super_group_op, primitive_configuration, shared_supercell);
119  ConfigEnumByPermutation enumerator{initial_configuration};
120  for (auto const &equivalent_configuration : enumerator) {
121  *result++ = equivalent_configuration;
122  }
123  }
124  }
125  }
126 
127  return result;
128 }
129 
130 } // namespace CASM
131 
132 #endif
SupercellSymInfo const & supercell_sym_info
Enumerate all equivalent Configurations obtained by permuations in a Supercell.
Configuration primitive() const
Return the primitive Configuration.
const Lattice & ideal_lattice() const
SymGroup const & factor_group() const
Subgroup of primitive-cell factor group operations that leave supercell lattice invariant.
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:42
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
double tol() const
Definition: Lattice.hh:195
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.
Definition: Lattice.cc:836
xtal::Coordinate copy_apply(const xtal::SymOp &op, xtal::Coordinate coord)
Copy and apply SymOp to a Coordinate.
Definition: Coordinate.cc:354
SymGroup invariant_subgroup(const SymGroup &super_group, const xtal::Lattice &lat)
Returns the subgroup of the given group that keeps the lattice invariant.
Definition: SymTools.cc:34
Main CASM namespace.
Definition: APICommand.hh:8
Configuration fill_supercell(Configuration const &motif, std::shared_ptr< Supercell const > const &shared_supercell)
ConfigOutputIterator make_all_super_configurations(Configuration const &configuration, std::shared_ptr< Supercell const > shared_supercell, ConfigOutputIterator result)
Make all super configurations that fill a particular supercell.