Exemplo n.º 1
0
    def test_include(self):
        soap = SOAP(
            species=[1, 6, 8],
            rcut=3,
            nmax=2,
            lmax=1,
            rbf="gto",
            sparse=False,
            periodic=False,
        )

        for method in ["numerical", "analytical"]:
            # Invalid include options
            with self.assertRaises(ValueError):
                soap.derivatives(H2O, include=[], method=method)
            with self.assertRaises(ValueError):
                soap.derivatives(H2O, include=[3], method=method)
            with self.assertRaises(ValueError):
                soap.derivatives(H2O, include=[-1], method=method)

            # Test that correct atoms are included and in the correct order
            D1, d1 = soap.derivatives(H2O, include=[2, 0], method=method)
            D2, d2 = soap.derivatives(H2O, method=method)
            self.assertTrue(np.array_equal(D1[:, 0], D2[:, 2]))
            self.assertTrue(np.array_equal(D1[:, 1], D2[:, 0]))

            # Test that using single list and multiple samples works
            D1, d1 = soap.derivatives([H2O, CO2],
                                      include=[1, 0],
                                      method=method)
            D2, d2 = soap.derivatives([H2O, CO2], method=method)
            self.assertTrue(np.array_equal(D1[:, :, 0], D2[:, :, 1]))
            self.assertTrue(np.array_equal(D1[:, :, 1], D2[:, :, 0]))
Exemplo n.º 2
0
 def test_return_descriptor(self):
     soap = SOAP(
         species=[1, 8],
         rcut=3,
         nmax=2,
         lmax=0,
         rbf="gto",
         sparse=False,
         periodic=False,
     )
     s = soap.derivatives(H2O, method="analytical", return_descriptor=False)
     D, d = soap.derivatives(H2O,
                             method="analytical",
                             return_descriptor=True)
     s = soap.derivatives(H2O, method="numerical", return_descriptor=False)
     D, d = soap.derivatives(H2O,
                             method="numerical",
                             return_descriptor=True)
Exemplo n.º 3
0
    def test_stratification(self):
        """Tests that the ordering of the output works, especially when the
        total chemical space is larger than the chemical space of individual
        samples.
        """
        soap = SOAP(
            species=[1, 6, 5, 8, 9],
            rcut=3,
            nmax=1,
            lmax=1,
            rbf="gto",
            average="off",
            crossover=True,
        )

        derivatives_n, d_n = soap.derivatives(CO2, method="numerical")
        derivatives_a, d_a = soap.derivatives(CO2, method="analytical")
        self.assertTrue(
            np.allclose(derivatives_n, derivatives_a, rtol=1e-6, atol=1e-6))
        self.assertTrue(np.allclose(d_n, d_a, rtol=1e-6, atol=1e-6))
Exemplo n.º 4
0
 def test_descriptor_output(self):
     """Tests that the descriptor is output correctly both for numerical and
     analytical version.
     """
     soap = SOAP(
         species=["H", "O"],
         rcut=3,
         nmax=3,
         lmax=3,
         crossover=True,
     )
     positions = H2O.get_positions()
     _, d_num = soap.derivatives(H2O,
                                 positions=positions,
                                 method="numerical")
     _, d_anal = soap.derivatives(H2O,
                                  positions=positions,
                                  method="analytical")
     d = soap.create(H2O, positions=positions)
     self.assertTrue(np.allclose(d, d_num))
     self.assertTrue(np.allclose(d, d_anal))
Exemplo n.º 5
0
    def test_sparse(self):
        """Test that the sparse values are identical to the dense ones."""
        positions = H2O.get_positions()

        soap = SOAP(
            species=["H", "O"],
            rcut=3,
            nmax=1,
            lmax=1,
            sparse=False,
            crossover=False,
        )
        D_dense, d_dense = soap.derivatives(H2O,
                                            positions=positions,
                                            method="analytical")
        soap.sparse = True
        D_sparse, d_sparse = soap.derivatives(H2O,
                                              positions=positions,
                                              method="analytical")
        self.assertTrue(np.allclose(D_dense, D_sparse.todense()))
        self.assertTrue(np.allclose(d_dense, d_sparse.todense()))
