def test_size_to_degree(self): """Test size to degree conversion.""" # first test nums = [38, 50, 74, 86, 110, 38, 50, 74] degs = size_to_degree(nums) ref_degs = [9, 11, 13, 15, 17, 9, 11, 13] assert_array_equal(degs, ref_degs) # second test nums = [6] degs = size_to_degree(nums) ref_degs = [3] assert_array_equal(degs, ref_degs)
def from_predefined( cls, atomic_num, rgrid, grid_type, *_, center=None, rotate=False, ): """High level to construct prefined atomic grid. Examples -------- # construct an atomic grid for H with fine grid setting >>> atgrid = AtomGrid.from_predefined(1, rgrid, "fine") Parameters ---------- atomic_num : int atomic number of atomic grid rgrid : RadialGrid points where sperical grids will be located grid_type : str different accuracy for atomic grid include: 'coarse', 'medium', 'fine', 'veryfine', 'ultrafine', 'insane' center : np.ndarray(3,), optional if not given, default (0., 0., 0.) is used coordinates of grid center rotate : bool or int , optional Flag to set auto rotation for atomic grid, if given int, the number will be used as a seed to generate rantom matrix. """ center = (np.zeros(3, dtype=float) if center is None else np.asarray(center, dtype=float)) cls._input_type_check(rgrid, center) # load radial points and with path("grid.data.prune_grid", f"prune_grid_{grid_type}.npz") as npz_file: data = np.load(npz_file) # load predefined_radial sectors and num_of_points in each sectors rad = data[f"{atomic_num}_rad"] npt = data[f"{atomic_num}_npt"] degs = size_to_degree(npt) rad_degs = AtomGrid._find_l_for_rad_list(rgrid.points, rad, degs) return cls(rgrid, degs=rad_degs, center=center, rotate=rotate)
def from_pruned( cls, rgrid, radius, *_, r_sectors, degs=None, size=None, center=None, rotate=False, ): """Initialize an instance for given r_sectors of radius and degrees. Examples -------- >>> r_sectors = [0.5, 1., 1.5] >>> degs = [3, 7, 5, 3] rad is the radius of atom # 0 <= r < 0.5rad, angular grid with degree 3 # 0.5rad <= r < rad, angular grid with degree 7 # rad <= r < 1.5rad, angular grid with degree 5 # 1.5rad <= r, angular grid with degree 3 >>> atgrid = AtomGrid.from_pruned(rgrid, radius, degs, r_sectors, center) Parameters ---------- rgrid : RadialGrid Radial grid. radius : float Atomic radius for target atom. r_sectors : np.ndarray(N,), keyword-only argument r_sectors to define different regions on the radial axis. The first region is ``[0, radius*r_sectors[0]]``, then ``[radius*r_sectors[0], radius*r_sectors[1]]``, and so on. degs : np.ndarray(N + 1, dtype=int), keyword-only argument The degree of Lebedev-Laikov grid points for each section of atomic radius region. size : np.ndarray(N + 1, dtype=int), keyword-only argument The degree of Lebedev-Laikov grid points for each section of atomic radius region. Note: either degs or size is needed to construct an atomic grid center : np.ndarray(3, ), keyword-only argument if not given, (0., 0., 0.) will be used Cartesian coordinates of to origin of the spherical grids. rotate : bool or int , optional Flag to set auto rotation for atomic grid, if given int, the number will be used as a seed to generate rantom matrix. Returns ------- AtomGrid Generated AtomGrid instance for this special init method. """ if degs is None: degs = size_to_degree(size) center = (np.zeros(3, dtype=float) if center is None else np.asarray(center, dtype=float)) cls._input_type_check(rgrid, center) degs = cls._generate_degree_from_radius(rgrid, radius, r_sectors, degs) return cls(rgrid, degs=degs, center=center, rotate=rotate)
def __init__( self, rgrid, *, degs=None, size=None, center=None, rotate=False, ): """Construct atomic grid for given arguments. Parameters ---------- rgrid : OneDGrid A 1D grid with positive domain representing the radial component of grid. degs : np.ndarray(N, dtype=int) or list, keyword-only argument Different degree value for each radial point size : np.ndarray(N, dtype=int) or list, keyword-only argument Different number of angular points for each radial point center : np.ndarray(3,), optional, keyword-only argument if not given, default to (0., 0., 0.) Central cartesian coordinates of atomic grid rotate : bool or int , optional Flag to set auto rotation for atomic grid, if given int, the number will be used as a seed to generate rantom matrix. Raises ------ TypeError ``rgrid`` needs to be an instance of ``Grid`` class. ValueError Length of ``degs`` should be one more than ``r_sectors``. """ # check stage, if center is None, set to (0., 0., 0.) center = (np.zeros(3, dtype=float) if center is None else np.asarray(center, dtype=float)) self._input_type_check(rgrid, center) # assign & check stage self._center = center self._rgrid = rgrid # check rotate if not isinstance(rotate, (int, np.integer)): raise TypeError( f"rotate needs to be an bool or integer, got {type(rotate)}") if (rotate is not False) and (not 0 <= rotate < 2**32): raise ValueError( f"rotate need to be an integer [0, 2^32 - 1]\n" f"rotate is not within [0, 2^32 - 1], got {rotate}") self._rot = rotate # check degs and size if degs is None: if not isinstance(size, (np.ndarray, list)): raise TypeError( f"size is not type: np.array or list, got {type(size)}") degs = size_to_degree(size) if not isinstance(degs, (np.ndarray, list)): raise TypeError( f"degs is not type: np.array or list, got {type(degs)}") if len(degs) == 1: degs = np.ones(rgrid.size) * degs self._rad_degs = degs self._points, self._weights, self._indices = self._generate_atomic_grid( self._rgrid, self._rad_degs, rotate=self._rot) self._size = self._weights.size
def __init__( self, radial_grid, *, degs=None, nums=None, center=np.array([0.0, 0.0, 0.0]), rotate=False, ): """Construct atomic grid for given arguments. Parameters ---------- radial_grid : RadialGrid Radial grid degs : np.ndarray(N, dtype=int) or list, keyword-only argument Different degree value for each radial point nums : np.ndarray(N, dtype=int) or list, keyword-only argument Different number of angular points for eah radial point center : np.ndarray(3,), optional, keyword-only argument Central cartesian coordinates of atomic grid rotate : bool or int , optional Flag to set auto rotation for atomic grid, if given int, the number will be used as a seed to generate rantom matrix. Raises ------ TypeError ``radial_grid`` needs to be an instance of ``Grid`` class. ValueError Length of ``degs`` should be one more than ``scales``. """ # check stage self._input_type_check(radial_grid, center) # assign stage self._center = np.array(center) self._radial_grid = radial_grid if degs is None: if not isinstance(nums, (np.ndarray, list)): raise TypeError( f"nums is not type: np.array or list, got {type(nums)}") degs = size_to_degree(nums) if not isinstance(degs, (np.ndarray, list)): raise TypeError( f"degs is not type: np.array or list, got {type(degs)}") if len(degs) == 1: degs = np.ones(radial_grid.size) * degs self._rad_degs = degs self._points, self._weights, self._indices = self._generate_atomic_grid( self._radial_grid, self._rad_degs) self._size = self._weights.size # add random rotation if rotate is not False: if rotate is True: rot_mt = R.random().as_dcm() self._points = np.dot(self._points, rot_mt) elif isinstance(rotate, (int, np.integer)) and rotate >= 0: rot_mt = R.random(random_state=rotate).as_dcm() self._points = np.dot(self._points, rot_mt) else: raise ValueError( f"rotate need to be an integer [0, 2^32 - 1]\n" f"rotate is not within [0, 2^32 - 1], got {rotate}")