56 using Vector3 = KCluster::Vector3;
66 com_(Vector3::Zero(3))
70 com_[0] = mol->center_of_mass()[0];
71 com_[1] = mol->center_of_mass()[1];
72 com_[2] = mol->center_of_mass()[2];
75 for(
auto i = 0; i < mol->natom(); ++i){
76 atoms_.push_back(
Atom(mol->atom(i), i));
88 nclusters_ = nclusters;
91 compute_clusters(nclusters_);
93 std::vector<Shell> shells = cluster_shells(new_parent_basis);
98 std::vector<KCluster>& get_clusters(std::size_t nclusters) {
99 nclusters_ = nclusters;
100 compute_clusters(nclusters_);
108 return compute_shell_ranges();
115 void compute_clusters(std::size_t nclusters){
125 void init_clusters(){
129 auto ordering = [&](
const Atom &a,
const Atom &b){
131 const Vector3 va = Eigen::Map<const Vector3>(a.r(),3);
132 const Vector3 vb = Eigen::Map<const Vector3>(b.r(),3);
135 double da = Vector3(va - com_).norm();
136 double db = Vector3(vb - com_).norm();
142 else if(va[0] != vb[0]){
143 return (va[0] < vb[0]);
145 else if(va[1] != vb[1]){
146 return (va[1] < vb[1]);
148 else if(va[2] != vb[2]){
149 return (va[2] < vb[2]);
156 std::sort(atoms_.begin(), atoms_.end(), ordering);
160 for(
auto i = 0; i < nclusters_; ++i){
162 Vector3(atoms_[i].r(0), atoms_[i].r(1), atoms_[i].r(2))
167 attach_to_closest_cluster();
173 void attach_to_closest_cluster(){
175 for(
const auto atom : atoms_){
177 double smallest = clusters_[0].distance(atom);
180 std::size_t kindex = 0;
183 for(
auto i = 1; i < nclusters_; ++i){
185 double dist = clusters_[i].distance(atom);
195 clusters_[kindex].add_atom(atom);
199 for(
auto& cluster : clusters_){
200 cluster.sort_atoms();
205 void k_means_search(std::size_t niter = 100){
208 for(
auto i = 0; i < niter; ++i){
213 for(
auto &cluster : clusters_){ cluster.guess_center(); }
216 attach_to_closest_cluster();
227 std::vector<Shell> shells;
229 for(
const auto& cluster : clusters_){
231 for(
const auto& atom : cluster.atoms()){
233 std::size_t center_ = atom.mol_index();
235 std::size_t nshells_on_atom =
239 for(
auto i = 0; i < nshells_on_atom; ++i){
240 shells.push_back(Shell(
241 new_parent_basis, center_,
242 basis_->operator()(center_, i)));
255 range.reserve(nclusters_);
261 for(
auto i = 0; i < nclusters_; ++i){
263 std::size_t shells_in_cluster = 0;
265 for(
const auto atom : clusters_[i].atoms()){
267 std::size_t atom_index = atom.mol_index();
272 range.push_back(range.at(i) + shells_in_cluster);
281 void sort_clusters(){
282 std::sort(clusters_.begin(), clusters_.end(),
283 [&](
const KCluster &a,
const KCluster &b){
284 return ((a.center()-com_).norm() < (b.center()-com_).norm());}
289 std::size_t nclusters_ = 0;
290 std::vector<Atom> atoms_;
292 std::vector<KCluster> clusters_;
std::vector< Shell > ordered_shells(std::size_t nclusters, const sc::GaussianBasisSet *new_parent_basis)
Returns a list of shells ordered by which cluster they belong to.
Definition shellorder.hpp:85