24 std::set<Index>
const &subcomponents,
25 std::map<std::set<Index>,
Index>
const &sublats,
Index dim) {
26 std::vector<Eigen::VectorXi> result;
28 std::vector<Index> compon(subcomponents.begin(), subcomponents.end());
32 Index k = sublats.size();
33 Index n = compon.size();
37 for (
Index ic = 0; ic < ncomb; ++ic) {
40 std::vector<Index> combo(tcombo.rbegin(), tcombo.rend());
44 std::vector<Index> priority;
45 for (
Index c : combo) priority.push_back(compon[c]);
51 Eigen::VectorXi tend(Eigen::VectorXi::Zero(dim));
53 for (
auto const &sublat : sublats) {
55 for (
Index i : priority) {
56 if (sublat.first.count(i)) {
66 if (success && !
contains(result, tend)) result.push_back(tend);
70 }
while (next_permutation(
84 static std::map<std::set<Index>, std::map<std::set<Index>,
Index> >
86 std::map<std::set<Index>, std::map<std::set<Index>,
Index> > result;
88 std::vector<std::string> compon =
94 std::map<std::set<Index>,
Index> occ_map;
95 for (
auto const &list : _allowed_occs) {
97 for (
auto const &occ : list) tocc.insert(
find_index(compon, occ));
98 auto it = occ_map.find(tocc);
99 if (it != occ_map.end())
117 std::set<Index> visited;
124 for (
Index i = 0; i < compon.size() && visited.size() < compon.size(); ++i) {
126 std::set<Index> q({i});
131 if (visited.count(i))
continue;
134 std::map<std::set<Index>,
Index> tmap;
137 Index j = *q.begin();
139 if (!visited.count(j)) {
142 for (
auto const &list : occ_map) {
146 if (list.first.count(j)) {
147 q.insert(list.first.begin(), list.first.end());
148 s.insert(list.first.begin(), list.first.end());
181 std::vector<std::string> result;
182 for (
auto const &site : _allowed_occs) {
183 for (
auto const &occ : site) {
185 result.push_back(occ);
196 : m_allowed_occs(
std::move(_allowed_occs)), m_prim_end_members(0, 0) {
208 const int &_rank_of_space,
const int &COMP_TYPE)
209 : m_allowed_occs(
std::move(_allowed_occs)) {
236 std::map<std::set<Index>, std::map<std::set<Index>,
Index> > subsystems =
239 std::vector<Eigen::VectorXi> tresult(
240 1, Eigen::VectorXi::Zero(
components().size()));
242 for (
auto const &subsystem : subsystems) {
244 subsystem.first, subsystem.second,
components().size());
245 std::vector<Eigen::VectorXi> tresult2;
246 tresult2.reserve(tresult.size() * tsubs.size());
247 for (
auto const &v1 : tresult) {
248 for (
auto const &v2 : tsubs) {
249 tresult2.push_back(v1 + v2);
255 std::map<Index, std::vector<Eigen::VectorXi> > tsort;
256 for (
auto const &v : tresult) {
257 tsort[v.squaredNorm()].push_back(v);
264 for (
auto it = tsort.rbegin(); it != tsort.rend(); ++it) {
267 for (
auto const &el : it->second) {
308 std::cerr <<
"WARNING in ParamComposition::generate_composition_space, "
309 "your allowed_list is non-empty. If you are not careful,you "
310 "may end up with repeats of allowed composition axes"
327 std::vector<Index> combo;
330 std::vector<Eigen::VectorXd> tspanning;
331 for (
Index c = 0; c < ncomb; ++c) {
333 for (
Index i = 0; i < K; ++i) {
337 if (qr.compute(tmembers).rank() < K)
continue;
340 double p =
round(1e4 *
double(c) /
double(ncomb)) / 100.;
341 log() <<
"combo #" << c <<
": " << combo << std::endl;
343 log() << p <<
"% complete. Considering possible origins for set \n"
344 << tmembers << std::endl;
348 for (
Index i_o = 0; i_o < K; ++i_o) {
349 torigin = tmembers.col(i_o);
352 log() <<
"The origin is: " << torigin.transpose() <<
"\n---"
359 for (
Index j = 0; j < K; ++j) {
361 tspanning.push_back(tmembers.col(j) - torigin);
371 if (verbose)
log() <<
"Calculated compositions:" << std::endl;
374 bool is_positive =
true;
384 for (
Index k = 0; k < test_comp.size(); k++) {
389 if (test_comp(k) < -
TOL) {
412 std::ostream &stream,
const int &stream_width)
const {
413 int composition_var = (int)
'a';
414 std::stringstream tstr;
416 bool first_char =
true;
428 tstr << (char)(composition_var + j);
431 tstr <<
'+' << (char)(composition_var + j);
434 tstr <<
'-' << (char)(composition_var + j);
444 stream << tstr.str().c_str();
452 std::ostream &stream,
453 const int &stream_width)
const {
454 std::stringstream tstr;
455 for (
EigenIndex i = 0; i < member.size(); i++) {
465 stream << std::setw(stream_width) << tstr.str().c_str();
471 const int &stream_width)
const {
478 stream <<
"Number of choices of composition axes: " <<
m_allowed_list.size()
483 stream << std::setw(10) <<
"INDEX";
484 stream << std::setw(10) <<
"ORIGIN";
486 stream << std::setw(10) << (char)((
int)
'a' + i);
489 stream <<
"GENERAL FORMULA";
492 stream << std::setw(10) <<
" ---";
493 stream << std::setw(10) <<
" ---";
495 stream << std::setw(10) <<
" ---";
498 stream <<
"---" << std::endl;
501 stream << std::setw(10) << i;
503 std::vector<Eigen::VectorXd> allowed_spanning_end_members;
504 allowed_spanning_end_members =
m_allowed_list[i].spanning_end_members();
505 for (
Index j = 0; j < allowed_spanning_end_members.size(); j++) {
525 stream << std::setw(20) <<
"ORIGIN";
527 stream << std::setw(10) << (char)((
int)
'a' + i);
530 stream <<
"GENERAL FORMULA";
533 stream << std::setw(20) <<
" ---";
535 stream << std::setw(10) <<
" ---";
538 stream <<
"---" << std::endl;
541 std::vector<Eigen::VectorXd> allowed_spanning_end_members;
543 for (
int j = 0; j < allowed_spanning_end_members.size(); j++) {
602 const std::vector<Eigen::VectorXd> tspanning) {
614 for (
Index i = 0; i < tspanning.size(); i++) {
615 tmat.col(i) = tspanning[i];
619 if (tspanning.size() < (
components().size())) {
620 Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qr(
621 tmat.leftCols(tspanning.size()));
623 tmat.rightCols((
components().size() - tspanning.size())) =
624 torthogonal.rightCols((
components().size() - tspanning.size()));
641 Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qr(
645 torthogonal.rightCols(
666 std::vector<Eigen::VectorXd> tspan_end;
668 std::cerr <<
"WARNING something is wrong in "
669 "ParamComposition::spanning_end_members. The rank_of_space in "
670 "the ParamComposition object is <=0. I do not know how to "
671 "calculate the end_members in such a space"
690 std::cerr <<
"ERROR in ParamComposition::select_composition_axes. Your "
691 "value of choice is outside the range of allowed_list"
707 std::stringstream ss;
std::set< std::string > & s
Eigen::VectorXd calc_num_atoms(const Eigen::VectorXd ¶m_composition) const
void print_origin_formula(std::ostream &stream, const int &stream_width) const
void select_composition_axes(const Index &choice)
static std::vector< std::string > string_components(ParamComposition::AllowedOccupants const &_allowed_occs)
Eigen::VectorXd m_origin
The origin of the composition space.
std::vector< Eigen::VectorXd > m_spanning_end_members
std::vector< std::string > m_components
The list of all allowed components, based on allowed_occs()
void print_composition_formula(std::ostream &stream, const int &stream_width) const
std::string composition_formula() const
Eigen::MatrixXd m_prim_end_members
std::vector< std::vector< std::string > > AllowedOccupants
const std::vector< std::vector< std::string > > & allowed_occs() const
For each sublattice, a list of occupants allowed on that sublattice.
std::vector< Eigen::MatrixXd > m_comp
void print_member_formula(const Eigen::VectorXd &member, std::ostream &stream, const int &stream_width) const
void calc_transformation_matrices()
void print_composition_axes(std::ostream &stream) const
void generate_prim_end_members()
Eigen::VectorXd calc_param_composition(const Eigen::VectorXd &num_atoms_per_prim) const
void generate_composition_space(bool verbose=false)
Eigen::VectorXd calc(const Eigen::VectorXd &tcomp, const int &MODE)
std::vector< ParamComposition > m_allowed_list
void print_curr_composition_axes(std::ostream &stream) const
const std::vector< std::string > & components() const
Components are in order of appearance precedence in allowed_occs()
const std::vector< Eigen::VectorXd > & spanning_end_members() const
void calc_spanning_end_members()
ParamComposition calc_composition_object(const Eigen::VectorXd &torigin, const std::vector< Eigen::VectorXd > tspanning)
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
Eigen::Matrix3l transf_mat(const Lattice &prim_lat, const Lattice &super_lat)
static std::vector< Eigen::VectorXi > _sub_extremes(std::set< Index > const &subcomponents, std::map< std::set< Index >, Index > const &sublats, Index dim)
static std::map< std::set< Index >, std::map< std::set< Index >, Index > > _chemical_subsystems(ParamComposition::AllowedOccupants const &_allowed_occs)
IntType nchoosek(IntType n, IntType k)
Index find_index(Iterator begin, Iterator end, const T &value)
Equivalent to std::distance(begin, std::find(begin, end, value))
void swap(ConfigDoF &A, ConfigDoF &B)
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
Eigen::MatrixXd::Index EigenIndex
INDEX_TYPE Index
For long integer indexing:
std::vector< IntType > index_to_kcombination(IntType ind, IntType k)