CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
ConfigEnumStrain.cc
Go to the documentation of this file.
2 #include <algorithm>
3 #include "casm/clex/PrimClex.hh"
4 #include "casm/clex/Supercell.hh"
6 #include "casm/clex/PrimClex.hh"
7 #include "casm/misc/CASM_math.hh"
8 #include "casm/misc/algorithm.hh"
9 
10 extern "C" {
13  }
14 }
15 
16 namespace CASM {
17 
18  const std::string ConfigEnumStrain::enumerator_name = "ConfigEnumStrain";
19 
20  const std::string ConfigEnumStrain::interface_help =
21  "ConfigEnumStrain: \n\n"
22 
23  " ... include help documentation here ... \n\n";
24 
27  const jsonParser &_kwargs,
28  const Completer::EnumOption &enum_opt) {
29  throw std::runtime_error("EnumInterface<Strain>::run is not implemented");
30  }
31 
33  const Configuration &_init,
34  const std::vector<Index> &linear_partitions,
35  const std::vector<double> &magnitudes,
36  std::string _mode) :
37  m_current(_init),
38  m_equiv_ind(0),
39  m_strain_calc(_mode),
40  m_perm_begin(_scel.permute_begin()),
41  m_perm_end(_scel.permute_end()),
42  m_shape_factor(Eigen::MatrixXd::Identity(m_strain_calc.dim(), m_strain_calc.dim())) {
43 
44  auto eigen_compare = [](const Eigen::MatrixXd & a, const Eigen::MatrixXd & b)->bool {
45  // required because Eigen::almost_equal takes 3 args (function pointers don't know about default args)
46  return Eigen::almost_equal(a, b);
47  };
48 
49  Index sdim(m_strain_calc.dim());
50  // Force magnitudes to be positive
51  std::vector<double> absmags;
52  std::transform(magnitudes.cbegin(), magnitudes.cend(), std::back_inserter(absmags), std::abs<double>);
53 
55 
56  //Eigen::MatrixXd axes=m_strain_calc.sop_transf_mat();
57  std::vector<Index> mult;
58  std::vector<Eigen::MatrixXd> wedges = m_strain_calc.irreducible_wedges(_scel.get_primclex().get_prim().point_group(), mult);
59  Eigen::VectorXd init(sdim), final(sdim), inc(sdim);
60  Index num_sub = wedges.size();
61 
62  Index nc = 0;
63  for(Index s = 0; s < num_sub; s++) {
64  double wedgevol = sqrt((wedges[s].transpose() * wedges[s]).determinant());
65  Index N = round(pow(linear_partitions[s], wedges[s].cols()));
66  //double density = double(N) / pow(magnitudes[s], wedges[s].cols());
67  std::cout << "wedgevol: " << wedgevol << ", N: " << N;// << ", density: " << density;
68  N = max(1, (int) ceil(pow(wedgevol * double(N), 1.0 / double(wedges[s].cols())) - TOL));
69  std::cout << ", linearN: " << N << "\n";
70  std::cout << "mult.size() is: " << mult.size() << " and mult is ";
71  for(auto m : mult)
72  std::cout << m << " ";
73  std::cout << "\n";
74 
75  for(Index i = 0; i < wedges[s].cols(); i++, nc++) {
76  if(mult[nc] == 1 && linear_partitions[s] > 1) {
77  init(nc) = -absmags[s];
78  //inc(nc)=2*absmags[s]/double(subspace_partitions[s]);
79  }
80  else {
81  init(nc) = 0.0;
82  //inc(nc)=absmags[s]/double(subspace_partitions[s]);
83  }
84 
85  if(absmags[s] > TOL)
86  m_shape_factor(nc, nc) /= absmags[s] * absmags[s];
87 
88  if(linear_partitions[s] < 2) {
89  final(nc) = init(nc);
90  inc(nc) = 10 * TOL;
91  }
92  else {
93  final(nc) = absmags[s] + TOL;
94  inc(nc) = absmags[s] / double(N);
95  }
96  }
97  }
98 
99  //Handle for strain symrep
101  //wedge_orbits[w] is orbit of wedges[w]
102  multivector<Eigen::MatrixXd>::X<2> wedge_orbits(wedges.size());
103  //max_equiv[w] is wedge_orbits[w].size()-1
104  std::vector<Index> max_equiv(wedges.size());
105  for(Index w = 0; w < wedges.size(); w++) {
106  //don't bother with symmetry if we aren't perturbing the current wedge
107  if(absmags[w] < TOL) {
108  wedge_orbits[w].push_back(0.0 * wedges[w]);
109  continue;
110  }
111 
112  //Start getting orbit of wedges[w]
113  for(Index p = 0; p < trep.size(); p++) {
114  Eigen::MatrixXd twedge(m_strain_calc.sop_transf_mat() * (*(trep[p]->get_MatrixXd()))*m_strain_calc.sop_transf_mat().transpose()*wedges[w]);
115  if(contains(wedge_orbits[w], twedge, eigen_compare))
116  continue;
117  wedge_orbits[w].push_back(twedge);
118  }
119  //Finish getting orbit of wedge[w]
120  max_equiv[w] = wedge_orbits[w].size() - 1;
121  }
122 
123  //Counter over combinations of equivalent wedges
124  Counter<std::vector<Index> > wcount(std::vector<Index>(wedges.size(), 0), max_equiv, std::vector<Index>(wedges.size(), 1));
125  multivector<Eigen::MatrixXd>::X<2> trans_mat_orbits;
126  for(; wcount; ++wcount) {
127  Eigen::MatrixXd ttrans(sdim, sdim);
128  Index l = 0;
129  for(Index i = 0; i < wedges.size(); i++) {
130  for(Index j = 0; j < wedges[i].cols(); j++)
131  ttrans.col(l++) = wedge_orbits[i][wcount[i]].col(j);
132  }
133 
134  if(contains_if(trans_mat_orbits,
135  [&ttrans, eigen_compare](const std::vector<Eigen::MatrixXd> &_orbit)->bool {
136  return contains(_orbit, ttrans, eigen_compare);
137  })
138  ) continue;
139  trans_mat_orbits.push_back(std::vector<Eigen::MatrixXd>(1, ttrans));
140  m_trans_mats.push_back(ttrans);
141  for(Index p = 0; p < trep.size(); p++) {
142  Eigen::MatrixXd symtrans(m_strain_calc.sop_transf_mat() * (*(trep[p]->get_MatrixXd()))*m_strain_calc.sop_transf_mat().transpose()*ttrans);
143  if(!contains(trans_mat_orbits.back(), symtrans, eigen_compare))
144  trans_mat_orbits.back().push_back(symtrans);
145  }
146  }
147 
148 
149 
150  m_counter = EigenCounter<Eigen::VectorXd>(init, final, inc);
151 
152  std::cout << "Project matrices are \n";
153  for(Index i = 0; i < m_trans_mats.size(); i++)
154  std::cout << i << " of " << m_trans_mats.size() << "\n" << m_trans_mats[i] << "\n\n";
156 
157  m_counter.reset();
158  while(m_counter.valid() && double(m_counter().transpose()*m_trans_mats[m_equiv_ind].transpose()*m_shape_factor * m_trans_mats[m_equiv_ind]*m_counter()) > 1.0 + TOL) {
159  ++m_counter;
160  }
161 
163  this->_initialize(&m_current);
164 
165  if(!m_counter.valid()) {
166  this->_invalidate();
167  }
168  _current().set_source(this->source(step()));
169  }
170 
171  // Implements _increment
173  //bool is_valid_config(false);
174  //std::cout << "Incrementing...\n";
175 
176  while(++m_counter && double(m_counter().transpose()*m_trans_mats[m_equiv_ind].transpose()*m_shape_factor * m_trans_mats[m_equiv_ind]*m_counter()) > 1.0 + TOL) {
177  //just burning throught the count
178  }
179 
180  // move to next part of wedge if necessary
181  if(!m_counter.valid() && m_equiv_ind + 1 < m_trans_mats.size()) {
182  m_counter.reset();
183  ++m_equiv_ind;
184  std::cout << "INCREMENTING m_equiv_ind to " << m_equiv_ind << "\n";
185  }
186 
187  while(m_counter && double(m_counter().transpose()*m_trans_mats[m_equiv_ind].transpose()*m_shape_factor * m_trans_mats[m_equiv_ind]*m_counter()) > 1.0 + TOL) {
188  //just burning throught the count
189  ++m_counter;
190  }
191 
192  if(m_counter.valid()) {
194  std::cout << "Counter is " << m_counter().transpose() << "\n\n";
195  //std::cout << "strain vector is \n" << m_trans_mats[m_equiv_ind]*m_counter() << "\n\n";
196  //std::cout << "DEFORMATION IS\n" << _current().deformation() << "\n\n";
197  //is_valid_config = current().is_canonical(_perm_begin(), _perm_end());
198  //std::cout << "counter() is: " << m_counter() << "; is_valid_config: " << is_valid_config
199  //<< "; is_valid_counter: " << m_counter.valid() << "\n";
200  _increment_step();
201  }
202  else {
203  //std::cout << "REACHED END OF THE LINE!\n";
204  _invalidate();
205  }
206  _current().set_source(this->source(step()));
207  //std::cout << "--FINISHED SEARCH " << _step()<< "--\n";
208  return;
209  }
210 
211 }
212 
Eigen::MatrixXd MatrixXd
const Eigen::MatrixXd & sop_transf_mat() const
void reset_properties(ConfigDoF &_dof)
Definition: ConfigDoF.hh:202
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:71
void set_deformation(const Eigen::Matrix3d &_deformation)
Set applied strain.
const SymGroup & point_group() const
Definition: Structure.cc:101
CASM::EnumInterfaceBase * make_ConfigEnumStrain_interface()
const Structure & get_prim() const
Definition: Supercell.cc:74
PrimClex * primclex
Definition: settings.cc:101
bool contains_if(const Container &container, UnaryPredicate p)
Equivalent to container.end() != std::find_if(container.begin(), container.end(), p) ...
Definition: algorithm.hh:78
Matrix3d unrolled_strain_metric_to_F(const VectorXd &E) const
Base class for generic use of enumerators that may be accessed through the API.
Definition: Enumerator.hh:418
virtual jsonParser source(step_type step) const
Definition: Enumerator.hh:131
Eigen::MatrixXd m_shape_factor
Main CASM namespace.
Definition: complete.cpp:8
const double TOL
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
SymGroupRepID symrep_ID() const
PrimClex & get_primclex() const
Definition: Supercell.hh:201
void increment() override
Implements increment over all strain states.
Template class to be specialized for each enumerator that may be accessed via the API...
Definition: Enumerator.hh:521
value_type & _current()
Access the current ObjectType by reference.
Definition: Enumerator.hh:244
const MasterSymGroup & factor_group() const
Definition: Structure.cc:94
static int run(PrimClex &primclex, const jsonParser &kwargs, const Completer::EnumOption &enum_opt)
typename multivector_impl::multivector_tmp< T, N >::type X
Definition: multivector.hh:28
EigenIndex Index
For long integer indexing:
void _invalidate()
Call if enumeration complete.
Definition: Enumerator.hh:169
step_type step() const
Increments with each enumerated object.
Definition: Enumerator.hh:113
ConfigEnumStrain(Supercell &scel, const Configuration &_init, const std::vector< Index > &subspace_partitions, const std::vector< double > &magnitudes, std::string _mode)
Eigen::VectorXd VectorXd
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
void set_symmetrized_sop(const SymGroup &pg)
T max(const T &A, const T &B)
Definition: CASM_math.hh:32
std::vector< Eigen::MatrixXd > irreducible_wedges(const SymGroup &pg, std::vector< Index > &multiplicities)
void set_source(const jsonParser &source)
static const std::string interface_help
bool almost_equal(const Eigen::MatrixBase< Derived1 > &val1, const Eigen::MatrixBase< Derived2 > &val2, double tol=CASM::TOL)
Definition: CASM_math.hh:491
static const std::string enumerator_name
std::vector< Eigen::MatrixXd > m_trans_mats
StrainConverter m_strain_calc
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
Definition: algorithm.hh:66
EigenCounter< Eigen::VectorXd > m_counter
void _increment_step()
Increment current step value.
Definition: Enumerator.hh:159
A Configuration represents the values of all degrees of freedom in a Supercell.
const Structure & get_prim() const
const Access to primitive Structure
Definition: PrimClex.cc:260
int round(double val)
Definition: CASM_math.cc:6