Exemplo n.º 6
0
    def test_dtype(self):
        """Tests that the the specified data type is respected."""
        # Dense, float32
        soap = SOAP(species=[1, 8], rcut=3, nmax=1, lmax=1, dtype="float32")
        desc1 = soap.create(H2O)
        der, desc2 = soap.derivatives(H2O)
        self.assertTrue(desc1.dtype == np.float32)
        self.assertTrue(desc2.dtype == np.float32)
        self.assertTrue(der.dtype == np.float32)

        # Sparse, float32
        soap = SOAP(
            species=[1, 8], rcut=3, nmax=1, lmax=1, sparse=True, dtype="float32"
        )
        desc1 = soap.create(H2O)
        der, desc2 = soap.derivatives(H2O)
        self.assertTrue(desc1.dtype == np.float32)
        self.assertTrue(desc2.dtype == np.float32)
        self.assertTrue(der.dtype == np.float32)

        # Dense, float64
        soap = SOAP(species=[1, 8], rcut=3, nmax=1, lmax=1, dtype="float64")
        desc1 = soap.create(H2O)
        der, desc2 = soap.derivatives(H2O)
        self.assertTrue(desc1.dtype == np.float64)
        self.assertTrue(desc2.dtype == np.float64)
        self.assertTrue(der.dtype == np.float64)

        # Sparse, float64
        soap = SOAP(
            species=[1, 8], rcut=3, nmax=1, lmax=1, sparse=True, dtype="float64"
        )
        desc1 = soap.create(H2O)
        der, desc2 = soap.derivatives(H2O)
        self.assertTrue(desc1.dtype == np.float64)
        self.assertTrue(desc2.dtype == np.float64)
        self.assertTrue(der.dtype == np.float64)
Exemplo n.º 7
0
 def test_crossover(self):
     """Tests the analytical soap derivatives implementation with crossover
     against the numerical implementation.
     """
     soap = SOAP(
         species=["H", "O"],
         rcut=3,
         nmax=9,
         lmax=9,
         sparse=False,
         crossover=True,
     )
     positions = H2O.get_positions()
     derivatives_cpp, d_num = soap.derivatives(H2O,
                                               positions=positions,
                                               method="numerical")
     derivatives_anal, d_anal = soap.derivatives(H2O,
                                                 positions=positions,
                                                 method="analytical")
     self.assertTrue(
         np.allclose(derivatives_cpp,
                     derivatives_anal,
                     rtol=1e-6,
                     atol=1e-6))
Exemplo n.º 8
0
def soap_sparse_vs_dense(version):
    """Tests sparse vs. dense derivatives calculation.
    """
    nmax = 4
    lmax = 4
    fig = mpl.figure(figsize=[9, 7])
    ax = fig.add_subplot(111)
    ax.set_title("SOAP derivatives nmax={}, lmax={}, version={}".format(
        nmax, lmax, version))
    ax.set_xlabel("Number of atoms")
    ax.set_ylabel("Time (s)")
    system = system_periodic * (5, 5, 5)

    # Loop over different system sizes
    vals = []
    for sparse in [True, False]:
        N = []
        t = []
        for ncells in tqdm(range(1, 6)):
            soap_generator = SOAP(
                rcut=3.0,
                nmax=nmax,
                lmax=lmax,
                species=["Ni", "Ti"],
                rbf="gto",
                crossover=True,
                periodic=False,
                sparse=sparse,
            )

            i_system = system.copy() * [ncells, 1, 1]
            t0 = time()
            der, des = soap_generator.derivatives(i_system,
                                                  method="analytical")
            vals.append(der)
            t1 = time()
            N.append(len(i_system))
            t.append(t1 - t0)
        ax.plot(N, t, "o--", label="sparse={}".format(sparse))

    mpl.legend()
    mpl.show()
Exemplo n.º 9
0
def soap_derivatives(version):
    """Tests how the SOAP derivative calculation (numerical+analytical) scales
    with system size.
    """
    nmax = 4
    lmax = 4
    fig = mpl.figure(figsize=[9, 7])
    ax = fig.add_subplot(111)
    ax.set_title("SOAP derivatives nmax={}, lmax={}, version={}".format(nmax, lmax, version))
    ax.set_xlabel("lmax")
    ax.set_ylabel("Time (s)")
    system = system_periodic*(5,5,5)

    for method in ["numerical", "analytical"]:
        N = []
        t = []
        for ncells in tqdm(range(1, 5)):
            i_system = system.copy() * [ncells, 1, 1]
            soap_generator = SOAP(
                rcut=3.0,
                nmax=nmax,
                lmax=lmax,
                species=["Ni", "Ti"],
                rbf="gto",
                crossover=True,
                periodic=False
            )

            t0 = time()
            der, des = soap_generator.derivatives(i_system, method=method)
            t1 = time()
            N.append(len(i_system))
            t.append(t1 - t0)

        ax.plot(N, t, "o--", label="{}".format(method))

    mpl.legend()
    mpl.show()
