示例#1
0
    def test_equidistant_trimer(self):
        with DescriptorSet(['Ag'], cutoff=8.0) as ds:
            types = ['Ag', 'Ag', 'Ag']

            N = 30
            r_vec = np.linspace(1., 5., N)
            theta_vec = np.linspace(0.0 * np.pi, 2. * np.pi, N, endpoint=True)
            for ri in r_vec:
                for ti in theta_vec:
                    xyzs = np.array([[0.0, 0.0, 0.0], [ri, 0.0, 0.0],
                                     [ri * np.cos(ti), ri * np.sin(ti), 0.0]])

                    Gs = ds.eval(types, xyzs)
                    Gs_atomwise = ds.eval_atomwise(types, xyzs)
                    np.testing.assert_allclose(Gs,
                                               Gs_atomwise,
                                               equal_nan=False)

                    dGs = ds.eval_derivatives(types, xyzs)
                    dGs_atomwise = ds.eval_derivatives_atomwise(types, xyzs)
                    np.testing.assert_allclose(dGs,
                                               dGs_atomwise,
                                               equal_nan=False)

                    Gs, dGs = ds.eval_with_derivatives(types, xyzs)
                    Gs_atomwise, dGs_atomwise = (
                        ds.eval_with_derivatives_atomwise(types, xyzs))
                    np.testing.assert_allclose(Gs,
                                               Gs_atomwise,
                                               equal_nan=False)
                    np.testing.assert_allclose(dGs,
                                               dGs_atomwise,
                                               equal_nan=False,
                                               atol=1e-15)
示例#2
0
    def test_derivaties(self):
        with DescriptorSet(['Ni', 'Au'], cutoff=10.) as ds:
            pos = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0],
                            [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]])
            types = ['Ni', 'Ni', 'Au', 'Ni', 'Au']

            rss = [0.0, 0.0, 0.0]
            etas = [1.0, 0.01, 0.0001]

            ds.add_G2_functions(rss, etas)
            ds.add_G5_functions(etas, [1.0], [1.0])

            out_cpp = ds.eval(types, pos)
            analytical_derivatives = ds.eval_derivatives(types, pos)
            numerical_derivatives = np.zeros(
                (len(out_cpp), out_cpp[0].size, pos.size))
            dx = np.sqrt(np.finfo(float).eps)
            for i in range(pos.size):
                dpos = np.zeros(pos.shape)
                dpos[np.unravel_index(i, dpos.shape)] += dx
                numerical_derivatives[:, :, i] = (
                    np.array(ds.eval(types, pos + dpos)) -
                    np.array(ds.eval(types, pos - dpos))) / (2 * dx)

        np.testing.assert_array_almost_equal(
            numerical_derivatives.flatten(),
            np.array(analytical_derivatives).flatten())
示例#3
0
    def test_eval_with_derivatives(self):
        xyzs = np.array([
            [1.19856, 0.00000, 0.71051],  # C
            [2.39807, 0.00000, 0.00000],  # C
            [2.35589, 0.00000, -1.39475],  # C
            [1.19865, 0.00000, -2.09564],  # N
            [0.04130, 0.00000, -1.39453],  # C
            [0.00000, 0.00000, 0.00000],  # C
            [-0.95363, 0.00000, 0.52249],  # H
            [3.35376, 0.00000, 0.51820],  # H
            [3.26989, 0.00000, -1.98534],  # H
            [-0.87337, 0.00000, -1.98400],  # H
            [1.19077, 0.00000, 2.07481],  # O
            [2.10344, 0.00000, 2.41504]
        ])  # H
        types = ['C', 'C', 'C', 'N', 'C', 'C', 'H', 'H', 'H', 'H', 'O', 'H']

        with DescriptorSet(['C', 'N', 'H', 'O'], cutoff=7.0) as ds:
            # Parameters from Artrith and Kolpak Nano Lett. 2014, 14, 2670
            ds.add_Artrith_Kolpak_set()

            Gs_ref = ds.eval(types, xyzs)
            dGs_ref = ds.eval_derivatives(types, xyzs)
            Gs, dGs = ds.eval_with_derivatives(types, xyzs)
            np.testing.assert_allclose(Gs, Gs_ref)
            np.testing.assert_allclose(dGs, dGs_ref)
