Beispiel #1
0
def test_atomic_grid_basics1():
    center = np.random.uniform(-1, 1, 3)
    rtf = ExpRTransform(0.1, 1e1, 4)
    rgrid = RadialGrid(rtf)
    for random_rotate in True, False:
        ag0 = AtomicGrid(1, 1, center, (rgrid, 6), random_rotate)
        assert abs(ag0.points.mean(axis=0) - center).max() < 1e-10
        assert (ag0.nlls == 6).all()
        assert ag0.nsphere == 4
        assert (ag0.lmaxs == 3).all()
        ag1 = AtomicGrid(1, 1, center, (rgrid, [6, 6, 6, 6]), random_rotate)
        assert abs(ag1.points.mean(axis=0) - center).max() < 1e-10
        assert (ag0.nlls == 6).all()
        assert ag0.nsphere == 4
        assert (ag0.lmaxs == 3).all()
        assert abs(ag0.weights - ag1.weights).max() < 1e-10
        assert (abs(ag0.points - ag1.points).max() < 1e-10) ^ random_rotate
Beispiel #2
0
def test_spherical_average_grads1():
    center = np.random.uniform(-1, 1, 3)
    rtf = PowerRTransform(1e-3, 2e1, 100)
    rgrid = RadialGrid(rtf)
    ag = AtomicGrid(1, 1, center, (rgrid, 110), 100)

    delta = ag.points - ag.center
    d = np.sqrt(delta[:, 0]**2 + delta[:, 1]**2 + delta[:, 2]**2)

    fy1 = np.exp(-d**2)
    fg1 = -2 * delta * (np.exp(-d**2)).reshape(-1, 1)

    r = ag.rgrid.rtransform.get_radii()
    say, sad = ag.get_spherical_average(fy1, grads=[fg1])
    say_check = np.exp(-r**2)
    sad_check = -2 * r * np.exp(-r**2)
    assert abs(say - say_check).max() < 1e-10
    assert abs(sad - sad_check).max() < 1e-10
Beispiel #3
0
def get_hydrogen_1s():
    # density of the 1s orbital
    center = np.random.uniform(-1, 1, 3)
    rtf = PowerRTransform(1e-3, 2e1, 100)
    rgrid = RadialGrid(rtf)
    ag = AtomicGrid(1, 1, center, (rgrid, 110), 100)
    distances = np.sqrt(((center - ag.points)**2).sum(axis=1))
    fn = np.exp(-2 * distances) / np.pi
    return ag, fn
Beispiel #4
0
def test_atomic_grid_basics2():
    center = np.random.uniform(-1, 1, 3)
    rtf = ExpRTransform(0.1, 1e1, 3)
    rgrid = RadialGrid(rtf)
    ag2 = AtomicGrid(1, 1, center, (rgrid, [6, 14, 26]))
    assert abs(ag2.points.mean(axis=0) - center).max() < 1e-10
    assert (ag2.nlls == [6, 14, 26]).all()
    assert ag2.nsphere == 3
    assert (ag2.lmaxs == [3, 5, 7]).all()
Beispiel #5
0
def get_hydrogen_1pz():
    # density of the 1pz orbital
    center = np.random.uniform(-1, 1, 3)
    rtf = PowerRTransform(1e-3, 2e1, 100)
    rgrid = RadialGrid(rtf)
    ag = AtomicGrid(1, 1, center, (rgrid, 110), 100)
    z = ag.points[:, 2] - center[2]
    distances = np.sqrt(((center - ag.points)**2).sum(axis=1))
    fn = np.exp(-distances) / (32.0 * np.pi) * z**2
    return ag, fn