Exemplo n.º 10
0
import numpy as np
from ase.build import molecule
from dscribe.descriptors import SOAP
from dscribe.descriptors import CoulombMatrix

# Define atomic structures
samples = [molecule("H2O"), molecule("NO2"), molecule("CO2")]

# Setup descriptors
cm_desc = CoulombMatrix(n_atoms_max=3, permutation="sorted_l2")
soap_desc = SOAP(species=["C", "H", "O", "N"], rcut=5, nmax=8, lmax=6, crossover=True)

# Create descriptors as numpy arrays or sparse arrays
water = samples[0]
coulomb_matrix = cm_desc.create(water)
soap = soap_desc.create(water, positions=[0])

# Easy to use also on multiple systems, can be parallelized across processes
coulomb_matrices = cm_desc.create(samples)
coulomb_matrices = cm_desc.create(samples, n_jobs=3)
oxygen_indices = [np.where(x.get_atomic_numbers() == 8)[0] for x in samples]
oxygen_soap = soap_desc.create(samples, oxygen_indices, n_jobs=3)

# Some descriptors also allow calculating derivatives with respect to atomic
# positions
der, des = soap_desc.derivatives(samples, method="auto", return_descriptor=True)
Exemplo n.º 11
0
    def test_combinations(self):
        """Tests that different combinations of centers/atoms work as intended
        and are equal between analytical/numerical code.
        """
        # Elaborate test system with multiple species, non-cubic cell, and
        # close-by atoms.
        a = 1
        system = (Atoms(
            symbols=["C", "C", "C"],
            cell=[[0, a, a], [a, 0, a], [a, a, 0]],
            scaled_positions=[
                [0, 0, 0],
                [1 / 3, 1 / 3, 1 / 3],
                [2 / 3, 2 / 3, 2 / 3],
            ],
            pbc=[True, True, True],
        ) * (3, 3, 3))

        soap = SOAP(
            species=[6],
            rcut=3,
            nmax=1,
            lmax=1,
            rbf="gto",
            sparse=False,
            average="off",
            crossover=True,
            periodic=False,
        )
        centers = [5, 3, 4]
        include = [3, 0, 2]

        # The typical full set: derivatives for all atoms, all atoms act as
        # centers.
        derivatives_n, d_n = soap.derivatives(system, method="numerical")
        derivatives_a, d_a = soap.derivatives(system, method="analytical")
        self.assertTrue(
            np.allclose(derivatives_n, derivatives_a, rtol=1e-6, atol=1e-6))
        self.assertTrue(np.allclose(d_n, d_a, rtol=1e-6, atol=1e-6))

        # Derivatives for all atoms, only some atoms act as centers
        derivatives_n, d_n = soap.derivatives(system,
                                              positions=centers,
                                              method="numerical")
        derivatives_a, d_a = soap.derivatives(system,
                                              positions=centers,
                                              method="analytical")
        self.assertTrue(
            np.allclose(derivatives_n, derivatives_a, rtol=1e-6, atol=1e-6))
        self.assertTrue(np.allclose(d_n, d_a, rtol=1e-6, atol=1e-6))

        # Derivatives for some atoms, all atoms act as centers
        derivatives_n, d_n = soap.derivatives(system,
                                              include=include,
                                              method="numerical")
        derivatives_a, d_a = soap.derivatives(system,
                                              include=include,
                                              method="analytical")
        self.assertTrue(
            np.allclose(derivatives_n, derivatives_a, rtol=1e-6, atol=1e-6))
        self.assertTrue(np.allclose(d_n, d_a, rtol=1e-6, atol=1e-6))

        # Mixed set of derivatives and centers
        derivatives_n, d_n = soap.derivatives(system,
                                              positions=centers,
                                              include=include,
                                              method="numerical")
        derivatives_a, d_a = soap.derivatives(system,
                                              positions=centers,
                                              include=include,
                                              method="analytical")
        self.assertTrue(
            np.allclose(derivatives_n, derivatives_a, rtol=1e-6, atol=1e-6))
        self.assertTrue(np.allclose(d_n, d_a, rtol=1e-6, atol=1e-6))
