def test_from_predefined(self): """Test grid construction with predefined grid.""" # test coarse grid pts = HortonLinear(20) tf = PowerRTransform(7.0879993828935345e-06, 16.05937640019924) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "coarse") # 604 points for coarse H atom assert_equal(atgrid.size, 604) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56840953, ) # test medium grid pts = HortonLinear(24) tf = PowerRTransform(3.69705074304963e-06, 19.279558946793685) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "medium") # 928 points for coarse H atom assert_equal(atgrid.size, 928) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56834559, ) # test fine grid pts = HortonLinear(34) tf = PowerRTransform(2.577533167224667e-07, 16.276983371222354) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "fine") # 1984 points for coarse H atom assert_equal(atgrid.size, 1984) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56832800, ) # test veryfine grid pts = HortonLinear(41) tf = PowerRTransform(1.1774580743206259e-07, 20.140888089596444) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "veryfine") # 3154 points for coarse H atom assert_equal(atgrid.size, 3154) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56832800, ) # test ultrafine grid pts = HortonLinear(49) tf = PowerRTransform(4.883104847991021e-08, 21.05456999309752) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "ultrafine") # 4546 points for coarse H atom assert_equal(atgrid.size, 4546) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56832800, ) # test insane grid pts = HortonLinear(59) tf = PowerRTransform(1.9221827244049134e-08, 21.413278983919113) rad_grid = tf.transform_1d_grid(pts) atgrid = AtomGrid.from_predefined(1, rad_grid, "insane") # 6622 points for coarse H atom assert_equal(atgrid.size, 6622) assert_almost_equal( np.sum(np.exp(-np.sum(atgrid.points**2, axis=1)) * atgrid.weights), 5.56832800, )
def test_make_grid_different_grid_type(self): """Test different kind molgrid initizalize setting.""" # three different radial grid rad2 = GaussLaguerre(50) rad3 = GaussLaguerre(70) # construct grid numbers = np.array([1, 8, 1]) coordinates = np.array( [[0.0, 0.0, -0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0]], float) becke = BeckeWeights(order=3) # grid_type test with list mg = MolGrid.make_grid( numbers, coordinates, rad2, ["fine", "veryfine", "medium"], becke, store=True, ) 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.exp(-2 * dist1) + np.exp(-2 * dist2)) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 3, decimal=3) atgrid1 = AtomGrid.from_predefined(numbers[0], rad2, "fine", center=coordinates[0]) atgrid2 = AtomGrid.from_predefined(numbers[1], rad2, "veryfine", center=coordinates[1]) atgrid3 = AtomGrid.from_predefined(numbers[2], rad2, "medium", center=coordinates[2]) assert_allclose(mg._atomic_grids[0].points, atgrid1.points) assert_allclose(mg._atomic_grids[1].points, atgrid2.points) assert_allclose(mg._atomic_grids[2].points, atgrid3.points) # grid type test with dict mg = MolGrid.make_grid(numbers, coordinates, rad3, { 1: "fine", 8: "veryfine" }, becke, store=True) 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.exp(-2 * dist1) + np.exp(-2 * dist2)) / np.pi occupation = mg.integrate(fn) assert_almost_equal(occupation, 3, decimal=3) atgrid1 = AtomGrid.from_predefined(numbers[0], rad3, "fine", center=coordinates[0]) atgrid2 = AtomGrid.from_predefined(numbers[1], rad3, "veryfine", center=coordinates[1]) atgrid3 = AtomGrid.from_predefined(numbers[2], rad3, "fine", center=coordinates[2]) assert_allclose(mg._atomic_grids[0].points, atgrid1.points) assert_allclose(mg._atomic_grids[1].points, atgrid2.points) assert_allclose(mg._atomic_grids[2].points, atgrid3.points)
def make_grid( cls, atom_nums, coordinates, radial_grid, grid_type, aim_weights, *_, rotate=False, store=False, ): """Contruct molecular grid wih preset parameters. Parameters ---------- atom_nums : np.ndarray(N,) array of atomic number coordinates : np.ndarray(N, 3) atomic coordinates of atoms radial_grid : OneDGrid one dimension grid to construct spherical grid grid_type : str preset grid accuracy scheme, support "coarse", "medium", "fine", "veryfine", "ultrafine", "insane" aim_weights : Callable or np.ndarray(K,) Atoms in molecule weights. rotate : bool, optional Random rotate for each shell of atomic grid store : bool, optional Store atomic grid separately """ # construct for a atom molecule if coordinates.ndim != 2: raise ValueError("The dimension of coordinates need to be 2\n" f"got shape: {coordinates.ndim}") if len(atom_nums) != coordinates.shape[0]: raise ValueError( "shape of atomic nums does not match with coordinates\n" f"atomic numbers: {atom_nums.shape}, coordinates: {coordinates.shape}" ) total_atm = len(atom_nums) atomic_grids = [] for i in range(total_atm): # get proper radial grid if isinstance(radial_grid, OneDGrid): rad = radial_grid elif isinstance(radial_grid, list): rad = radial_grid[i] elif isinstance(radial_grid, dict): rad = radial_grid[atom_nums[i]] else: raise TypeError("not supported radial grid input\n" f"got input type: {type(radial_grid)}") # get proper grid type if isinstance(grid_type, str): gd_type = grid_type elif isinstance(grid_type, list): gd_type = grid_type[i] elif isinstance(grid_type, dict): gd_type = grid_type[atom_nums[i]] else: raise TypeError("not supported grid_type input\n" f"got input type: {type(grid_type)}") at_grid = AtomGrid.from_predefined(atom_nums[i], rad, gd_type, center=coordinates[i], rotate=rotate) atomic_grids.append(at_grid) return cls(atomic_grids, aim_weights, atom_nums, store=store)