CASM  1.1.0
A Clusters Approach to Statistical Mechanics
ConfigEnumSiteDoFs.cc
Go to the documentation of this file.
2 
6 
7 namespace CASM {
8 
11  ConfigEnumSiteDoFsParams const &params)
12  : ConfigEnumSiteDoFs(_in_config, params.dof, params.axes, params.min_val,
13  params.max_val, params.inc_val, params.min_nonzero,
14  params.max_nonzero) {}
15 
18  ConfigEnumInput const &_init, DoFKey const &_dof,
19  Eigen::Ref<const Eigen::MatrixXd> const &_axes,
20  Eigen::Ref<const Eigen::VectorXd> const &min_val,
21  Eigen::Ref<const Eigen::VectorXd> const &max_val,
22  Eigen::Ref<const Eigen::VectorXd> const &inc_val, Index _min_nonzero,
23  Index _max_nonzero)
24  :
25 
26  // m_current(_init.config()),
27  m_dof_key(_dof),
28  m_min_nonzero(_min_nonzero),
29  m_max_nonzero(_max_nonzero),
30  m_axes(_axes),
31  m_min(min_val),
32  m_max(max_val),
33  m_inc(inc_val),
34  m_unit_length(DoF::BasicTraits(_dof).unit_length()),
35  m_sites(_init.sites().begin(), _init.sites().end()),
36  m_subset_mode(false),
37  // m_combo_mode(false),
38  m_combo_index(0) {
39  if (_init.configuration().size() != _init.sites().size())
40  m_subset_mode = true;
41 
42  if (m_axes.cols() == 0) {
43  this->_invalidate();
44  } else {
45  m_current = notstd::make_cloneable<Configuration>(_init.configuration());
47 
48  m_dof_vals = &(m_current->configdof().local_dof(m_dof_key));
49  auto const &dof_info = m_dof_vals->info();
50  for (Index l : m_sites)
51  m_dof_dims.push_back(dof_info[m_current->sublat(l)].dim());
52 
53  if (m_max_nonzero > m_axes.cols() / 3) {
54  m_combo.resize(m_max_nonzero - 1);
56  }
57 
58  if (_increment_combo()) {
59  this->_initialize(&(*m_current));
60  }
61 
62  _set_dof();
63  m_current->set_source(this->source(step()));
64  }
65 }
66 
67 std::string ConfigEnumSiteDoFs::name() const { return enumerator_name; }
68 
69 const std::string ConfigEnumSiteDoFs::enumerator_name = "ConfigEnumSiteDoFs";
70 
72  Index k = max<Index>(m_combo.size(), m_min_nonzero);
73  bool invalid = true;
74  // std::cout << "COMBO INCREMENT: " << m_combo << " to ";
75  while (invalid) {
76  if (m_combo_index >= nchoosek(m_axes.cols(), k)) {
77  ++k;
78  m_combo_index = 0;
79  }
80  if (k > m_max_nonzero) break;
81  invalid = false;
83  Eigen::VectorXd vmin(m_combo.size()), vmax(m_combo.size()),
84  vinc(m_combo.size());
85  for (Index i = 0; i < m_combo.size(); ++i) {
86  vmin[i] = m_min[m_combo[i]];
87  vmax[i] = m_max[m_combo[i]];
88  vinc[i] = m_inc[m_combo[i]];
89  if (almost_zero(vmin[i]) && almost_zero(vmax[i])) invalid = true;
90  }
91  m_combo_index++;
92  m_counter = EigenCounter<Eigen::VectorXd>(vmin, vmax, vinc);
93  }
94 
95  // std::cout << m_combo << "\n";
96 
97  // std::cout << "counter.valid() = " << m_counter.valid() << "; values: " <<
98  // m_counter().transpose() << "\n";
99  return !invalid;
100 }
101 
103  Eigen::MatrixXd vals = m_current->configdof().local_dof(m_dof_key).values();
104  Eigen::VectorXd pert_vals(Eigen::VectorXd::Zero(m_axes.rows()));
105 
106  for (Index i = 0; i < m_combo.size(); ++i) {
107  pert_vals += m_counter[i] * m_axes.col(m_combo[i]);
108  }
109 
110  Index l = 0;
111 
112  for (Index i = 0; i < m_sites.size(); ++i) {
113  for (Index j = 0; j < m_dof_dims[i]; ++j, ++l) {
114  vals(j, m_sites[i]) = pert_vals(l);
115  }
116 
117  if (m_unit_length) {
118  double tnorm = vals.col(m_sites[i]).norm();
119  if (!almost_zero(tnorm)) vals.col(m_sites[i]) /= tnorm;
120  }
121  }
122 
123  m_current->configdof().set_local_dof(m_dof_key, vals);
124 }
125 
128  // std::cout << "m_combo before increment: " << m_combo << "\n";
129  bool is_valid_config = false;
130  while (!is_valid_config && (++m_counter || _increment_combo())) {
131  // std::cout << "Counting point: " << m_counter() << "\n";
132  if (_check_sparsity()) {
133  // std::cout << "Sparsity is good!\n";
134  _set_dof();
135  is_valid_config = _check_current();
136  }
137  // std::cout << "is_valid? " << (is_valid_config? "yes\n" : "no\n");
138  }
139  // std::cout << "m_combo after increment: " << m_combo << "\n";
140  // std::cout << "OUTSIDE!! is_valid? " << (is_valid_config? "yes\n" : "no\n");
141  if (is_valid_config) {
142  this->_increment_step();
143  m_current->set_source(this->source(step()));
144  } else {
145  this->_invalidate();
146  }
147 }
148 
150  if (m_min_nonzero == 0 && m_max_nonzero == m_axes.cols()) return true;
151 
152  Index nonzero = 0;
153  for (Index i = 0; i < m_counter().size(); ++i) {
154  nonzero += almost_zero(m_counter[i]) ? 0 : 1;
155  }
156  return (m_min_nonzero <= nonzero && nonzero <= m_max_nonzero);
157 }
158 
161  return true;
162  // return current().is_primitive() && _check_sparsity() && (m_subset_mode ||
163  // current().is_canonical());
164 }
165 } // namespace CASM
notstd::cloneable_ptr< Configuration > m_current
static const std::string enumerator_name
void increment() override
Implements increment over all strain states.
ConfigEnumSiteDoFs(ConfigEnumInput const &_in_config, ConfigEnumSiteDoFsParams const &params)
See ConfigEnumSiteDoFsParams for method and parameter details.
std::vector< Index > m_dof_dims
std::vector< Index > m_sites
LocalContinuousConfigDoFValues * m_dof_vals
std::string name() const override
Derived enumerators must implement name, via ENUM_MEMBERS.
EigenCounter< Eigen::VectorXd > m_counter
std::vector< Index > m_combo
bool _check_current() const
Returns true if current() is primitive and canonical.
Index size() const
Returns number of sites, NOT the number of primitives that fit in here.
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:109
std::vector< DoFSetInfo > const & info() const
DoFSetInfo provides the basis and symmetry representations for values
virtual jsonParser source(step_type step) const
Definition: Enumerator.hh:129
void _invalidate()
Call if enumeration complete.
Definition: Enumerator.hh:159
void _increment_step()
Increment current step value.
Definition: Enumerator.hh:153
step_type step() const
Increments with each enumerated object.
Definition: Enumerator.hh:115
std::set< Index > const & sites() const
Configuration const & configuration() const
AnisoValTraits BasicTraits
Definition: DoF.hh:34
Main CASM namespace.
Definition: APICommand.hh:8
Eigen::MatrixXd MatrixXd
IntType nchoosek(IntType n, IntType k)
Definition: CASM_math.hh:207
void reset_properties(ConfigType &config)
Definition: Calculable.cc:147
std::string DoFKey
Definition: DoFDecl.hh:7
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:104
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Eigen::VectorXd VectorXd
std::vector< IntType > index_to_kcombination(IntType ind, IntType k)
Definition: CASM_math.hh:228