Exemplo n.º 12
0
    def test_exceptions(self):
        """Test the derivative interface."""
        soap = SOAP(
            species=[1, 8],
            rcut=3,
            nmax=2,
            lmax=0,
            sparse=False,
        )
        positions = [[0.0, 0.0, 0.0]]

        # Test that trying to get analytical derivatives with averaged output
        # raises an exception
        soap.sparse = False
        soap.average = "inner"
        with self.assertRaises(ValueError):
            soap.derivatives(H2, positions=positions, method="analytical")
        soap.average = "off"

        # Test that trying to get analytical derivatives with polynomial basis
        # raises an exception, but the numerical ones work.
        soap_poly = SOAP(
            species=[1, 8],
            rcut=3,
            nmax=2,
            lmax=0,
            rbf="polynomial",
            sparse=False,
        )
        with self.assertRaises(ValueError):
            soap_poly.derivatives(H2, positions=positions, method="analytical")
        soap_poly.derivatives(H2, positions=positions, method="numerical")

        # Test that trying to provide both include and exclude raises an error
        with self.assertRaises(ValueError):
            soap.derivatives(H2, include=[0], exclude=[1])

        # Test that trying to get derivatives with periodicicity on raises an
        # exception
        soap = SOAP(
            species=[1, 8],
            rcut=3,
            nmax=2,
            lmax=0,
            rbf="gto",
            sparse=False,
            periodic=True,
        )
        with self.assertRaises(ValueError):
            soap.derivatives(H2, positions=positions, method="analytical")
        with self.assertRaises(ValueError):
            soap.derivatives(H2, positions=positions, method="numerical")
Exemplo n.º 13
0
    def test_numerical(self):
        """Test numerical values against a naive python implementation."""
        # Elaborate test system with multiple species, non-cubic cell, and
        # close-by atoms.
        a = 1
        system = (Atoms(
            symbols=["C", "H", "O"],
            cell=[[0, a, a], [a, 0, a], [a, a, 0]],
            scaled_positions=[
                [0, 0, 0],
                [1 / 3, 1 / 3, 1 / 3],
                [2 / 3, 2 / 3, 2 / 3],
            ],
            pbc=[True, True, True],
        ) * (3, 3, 3))
        # view(system)

        # Two centers: one in the middle, one on the edge.
        centers = [np.sum(system.get_cell(), axis=0) / 2, [0, 0, 0]]

        h = 0.0001
        n_atoms = len(system)
        n_comp = 3

        # The maximum error depends on how big the system is. With a small
        # system the error is smaller for non-periodic systems than the
        # corresponding error when periodicity is turned on. The errors become
        # equal (~1e-5) when the size of the system is increased.
        for periodic in [False]:
            for rbf in ["gto", "polynomial"]:
                for average in ["off", "outer", "inner"]:
                    soap = SOAP(
                        species=[1, 8, 6],
                        rcut=3,
                        nmax=4,
                        lmax=4,
                        rbf=rbf,
                        sparse=False,
                        average=average,
                        crossover=True,
                        periodic=periodic,
                        dtype=
                        "float64",  # The numerical derivatives require double precision
                    )
                    n_features = soap.get_number_of_features()
                    if average != "off":
                        n_centers = 1
                        derivatives_python = np.zeros(
                            (n_atoms, n_comp, n_features))
                    else:
                        n_centers = len(centers)
                        derivatives_python = np.zeros(
                            (n_centers, n_atoms, n_comp, n_features))
                    d0 = soap.create(system, centers)
                    coeffs = [-1.0 / 2.0, 1.0 / 2.0]
                    deltas = [-1.0, 1.0]
                    for i_atom in range(len(system)):
                        for i_center in range(n_centers):
                            for i_comp in range(3):
                                for i_stencil in range(2):
                                    if average == "off":
                                        i_cent = [centers[i_center]]
                                    else:
                                        i_cent = centers
                                    system_disturbed = system.copy()
                                    i_pos = system_disturbed.get_positions()
                                    i_pos[i_atom,
                                          i_comp] += h * deltas[i_stencil]
                                    system_disturbed.set_positions(i_pos)
                                    d1 = soap.create(system_disturbed, i_cent)
                                    if average != "off":
                                        derivatives_python[
                                            i_atom,
                                            i_comp, :] += (coeffs[i_stencil] *
                                                           d1 / h)
                                    else:
                                        derivatives_python[
                                            i_center, i_atom,
                                            i_comp, :] += (coeffs[i_stencil] *
                                                           d1[0, :] / h)

                    # Calculate with central finite difference implemented in C++.
                    # Try both cartesian centers and indices.
                    for c in [centers]:
                        derivatives_cpp, d_cpp = soap.derivatives(
                            system, positions=c, method="numerical")

                        # Test that descriptor values are correct
                        self.assertTrue(np.allclose(d0, d_cpp, atol=1e-6))

                        # Compare values
                        # print(np.abs(derivatives_python).max())
                        # print(derivatives_python[0,1,:,:])
                        # print(derivatives_cpp[0,0,:,:])
                        self.assertTrue(
                            np.allclose(derivatives_python,
                                        derivatives_cpp,
                                        atol=2e-5))
