1 #ifndef CASM_Orbit_impl
2 #define CASM_Orbit_impl
4 #include <boost/iterator/transform_iterator.hpp>
19 namespace Orbit_impl {
34 const std::vector<std::vector<Index>> &tmp_eq_map,
const SymGroup &g)
38 for (
Index j = 0; j < tmp_eq_map[
b].size(); ++j) {
41 }
catch (
const std::exception &e) {
43 "Error in Orbit constructor: Failed constructing EqMapRow.");
52 return this->values < other.
values;
62 for (
Index b = 0; b < tmp_eq_map.size(); ++b) {
63 map.emplace(
a, b, tmp_eq_map, g);
65 }
catch (
const std::exception &e) {
67 "Error in Orbit constructor: Failed constructing RelEqMap.");
72 std::set<EqMapRow>
map;
77 std::ostream &
operator<<(std::ostream &sout,
const RelEqMap &map);
90 template <
typename _SymCompareType>
94 : m_generating_group(generating_group),
95 m_sym_compare(sym_compare),
96 m_invariants(sym_compare.make_invariants(generating_element)) {
122 std::map<Element, std::set<Index>, decltype(
compare)> t_equiv(
compare);
124 for (
Index i = 0; i < g.size(); i++) {
129 }
catch (
const std::exception &e) {
131 "Error in Orbit constructor: Failed generating unique equivalents.");
135 std::vector<Element> tmp_element;
136 std::vector<std::vector<Index>> tmp_equivalence_map;
140 for (
auto const &_equiv : t_equiv) {
141 tmp_element.push_back(_equiv.first);
142 tmp_equivalence_map.emplace_back();
143 for (
Index op_i : _equiv.second) {
144 tmp_equivalence_map.back().push_back(g.
ind_prod(op_i, first2proto));
149 for (
Index j = 1; j < tmp_equivalence_map.size(); ++j) {
150 if (tmp_equivalence_map[0].
size() != tmp_equivalence_map[j].
size()) {
152 "Error in Orbit constructor: equivalence map is not rectangular");
155 }
catch (
const std::exception &e) {
157 std::string(
"Error in Orbit constructor: ") +
158 "Failed generating initial equivalence map: " + e.what());
168 for (
Index a = 1; a < tmp_equivalence_map.size(); ++a) {
173 best = std::move(test);
176 }
catch (
const std::exception &e) {
178 "Error in Orbit constructor: Failed generating sorted equivalence "
184 Index newproto_i = best.
map.begin()->b;
187 for (
const auto &row : best.
map) {
189 Index proto2i = *(row.values.begin());
192 m_sym_compare.copy_apply(g[proto2i], tmp_element[newproto_i]));
196 tmp_element[newproto_i]));
199 for (
const auto &cg_j : best.
map.begin()->values) {
203 m_sym_compare.copy_apply(g[value], tmp_element[newproto_i]));
209 }
catch (
const std::exception &e) {
211 "Error in Orbit constructor: Failed copying sorted elements and "
217 "Error in Orbit constructor: First equivalence map element is not "
223 template <
typename _SymCompareType>
226 for (
auto it = m_element.begin(); it != m_element.end(); ++it) {
227 *it = m_sym_compare.copy_apply(op, *it);
231 for (
auto it = m_equivalence_map.begin(); it != m_equivalence_map.end();
233 for (
auto op_it = it->begin(); op_it != it->end(); ++op_it) {
245 template <
typename _SymCompareType>
247 return m_sym_compare.inter_orbit_compare(prototype(), invariants(),
251 template <
typename _SymCompareType>
253 if (equivalence_map().size() == 0)
255 "In Orbit::_construct_canonization_rep(), equivalence_map is "
256 "uninitialized or empty! Cannot continue.");
263 m_canonization_rep_ID =
264 equivalence_map()[0][0].master_group().allocate_representation();
266 for (
Index j = 0; j < equivalence_map()[0].size(); j++) {
267 std::unique_ptr<SymOpRepresentation> new_rep =
269 .canonical_transform(
270 m_sym_compare.copy_apply(equivalence_map()[0][j], prototype()))
273 for (
Index i = 0; i < equivalence_map().size(); i++) {
274 equivalence_map()[i][j].set_rep(m_canonization_rep_ID, *new_rep);
294 template <
typename OrbitIterator,
typename Element>
295 OrbitIterator
find_orbit(OrbitIterator begin, OrbitIterator end, Element e) {
296 typedef typename std::iterator_traits<OrbitIterator>::value_type orbit_type;
297 typedef typename orbit_type::InvariantsType InvariantsType;
298 const auto &sym_compare = begin->sym_compare();
299 auto e_invariants = sym_compare.make_invariants(e);
302 auto compare = [&](
const InvariantsType &A,
const InvariantsType &B) {
303 return sym_compare.invariants_compare(A, B);
311 auto contains = [&](
const orbit_type &orbit) {
return orbit.contains(e); };
312 auto res = std::find_if(_range.first.base(), _range.second.base(),
contains);
313 if (res == _range.second.base()) {
InvariantsType const & invariants() const
Orbit(Element generating_element, SymGroup const &generating_group, SymCompareType const &sym_compare)
Construct an Orbit from a generating_element Element, using provided symmetry group.
std::vector< Element > m_element
All symmetrically equivalent elements (excluding those that SymCompare equivalent)
void _construct_canonization_rep() const
Orbit & apply_sym(const SymOp &op)
Apply symmetry to Orbit.
const Element & prototype() const
Identical to element(0)
multivector< SymOp >::X< 2 > m_equivalence_map
element(i) compares equivalent to prototype().copy_apply(m_equivalence_map[i][j]) for all j
const SymGroup & generating_group() const
Return the generating SymGroup.
bool operator<(const Orbit &B) const
Compare orbits, using SymCompareType::inter_orbit_compare.
typename _SymCompareType::Element Element
SymCompareType m_sym_compare
Functor used to check compare Element, including symmetry rules, and make canonical forms.
_SymCompareType SymCompareType
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Index ind_inverse(Index i) const
Get index of operation that is inverse of operation at(i)
Index ind_prod(Index i, Index j) const
Get index of operation that is result of multiplication of at(i)*at(j)
static SymGroupRepID identity(Index dim)
Static function to construct an ID for identity representations.
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
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.
std::ostream & operator<<(std::ostream &sout, const RelEqMap &map)
bool compare(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Compare ClusterInvariants.
OrbitIterator find_orbit(OrbitIterator begin, OrbitIterator end, Element e)
Find orbit containing an element in a range of Orbit.
InvariantsIterator< OrbitIterator > invariants_iterator(OrbitIterator orbit_it)
Convert an Orbit iterator to an invariants iterator.
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
INDEX_TYPE Index
For long integer indexing:
bool operator<(const EqMapRow &other) const
EqMapRow(Index _a, Index _b, const std::vector< std::vector< Index >> &tmp_eq_map, const SymGroup &g)
RelEqMap(Index _a, const std::vector< std::vector< Index >> &tmp_eq_map, const SymGroup &g)
generate eq_map row for tmp_element[b] relative to tmp_element[a]
bool operator<(const RelEqMap &other) const