def test_total_atomic_grid(self): """Normal initialization test.""" radial_pts = np.arange(0.1, 1.1, 0.1) radial_wts = np.ones(10) * 0.1 rgrid = OneDGrid(radial_pts, radial_wts) rad = 0.5 r_sectors = np.array([0.5, 1, 1.5]) degs = np.array([6, 14, 14, 6]) # generate a proper instance without failing. ag_ob = AtomGrid.from_pruned(rgrid, radius=rad, sectors_r=r_sectors, sectors_degree=degs) assert isinstance(ag_ob, AtomGrid) assert len(ag_ob.indices) == 11 assert ag_ob.l_max == 15 ag_ob = AtomGrid.from_pruned(rgrid, radius=rad, sectors_r=np.array([]), sectors_degree=np.array([6])) assert isinstance(ag_ob, AtomGrid) assert len(ag_ob.indices) == 11 ag_ob = AtomGrid(rgrid, sizes=[110]) assert ag_ob.l_max == 17 assert_array_equal(ag_ob._degs, np.ones(10) * 17) assert ag_ob.size == 110 * 10 # new init AtomGrid ag_ob2 = AtomGrid(rgrid, degrees=[17]) assert ag_ob2.l_max == 17 assert_array_equal(ag_ob2._degs, np.ones(10) * 17) assert ag_ob2.size == 110 * 10 assert isinstance(ag_ob.rgrid, OneDGrid) assert_allclose(ag_ob.rgrid.points, rgrid.points) assert_allclose(ag_ob.rgrid.weights, rgrid.weights)
def test_from_size(self): """Test horton style grid.""" nums = np.array([1, 1]) coors = np.array([[0, 0, -0.5], [0, 0, 0.5]]) becke = BeckeWeights(order=3) mol_grid = MolGrid.from_size(nums, coors, self.rgrid, 110, becke, rotate=False) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, sectors_r=np.array([]), sectors_degree=np.array([17]), center=coors[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, sectors_r=np.array([]), sectors_degree=np.array([17]), center=coors[1], ) ref_grid = MolGrid(nums, [atg1, atg2], becke, store=True) assert_allclose(ref_grid.points, mol_grid.points) assert_allclose(ref_grid.weights, mol_grid.weights)
def test_integrate_hydrogen_trimer_1s(self): """Test molecular integral in H3.""" coordinates = np.array( [[0.0, 0.0, -0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0]], float) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[1], ) atg3 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[2], ) becke = BeckeWeights(order=3) mg = MolGrid([atg1, atg2, atg3], becke, np.array([1, 1, 1])) dist0 = np.sqrt(((coordinates[0] - mg.points)**2).sum(axis=1)) dist1 = np.sqrt(((coordinates[1] - mg.points)**2).sum(axis=1)) dist2 = np.sqrt(((coordinates[2] - mg.points)**2).sum(axis=1)) fn = (np.exp(-2 * dist0) / np.pi + np.exp(-2 * dist1) / np.pi + np.exp(-2 * dist2) / np.pi) occupation = mg.integrate(fn) assert_almost_equal(occupation, 3.0, decimal=4)
def test_interpolation_of_laplacian_of_exponential(self): r"""Test the interpolation of Laplacian of exponential.""" odg = OneDGrid(np.linspace(0.01, 1, num=1000), np.ones(1000), (0, np.inf)) degree = 10 atgrid = AtomGrid.from_pruned(odg, 1, sectors_r=[], sectors_degree=[degree]) def func(cart_pts): radius = np.linalg.norm(cart_pts, axis=1) return np.exp(-radius) func_values = func(atgrid.points) laplacian = atgrid.interpolate_laplacian(func_values) # Test on the same points used for interpolation and random points. for grid in [atgrid.points, np.random.uniform(-0.5, 0.5, (250, 3))]: actual = laplacian(grid) spherical_pts = atgrid.convert_cartesian_to_spherical(grid) # Laplacian of exponential is e^-x (x - 2) / x desired = (np.exp(-spherical_pts[:, 0]) * (spherical_pts[:, 0] - 2.0) / spherical_pts[:, 0]) assert_almost_equal(actual, desired, decimal=3)
def test_spline_with_sph_harms(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) # generate ref for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) # Convert to spherical harmonics r = np.linalg.norm(sh_grid._points, axis=1) theta = np.arctan2(sh_grid._points[:, 1], sh_grid._points[:, 0]) phi = np.arccos(sh_grid._points[:, 2] / r) # General all spherical harmonics up to l_max r_sph = generate_real_sph_harms(l_max, theta, phi) # Project the function 2x^2 + 3y^2 + 4z^2 r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) # Check the actual projection against the cubic spline interpolation. assert_allclose(r_sph_proj, result(shell), atol=1e-10)
def test_cubicspline_and_interp(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad_grid = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad_grid, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values) # same result from points and interpolation assert_allclose( interp, values[atgrid.indices[i]:atgrid.indices[i + 1]]) # test random x, y, z for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) # xyz /= np.linalg.norm(xyz, axis=-1)[:, None] # rad = np.random.normal() * np.random.randint(1, 11) # xyz *= rad ref_value = self.helper_func_power(xyz) interp = atgrid.interpolate(xyz, values) assert_allclose(interp, ref_value)
def test_cubicspline_and_deriv(self): """Test spline for derivation.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values, deriv=1, ) # same result from points and interpolation ref_deriv = self.helper_func_power_deriv( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]]) assert_allclose(interp, ref_deriv) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power_deriv(xyz) interp = atgrid.interpolate(xyz, values, deriv=1) assert_allclose(interp, ref_value)
def test_interpolation_of_laplacian_with_spherical_harmonic(self): r"""Test the interpolation of Laplacian of spherical harmonic is eigenvector.""" odg = OneDGrid(np.linspace(0.0, 10, num=2000), np.ones(2000), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) degree = 6 * 2 + 2 atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) def func(sph_points): # Spherical harmonic of order 6 and magnetic 0 r, phi, theta = sph_points.T return (np.sqrt(2.0) * np.sqrt(13) / (np.sqrt(np.pi) * 32) * (231 * np.cos(theta)**6.0 - 315 * np.cos(theta)**4.0 + 105 * np.cos(theta)**2.0 - 5.0)) # Get spherical points from atomic grid spherical_pts = atgrid.convert_cartesian_to_spherical(atgrid.points) func_values = func(spherical_pts) laplacian = atgrid.interpolate_laplacian(func_values) # Test on the same points used for interpolation and random points. for grid in [atgrid.points, np.random.uniform(-0.75, 0.75, (250, 3))]: actual = laplacian(grid) spherical_pts = atgrid.convert_cartesian_to_spherical(grid) # Eigenvector spherical harmonic times l(l + 1) / r^2 with np.errstate(divide="ignore", invalid="ignore"): desired = (-func(spherical_pts) * 6 * (6 + 1) / spherical_pts[:, 0]**2.0) desired[spherical_pts[:, 0]**2.0 < 1e-10] = 0.0 assert_almost_equal(actual, desired, decimal=3)
def test_error_raises(self): """Tests for error raises.""" with self.assertRaises(TypeError): AtomGrid.from_pruned(np.arange(3), 1.0, r_sectors=np.arange(2), degs=np.arange(3)) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, r_sectors=np.arange(2), degs=np.arange(0), ) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, r_sectors=np.arange(2), degs=np.arange(4), ) with self.assertRaises(ValueError): AtomGrid._generate_atomic_grid( OneDGrid(np.arange(3), np.arange(3)), np.arange(2)) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, r_sectors=np.array([0.3, 0.5, 0.7]), degs=np.array([3, 5, 7, 5]), center=np.array([0, 0, 0, 0]), ) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), size=110) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degs=17) with self.assertRaises(ValueError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degs=[17], rotate=-1) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degs=[17], rotate="asdfaf") # error of radial grid with self.assertRaises(TypeError): AtomGrid(Grid(np.arange(1, 5, 1), np.ones(4)), degs=[2, 3, 4, 5]) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(-2, 2, 1), np.ones(4)), degs=[2, 3, 4, 5]) with self.assertRaises(TypeError): rgrid = OneDGrid(np.arange(1, 3, 1), np.ones(2), domain=(-1, 5)) AtomGrid(rgrid, degs=[2]) with self.assertRaises(TypeError): rgrid = OneDGrid(np.arange(-1, 1, 1), np.ones(2)) AtomGrid(rgrid, degs=[2])
def test_molgrid_attrs(self): """Test MolGrid attributes.""" # numbers = np.array([6, 8], int) coordinates = np.array([[0.0, 0.2, -0.5], [0.1, 0.0, 0.5]], float) atg1 = AtomGrid.from_pruned( self.rgrid, 1.228, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.945, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[1], ) becke = BeckeWeights(order=3) mg = MolGrid([atg1, atg2], becke, np.array([6, 8]), store=True) assert mg.size == 2 * 110 * 100 assert mg.points.shape == (mg.size, 3) assert mg.weights.shape == (mg.size, ) assert mg.aim_weights.shape == (mg.size, ) assert mg.get_atomic_grid(0) is atg1 assert mg.get_atomic_grid(1) is atg2 simple_ag1 = mg.get_atomic_grid(0) simple_ag2 = mg.get_atomic_grid(1) assert_allclose(simple_ag1.points, atg1.points) assert_allclose(simple_ag1.weights, atg1.weights) assert_allclose(simple_ag2.weights, atg2.weights) # test molgrid is not stored mg2 = MolGrid([atg1, atg2], becke, np.array([6, 8]), store=False) assert mg2._atomic_grids is None simple2_ag1 = mg2.get_atomic_grid(0) simple2_ag2 = mg2.get_atomic_grid(1) assert isinstance(simple2_ag1, LocalGrid) assert isinstance(simple2_ag2, LocalGrid) assert_allclose(simple2_ag1.points, atg1.points) assert_allclose(simple2_ag1.weights, atg1.weights) assert_allclose(simple2_ag2.weights, atg2.weights)
def test_molgrid_attrs_subgrid(self): """Test sub atomic grid attributes.""" # numbers = np.array([6, 8], int) coordinates = np.array([[0.0, 0.2, -0.5], [0.1, 0.0, 0.5]], float) atg1 = AtomGrid.from_pruned( self.rgrid, 1.228, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.945, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[1], ) becke = BeckeWeights(order=3) mg = MolGrid([atg1, atg2], becke, np.array([6, 8]), store=True) # mg = BeckeMolGrid(coordinates, numbers, None, (rgrid, 110), mode='keep') assert mg.size == 2 * 110 * 100 assert mg.points.shape == (mg.size, 3) assert mg.weights.shape == (mg.size, ) assert mg.aim_weights.shape == (mg.size, ) assert len(mg._indices) == 2 + 1 # assert mg.k == 3 # assert mg.random_rotate for i in range(2): atgrid = mg[i] assert isinstance(atgrid, AtomGrid) assert atgrid.size == 100 * 110 assert atgrid.points.shape == (100 * 110, 3) assert atgrid.weights.shape == (100 * 110, ) assert (atgrid.center == coordinates[i]).all() mg = MolGrid([atg1, atg2], becke, np.array([6, 8])) for i in range(2): atgrid = mg[i] assert isinstance(atgrid, LocalGrid) assert_allclose(atgrid.center, mg._coors[i])
def test_from_pruned_with_degs_and_size(self): """Test different initilize method.""" radial_pts = np.arange(0.1, 1.1, 0.1) radial_wts = np.ones(10) * 0.1 rgrid = OneDGrid(radial_pts, radial_wts) rad = 0.5 r_sectors = np.array([0.5, 1, 1.5]) degs = np.array([3, 5, 7, 5]) size = np.array([6, 14, 26, 14]) # construct atomic grid with degs atgrid1 = AtomGrid.from_pruned( rgrid, radius=rad, sectors_r=r_sectors, sectors_degree=degs ) # construct atomic grid with size atgrid2 = AtomGrid.from_pruned( rgrid, radius=rad, sectors_r=r_sectors, sectors_size=size ) # test two grids are the same assert_equal(atgrid1.size, atgrid2.size) assert_allclose(atgrid1.points, atgrid2.points) assert_allclose(atgrid1.weights, atgrid2.weights)
def test_cubicspline_and_interp_mol(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) result = spline_with_atomic_grid(atgrid, values) sph_coor = atgrid.convert_cart_to_sph() semi_sph_c = sph_coor[atgrid.indices[5] : atgrid.indices[6]] interp = interpolate(result, rad.points[5], semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5] : atgrid.indices[6]])
def test_cubicspline_and_interp_mol(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[i]:atgrid.indices[i + 1]])
def test_derivative_of_interpolate_given_splines(self): """Test the spline interpolating derivative of function in radial coordinate.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=1) # same result from points and interpolation ref_deriv = self.helper_func_power_deriv( atgrid.points[atgrid.indices[5]:atgrid.indices[6]]) assert_allclose(interp, ref_deriv) # test random x, y, z with fd xyz = np.random.rand(1, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power_deriv(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate_given_splines(result, np.abs(rad), theta, phi, deriv=1) assert_allclose(interp, ref_value) with self.assertRaises(ValueError): interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=4) with self.assertRaises(ValueError): interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=-1)
def test_horton_molgrid(self): """Test horton style grid.""" nums = np.array([1, 1]) coors = np.array([[0, 0, -0.5], [0, 0, 0.5]]) becke = BeckeWeights(order=3) mol_grid = MolGrid.horton_molgrid(coors, nums, self.rgrid, 110, becke) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coors[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coors[1], ) ref_grid = MolGrid([atg1, atg2], becke, nums, store=True) assert_allclose(ref_grid.points, mol_grid.points) assert_allclose(ref_grid.weights, mol_grid.weights)
def test_integrate_hirshfeld_weights_pair_1s(self): """Test molecular integral in H2.""" coordinates = np.array([[0.0, 0.0, -0.5], [0.0, 0.0, 0.5]]) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[1], ) mg = MolGrid([atg1, atg2], HirshfeldWeights(), np.array([1, 1])) dist0 = np.sqrt(((coordinates[0] - mg.points)**2).sum(axis=1)) dist1 = np.sqrt(((coordinates[1] - mg.points)**2).sum(axis=1)) fn = np.exp(-2 * dist0) / np.pi + 1.5 * np.exp(-2 * dist1) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 2.5, decimal=5)
def test_different_aim_weights_h2(self): """Test different aim_weights for molgrid.""" coordinates = np.array([[0.0, 0.0, -0.5], [0.0, 0.0, 0.5]], float) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates[1], ) # use an array as aim_weights mg = MolGrid([atg1, atg2], np.ones(22000), np.array([1, 1])) dist0 = np.sqrt(((coordinates[0] - mg.points)**2).sum(axis=1)) dist1 = np.sqrt(((coordinates[1] - mg.points)**2).sum(axis=1)) fn = np.exp(-2 * dist0) / np.pi + np.exp(-2 * dist1) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 4.0, decimal=4)
def test_integrate_hydrogen_pair_1s(self): """Test molecular integral in H2.""" coordinates = np.array([[0.0, 0.0, -0.5], [0.0, 0.0, 0.5]], float) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, sectors_r=np.array([]), sectors_degree=np.array([17]), center=coordinates[0], ) atg2 = AtomGrid.from_pruned( self.rgrid, 0.5, sectors_r=np.array([]), sectors_degree=np.array([17]), center=coordinates[1], ) becke = BeckeWeights(order=3) mg = MolGrid(np.array([1, 1]), [atg1, atg2], becke) dist0 = np.sqrt(((coordinates[0] - mg.points) ** 2).sum(axis=1)) dist1 = np.sqrt(((coordinates[1] - mg.points) ** 2).sum(axis=1)) fn = np.exp(-2 * dist0) / np.pi + np.exp(-2 * dist1) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 2.0, decimal=6)
def test_interpolate_given_splines(self): """Test points to interpolate to is the same as original function values.""" # Construct grid odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) # Construct the function values and splies. values = self.helper_func_power(atgrid.points) result = spline_with_atomic_grid(atgrid, values) # Obtain the spherical coordinates and interpolate from indices[5] to indices[6] sph_coor = atgrid.convert_cart_to_sph() semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, rad.points[5], semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5]:atgrid.indices[6]])
def test_get_localgrid_1s(self): """Test local grid for a molecule with one atom.""" nums = np.array([1]) coords = np.array([0.0, 0.0, 0.0]) # initialize MolGrid with atomic grid atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, sectors_r=np.array([]), sectors_degree=np.array([17]), center=coords, ) grid = MolGrid(np.array([1]), [atg1], BeckeWeights(), store=False) fn = np.exp(-2 * np.linalg.norm(grid.points, axis=-1)) assert_allclose(grid.integrate(fn), np.pi) # conventional local grid localgrid = grid.get_localgrid(coords, 12.0) localfn = np.exp(-2 * np.linalg.norm(localgrid.points, axis=-1)) assert localgrid.size < grid.size assert localgrid.size == 10560 assert_allclose(localgrid.integrate(localfn), np.pi) assert_allclose(fn[localgrid.indices], localfn) # "whole" loal grid, useful for debugging code using local grids wholegrid = grid.get_localgrid(coords, np.inf) assert wholegrid.size == grid.size assert_allclose(wholegrid.points, grid.points) assert_allclose(wholegrid.weights, grid.weights) assert_allclose(wholegrid.indices, np.arange(grid.size)) # initialize MolGrid like horton grid = MolGrid.from_size(nums, coords[np.newaxis, :], self.rgrid, 110, BeckeWeights(), store=True) fn = np.exp(-4.0 * np.linalg.norm(grid.points, axis=-1)) assert_allclose(grid.integrate(fn), np.pi / 8) localgrid = grid.get_localgrid(coords, 5.0) localfn = np.exp(-4.0 * np.linalg.norm(localgrid.points, axis=-1)) assert localgrid.size < grid.size assert localgrid.size == 9900 assert_allclose(localgrid.integrate(localfn), np.pi / 8, rtol=1e-5) assert_allclose(fn[localgrid.indices], localfn)
def test_integrate_hirshfeld_weights_single_1s(self): """Test molecular integral in H atom with Hirshfeld weights.""" pts = HortonLinear(100) tf = ExpRTransform(1e-5, 2e1) rgrid = tf.transform_1d_grid(pts) coordinates = np.array([0.0, 0.0, -0.5]) atg1 = AtomGrid.from_pruned( rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates, ) mg = MolGrid([atg1], HirshfeldWeights(), np.array([7])) dist0 = np.sqrt(((coordinates - mg.points)**2).sum(axis=1)) fn = np.exp(-2 * dist0) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 1.0, decimal=6)
def test_cubicspline_and_interp_gauss(self): """Test cubicspline interpolation values.""" oned = GaussLegendre(30) btf = BeckeTF(0.0001, 1.5) rad = btf.transform_1d_grid(oned) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) value_array = self.helper_func_gauss(atgrid.points) # random test points on gauss function for _ in range(20): r = np.random.rand(1)[0] * 2 theta = np.random.rand(10) phi = np.random.rand(10) x = r * np.sin(phi) * np.cos(theta) y = r * np.sin(phi) * np.sin(theta) z = r * np.cos(phi) inters = atgrid.interpolate(np.array((x, y, z)).T, value_array) assert_allclose(self.helper_func_gauss(np.array([x, y, z]).T), inters, atol=1e-4)
def test_integrate_hydrogen_single_1s(self): """Test molecular integral in H atom.""" # numbers = np.array([1], int) coordinates = np.array([0.0, 0.0, -0.5], float) # rgrid = BeckeTF.transform_grid(oned, 0.001, 0.5)[0] # rtf = ExpRTransform(1e-3, 1e1, 100) # rgrid = RadialGrid(rtf) atg1 = AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=coordinates, ) becke = BeckeWeights(order=3) mg = MolGrid([atg1], becke, np.array([1])) # mg = BeckeMolGrid(coordinates, numbers, None, (rgrid, 110), random_rotate=False) dist0 = np.sqrt(((coordinates - mg.points)**2).sum(axis=1)) fn = np.exp(-2 * dist0) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 1.0, decimal=6)
def test_value_fitting(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) spls = atgrid.fit(values) assert len(spls) == 16 for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) r = np.linalg.norm(sh_grid._points, axis=1) theta = np.arctan2(sh_grid._points[:, 1], sh_grid._points[:, 0]) phi = np.arccos(sh_grid._points[:, 2] / r) l_max = atgrid.l_max // 2 r_sph = atgrid._generate_real_sph_harm(l_max, theta, phi) r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) assert_allclose(r_sph_proj, [spl(shell) for spl in spls], atol=1e-10)
def test_interpolate_and_its_derivatives(self): """Test interpolation of derivative of polynomial function.""" odg = OneDGrid(np.linspace(0.01, 10, num=50), np.ones(50), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): points = atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]] interp_func = atgrid.interpolate(values) # same result from points and interpolation ref_deriv = self.helper_func_power(points, deriv=1) assert_almost_equal(interp_func(points, deriv=1), ref_deriv) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power(xyz, deriv=1) interp_func = atgrid.interpolate(values) interp = interp_func(xyz, deriv=1) assert_allclose(interp, ref_value) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power_deriv(xyz) interp_func = atgrid.interpolate(values) interp = interp_func(xyz, deriv=1, only_radial_derivs=True) assert_allclose(interp, ref_value) with self.assertRaises(ValueError): # Raise error since it can't do derivative beyond one. interp_func(xyz, deriv=3)
def test_interpolate_given_splines_at_random_points(self): """Test interpolation given splines at random points.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5]:atgrid.indices[6]]) # random multiple interpolation test for _ in range(100): indices = np.random.randint(1, 11, np.random.randint(1, 10)) interp = interpolate_given_splines(result, indices, semi_sph_c[:, 1], semi_sph_c[:, 2]) for i, j in enumerate(indices): assert_allclose( interp[i], values[atgrid.indices[j - 1]:atgrid.indices[j]]) # test random x, y, z xyz = np.random.rand(10, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate_given_splines(result, np.abs(rad), theta, phi) assert_allclose(interp, ref_value)
def test_integrate_hydrogen_8_1s(self): """Test molecular integral in H2.""" x, y, z = np.meshgrid(*(3 * [[-0.5, 0.5]])) centers = np.stack([x.ravel(), y.ravel(), z.ravel()], axis=1) atgs = [ AtomGrid.from_pruned( self.rgrid, 0.5, r_sectors=np.array([]), degs=np.array([17]), center=center, ) for center in centers ] becke = BeckeWeights(order=3) mg = MolGrid(atgs, becke, np.array([1] * len(centers))) fn = 0 for center in centers: dist = np.linalg.norm(center - mg.points, axis=1) fn += np.exp(-2 * dist) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, len(centers), decimal=2)
def test_value_fitting(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) spls = atgrid.radial_component_splines(values) assert len(spls) == 16 for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) spherical_pts = atgrid.convert_cartesian_to_spherical( sh_grid.points) _, theta, phi = spherical_pts.T l_max = atgrid.l_max // 2 r_sph = generate_real_spherical_harmonics(l_max, theta, phi) r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) assert_allclose(r_sph_proj, [spl(shell) for spl in spls], atol=1e-10)
def test_error_raises(self): """Tests for error raises.""" with self.assertRaises(TypeError): AtomGrid.from_pruned(np.arange(3), 1.0, sectors_r=np.arange(2), sectors_degree=np.arange(3)) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, sectors_r=np.arange(2), sectors_degree=np.arange(0), ) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, sectors_r=np.arange(2), sectors_degree=np.arange(4), ) with self.assertRaises(ValueError): AtomGrid._generate_atomic_grid( OneDGrid(np.arange(3), np.arange(3)), np.arange(2)) with self.assertRaises(ValueError): AtomGrid.from_pruned( OneDGrid(np.arange(3), np.arange(3)), radius=1.0, sectors_r=np.array([0.3, 0.5, 0.7]), sectors_degree=np.array([3, 5, 7, 5]), center=np.array([0, 0, 0, 0]), ) # test preset with self.assertRaises(ValueError): AtomGrid.from_preset(atnum=1, preset="fine") with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), sizes=110) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degrees=17) with self.assertRaises(ValueError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degrees=[17], rotate=-1) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(3), np.arange(3)), degrees=[17], rotate="asdfaf") # error of radial grid with self.assertRaises(TypeError): AtomGrid(Grid(np.arange(1, 5, 1), np.ones(4)), degrees=[2, 3, 4, 5]) with self.assertRaises(TypeError): AtomGrid(OneDGrid(np.arange(-2, 2, 1), np.ones(4)), degrees=[2, 3, 4, 5]) with self.assertRaises(TypeError): rgrid = OneDGrid(np.arange(1, 3, 1), np.ones(2), domain=(-1, 5)) AtomGrid(rgrid, degrees=[2]) with self.assertRaises(TypeError): rgrid = OneDGrid(np.arange(-1, 1, 1), np.ones(2)) AtomGrid(rgrid, degrees=[2]) with self.assertRaises(ValueError): AtomGrid._generate_real_sph_harm(-1, np.random.rand(10), np.random.rand(10)) with self.assertRaises(ValueError): oned = GaussLegendre(30) btf = BeckeTF(0.0001, 1.5) rad = btf.transform_1d_grid(oned) atgrid = AtomGrid.from_preset(rad, atnum=1, preset="fine") atgrid.fit_values(np.random.rand(100))