def test_becke_sum3_one(self): """Test becke weights add up to one with three centers.""" npoint = 100 points = np.random.uniform(-5, 5, (npoint, 3)) weights0 = np.ones(npoint, float) weights1 = np.ones(npoint, float) weights2 = np.ones(npoint, float) radii = np.array([0.5, 0.8, 5.0]) centers = np.array([[1.2, 2.3, 0.1], [-0.4, 0.0, -2.2], [2.2, -1.5, 0.0]]) weights0 = BeckeWeights.generate_becke_weights(points, radii, centers, select=[0], order=3) weights1 = BeckeWeights.generate_becke_weights(points, radii, centers, select=[1], order=3) weights2 = BeckeWeights.generate_becke_weights(points, radii, centers, select=[2], order=3) assert_allclose(weights0 + weights1 + weights2, np.ones(100))
def __init__(self, atomic_grids, radii, aim_weights="becke", store=False): """Initialize molgrid class. Parameters ---------- atomic_grids : list[AtomicGrid] list of atomic grid radii : np.ndarray(N,) Radii for each atom in the molecular grid aim_weights : str or np.ndarray(K,), default to "becke" Atoms in molecule weights. If str, certain function will be called to compute aim_weights, if np.ndarray, it will be treated as the aim_weights """ # initialize these attributes self._coors = np.zeros((len(radii), 3)) self._indices = np.zeros(len(radii) + 1, dtype=int) self._size = np.sum([atomgrid.size for atomgrid in atomic_grids]) self._points = np.zeros((self._size, 3)) self._weights = np.zeros(self._size) self._atomic_grids = atomic_grids if store else None for i, atom_grid in enumerate(atomic_grids): self._coors[i] = atom_grid.center self._indices[i + 1] += self._indices[i] + atom_grid.size self._points[self._indices[i] : self._indices[i + 1]] = atom_grid.points self._weights[self._indices[i] : self._indices[i + 1]] = atom_grid.weights if isinstance(aim_weights, str): if aim_weights == "becke": self._aim_weights = BeckeWeights.generate_becke_weights( self._points, radii, self._coors, pt_ind=self._indices ) else: raise NotImplementedError( f"Given aim_weights is not supported, got {aim_weights}" ) elif isinstance(aim_weights, np.ndarray): if aim_weights.size != self.size: raise ValueError( "aim_weights is not the same size as grid.\n" f"aim_weights.size: {aim_weights.size}, grid.size: {self.size}." ) self._aim_weights = aim_weights else: raise TypeError(f"Not supported aim_weights type, got {type(aim_weights)}.")
def test_becke_special_points(self): """Test becke weights for special cases.""" radii = np.array([0.5, 0.8, 5.0]) centers = np.array([[1.2, 2.3, 0.1], [-0.4, 0.0, -2.2], [2.2, -1.5, 0.0]]) weights = BeckeWeights.generate_becke_weights(centers, radii, centers, select=[0], order=3) assert_allclose(weights, [1, 0, 0]) weights = BeckeWeights.generate_becke_weights(centers, radii, centers, select=[1], order=3) assert_allclose(weights, [0, 1, 0]) weights = BeckeWeights.generate_becke_weights(centers, radii, centers, select=[2], order=3) assert_allclose(weights, [0, 0, 1]) # each point in seperate sectors. weights = BeckeWeights.generate_becke_weights(centers, radii, centers, pt_ind=[0, 1, 2, 3]) assert_allclose(weights, [1, 1, 1]) weights = BeckeWeights.generate_becke_weights(centers, radii, centers, select=[0, 1], pt_ind=[0, 1, 3]) assert_allclose(weights, [1, 1, 0]) weights = BeckeWeights.generate_becke_weights(centers, radii, centers, select=[2, 0], pt_ind=[0, 2, 3]) assert_allclose(weights, [0, 0, 0])
def test_raise_errors(self): """Test errors raise.""" npoint = 100 points = np.random.uniform(-5, 5, (npoint, 3)) radii = np.array([0.5, 0.8]) centers = np.array([[1.2, 2.3, 0.1], [-0.4, 0.0, -2.2]]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers, select=[]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers, pt_ind=[3]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers, pt_ind=[3, 6]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers, select=[], pt_ind=[]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers, select=[0, 1], pt_ind=[0, 10, 50, 99]) with self.assertRaises(ValueError): BeckeWeights.generate_becke_weights(points, radii, centers[0], select=[0, 1], pt_ind=[0, 10, 50, 99])
def __init__(self, atomic_grids, numbers, aim_weights="becke", store=False): """Initialize molgrid class. Parameters ---------- atomic_grids : list[AtomicGrid] list of atomic grid radii : np.ndarray(N,) Radii for each atom in the molecular grid aim_weights : str or np.ndarray(K,), default to "becke" Atoms in molecule weights. If str, certain function will be called to compute aim_weights, if np.ndarray, it will be treated as the aim_weights """ # initialize these attributes numbers = np.array(numbers) radii = get_cov_radii(numbers) self._coors = np.zeros((len(radii), 3)) self._indices = np.zeros(len(radii) + 1, dtype=int) self._size = np.sum([atomgrid.size for atomgrid in atomic_grids]) self._points = np.zeros((self._size, 3)) self._weights = np.zeros(self._size) self._atomic_grids = atomic_grids if store else None for i, atom_grid in enumerate(atomic_grids): self._coors[i] = atom_grid.center self._indices[i + 1] += self._indices[i] + atom_grid.size self._points[self._indices[i]:self._indices[i + 1]] = atom_grid.points self._weights[self._indices[i]:self. _indices[i + 1]] = atom_grid.weights if isinstance(aim_weights, str): if aim_weights == "becke": # Becke weights are computed for "chunks" of grid points # to counteract the scaling of the memory usage of the # vectorized implementation of the Becke partitioning. chunk_size = max(1, (10 * self._size) // self._coors.shape[0]**2) self._aim_weights = np.concatenate([ BeckeWeights.generate_becke_weights( self._points[ibegin:ibegin + chunk_size], radii, self._coors, pt_ind=(self._indices - ibegin).clip(min=0), ) for ibegin in range(0, self._size, chunk_size) ]) else: raise NotImplementedError( f"Given aim_weights is not supported, got {aim_weights}") elif isinstance(aim_weights, np.ndarray): if aim_weights.size != self.size: raise ValueError( "aim_weights is not the same size as grid.\n" f"aim_weights.size: {aim_weights.size}, grid.size: {self.size}." ) self._aim_weights = aim_weights else: raise TypeError( f"Not supported aim_weights type, got {type(aim_weights)}.")