CASM  1.1.0
A Clusters Approach to Statistical Mechanics
FillSupercell.cc
Go to the documentation of this file.
2 
4 #include "casm/clex/Supercell.hh"
8 #include "casm/symmetry/SymOp.hh"
10 
11 namespace CASM {
12 
20 bool is_valid_sub_configuration(Lattice const &sub_configuration_lattice,
21  Supercell const &supercell) {
22  FillSupercell f{supercell};
23  return f.find_symop(sub_configuration_lattice) != nullptr;
24 }
25 
34  Configuration const &motif,
35  std::shared_ptr<Supercell const> const &shared_supercell) {
36  FillSupercell f{shared_supercell};
37  return f(motif);
38 }
39 
49  Supercell const &supercell) {
50  FillSupercell f{supercell};
51  return f(motif);
52 }
53 
60  SymOp const &symop, Configuration const &motif,
61  std::shared_ptr<Supercell const> const &shared_supercell) {
62  FillSupercell f{shared_supercell};
63  return f(symop, motif);
64 }
65 
72 Configuration fill_supercell(SymOp const &symop, Configuration const &motif,
73  Supercell const &supercell) {
74  FillSupercell f{supercell};
75  return f(symop, motif);
76 }
77 
84  std::shared_ptr<Supercell const> const &_shared_supercell)
85  : m_shared_supercell(_shared_supercell),
86  m_supercell_ptr(m_shared_supercell.get()),
87  m_symop_ptr(nullptr),
88  m_motif_supercell(nullptr) {}
89 
96  : m_supercell_ptr(&_supercell),
97  m_symop_ptr(nullptr),
98  m_motif_supercell(nullptr) {}
99 
101  if (&motif.supercell() != m_motif_supercell) {
103  _init(motif.supercell());
104  }
105  return (*this)(*m_symop_ptr, motif);
106 }
107 
109  Configuration const &motif) const {
110  if (&motif.supercell() != m_motif_supercell || &symop != m_symop_ptr) {
111  if (&symop != m_symop_ptr) {
112  Lattice const &motif_lattice = motif.supercell().lattice();
114  sym::copy_apply(symop, motif_lattice),
115  motif_lattice.tol())
116  .first) {
117  throw std::runtime_error(
118  "Error in 'FillSupercell: super lattice != sym::copy_apply(symop, "
119  "motif lattice)");
120  }
121  m_symop_ptr = &symop;
122  }
123  _init(motif.supercell());
124  }
125 
126  std::unique_ptr<Configuration> result;
127  if (m_shared_supercell) {
128  result = notstd::make_unique<Configuration>(m_shared_supercell);
129  } else {
130  result = notstd::make_unique<Configuration>(*m_supercell_ptr);
131  }
132 
133  // We reorien the starting configuration (motif) by symop in two steps.
134  // In the first step, we transform the DoFs of motif by symop, without
135  // permuting their site indices Then, we utilize m_index_table to decorate the
136  // new cell with these transformed DoFs. m_index_table is built in
137  // FillSupercel::_init() by explicitly transforming each UnitCellCoordinate of
138  // the starting supercell (*m_motif_supercell) and finding it in the resultant
139  // supercell (*m_supercell_ptr) This ensures that sublattice permutation and
140  // microscopic translations are handled appropriately
141  ConfigDoF trans_motif(motif.configdof());
142  trans_motif.apply_sym_no_permute(symop);
143 
144  // copy transformed dof, as many times as necessary to fill the supercell
145  for (auto const &dof : trans_motif.global_dofs())
146  result->configdof().set_global_dof(dof.first, dof.second.values());
147 
148  for (Index s = 0; s < m_index_table.size(); ++s) {
149  for (Index i = 0; i < m_index_table[s].size(); ++i) {
150  Index scel_s = m_index_table[s][i];
151 
152  if (trans_motif.has_occupation()) {
153  result->configdof().occ(scel_s) = trans_motif.occ(s);
154  }
155  }
156  }
157 
158  for (auto const &dof : trans_motif.local_dofs()) {
160  result->configdof().local_dof(dof.first));
161  for (Index s = 0; s < m_index_table.size(); ++s) {
162  for (Index i = 0; i < m_index_table[s].size(); ++i) {
163  Index scel_s = m_index_table[s][i];
164  res_ref.site_value(scel_s) = dof.second.site_value(s);
165  }
166  }
167  }
168  return *result;
169 }
170 
173 SymOp const *FillSupercell::find_symop(Lattice const &motif_lattice) const {
174  const Lattice &scel_lattice = m_supercell_ptr->lattice();
175  auto begin = m_supercell_ptr->prim().factor_group().begin();
176  auto end = m_supercell_ptr->prim().factor_group().end();
177  auto res = xtal::is_equivalent_superlattice(scel_lattice, motif_lattice,
178  begin, end, motif_lattice.tol());
179  if (res.first == end) {
180  return nullptr;
181  }
182  return &(*res.first);
183 }
184 
185 void FillSupercell::_init(Supercell const &_motif_supercell) const {
186  m_motif_supercell = &_motif_supercell;
187 
188  // ------- site dof ----------
189  Lattice oriented_motif_lat =
191 
192  auto oriended_motif_lattice_points = xtal::make_lattice_points(
193  oriented_motif_lat, m_supercell_ptr->lattice(), TOL);
194 
195  const Structure &prim = m_supercell_ptr->prim();
197 
198  // for each site in motif
199  for (Index s = 0; s < m_motif_supercell->num_sites(); s++) {
200  // apply symmetry to re-orient and find unit cell coord
201  UnitCellCoord oriented_uccoord =
203  prim.lattice(), prim.basis_permutation_symrep_ID());
204 
205  // for each unit cell of the oriented motif in the supercell, copy the
206  // occupation
207  for (const UnitCell &oriented_motif_uc : oriended_motif_lattice_points) {
208  UnitCell oriented_motif_uc_relative_to_prim =
209  oriented_motif_uc.reset_tiling_unit(oriented_motif_lat,
210  prim.lattice());
211 
212  Index prim_motif_tile_ind =
214  oriented_motif_uc_relative_to_prim);
215 
216  UnitCellCoord mc_uccoord(
217  oriented_uccoord.sublattice(),
219  prim_motif_tile_ind) +
220  oriented_uccoord.unitcell());
221 
222  m_index_table[s].push_back(m_supercell_ptr->linear_index(mc_uccoord));
223  }
224  }
225 }
226 
227 } // namespace CASM
std::set< std::string > & s
std::map< DoFKey, LocalContinuousConfigDoFValues > const & local_dofs() const
Definition: ConfigDoF.cc:119
void set_global_dof(DoFKey const &_key, Eigen::Ref< const Eigen::VectorXd > const &_val)
Set global continuous DoF values.
Definition: ConfigDoF.cc:99
std::map< DoFKey, GlobalContinuousConfigDoFValues > const & global_dofs() const
Definition: ConfigDoF.cc:65
bool has_occupation() const
Definition: ConfigDoF.cc:60
ConfigDoF & apply_sym_no_permute(SymOp const &_op)
Definition: ConfigDoF.cc:220
int & occ(Index i)
Reference occupation value on site i.
Definition: ConfigDoF.cc:34
const ConfigDoF & configdof() const
const Access the DoF
const Supercell & supercell() const
Get the Supercell for this Configuration.
Supercell const * m_motif_supercell
const SymOp & symop() const
Returns the SymOp used by operator()
FillSupercell(std::shared_ptr< Supercell const > const &_shared_supercell)
Constructor.
SymOp const * m_symop_ptr
void _init(Supercell const &_motif_scel) const
Configuration operator()(Configuration const &motif) const
const SymOp * find_symop(xtal::Lattice const &_motif_lattice) const
Find first SymOp in the prim factor group such that apply(op, motif) can be used to fill the Supercel...
std::vector< std::vector< Index > > m_index_table
Supercell const * m_supercell_ptr
std::shared_ptr< Supercell const > m_shared_supercell
SiteReference site_value(Index l)
Access site DoF value vector.
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:30
const Lattice & lattice() const
Definition: Structure.hh:100
const MasterSymGroup & factor_group() const
Definition: Structure.cc:107
SymGroupRepID basis_permutation_symrep_ID() const
Definition: Structure.cc:122
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:51
Index linear_index(const Coordinate &coord, double tol=TOL) const
Given a Coordinate and tolerance, return linear index into Configuration.
Definition: Supercell.cc:183
UnitCellCoord uccoord(Index linear_index) const
Return the integral coordinates corresponding to a linear index.
Definition: Supercell.cc:209
const Lattice & lattice() const
The super lattice.
Definition: Supercell.cc:239
Index num_sites() const
Definition: Supercell.cc:233
const Structure & prim() const
Definition: Supercell.cc:113
const SupercellSymInfo & sym_info() const
Definition: Supercell.cc:265
const xtal::UnitCellIndexConverter & unitcell_index_converter() const
UnitCellIndexConverter for this superlattice/primlattice pair Used to convert from lattice translatio...
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
Unit Cell Coordinates.
const UnitCell & unitcell() const
Unit Cell Indices.
UnitCell reset_tiling_unit(const Lattice &current_tiling_unit, const Lattice &new_tiling_unit) const
Finds a new UnitCell with values relative to the given tiling unit.
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
std::vector< UnitCell > make_lattice_points(const Eigen::Matrix3l &transformation_matrix)
std::pair< OpIterator, Eigen::Matrix3d > is_equivalent_superlattice(const Object &scel, const Object &unit, OpIterator begin, OpIterator end, double tol)
Definition: SymTools.hh:110
Main CASM namespace.
Definition: APICommand.hh:8
Configuration fill_supercell(Configuration const &motif, std::shared_ptr< Supercell const > const &shared_supercell)
const double TOL
Definition: definitions.hh:30
DoFSpecsType const & get(DoFKey const &key, BasisFunctionSpecs const &basis_function_specs)
bool is_valid_sub_configuration(xtal::Lattice const &sub_configuration_lattice, Supercell const &supercell)
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39