示例#4
0
 def test_exceptions(self):
     with DescriptorSet(['H', 'O']) as ds:
         try:
             ds.add_two_body_descriptor('H', 'O', 'FOO', [])
         except TypeError:
             pass
         try:
             ds.add_three_body_descriptor('H', 'O', 'H', 'FOO', [])
         except TypeError:
             pass
         try:
             ds.add_two_body_descriptor('H',
                                        'O',
                                        'BehlerG1', [],
                                        cuttype='FOO')
         except TypeError:
             pass
         try:
             ds.add_three_body_descriptor('H',
                                          'O',
                                          'O',
                                          'BehlerG4', [1.0, 1.0, 1.0],
                                          cuttype='FOO')
         except TypeError:
             pass
示例#5
0
    def test_dimer_polynomial(self):
        with DescriptorSet(['Au'], cutoff=7.) as ds:
            types = ['Au', 'Au']
            rss = [0.0, 0.0, 0.0]
            bohr2ang = 0.529177249
            etas = np.array([0.01, 0.1, 1.0]) / bohr2ang**2

            ds.add_G2_functions(rss, etas, cuttype='polynomial')

            def cutfun(r):
                return (1 - 10.0 * (r / ds.cutoff)**3 + 15.0 *
                        (r / ds.cutoff)**4 - 6.0 *
                        (r / ds.cutoff)**5) * (r < ds.cutoff)

            dr = np.sqrt(np.finfo(float).eps)
            for ri in np.linspace(2, 8, 10):
                Gi = ds.eval(types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0,
                                                                ri]]))
                # Assert Symmmetry
                np.testing.assert_array_equal(Gi[0], Gi[1])
                # Assert Values
                np.testing.assert_allclose(
                    Gi[0],
                    np.exp(-etas * (ri - rss)**2) * cutfun(ri))
                # Derivatives
                dGa = ds.eval_derivatives(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri]]))
                # Assert Symmmetry
                np.testing.assert_array_equal(dGa[0], dGa[1])
                # Assert Values
                np.testing.assert_allclose(
                    dGa[0][:, 1, -1],
                    np.exp(-etas * (ri - rss)**2) *
                    (cutfun(ri) * 2.0 * (-etas) * (ri - rss) +
                     (-30.0 * (ri**2 / ds.cutoff**3) + 60.0 *
                      (ri**3 / ds.cutoff**4) - 30.0 * (ri**4 / ds.cutoff**5)) *
                     (ri < ds.cutoff)))

                Gi_drp = ds.eval(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri + dr]]))
                Gi_drm = ds.eval(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri - dr]]))
                dGn = [(Gi_drp[i] - Gi_drm[i]) / (2 * dr) for i in [0, 1]]
                # Assert Symmetry
                np.testing.assert_array_equal(dGn[0], dGn[1])
                # Assert Values
                np.testing.assert_allclose(dGa[0][:, 1, -1],
                                           dGn[0],
                                           rtol=1E-7,
                                           atol=1E-7)
