// sampleGridArroundAtoms // takes from a 3D grid values at grid points which are in area between $atom_Rmin[i] to $atom_Rmaxs[i] distance from any i-th atom at position $atom_posp[i] // if $canStore == true it will save values to $sampled_val and postions to $sampled_pos else it only returns number of gridpoints fullfilling the conditions int sampleGridArroundAtoms( int natoms, Vec3d * atom_pos_, double * atom_Rmin, double * atom_Rmax, bool * atom_mask, double * sampled_val, Vec3d * sampled_pos_, bool canStore, bool pbc, bool show_where ){ Vec3d * atom_pos = (Vec3d*) atom_pos_; Vec3d * sampled_pos = (Vec3d*) sampled_pos_; int nx = GRID::n.x; int ny = GRID::n.y; int nz = GRID::n.z; int nxy = ny * nx; // used in macro i3D( ia, ib, ic ) Vec3d rProbe; rProbe.set( 0.0, 0.0, 0.0 ); // we may shift here int points_found = 0; int nimg = 1; if (pbc) nimg = 27; // PBC ? for ( int ia=0; ia<nx; ia++ ){ //printf( " ia %i \n", ia ); rProbe.add( GRID::dCell.a ); for ( int ib=0; ib<ny; ib++ ){ rProbe.add( GRID::dCell.b ); for ( int ic=0; ic<nz; ic++ ){ rProbe.add( GRID::dCell.c ); bool withinRmin = false; bool withinRmax = false; for ( int iimg=0; iimg<nimg; iimg++ ){ Vec3d cell_shift; cell_shift.set_lincomb( images[iimg][0], images[iimg][1], images[iimg][2], GRID::cell.a, GRID::cell.b, GRID::cell.c ); for ( int iatom=0; iatom<natoms; iatom++ ){ Vec3d dr; dr.set_sub( rProbe, atom_pos[iatom] ); dr.sub( cell_shift ); double r2 = dr.norm2(); double rmin = atom_Rmin[iatom]; double rmax = atom_Rmax[iatom]; if( r2<(rmax*rmax) ){ if( atom_mask[iatom] ){ withinRmax = true; } if( r2<(rmin*rmin) ){ withinRmin = true; break; } } } } if( withinRmax && (!withinRmin) ){ if( canStore ){ sampled_val[points_found] = GRID::grid[ i3D( ia, ib, ic ) ]; if( show_where ) GRID::grid[ i3D( ia, ib, ic ) ] = +100.0d; sampled_pos[points_found].set( rProbe ); } points_found++; } } rProbe.add_mul( GRID::dCell.c, -nz ); } rProbe.add_mul( GRID::dCell.b, -ny ); } return points_found; }