CASM  1.1.0
A Clusters Approach to Statistical Mechanics
ClusterOrbits_impl.hh
Go to the documentation of this file.
1 #ifndef CASM_ClusterOrbits_impl
2 #define CASM_ClusterOrbits_impl
3 
16 
17 namespace CASM {
18 
19 /* -- Cluster Orbit generating function definitions
20  * ------------------------------------- */
21 
37 template <typename OutputIterator>
38 OutputIterator neighborhood(Structure const &unit, double max_radius,
39  SiteFilterFunction site_filter,
40  OutputIterator result, double xtal_tol) {
41  auto dim = unit.lattice().enclose_sphere(max_radius);
42  EigenCounter<Eigen::Vector3i> grid_count(-dim, dim,
43  Eigen::Vector3i::Constant(1));
44  xtal::Coordinate lat_point(unit.lattice());
45  const auto &basis = unit.basis();
46 
47  do {
48  lat_point.frac() = grid_count().cast<double>();
49 
50  for (auto it = basis.begin(); it != basis.end(); ++it) {
51  if (!site_filter(*it)) {
52  continue;
53  }
54 
55  xtal::Coordinate test(*it + lat_point);
56  auto within_radius = [&](const xtal::Coordinate &coord) {
57  return test.dist(coord) < max_radius;
58  };
59  if (std::any_of(basis.begin(), basis.end(), within_radius)) {
60  *result++ = xtal::UnitCellCoord::from_coordinate(unit, test, xtal_tol);
61  }
62  }
63  } while (++grid_count);
64  return result;
65 }
66 
82 template <typename OutputIterator>
83 OutputIterator neighborhood(IntegralCluster const &phenomenal,
84  double cutoff_radius,
85  SiteFilterFunction site_filter,
86  bool include_phenomenal_sites,
87  OutputIterator result, double xtal_tol) {
88  const auto &prim = phenomenal.prim();
89 
90  int max_low_shift = 0;
91  int max_high_shift = 0;
92  for (auto it = phenomenal.begin(); it != phenomenal.end(); it++) {
93  Eigen::Vector3l vec = it->unitcell();
94  if (vec.maxCoeff() > max_high_shift) {
95  max_high_shift = vec.maxCoeff();
96  }
97  if (vec.minCoeff() < max_low_shift) {
98  max_low_shift = vec.minCoeff();
99  }
100  }
101 
102  // make grid counter
103  auto dim = prim.lattice().enclose_sphere(cutoff_radius);
104  Eigen::Vector3i ones(1, 1, 1);
106  -dim + (max_low_shift * ones).cast<int>(),
107  dim + (max_high_shift * ones).cast<int>(), Eigen::Vector3i::Constant(1));
108 
110  xtal::Coordinate lat_point(prim.lattice());
111 
112  const auto &basis = prim.basis();
113 
114  do {
115  lat_point.frac() = grid_count().cast<double>();
116 
117  for (auto it = basis.begin(); it != basis.end(); ++it) {
118  if (!site_filter(*it)) {
119  continue;
120  }
121 
122  xtal::Coordinate test{*it + lat_point};
123 
124  if (!include_phenomenal_sites) {
125  auto is_almost_equal = [&](const xtal::UnitCellCoord &uccoord) {
126  return test.dist(uccoord.coordinate(prim)) < xtal_tol;
127  };
128  if (std::any_of(phenomenal.begin(), phenomenal.end(),
129  is_almost_equal)) {
130  continue;
131  }
132  }
133 
134  auto within_radius = [&](const xtal::UnitCellCoord &uccoord) {
135  return test.dist(uccoord.coordinate(prim)) < cutoff_radius;
136  };
137  if (std::any_of(phenomenal.begin(), phenomenal.end(), within_radius)) {
138  *result++ = xtal::UnitCellCoord::from_coordinate(prim, test, xtal_tol);
139  }
140  }
141  } while (++grid_count);
142  return result;
143 }
144 
156 template <typename OrbitType, typename OutputIterator>
157 OutputIterator local_orbit_neighborhood(const OrbitType &orbit,
158  OutputIterator result) {
159  for (const auto &equiv : orbit) {
160  for (const auto &site : equiv) {
161  *result++ = site;
162  }
163  }
164  return result;
165 }
166 
177 template <typename ClusterOrbitIterator, typename OutputIterator>
178 OutputIterator local_neighborhood(ClusterOrbitIterator begin,
179  ClusterOrbitIterator end,
180  OutputIterator result) {
181  // create a neighborhood of all UnitCellCoord that an Orbitree touches
182  for (auto it = begin; it != end; ++it) {
183  result = local_orbit_neighborhood(*it, result);
184  }
185  return result;
186 }
187 
194 template <typename OrbitType>
195 bool has_local_neighborhood_overlap(std::vector<OrbitType> const &local_orbits,
196  Eigen::Matrix3i const &transf_mat) {
197  // use set of pair: <b, lattice site index> to check for site overlap
198  std::set<std::pair<Index, Index>> present;
200  for (auto const &orbit : local_orbits) {
201  for (auto const &cluster : orbit) {
202  for (auto const &uccoord : cluster) {
203  auto res =
204  present.emplace(uccoord.sublattice(), convert[uccoord.unitcell()]);
205  // if no insert took place, there is an overlap, so return true
206  if (!res.second) {
207  return true;
208  }
209  }
210  }
211  }
212  // if no set insertion collision then no overlap
213  return false;
214 }
215 
223 template <typename OrbitType>
224 std::vector<Eigen::Matrix3i> viable_supercells(
225  std::vector<OrbitType> &local_orbits,
226  const std::vector<Eigen::Matrix3i> &transf_mat_options) {
227  std::vector<Eigen::Matrix3i> results;
228  for (auto &transf_mat : transf_mat_options) {
229  if (!has_local_neighborhood_overlap(local_orbits, transf_mat)) {
230  results.push_back(transf_mat);
231  }
232  }
233  return results;
234 }
235 
236 /* -- Custom clusters --- */
237 
249 template <typename OrbitType>
251  typename OrbitType::Element cluster,
252  OrbitGenerators<OrbitType> &generators) {
253  typedef typename OrbitType::Element cluster_type;
254  typedef OrbitType orbit_type;
255 
256  // Construct a functor that returns takes a cluster and returns it in a
257  // canonical form
258  CanonicalGenerator<orbit_type> canonical_generator(generators.group,
259  generators.sym_compare);
260 
261  // SubClusterGenerator allows iterating over subclusters (includes null and
262  // original cluster)
265 
266  while (it != end) {
267  generators.elements.insert(canonical_generator(*it++));
268  }
269 
270  return generators;
271 }
272 
273 /* -- Cluster Orbit access/usage function definitions
274  * ------------------------------------- */
275 
281 template <typename OrbitIterator>
282 std::pair<OrbitIterator, OrbitIterator> orbit_branch(OrbitIterator begin,
283  OrbitIterator end,
284  Index size) {
285  auto branch_begin = std::find_if(
286  begin, end, [&](const typename OrbitIterator::value_type &orbit) {
287  return orbit.prototype().size() == size;
288  });
289 
290  auto branch_end = std::find_if(
291  branch_begin, end, [&](const typename OrbitIterator::value_type &orbit) {
292  return orbit.prototype().size() == size + 1;
293  });
294 
295  return std::pair<OrbitIterator, OrbitIterator>(branch_begin, branch_end);
296 }
297 
298 // ------- Generating elements generation ------------------------------------
299 
300 namespace {
301 
310 template <typename OrbitType>
311 OrbitGenerators<OrbitType> &_insert_null_cluster_generator(
312  const Structure &prim, OrbitGenerators<OrbitType> &generators) {
313  typedef typename OrbitType::Element cluster_type;
314 
315  // create a prototype cluster
316  cluster_type test(prim);
317  generators.insert(test);
318 
319  return generators;
320 }
321 
331 template <typename OrbitType>
332 OrbitGenerators<OrbitType> &_insert_asymmetric_unit_generators(
333  const Structure &prim, OrbitGenerators<OrbitType> &generators) {
334  typedef typename OrbitType::Element cluster_type;
335 
336  // for all sites in the basis
337  for (int i = 0; i < prim.basis().size(); i++) {
338  // create a prototype cluster
339  cluster_type test(prim);
340  test.elements().emplace_back(i, xtal::UnitCell(0, 0, 0));
341  generators.insert(test);
342  }
343 
344  return generators;
345 }
346 
360 template <typename OrbitType, typename OrbitGeneratorIterator>
361 OrbitGenerators<OrbitType> &_insert_next_orbitbranch_generators(
362  OrbitGeneratorIterator begin, OrbitGeneratorIterator end,
363  const OrbitBranchSpecs<OrbitType> &specs,
364  OrbitGenerators<OrbitType> &generators, std::ostream &status) {
365  typedef typename OrbitType::Element cluster_type;
366 
367  const auto &filter = specs.filter();
368 
369  // print status messages
370  std::string clean(100, ' ');
371 
372  // contains a pair of iterators over candidate UnitCellCoord
373  auto candidate_sites = specs.candidate_sites();
374 
375  // for each orbit generator of size n
376  for (auto orbit_generator_it = begin; orbit_generator_it != end;
377  ++orbit_generator_it) {
378  Index orig_size = generators.elements.size();
379 
380  // print status messages
381  status << clean << '\r' << " Calculating orbit branch "
382  << orbit_generator_it->size() + 1 << ": Expanding orbit "
383  << std::distance(begin, orbit_generator_it) << " / "
384  << std::distance(begin, end) << " of branch "
385  << orbit_generator_it->size() << "." << std::flush;
386 
387  // by looping over each site in the grid,
388  for (auto site_it = candidate_sites.first;
389  site_it != candidate_sites.second; ++site_it) {
390  // don't duplicate sites in cluster
391  if (contains(*orbit_generator_it, *site_it)) {
392  continue;
393  }
394 
395  // create a test cluster from prototype
396  cluster_type test(*orbit_generator_it);
397 
398  // add the new site
399  test.elements().push_back(*site_it);
400  // filter clusters
401  if (!filter(test)) {
402  continue;
403  }
404 
405  // try inserting test (only uniques will be kept)
406  generators.insert(test);
407  }
408 
409  status << " New orbits: " << generators.elements.size() - orig_size
410  << std::endl;
411  }
412 
413  return generators;
414 }
415 } // namespace
416 
417 // ------- Generating asymmetric unit orbits ---------------------------------
418 
426 template <typename OrbitType, typename OrbitOutputIterator>
427 OrbitOutputIterator make_asymmetric_unit(
428  const OrbitBranchSpecs<OrbitType> &specs, OrbitOutputIterator result,
429  std::ostream &status) {
430  IntegralCluster empty(specs.prim());
431  const SymGroup &g = specs.generating_group();
432 
433  // generate the null cluster orbit
434  OrbitType null_cluster_orbit(empty, g, specs.sym_compare());
435 
436  // Use it to generate the first orbit branch
437  std::vector<OrbitType> orbits(1, null_cluster_orbit);
438  return make_next_orbitbranch(orbits.cbegin(), orbits.cend(), specs, result,
439  status);
440 }
441 
451 template <typename OrbitType, typename OrbitInputIterator,
452  typename OrbitOutputIterator>
453 OrbitOutputIterator make_next_orbitbranch(
454  OrbitInputIterator begin, OrbitInputIterator end,
455  const OrbitBranchSpecs<OrbitType> &specs, OrbitOutputIterator result,
456  std::ostream &status) {
458  OrbitGenerators<OrbitType> generators(specs.generating_group(),
459  specs.sym_compare());
460 
463  _insert_next_orbitbranch_generators(prototype_iterator(begin),
464  prototype_iterator(end), specs,
465  generators, status);
466 
468  return generators.make_orbits(result);
469 }
470 
478 template <typename OrbitBranchSpecsIterator, typename OrbitOutputIterator>
479 OrbitOutputIterator make_orbits(
480  OrbitBranchSpecsIterator begin, OrbitBranchSpecsIterator end,
481  const std::vector<IntegralClusterOrbitGenerator> &custom_generators,
482  OrbitOutputIterator result, std::ostream &status) {
483  if (begin == end) {
484  throw libcasm_runtime_error(
485  "Error in make_orbits: No OrbitBranchSpecs (begin==end)");
486  }
487 
488  typedef typename OrbitOutputIterator::container_type container_type;
489  typedef typename container_type::value_type orbit_type;
490 
491  // -- Collect orbit generating elements for each branch, to generate the next
492  // branch
493  std::vector<OrbitGenerators<orbit_type>> generators;
494  generators.reserve(std::distance(begin, end));
495 
496  // -- Combines all orbit branches
497  OrbitGenerators<orbit_type> all_generators(begin->generating_group(),
498  begin->sym_compare());
499 
500  // branches should be ordered already, so insert with end as hint
501  auto insert_branch = [&](OrbitGenerators<orbit_type> &all,
502  OrbitGenerators<orbit_type> &branch) {
503  for (auto it = branch.elements.begin(); it != branch.elements.end(); ++it) {
504  all.elements.insert(all.elements.end(), *it);
505  }
506  };
507  // -- construct null cluster orbit
508  status << " Adding null orbit branch." << std::flush;
509 
510  auto specs_it = begin;
511  if (specs_it != end) {
512  generators.emplace_back(begin->generating_group(), begin->sym_compare());
513  _insert_null_cluster_generator(specs_it->prim(), generators.back());
514  ++specs_it;
515  insert_branch(all_generators, generators.back());
516  }
517  status << " New orbits: 1" << std::endl;
518 
519  // -- construct additional branches
520  // print status messages
521  std::string clean(100, ' ');
522 
523  // generate orbit branches 1+ using the previously generated branch:
524  auto prev_gen = generators.begin();
525  while (specs_it != end) {
526  generators.emplace_back(specs_it->generating_group(),
527  specs_it->sym_compare());
528  _insert_next_orbitbranch_generators(prev_gen->elements.begin(),
529  prev_gen->elements.end(), *specs_it,
530  generators.back(), status);
531  ++specs_it;
532  ++prev_gen;
533  insert_branch(all_generators, generators.back());
534  }
535 
536  // -- add custom orbit generators
537 
538  for (int i = 0; i < custom_generators.size(); ++i) {
539  status << " Adding custom orbit " << i << "/" << custom_generators.size()
540  << "." << std::flush;
541  if (custom_generators[i].include_subclusters) {
542  status << " Include subclusters." << std::flush;
543  }
544 
545  Index orig_size = all_generators.elements.size();
546 
547  all_generators.insert(custom_generators[i].prototype);
548  if (custom_generators[i].include_subclusters) {
549  insert_subcluster_generators(custom_generators[i].prototype,
550  all_generators);
551  }
552 
553  status << " New orbits: " << all_generators.elements.size() - orig_size
554  << std::endl;
555  }
556 
557  status << std::endl;
558 
559  // make orbits
560  return all_generators.make_orbits(result);
561 }
562 
563 /* -- SymCompareType-Specific IntegralCluster Orbit functions --- */
564 
583 template <typename OrbitOutputIterator>
585  std::shared_ptr<Structure const> prim_ptr,
586  SiteFilterFunction const &site_filter, double xtal_tol,
587  OrbitOutputIterator result, std::ostream &status) {
588  typedef PrimPeriodicOrbit<IntegralCluster> orbit_type;
589  typedef typename orbit_type::Element cluster_type;
590  typedef PrimPeriodicSymCompare<IntegralCluster> symcompare_type;
591 
592  SymGroup const &generating_grp = prim_ptr->factor_group();
593 
594  symcompare_type sym_compare(prim_ptr, xtal_tol);
595 
596  std::vector<xtal::UnitCellCoord> candidate_sites;
597  for (int i = 0; i < prim_ptr->basis().size(); ++i) {
598  if (site_filter(prim_ptr->basis()[i])) {
599  candidate_sites.emplace_back(i, 0, 0, 0);
600  }
601  }
602 
604  *prim_ptr, candidate_sites.begin(), candidate_sites.end(), generating_grp,
605  [](cluster_type const &test) { return true; }, sym_compare);
606 
607  return make_asymmetric_unit(specs, result, status);
608 }
609 
632 template <typename OrbitOutputIterator>
633 OrbitOutputIterator make_prim_periodic_orbits(
634  std::shared_ptr<Structure const> prim_ptr,
635  std::vector<double> const &max_length,
636  std::vector<IntegralClusterOrbitGenerator> const &custom_generators,
637  SiteFilterFunction const &site_filter, double xtal_tol,
638  OrbitOutputIterator result, std::ostream &status) {
639  typedef PrimPeriodicOrbit<IntegralCluster> orbit_type;
640  typedef typename orbit_type::Element cluster_type;
641  typedef PrimPeriodicSymCompare<IntegralCluster> symcompare_type;
642 
643  SymGroup const &generating_grp = prim_ptr->factor_group();
644 
645  symcompare_type sym_compare(prim_ptr, xtal_tol);
646 
647  // collect OrbitBranchSpecs here
648  std::vector<OrbitBranchSpecs<orbit_type>> specs;
649 
650  // collect the environment of sites here
651  std::vector<xtal::UnitCellCoord> candidate_sites;
652 
653  // --- add specs for null cluster orbit ------------------
654  if (max_length.size() >= 1) {
655  specs.emplace_back(
656  *prim_ptr, candidate_sites.begin(), candidate_sites.end(),
657  generating_grp, [](cluster_type const &test) { return true; },
658  sym_compare);
659  }
660 
661  // --- add specs for asymmetric unit orbit ------------------
662  if (max_length.size() >= 2) {
663  for (int i = 0; i < prim_ptr->basis().size(); ++i) {
664  if (site_filter(prim_ptr->basis()[i])) {
665  candidate_sites.emplace_back(i, 0, 0, 0);
666  }
667  }
668  specs.emplace_back(
669  *prim_ptr, candidate_sites.begin(), candidate_sites.end(),
670  generating_grp, [](cluster_type const &test) { return true; },
671  sym_compare);
672  }
673 
674  // --- add specs for additional orbit branches ------------------
675  for (auto it = max_length.begin() + 2; it != max_length.end(); ++it) {
676  // construct the neighborhood of sites to consider for the orbit
677  candidate_sites.clear();
678  neighborhood(*prim_ptr, *it, site_filter,
679  std::back_inserter(candidate_sites), xtal_tol);
680 
681  auto max_length_filter = [=](cluster_type const &test) {
682  return sym_compare.make_invariants(test).displacement().back() < *it;
683  };
684 
685  specs.emplace_back(*prim_ptr, candidate_sites.begin(),
686  candidate_sites.end(), generating_grp, max_length_filter,
687  sym_compare);
688  }
689 
690  // now generate orbits
691  return make_orbits(specs.begin(), specs.end(), custom_generators, result,
692  status);
693 }
694 
708 template <typename OutputIterator>
710  PrimPeriodicOrbit<IntegralCluster> const &orbit, OutputIterator result) {
711  for (const auto &equiv : orbit) {
712  // UnitCellCoord for all sites in cluster
713  std::vector<xtal::UnitCellCoord> coord(equiv.begin(), equiv.end());
714 
715  // UnitCellCoord for 'flowertree': all clusters that touch origin unitcell
716  // (includes translationally equivalent clusters)
717  for (int ns_i = 0; ns_i < coord.size(); ++ns_i) {
718  for (int ns_j = 0; ns_j < coord.size(); ++ns_j) {
719  *result++ = xtal::UnitCellCoord(
720  coord[ns_j].sublattice(),
721  coord[ns_j].unitcell() - coord[ns_i].unitcell());
722  }
723  }
724  }
725  return result;
726 }
727 
739 template <typename ClusterOrbitIterator, typename OutputIterator>
740 OutputIterator prim_periodic_neighborhood(ClusterOrbitIterator begin,
741  ClusterOrbitIterator end,
742  OutputIterator result) {
743  // create a neighborhood of all UnitCellCoord that an Orbitree touches
744  for (auto it = begin; it != end; ++it) {
745  result = prim_periodic_orbit_neighborhood(*it, result);
746  }
747  return result;
748 }
749 
763 template <typename OutputIterator, typename OrbitType>
764 OutputIterator flower_neighborhood(OrbitType const &orbit,
765  OutputIterator result) {
766  xtal::UnitCellCoord const *ucc_ptr(nullptr);
767  for (auto const &equiv : orbit) {
768  for (xtal::UnitCellCoord const &ucc : equiv) {
769  ucc_ptr = &ucc;
770  break;
771  }
772  if (ucc_ptr) break;
773  }
774 
775  if (!ucc_ptr) return result;
776 
777  SymGroup identity_group(
778  orbit.prototype().prim().factor_group().begin(),
779  (orbit.prototype().prim().factor_group().begin()) + 1);
780  OrbitType empty_orbit(typename OrbitType::Element(orbit.prototype().prim()),
781  identity_group, orbit.sym_compare());
782  typename OrbitType::Element test(empty_orbit.prototype());
783  test.elements().push_back(*ucc_ptr);
784 
785  // Loop over each site in each cluster of the orbit
786  for (auto const &equiv : orbit) {
787  for (xtal::UnitCellCoord const &ucc : equiv) {
788  // create a test cluster from prototype
789  // add the new site
790  test.elements()[0] = ucc;
791 
792  test = orbit.sym_compare().prepare(test);
793 
794  xtal::UnitCell trans = test.element(0).unitcell() - ucc.unitcell();
795  for (xtal::UnitCellCoord const &ucc2 : equiv) {
796  *result++ = (ucc2 + trans);
797  }
798  }
799  }
800 
801  return result;
802 }
803 
815 template <typename ClusterOrbitIterator, typename OutputIterator>
816 OutputIterator flower_neighborhood(ClusterOrbitIterator begin,
817  ClusterOrbitIterator end,
818  OutputIterator result) {
819  // create a neighborhood of all UnitCellCoord that an Orbitree touches
820  for (auto it = begin; it != end; ++it) {
821  result = flower_neighborhood(*it, result);
822  }
823  return result;
824 }
825 } // namespace CASM
826 
827 #endif
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:109
iterator end()
Iterator to the past-the-last element in the cluster.
iterator begin()
Iterator to first element in the cluster.
OrbitOutputIterator make_prim_periodic_orbits(std::shared_ptr< Structure const > prim_ptr, std::vector< double > const &max_length, std::vector< IntegralClusterOrbitGenerator > const &custom_generators, SiteFilterFunction const &site_filter, double xtal_tol, OrbitOutputIterator result, std::ostream &status)
Generate Orbit<IntegralCluster> by specifying max cluster length for each branch.
OrbitOutputIterator make_prim_periodic_asymmetric_unit(std::shared_ptr< Structure const > prim_ptr, SiteFilterFunction const &site_filter, double xtal_tol, OrbitOutputIterator result, std::ostream &status)
Generate the prim periodic asymmetric unit.
const PrimType & prim() const
OrbitOutputIterator make_asymmetric_unit(const OrbitBranchSpecs< OrbitType > &specs, OrbitOutputIterator result, std::ostream &status)
Generate the asymmetric unit, using OrbitBranchSpecs.
Store data used to generate an orbit branch of IntegralCluster.
const PrimType & prim() const
const SymCompareType & sym_compare() const
const SymGroup & generating_group() const
An Orbit of Element.
Definition: Orbit.hh:43
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:30
const Lattice & lattice() const
Definition: Structure.hh:100
const std::vector< xtal::Site > & basis() const
Definition: Structure.hh:102
Generates subclusters of a cluster with an iterator-like interface.
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
Definition: SymGroup.hh:42
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
Definition: Coordinate.hh:550
double dist(const Coordinate &neighbor) const
distance (in Angstr) of neighbor from *this
Definition: Coordinate.cc:148
Eigen::Vector3i enclose_sphere(double radius) const
Definition: Lattice.cc:444
Unit Cell Coordinates.
static UnitCellCoord from_coordinate(const PrimType &, const Coordinate &coord, double tol)
Unit Cell Indices.
std::pair< OrbitIterator, OrbitIterator > orbit_branch(OrbitIterator begin, OrbitIterator end, Index size)
Returns the first range containing orbits of the requested orbit branch in the given range of Orbit.
OutputIterator neighborhood(Structure const &unit, double max_radius, SiteFilterFunction site_filter, OutputIterator result, double xtal_tol)
Output the neighborhood of UnitCellCoord within max_radius of any sites in unit cell.
OrbitGenerators< OrbitType > & insert_subcluster_generators(typename OrbitType::Element cluster, OrbitGenerators< OrbitType > &generators)
Given a cluster, generate all subcluster generators.
OutputIterator flower_neighborhood(OrbitType const &orbit, OutputIterator result)
Iterate over all sites in an orbit and insert a UnitCellCoord.
OrbitOutputIterator make_next_orbitbranch(OrbitInputIterator begin, OrbitInputIterator end, const OrbitBranchSpecs< OrbitType > &specs, OrbitOutputIterator result, std::ostream &status)
Use orbits of size n to generate orbits of size n+1.
OutputIterator local_orbit_neighborhood(const OrbitType &orbit, OutputIterator result)
Iterate over all sites in an orbit and insert a UnitCellCoord.
OutputIterator prim_periodic_orbit_neighborhood(const PrimPeriodicOrbit< IntegralCluster > &orbit, OutputIterator result)
Iterate over all sites in an orbit and insert a UnitCellCoord.
OutputIterator prim_periodic_neighborhood(ClusterOrbitIterator begin, ClusterOrbitIterator end, OutputIterator result)
Iterate over all sites in all orbits and insert a UnitCellCoord.
OutputIterator local_neighborhood(ClusterOrbitIterator begin, ClusterOrbitIterator end, OutputIterator result)
Iterate over all sites in all orbits and insert a UnitCellCoord.
Eigen::Matrix3l transf_mat(const Lattice &prim_lat, const Lattice &super_lat)
typename _LinearIndexConverter< IntegralCoordinateType >::type LinearIndexConverter
Main CASM namespace.
Definition: APICommand.hh:8
OrbitOutputIterator make_orbits(OrbitBranchSpecsIterator begin, OrbitBranchSpecsIterator end, const std::vector< IntegralClusterOrbitGenerator > &custom_generators, OrbitOutputIterator result, std::ostream &status)
Generate orbits of IntegralCluster using OrbitBranchSpecs.
bool has_local_neighborhood_overlap(std::vector< OrbitType > &local_orbits, const Eigen::Matrix3i &transf_mat)
Check if periodic images of sites in an orbit are overlapping in supercells defined by the given supe...
std::function< bool(xtal::Site)> SiteFilterFunction
std::vector< Eigen::Matrix3i > viable_supercells(std::vector< OrbitType > &local_orbits, const std::vector< Eigen::Matrix3i > &transf_mat)
Return superlattice transf. matrices for which has_local_neighborhood_overlap is false.
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
Definition: algorithm.hh:83
OrbitOutputIterator make_asymmetric_unit(const OrbitBranchSpecs< OrbitType > &specs, OrbitOutputIterator result, std::ostream &status)
Generate the asymmetric unit, using OrbitBranchSpecs.
PrototypeIterator< OrbitIterator > prototype_iterator(OrbitIterator orbit_it)
Convert an Orbit iterator to a prototype iterator.
Definition: Orbit.hh:210
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Matrix< long int, 3, 1 > Vector3l
Definition: eigen.hh:13
Functor to find the canonical generating element for an orbit.
Data structure that holds canonical generating elements and can then make sorted orbits.
OrbitGeneratorSet< OrbitType > elements
OrbitOutputIterator make_orbits(OrbitOutputIterator result)
Construct Orbit from all generating elements.
const SymCompareType & sym_compare
std::pair< typename OrbitGeneratorSet< OrbitType >::iterator, bool > insert(const Element &test)
Try inserting an element, after generating the canonical form.
const SymGroup & group