#include "CBLattice.h" #include "CbPotential.h" #include namespace ATC { // removes any overlapping atoms (avoid calling because it scales n^2.) INDEX AtomCluster::remove_overlap() { INDEX removed_count = 0; std::vector::iterator r(cur_bond_len_.begin()); std::vector::iterator R(ref_coords_.begin()), Rp; const double TOL = 1.0e-6 * R->dot(*R); for (; R!=ref_coords_.end(); R++, r++) { for (Rp=R+1; Rp!=ref_coords_.end(); Rp++) { if (sum_difference_squared(*Rp, *R) < TOL) { ref_coords_.erase(R--); cur_bond_len_.erase(r--); ++removed_count; break; } } } return removed_count; } //========================================================================= // writes cluster to 3 column data format //========================================================================= void AtomCluster::write_to_dat(std::string path, bool current_config) { const int npts = int(ref_coords_.size()); if (path.substr(path.size()-5,4) != ".dat") path += ".dat"; std::fstream fid(path.c_str(), std::ios::out); for (int i=0; iphi_r(d)/d); } return f; } //============================================================================= // Computes the force constant matrix between atoms I and 0. //============================================================================= DENS_MAT AtomCluster::force_constants(INDEX I, const CbPotential *p) const { DENS_MAT D(3,3); for (INDEX i=0; i<3; i++) { DENS_VEC du(3); du(i) = 1.0e-6; // take central difference row(D,i) = perturbed_force(p, I, &du); du(i) = -du(i); row(D,i) -= perturbed_force(p, I, &du); } D *= 0.5e6; return D; } //============================================================================= // performs an iterative search for all neighbors within cutoff //============================================================================= void CBLattice::_FindAtomsInCutoff(AtomCluster &v) { static const int dir[2] = {-1, 1}; int a, b, c, abc; std::stack queue(queue0_); std::set done; // search in each direction while (!queue.empty()) { abc = queue.top(); queue.pop(); if (done.find(abc) == done.end()) { // value not in set unhash(abc,a,b,c); // convert abc to a,b,c if (_CheckUnitCell(a, b, c, v)) { done.insert(abc); // add direct 'outward' neighbors to queue queue.push(hash(a+dir[a>0], b, c)); queue.push(hash(a, b+dir[b>0], c)); queue.push(hash(a, b, c+dir[c>0])); } } } } //=========================================================================== // Computes \f$r^2 = \Vert a n_1 + b n_2 +c n_3 + b_d \Vert^2 \f$ // and adds atom (a,b,c,d) if \f$r^2 < r_{cutoff}^2 \f$ // @param a cell x-index // @param b cell y-index // @param c cell z-index //=========================================================================== bool CBLattice::_CheckUnitCell(char a, char b, char c, AtomCluster &v) { const int nsd = n_.nRows(); // number of spatial dimensions const double A=double(a), B=double(b), C=double(c); bool found=false; DENS_VEC r0(nsd,false), R0(nsd,false), Rd(nsd,false); // don't initialize for (int i=0; i