示例#6
0
    def test_dimer_cos(self):
        with DescriptorSet(['Au'], cutoff=7.) as ds:
            types = ['Au', 'Au']
            rss = [0.0, 0.0, 0.0]
            etas = np.array([0.01, 0.1, 1.0])

            ds.add_G2_functions(rss, etas)

            def cutfun(r):
                return 0.5 * (1.0 +
                              np.cos(np.pi * r / ds.cutoff)) * (r < ds.cutoff)

            dr = np.sqrt(np.finfo(float).eps)
            for ri in np.linspace(0.1, 8, 101):
                Gi = ds.eval(types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0,
                                                                ri]]))
                # Assert Symmmetry
                np.testing.assert_array_equal(Gi[0], Gi[1])
                # Assert Values
                np.testing.assert_allclose(
                    Gi[0],
                    np.exp(-etas * (ri - rss)**2) * cutfun(ri))
                # Derivatives
                dGa = ds.eval_derivatives(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri]]))
                # Assert Symmetry
                np.testing.assert_array_equal(dGa[0], dGa[1])
                # Assert Values
                np.testing.assert_allclose(
                    dGa[0][:, 1, -1],
                    np.exp(-etas * (ri - rss)**2) *
                    (cutfun(ri) * 2.0 * (-etas) * (ri - rss) + 0.5 *
                     (-np.sin(np.pi * ri / ds.cutoff) * np.pi / ds.cutoff) *
                     (ri < ds.cutoff)))

                Gi_drp = ds.eval(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri + dr]]))
                Gi_drm = ds.eval(
                    types, np.array([[0.0, 0.0, 0.0], [0.0, 0.0, ri - dr]]))
                dGn = [(Gi_drp[i] - Gi_drm[i]) / (2 * dr) for i in [0, 1]]
                # Assert Symmetry
                np.testing.assert_array_equal(dGn[0], dGn[1])
                # Assert Values
                np.testing.assert_allclose(dGa[0][:, 1, -1],
                                           dGn[0],
                                           rtol=1E-7,
                                           atol=1E-7)
示例#7
0
        def test_derivatives_numerically(self):
            with DescriptorSet(['Au', 'Ag'], cutoff=self.cutoff) as ds:
                self.add_descriptor(ds)
                types = ['Au', 'Ag', 'Ag', 'Ag', 'Ag', 'Ag']
                xyzs = np.array([[0.0, 0.0, 0.0], [1.2, 0.0, 0.0],
                                 [-1.1, 0.0, 0.0], [0.0, 1.2, 0.0],
                                 [1., 2., 3.], [3, 2., 1.]])

                dG = ds.eval_derivatives_atomwise(types, xyzs)[0][0]
                dG_num = np.zeros_like(dG)
                delta = 1e-6
                for i in range(len(xyzs)):
                    for j in range(3):
                        dx = np.zeros_like(xyzs)
                        dx[i, j] = delta
                        G_plus = ds.eval_atomwise(types, xyzs + dx)[0]
                        G_minus = ds.eval_atomwise(types, xyzs - dx)[0]
                        dG_num[i, j] = (G_plus - G_minus) / (2 * delta)
                np.testing.assert_allclose(dG_num, dG, atol=1e-9)
示例#8
0
        def test_cutoff_function(self):
            r_vec = np.linspace(0.1, 8, 80)
            geos = [[('F', np.array([0.0, 0.0, 0.0])),
                    ('H', np.array([0.0, 0.0, ri]))] for ri in r_vec]
            with DescriptorSet(['H', 'F'], cutoff=6.5) as ds:
                for (t1, t2) in product(ds.atomtypes, repeat=2):
                    ds.add_two_body_descriptor(
                        t1, t2, 'BehlerG1', [], cuttype=self.cuttype)

                Gs = []
                dGs = []
                for geo in geos:
                    Gs.append(ds.eval_geometry(geo))
                    dGs.append(ds.eval_geometry_derivatives(geo))
                np.testing.assert_allclose(
                    np.array(Gs)[:, 0, 0],
                    self.function(r_vec, ds.cutoff), equal_nan=False)
                np.testing.assert_allclose(
                    np.array(dGs)[:, 0, 0, 1, -1],
                    self.function_derivative(r_vec, ds.cutoff),
                    atol=1e-12, equal_nan=False)