Exemplo n.º 14
0
    def test_parallel(self):
        """Tests parallel output validity for both dense and sparse output."""
        for sparse in [False, True]:
            desc = SOAP(
                species=[1, 6, 7, 8],
                rcut=5,
                nmax=3,
                lmax=3,
                sigma=1,
                periodic=False,
                crossover=True,
                average="off",
                sparse=sparse,
            )
            n_features = desc.get_number_of_features()

            samples = [molecule("CO"), molecule("NO"), molecule("OH")]
            centers = [[0], [0], [0]]

            # Determining number of jobs based on the amount of CPUs
            # desc.derivatives(system=samples, n_jobs=-1, only_physical_cores=False)
            # desc.derivatives(system=samples, n_jobs=-1, only_physical_cores=True)

            # Perhaps most common scenario: more systems than jobs, using all
            # centers and indices
            der, des = desc.derivatives(
                system=samples,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 2, 2, 3, n_features))
            self.assertTrue(des.shape == (3, 2, n_features))
            assumed_der = np.empty((3, 2, 2, 3, n_features))
            assumed_des = np.empty((3, 2, n_features))
            desc.sparse = False
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0],
                                                                    n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1],
                                                                    n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2],
                                                                    n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # More systems than jobs, using all centers and indices, not requesting
            # descriptors
            der = desc.derivatives(
                system=samples,
                return_descriptor=False,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 2, 2, 3, n_features))
            assumed_der = np.empty((3, 2, 2, 3, n_features))
            desc._sparse = False
            assumed_der[0, :] = desc.derivatives(samples[0],
                                                 n_jobs=1,
                                                 return_descriptor=False)
            assumed_der[1, :] = desc.derivatives(samples[1],
                                                 n_jobs=1,
                                                 return_descriptor=False)
            assumed_der[2, :] = desc.derivatives(samples[2],
                                                 n_jobs=1,
                                                 return_descriptor=False)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
            self.assertTrue(np.allclose(assumed_der, der))

            # More systems than jobs, using custom indices as centers
            der, des = desc.derivatives(
                system=samples,
                positions=centers,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 1, 2, 3, n_features))
            self.assertTrue(des.shape == (3, 1, n_features))
            assumed_der = np.empty((3, 1, 2, 3, n_features))
            assumed_des = np.empty((3, 1, n_features))
            desc._sparse = False
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0],
                                                                    centers[0],
                                                                    n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1],
                                                                    centers[1],
                                                                    n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2],
                                                                    centers[2],
                                                                    n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # More systems than jobs, using custom cartesian centers
            centers = [[[0, 1, 2]], [[2, 1, 0]], [[1, 2, 0]]]
            der, des = desc.derivatives(
                system=samples,
                positions=centers,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 1, 2, 3, n_features))
            self.assertTrue(des.shape == (3, 1, n_features))
            assumed_der = np.empty((3, 1, 2, 3, n_features))
            assumed_des = np.empty((3, 1, n_features))
            desc._sparse = False
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0],
                                                                    centers[0],
                                                                    n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1],
                                                                    centers[1],
                                                                    n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2],
                                                                    centers[2],
                                                                    n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # Includes
            includes = [[0], [0], [0]]
            der, des = desc.derivatives(
                system=samples,
                include=includes,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 2, 1, 3, n_features))
            self.assertTrue(des.shape == (3, 2, n_features))
            assumed_der = np.empty((3, 2, 1, 3, n_features))
            assumed_des = np.empty((3, 2, n_features))
            desc._sparse = False
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(
                samples[0], include=includes[0], n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(
                samples[1], include=includes[1], n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(
                samples[2], include=includes[2], n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # Excludes
            excludes = [[0], [0], [0]]
            der, des = desc.derivatives(
                system=samples,
                exclude=excludes,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 2, 1, 3, n_features))
            self.assertTrue(des.shape == (3, 2, n_features))
            assumed_der = np.empty((3, 2, 1, 3, n_features))
            assumed_des = np.empty((3, 2, n_features))
            desc._sparse = False
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(
                samples[0], exclude=excludes[0], n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(
                samples[1], exclude=excludes[1], n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(
                samples[2], exclude=excludes[2], n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # Test averaged output
            desc.average = "inner"
            positions = [[0], [0, 1], [1]]
            der, des = desc.derivatives(
                system=samples,
                positions=positions,
                n_jobs=2,
            )
            self.assertTrue(der.shape == (3, 1, 2, 3, n_features))
            self.assertTrue(des.shape == (3, 1, n_features))
            desc._sparse = False
            assumed_der = np.empty((3, 1, 2, 3, n_features))
            assumed_des = np.empty((3, 1, n_features))
            assumed_der[0, :], assumed_des[0, :] = desc.derivatives(
                samples[0], positions=positions[0], n_jobs=1)
            assumed_der[1, :], assumed_des[1, :] = desc.derivatives(
                samples[1], positions=positions[1], n_jobs=1)
            assumed_der[2, :], assumed_des[2, :] = desc.derivatives(
                samples[2], positions=positions[2], n_jobs=1)
            desc._sparse = sparse
            if sparse:
                der = der.todense()
                des = des.todense()
            self.assertTrue(np.allclose(assumed_der, der))
            self.assertTrue(np.allclose(assumed_des, des))

            # Variable size list output, as the systems have a different size
            desc.average = "off"
            samples = [molecule("CO"), molecule("NO2"), molecule("OH")]
            der, des = desc.derivatives(
                system=samples,
                n_jobs=2,
            )
            self.assertTrue(isinstance(der, list))
            self.assertTrue(der[0].shape == (2, 2, 3, n_features))
            self.assertTrue(der[1].shape == (3, 3, 3, n_features))
            self.assertTrue(der[2].shape == (2, 2, 3, n_features))
            desc._sparse = False
            for i in range(len(samples)):
                assumed_der, assumed_des = desc.derivatives(samples[i],
                                                            n_jobs=1)
                i_der = der[i]
                i_des = des[i]
                if sparse:
                    i_der = i_der.todense()
                    i_des = i_des.todense()
                self.assertTrue(np.allclose(assumed_der, i_der))
                self.assertTrue(np.allclose(assumed_des, i_des))
            desc._sparse = sparse
Exemplo n.º 15
0
energies = np.zeros(n_samples)
forces = np.zeros((n_samples, n_atoms, 3))
r = np.linspace(2.5, 5.0, n_samples)
for i, d in enumerate(r):
    a = ase.Atoms('HH', positions=[[-0.5 * d, 0, 0], [0.5 * d, 0, 0]])
    a.set_calculator(LennardJones(epsilon=1.0, sigma=2.9))
    traj.append(a)
    energies[i] = a.get_total_energy()
    forces[i, :, :] = a.get_forces()

# Plot the energies to validate them
fig, ax = plt.subplots(figsize=(8, 5))
plt.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.1)
line, = ax.plot(r, energies)
plt.xlabel("Distance (Å)")
plt.ylabel("Energy (eV)")
plt.show()

# Create the SOAP desciptors and their derivatives for all samples. One center
# is chosen to be directly between the atoms.
derivatives, descriptors = soap.derivatives(traj,
                                            positions=[[[0, 0, 0]]] * len(r),
                                            method="analytical")

# Save to disk for later training
np.save("r.npy", r)
np.save("E.npy", energies)
np.save("D.npy", descriptors)
np.save("dD_dr.npy", derivatives)
np.save("F.npy", forces)