static int psdist(Point p, Point a, Point b) { int num, den; p = subpt(p, a); b = subpt(b, a); num = p.x*b.x + p.y*b.y; if(num <= 0) return normsq(p); den = normsq(b); if(num >= den) return normsq(subpt(b, p)); return normsq(subpt(divpt(mulpt(b, num), den), p)); }
void BaderGrid::construct_voronoi(double otoler) { // Amount of radial shells on the atoms std::vector<size_t> nrad(basp->get_Nnuc()); Timer t; // Form radial shells std::vector<angshell_t> grids; for(size_t iat=0;iat<basp->get_Nnuc();iat++) { angshell_t sh; sh.atind=iat; sh.cen=basp->get_nuclear_coords(iat); sh.tol=otoler*PRUNETHR; // Compute necessary number of radial points for atom size_t nr=std::max(20,(int) round(-5*(3*log10(otoler)+8-element_row[basp->get_Z(iat)]))); // Get Chebyshev nodes and weights for radial part std::vector<double> rad, wrad; radial_chebyshev_jac(nr,rad,wrad); nr=rad.size(); // Sanity check nrad[iat]=nr; // Loop over radii for(size_t irad=0;irad<nr;irad++) { sh.R=rad[irad]; sh.w=wrad[irad]; grids.push_back(sh); } } // List of grid points std::vector<gridpoint_t> points; // Initialize list of maxima maxima.clear(); reggrid.clear(); for(size_t i=0;i<basp->get_Nnuc();i++) { nucleus_t nuc(basp->get_nucleus(i)); if(!nuc.bsse) { // Add to list maxima.push_back(nuc.r); std::vector<gridpoint_t> ghlp; reggrid.push_back(ghlp); } } Nnuc=maxima.size(); for(size_t ig=0;ig<grids.size();ig++) { // Construct the shell wrk.set_grid(grids[ig]); grids[ig]=wrk.construct_becke(otoler/nrad[grids[ig].atind]); // Form the grid again wrk.form_grid(); // Extract the points on the shell std::vector<gridpoint_t> shellpoints(wrk.get_grid()); // Loop over the points on the shell for(size_t ip=0;ip<shellpoints.size();ip++) { // Compute distances to atoms arma::vec dist(maxima.size()); for(size_t ia=0;ia<maxima.size();ia++) dist(ia)=normsq(shellpoints[ip].r-maxima[ia]); // Region is arma::uword idx; dist.min(idx); // Assign point to atom reggrid[idx].push_back(shellpoints[ip]); } } if(verbose) { printf("Voronoi grid constructed in %s.\n",t.elapsed().c_str()); // Amount of integration points arma::uvec np(basp->get_Nnuc()); np.zeros(); // Amount of function values arma::uvec nf(basp->get_Nnuc()); nf.zeros(); for(size_t i=0;i<grids.size();i++) { np(grids[i].atind)+=grids[i].np; nf(grids[i].atind)+=grids[i].nfunc; } printf("Composition of atomic integration grid:\n %7s %7s %10s\n","atom","Npoints","Nfuncs"); for(size_t i=0;i<basp->get_Nnuc();i++) printf(" %4i %-2s %7i %10i\n",(int) i+1, basp->get_symbol(i).c_str(), (int) np(i), (int) nf(i)); printf("\nAmount of grid points in the atomic regions:\n %7s %7s\n","region","Npoints"); for(size_t i=0;i<reggrid.size();i++) printf(" %4i %7i\n",(int) i+1, (int) reggrid[i].size()); fflush(stdout); } }
// compute magnitude of Vector3D this inline float norm() const { return sqrtf(normsq()); }