示例#9
0
        def test_derivative_numerically(self):
            with DescriptorSet(['H', 'F'], cutoff=6.5) as ds:
                for (t1, t2) in product(ds.atomtypes, repeat=2):
                    ds.add_two_body_descriptor(
                        t1, t2, 'BehlerG1', [], cuttype=self.cuttype)

                dr = 1e-5
                # deliberately chosen as to not include 6.5
                r_vec = np.linspace(0.1, 8, 81)
                dG = np.zeros_like(r_vec)
                dG_num = np.zeros_like(r_vec)
                for i, ri in enumerate(r_vec):
                    geo = [('F', np.array([0.0, 0.0, 0.0])),
                           ('H', np.array([0.0, 0.0, ri]))]
                    dG[i] = ds.eval_geometry_derivatives(geo)[0][0, 1, -1]
                    geo_p = [('F', np.array([0.0, 0.0, 0.0])),
                             ('H', np.array([0.0, 0.0, ri+dr]))]
                    geo_m = [('F', np.array([0.0, 0.0, 0.0])),
                             ('H', np.array([0.0, 0.0, ri-dr]))]
                    G_p = ds.eval_geometry(geo_p)[0][0]
                    G_m = ds.eval_geometry(geo_m)[0][0]
                    dG_num[i] = (G_p - G_m)/(2*dr)
                np.testing.assert_allclose(dG, dG_num, atol=1e-10)