Beispiel #6
0
def test_atgrid_attrs():
    center = np.array([0.7, 0.2, -0.5], float)
    rtf = ExpRTransform(1e-3, 1e1, 50)
    rgrid = RadialGrid(rtf)
    ag = AtomicGrid(3, 3, center, (rgrid, 26))

    assert ag.size == 50 * 26
    assert ag.points.shape == (50 * 26, 3)
    assert ag.weights.shape == (50 * 26, )
    assert ag.subgrids is None
    assert ag.number == 3
    assert (ag.center == center).all()
    assert ag.rgrid.rtransform == rtf
    assert (ag.nlls == [26] * 50).all()
    assert ag.nsphere == 50
    assert ag.random_rotate
Beispiel #7
0
    def __init__(self,
                 centers,
                 numbers,
                 pseudo_numbers=None,
                 agspec='medium',
                 k=3,
                 random_rotate=True,
                 mode='discard'):
        """
           **Arguments:**

           centers
                An array (N, 3) with centers for the atom-centered grids.

           numbers
                An array (N,) with atomic numbers.

           **Optional arguments:**

           pseudo_numbers
                An array (N,) with effective core charges. When not given, this
                defaults to ``numbers``.

           agspec
                A specifications of the atomic grid. This can either be an
                instance of the AtomicGridSpec object, or the first argument
                of its constructor.

           k
                The order of the switching function in Becke's weighting scheme.

           random_rotate
                Flag to control random rotation of spherical grids.

           mode
                Select one of the following options regarding atomic subgrids:

                * ``'discard'`` (the default) means that all information about
                  subgrids gets discarded.

                * ``'keep'`` means that a list of subgrids is kept, including
                  the integration weights of the local grids.

                * ``'only'`` means that only the subgrids are constructed and
                  that the computation of the molecular integration weights
                  (based on the Becke partitioning) is skipped.
        """
        natom, centers, numbers, pseudo_numbers = typecheck_geo(
            centers, numbers, pseudo_numbers)
        self._centers = centers
        self._numbers = numbers
        self._pseudo_numbers = pseudo_numbers

        # check if the mode argument is valid
        if mode not in ['discard', 'keep', 'only']:
            raise ValueError(
                'The mode argument must be \'discard\', \'keep\' or \'only\'.')

        # transform agspec into a usable format
        if not isinstance(agspec, AtomicGridSpec):
            agspec = AtomicGridSpec(agspec)
        self._agspec = agspec

        # assign attributes
        self._k = k
        self._random_rotate = random_rotate
        self._mode = mode

        # allocate memory for the grid
        size = sum(
            agspec.get_size(self.numbers[i], self.pseudo_numbers[i])
            for i in range(natom))
        points = np.zeros((size, 3), float)
        weights = np.zeros(size, float)
        self._becke_weights = np.ones(size, float)

        # construct the atomic grids
        if mode != 'discard':
            atgrids = []
        else:
            atgrids = None
        offset = 0

        if mode != 'only':
            # More recent covalent radii are used than in the original work of Becke.
            # No covalent radius is defined for elements heavier than Curium and a
            # default value of 3.0 Bohr is used for heavier elements.
            cov_radii = np.array([(periodic[n].cov_radius or 3.0)
                                  for n in self.numbers])

        # The actual work:
        logging.info('Preparing Becke-Lebedev molecular integration grid.')
        for i in range(natom):
            atsize = agspec.get_size(self.numbers[i], self.pseudo_numbers[i])
            atgrid = AtomicGrid(self.numbers[i], self.pseudo_numbers[i],
                                self.centers[i], agspec, random_rotate,
                                points[offset:offset + atsize])
            if mode != 'only':
                atbecke_weights = self._becke_weights[offset:offset + atsize]
                becke_helper_atom(points[offset:offset + atsize],
                                  atbecke_weights, cov_radii, self.centers, i,
                                  self._k)
                weights[offset:offset +
                        atsize] = atgrid.weights * atbecke_weights
            if mode != 'discard':
                atgrids.append(atgrid)
            offset += atsize

        # finish
        IntGrid.__init__(self, points, weights, atgrids)

        # Some screen info
        self._log_init()