CASM  1.1.0
A Clusters Approach to Statistical Mechanics
SubOrbits_impl.hh
Go to the documentation of this file.
1 #ifndef CASM_SubOrbits_impl
2 #define CASM_SubOrbits_impl
3 
7 
8 namespace CASM {
9 
10 namespace SubOrbits_impl {
11 
12 struct OpCompare {
13  bool operator()(SymOp const &LHS, SymOp const &RHS) const {
14  return LHS.master_group_index() < RHS.master_group_index();
15  }
16  bool operator()(PermuteIterator const &LHS,
17  PermuteIterator const &RHS) const {
18  return LHS < RHS;
19  }
20 };
21 
22 inline SymOp const &to_sym_op(SymOp const &sym_op) { return sym_op; }
23 
24 inline SymOp to_sym_op(PermuteIterator const &permute_it) {
25  return permute_it.sym_op();
26 }
27 
28 } // namespace SubOrbits_impl
29 
30 // --- MakeSubOrbitGenerators ---
31 //
32 
33 // /// Output generating elements for the sub-orbits corresponding to group ->
34 // subgroup symmetry breaking
35 // ///
36 // /// \param element An orbit generating element w.r.t. [group_begin,
37 // group_end)
38 // /// \param sym_compare SymCompareType functor for comparing elements and
39 // applying symmetry
40 // /// \param result Output iterator outputs sub-orbit generating elements
41 // w.r.t. [subgroup_begin, subgroup_end)
42 // ///
43 // /// The invariant subgroup of element w.r.t. [group_begin, group_end) is
44 // generated as an
45 // /// temporary intermediate. If it is already available use the other
46 // overload. template<typename GroupOpIterator, typename SubgroupOpIterator>
47 // template<typename Element, typename SymCompareType, typename
48 // ElementOutputIterator> ElementOutputIterator
49 // MakeSubOrbitGenerators<GroupOpIterator, SubgroupOpIterator>::operator()(
50 // Element const &element,
51 // SymCompareType const &sym_compare,
52 // ElementOutputIterator result) const {
53 //
54 // typedef typename
55 // std::remove_reference<decltype(*std::declval<GroupOpIterator &>())>::type
56 // OpType; std::vector<OpType> invariant_subgroup;
57 // make_invariant_subgroup(element, m_group_begin, m_group_end, sym_compare,
58 // std::back_inserter(invariant_subgroup)); return (*this)(element,
59 // sym_compare, invariant_subgroup.begin(), invariant_subgroup.end(), result);
60 // }
61 
73 template <typename GroupOpIterator, typename SubgroupOpIterator>
74 template <typename Element, typename CopyApplyFunctionType,
75  typename PrepareFunctionType, typename InvariantSubgroupOpIterator,
76  typename ElementOutputIterator>
77 ElementOutputIterator
79  Element const &element, CopyApplyFunctionType copy_apply_f,
80  PrepareFunctionType prepare_f,
81  InvariantSubgroupOpIterator invariant_subgroup_begin,
82  InvariantSubgroupOpIterator invariant_subgroup_end,
83  ElementOutputIterator result) const {
84  using namespace SubOrbits_impl;
85 
86  // Each vector element will contain the set of operations (a subset of
87  // [group_begin, group-end) that transform "element" into one of the new
88  // sub-orbits:
89  //
90  // suborbit_elements = subgroup_op * group_op * invariant_group_op *
91  // element
92  //
93  // The product (group_op * invariant_group_op) generates all the operations
94  // that transform element into the equivalent elements. Then, for any
95  // particular group_op, the product with subgroup_op generates all the
96  // operations that transform element into a particular sub-orbit. ways that
97  // element transforms into a particular sub-orbit.
98  typedef typename std::remove_cv<typename std::remove_reference<decltype(
99  *std::declval<GroupOpIterator &>())>::type>::type OpType;
100  std::vector<std::set<OpType, OpCompare>> transform_to_suborbit_sets;
101 
102  // For all operations in [group_begin, group_end)
103  for (auto group_it = m_group_begin; group_it != m_group_end; ++group_it) {
104  // Check if the operation (*group_it) has been added to a set
105  bool already_found = false;
106  for (auto const &current_set : transform_to_suborbit_sets) {
107  if (current_set.count(*group_it)) {
108  already_found = true;
109  }
110  }
111  if (already_found) {
112  continue;
113  }
114 
115  // If the operation (*group_it) has not yet been added to a set,
116  // use it to find all operations that transform element to the same
117  // sub-orbit
118  std::set<OpType, OpCompare> next_set;
119  auto invariant_subgroup_it = invariant_subgroup_begin;
120  for (; invariant_subgroup_it != invariant_subgroup_end;
121  ++invariant_subgroup_it) {
122  for (auto subgroup_it = m_subgroup_begin; subgroup_it != m_subgroup_end;
123  ++subgroup_it) {
124  next_set.insert((*subgroup_it) * (*group_it) *
125  (*invariant_subgroup_it));
126  }
127  }
128  transform_to_suborbit_sets.push_back(std::move(next_set));
129  }
130 
131  // Use the first operation in each set to
132  // transform element into a sub-orbit generator.
133  for (auto const &current_set : transform_to_suborbit_sets) {
134  *result++ =
135  prepare_f(copy_apply_f(to_sym_op(*current_set.begin()), element));
136  }
137  return result;
138 }
139 
140 template <typename GroupOpIterator, typename SubgroupOpIterator,
141  typename ElementIterator, typename SymCompareType,
142  typename ElementOutputIterator>
143 ElementOutputIterator make_suborbit_generators(
144  GroupOpIterator group_begin, GroupOpIterator group_end,
145  SubgroupOpIterator subgroup_begin, SubgroupOpIterator subgroup_end,
146  ElementIterator element_begin, ElementIterator element_end,
147  SymCompareType const &sym_compare, ElementOutputIterator result) {
149  group_begin, group_end, subgroup_begin, subgroup_end};
150  typedef typename std::remove_cv<typename std::remove_reference<decltype(
151  *std::declval<GroupOpIterator &>())>::type>::type OpType;
152  auto copy_apply_f = [&](SymOp const &op,
153  typename SymCompareType::Element obj) {
154  return sym_compare.copy_apply(op, obj);
155  };
156  auto prepare_f = [&](typename SymCompareType::Element obj) {
157  return sym_compare.prepare(obj);
158  };
159  for (auto it = element_begin; it != element_end; ++it) {
160  std::vector<OpType> invariant_subgroup;
161  make_invariant_subgroup(*it, group_begin, group_end, sym_compare,
162  std::back_inserter(invariant_subgroup));
163  result = f(*it, copy_apply_f, prepare_f, invariant_subgroup.begin(),
164  invariant_subgroup.end(), result);
165  }
166  return result;
167 }
168 
169 } // namespace CASM
170 
171 #endif
Output the orbit generators necessary to construct the sub-orbits corresponding to group -> subgroup ...
Definition: SubOrbits.hh:11
ElementOutputIterator operator()(Element const &element, CopyApplyFunctionType copy_apply_f, PrepareFunctionType prepare_f, InvariantSubgroupOpIterator invariant_subgroup_begin, InvariantSubgroupOpIterator invariant_subgroup_end, ElementOutputIterator result) const
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
Index master_group_index() const
Index of this operation within the master_group.
std::vector< PermuteIterator > make_invariant_subgroup(ConfigEnumInput const &config_enum_input)
SymOp const & to_sym_op(SymOp const &sym_op)
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
ElementOutputIterator make_suborbit_generators(GroupOpIterator group_begin, GroupOpIterator group_end, SubgroupOpIterator subgroup_begin, SubgroupOpIterator subgroup_end, ElementIterator element_begin, ElementIterator element_end, SymCompareType const &sym_compare, ElementOutputIterator result)
bool operator()(SymOp const &LHS, SymOp const &RHS) const
bool operator()(PermuteIterator const &LHS, PermuteIterator const &RHS) const