示例#10
0
    def test_invariances(self):
        with DescriptorSet(['C', 'H'], cutoff=6.5) as ds:
            ds.add_Artrith_Kolpak_set()

            types = ['H', 'H', 'H', 'C', 'C', 'H', 'H', 'H']
            xyzs = np.array([[1.0217062478, 0.0000000000, 1.1651331805],
                             [-0.5108531239, 0.8848235658, 1.1651331805],
                             [-0.5108531239, -0.8848235658, 1.1651331805],
                             [0.0000000000, 0.0000000000, 0.7662728375],
                             [0.0000000000, 0.0000000000, -0.7662728375],
                             [0.5108531239, -0.8848235658, -1.1651331805],
                             [-1.0217062478, 0.0000000000, -1.1651331805],
                             [0.5108531239, 0.8848235658, -1.1651331805]])

            Gs, dGs = ds.eval_with_derivatives_atomwise(types, xyzs)
            Gs = np.asarray(Gs)
            dGs = np.asarray(dGs)

            # Test for translational invariance
            Gs_test, dGs_test = ds.eval_with_derivatives_atomwise(
                types, xyzs + 10.)
            Gs_test = np.asarray(Gs_test)
            dGs_test = np.asarray(dGs_test)
            np.testing.assert_allclose(Gs, Gs_test, atol=1E-7)
            np.testing.assert_allclose(dGs, dGs_test, atol=1E-7)

            # Test for rotational invariance
            def rotation_matrix(axis, theta):
                """
                Stolen from
                https://stackoverflow.com/questions/6802577/rotation-of-3d-vector
                Return the rotation matrix associated with counterclockwise
                rotation about the given axis by theta radians.
                """
                axis = np.asarray(axis)
                axis = axis / np.linalg.norm(axis)
                a = np.cos(theta / 2.0)
                b, c, d = -axis * np.sin(theta / 2.0)
                aa, bb, cc, dd = a * a, b * b, c * c, d * d
                bc, ad, ac, ab, bd, cd = (b * c, a * d, a * c, a * b, b * d,
                                          c * d)
                return np.array(
                    [[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
                     [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
                     [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]])

            R = rotation_matrix([2, 1, 3], np.pi / 3.)
            Gs_test, dGs_test = ds.eval_with_derivatives_atomwise(
                types, xyzs.dot(R))
            Gs_test = np.asarray(Gs_test)
            # dGs_test has to be rotated back to the original orientation
            dGs_test = np.asarray(dGs_test).dot(np.linalg.inv(R))
            np.testing.assert_allclose(Gs, Gs_test, atol=1E-7)
            np.testing.assert_allclose(dGs, dGs_test, atol=1E-7)

            # Test for rotational invariance
            xyzs = xyzs[[1, 0, 2, 4, 3, 6, 5, 7]]
            Gs_test, dGs_test = ds.eval_with_derivatives_atomwise(
                types, xyzs + 10.)
            Gs_test = np.asarray(Gs_test)
            dGs_test = np.asarray(dGs_test)
            np.testing.assert_allclose(Gs, Gs_test, atol=1E-7)
示例#11
0
import numpy as np
from mlpot.descriptors import DescriptorSet
import json

ds = DescriptorSet(['Ni', 'Pt'])
ds.add_Artrith_Kolpak_set()

types = ['Ni'] * 5 + ['Pt'] * 8
xyzs = np.array([
    -0.014480168, 0.034207338, 3.241557994, 2.898730059, -1.086507438,
    -0.962365452, 0.628479665, -3.011745934, 1.021810156, -1.106421727,
    -0.938238334, 0.966816473, 0.014835984, -0.034293064, -3.241593337,
    -2.898807639, 1.086543157, 0.962013396, 2.255579722, 1.959448215,
    1.257961041, 1.106258420, 0.938154989, -0.966654169, -2.255797799,
    -1.959412496, -1.257693960, -0.628657260, 3.011781654, -1.021547837,
    0.767345025, 2.434319406, 3.240815029, 2.475190116, 0.450660540,
    3.269695405
]).reshape((-1, 3))

Gs, dGs = ds.eval_with_derivatives(types, xyzs)
Gs = [Gi.tolist() for Gi in Gs]
dGs = [dGi.tolist() for dGi in dGs]

with open('NiPt13.json', 'w') as fout:
    json.dump({'types': types, 'Gs': Gs, 'dGs': dGs}, fout)
示例#12
0
    def test_trimer(self):
        with DescriptorSet(['Ag'], cutoff=8.0) as ds:
            types = ['Ag', 'Ag', 'Ag']

            def fcut(r):
                return 0.5 * (1.0 +
                              np.cos(np.pi * r / ds.cutoff)) * (r < ds.cutoff)

            # Parameters from Artrith and Kolpak Nano Lett. 2014, 14, 2670
            etas = np.array([0.0009, 0.01, 0.02, 0.035, 0.06, 0.1, 0.2])
            for eta in etas:
                ds.add_two_body_descriptor('Ag',
                                           'Ag',
                                           'BehlerG2', [eta, 0.0],
                                           cuttype='cos')

            ang_etas = np.array([0.0001, 0.003, 0.008])
            zetas = np.array([1.0, 4.0])
            for ang_eta in ang_etas:
                for lamb in [-1.0, 1.0]:
                    for zeta in zetas:
                        ds.add_three_body_descriptor('Ag',
                                                     'Ag',
                                                     'Ag',
                                                     'BehlerG4',
                                                     [lamb, zeta, ang_eta],
                                                     cuttype='cos')

            # Also test BehlerG5
            for ang_eta in ang_etas:
                for lamb in [-1.0, 1.0]:
                    for zeta in zetas:
                        ds.add_three_body_descriptor('Ag',
                                                     'Ag',
                                                     'Ag',
                                                     'BehlerG5',
                                                     [lamb, zeta, ang_eta],
                                                     cuttype='cos')

            N = 30
            r_vec = np.linspace(1., 5., N)
            theta_vec = np.linspace(0.0 * np.pi, 2. * np.pi, N, endpoint=True)
            for ri in r_vec:
                for ti in theta_vec:
                    xyzs = np.array([[0.0, 0.0, 0.0], [0.5 * ri, 0.0, 0.0],
                                     [ri * np.cos(ti), ri * np.sin(ti), 0.0]])

                    rij = np.linalg.norm(xyzs[0, :] - xyzs[1, :])
                    rik = np.linalg.norm(xyzs[0, :] - xyzs[2, :])
                    rjk = np.linalg.norm(xyzs[1, :] - xyzs[2, :])
                    np.testing.assert_allclose(
                        rjk,
                        np.sqrt(rij**2 + rik**2 - 2. * rij * rik * np.cos(ti)),
                        atol=1E-12)

                    Gs = ds.eval(types, xyzs)
                    Gs_atomwise = ds.eval_atomwise(types, xyzs)
                    Gs_ref = np.concatenate([
                        np.exp(-etas * rij**2) * fcut(rij) +
                        np.exp(-etas * rik**2) * fcut(rik)
                    ] + [
                        2**(1. - zetas) * np.exp(-eta *
                                                 (rij**2 + rik**2 + rjk**2)) *
                        (1. + lamb * np.cos(ti))**zetas * fcut(rij) *
                        fcut(rik) * fcut(rjk) for eta in ang_etas
                        for lamb in [-1.0, 1.0]
                    ] + [
                        2**(1. - zetas) * np.exp(-eta * (rij**2 + rik**2)) *
                        (1. + lamb * np.cos(ti))**zetas * fcut(rij) * fcut(rik)
                        for eta in ang_etas for lamb in [-1.0, 1.0]
                    ])
                    np.testing.assert_allclose(Gs,
                                               Gs_atomwise,
                                               equal_nan=False)
                    np.testing.assert_allclose(Gs[0], Gs_ref, equal_nan=False)
                    np.testing.assert_allclose(Gs_atomwise[0],
                                               Gs_ref,
                                               equal_nan=False)

                    dGs = ds.eval_derivatives(types, xyzs)
                    dGs_atomwise = ds.eval_derivatives_atomwise(types, xyzs)
                    # Adding the equal_nan=False option shows a bug for
                    # descriptors using rik as input
                    np.testing.assert_allclose(dGs,
                                               dGs_atomwise,
                                               equal_nan=False)

                    Gs, dGs = ds.eval_with_derivatives(types, xyzs)
                    Gs_atomwise, dGs_atomwise = (
                        ds.eval_with_derivatives_atomwise(types, xyzs))
                    np.testing.assert_allclose(Gs,
                                               Gs_atomwise,
                                               equal_nan=False)
                    np.testing.assert_allclose(dGs,
                                               dGs_atomwise,
                                               equal_nan=False,
                                               atol=1e-15)
示例#13
0
 def test_print_functions(self):
     with DescriptorSet(['C', 'H', 'O']) as ds:
         ds.available_descriptors()
         ds.add_Artrith_Kolpak_set()
         ds.print_descriptors()
示例#14
0
    def test_acetone(self):
        from scipy.optimize import approx_fprime
        # TODO: switch to custom implementation!
        x0 = np.array([
            0.00000,
            0.00000,
            0.00000,  # C
            1.40704,
            0.00902,
            -0.67203,  # C
            1.67062,
            -0.92069,
            -1.22124,  # H
            2.20762,
            0.06960,
            0.11291,  # H
            1.61784,
            0.88539,
            -1.32030,  # H
            -1.40732,
            -0.00378,
            -0.67926,  # C
            -1.65709,
            0.91221,
            -1.25741,  # H
            -2.20522,
            -0.03081,
            0.10912,  # H
            -1.64457,
            -0.88332,
            -1.31507,  # H
            0.00000,
            -0.00000,
            1.20367
        ])  # O
        types = ['C', 'C', 'H', 'H', 'H', 'C', 'H', 'H', 'H', 'O']

        with DescriptorSet(['C', 'H', 'O'], cutoff=7.0) as ds:
            radial_etas = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0]
            rss = [0.0] * len(radial_etas)

            angular_etas = [0.0001, 0.003, 0.008]
            lambs = [1.0, -1.0]
            zetas = [1.0, 4.0]

            ds.add_G2_functions(rss, radial_etas)
            ds.add_G5_functions(angular_etas, zetas, lambs)
            f0 = ds.eval(types, x0.reshape((-1, 3)))
            df = ds.eval_derivatives(types, x0.reshape((-1, 3)))
            eps = np.sqrt(np.finfo(float).eps)

            for i in range(len(f0)):
                for j in range(len(f0[i])):

                    def f(x):
                        return np.array(ds.eval(types, x.reshape(
                            (-1, 3))))[i][j]

                    np.testing.assert_array_almost_equal(
                        df[i][j],
                        approx_fprime(x0, f, epsilon=eps).reshape((-1, 3)))